From f03d1d161a1c5b5d9024e2eb7214567c0db1d240 Mon Sep 17 00:00:00 2001 From: elliot Date: Fri, 1 May 2026 11:53:41 -0400 Subject: [PATCH 1/8] Add basic offline support with a service worker --- hub-client/OFFLINE.md | 95 + hub-client/package.json | 2 + hub-client/vite.config.ts | 58 +- package-lock.json | 11264 ++++++++++++++++++++++++------------ 4 files changed, 7745 insertions(+), 3674 deletions(-) create mode 100644 hub-client/OFFLINE.md diff --git a/hub-client/OFFLINE.md b/hub-client/OFFLINE.md new file mode 100644 index 000000000..e41066e8b --- /dev/null +++ b/hub-client/OFFLINE.md @@ -0,0 +1,95 @@ +# Offline Support + +Quarto Hub includes offline support via Vite PWA plugin powered by Workbox. + +## How it works + +The service worker is automatically generated at build time by `vite-plugin-pwa` and provides: + +1. **App shell precaching**: HTML and icon are precached on first visit +2. **Runtime caching**: JS, CSS, and fonts are cached as they're loaded +3. **Automatic updates**: Service worker auto-updates when new versions are deployed +4. **Google Fonts caching**: External fonts are cached for offline use + +## Caching strategy + +### Precached (available immediately on first load) +Everything is precached during service worker installation (~44 MB total): +- All HTML pages (`index.html`, `debug.html`, `ast-renderer.html`) +- All JavaScript bundles (including 3MB+ main bundles) +- All CSS files +- All WASM files (including 32MB quarto parser + 2MB Automerge WASM) +- All local fonts (.woff, .woff2) +- Icons and SVG assets + +### Runtime cached (external resources) + +- **Google Fonts CSS** - `CacheFirst` + - Cached permanently once loaded + - 1-year expiration, max 10 entries + +- **Google Fonts files** - `CacheFirst` + - Cached permanently once loaded + - 1-year expiration, max 10 entries + +## Why precache everything? + +Service workers don't control a page until the **second navigation**. On first visit: +1. Page loads normally from network +2. Service worker installs in background +3. Service worker is "waiting" and doesn't intercept requests yet + +This means runtime caching (NetworkFirst, etc.) **doesn't work** until the second visit. + +By precaching all assets during service worker installation: +- ✅ First visit: installs in background while page loads +- ✅ Refresh (even offline): everything loads from cache immediately +- ✅ No "second visit" needed - works offline right away + +## Limitations + +This is **basic offline support** - it provides: +- ✅ App shell loads when offline (after first visit) +- ✅ Previously loaded pages/assets work offline +- ❌ No offline editing (requires server connection for Automerge sync) +- ❌ No background sync +- ❌ No push notifications + +## Development + +The service worker only registers in production builds. During development (`npm run dev`), it's disabled to avoid caching issues. + +## Testing offline behavior + +1. Build for production: `npm run build` +2. Serve the build: `npm run preview` +3. Open http://localhost:4173 in browser +4. Open DevTools → Application → Service Workers to verify registration +5. Navigate around the app to populate cache +6. Enable "Offline" mode in DevTools → Network tab +7. Reload the page - it should load from cache + +## Configuration + +PWA settings are in `vite.config.ts`: + +```typescript +VitePWA({ + registerType: 'autoUpdate', + workbox: { + globPatterns: ['**/*.{html,svg}'], + maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, + runtimeCaching: [/* ... */] + } +}) +``` + +## Cache management + +The service worker automatically: +- Updates when new versions are deployed +- Cleans up old caches +- Enforces size limits (max entries, max age) +- Handles cache storage quota exceeded errors + +No manual cache version bumping is required - Workbox handles versioning automatically. diff --git a/hub-client/package.json b/hub-client/package.json index d2f8b5994..7ff0adcaa 100644 --- a/hub-client/package.json +++ b/hub-client/package.json @@ -73,8 +73,10 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.46.4", "vite": "^7.2.4", + "vite-plugin-pwa": "^1.2.0", "vite-plugin-wasm": "^3.5.0", "vitest": "^4.0.17", + "workbox-window": "^7.4.0", "ws": "^8.19.0", "yaml": "^2.8.2" } diff --git a/hub-client/vite.config.ts b/hub-client/vite.config.ts index fd63b5e1b..d086eddc7 100644 --- a/hub-client/vite.config.ts +++ b/hub-client/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import wasm from 'vite-plugin-wasm' +import { VitePWA } from 'vite-plugin-pwa' import path from 'path' import { execSync } from 'child_process' @@ -24,7 +25,62 @@ export default defineConfig({ base: './', plugins: [ react(), - wasm() + wasm(), + VitePWA({ + registerType: 'autoUpdate', + includeAssets: ['quarto-icon.svg'], + manifest: { + name: 'Quarto Hub', + short_name: 'Quarto Hub', + description: 'Collaborative editing for Quarto projects', + theme_color: '#447099', + icons: [ + { + src: 'quarto-icon.svg', + sizes: 'any', + type: 'image/svg+xml' + } + ] + }, + workbox: { + // Precache all static assets including JS/CSS bundles and WASM + globPatterns: ['**/*.{html,js,css,svg,woff,woff2,wasm}'], + // Increase limit to 35MB to include WASM files (largest is ~32MB) + maximumFileSizeToCacheInBytes: 35 * 1024 * 1024, + // Don't warn about large files - we know they're big + dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, + runtimeCaching: [ + { + urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i, + handler: 'CacheFirst', + options: { + cacheName: 'google-fonts-cache', + expiration: { + maxEntries: 10, + maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year + }, + cacheableResponse: { + statuses: [0, 200] + } + } + }, + { + urlPattern: /^https:\/\/fonts\.gstatic\.com\/.*/i, + handler: 'CacheFirst', + options: { + cacheName: 'google-fonts-static', + expiration: { + maxEntries: 10, + maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year + }, + cacheableResponse: { + statuses: [0, 200] + } + } + } + ] + } + }) ], define: { __GIT_COMMIT_HASH__: JSON.stringify(gitInfo.commitHash), diff --git a/package-lock.json b/package-lock.json index 90c8aa575..e12d29a7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,8 +71,10 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.46.4", "vite": "^7.2.4", + "vite-plugin-pwa": "^1.2.0", "vite-plugin-wasm": "^3.5.0", "vitest": "^4.0.17", + "workbox-window": "^7.4.0", "ws": "^8.19.0", "yaml": "^2.8.2" } @@ -357,6 +359,7 @@ "version": "8.50.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/types": "8.50.1", @@ -559,17 +562,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "hub-client/node_modules/acorn": { - "version": "8.15.0", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "hub-client/node_modules/acorn-jsx": { "version": "5.3.2", "dev": true, @@ -612,10 +604,6 @@ "dev": true, "license": "Python-2.0" }, - "hub-client/node_modules/async": { - "version": "3.2.6", - "license": "MIT" - }, "hub-client/node_modules/brace-expansion": { "version": "1.1.12", "dev": true, @@ -661,24 +649,10 @@ "hub-client/node_modules/dompurify": { "version": "3.2.7", "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, - "hub-client/node_modules/ejs": { - "version": "3.1.10", - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "hub-client/node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -694,6 +668,7 @@ "version": "9.39.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -846,19 +821,6 @@ "node": ">=4.0" } }, - "hub-client/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "hub-client/node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, "hub-client/node_modules/fast-levenshtein": { "version": "2.0.6", "dev": true, @@ -875,30 +837,6 @@ "node": ">=16.0.0" } }, - "hub-client/node_modules/filelist": { - "version": "1.0.4", - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "hub-client/node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "hub-client/node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "hub-client/node_modules/find-up": { "version": "5.0.0", "dev": true, @@ -997,21 +935,6 @@ "node": ">=0.8.19" } }, - "hub-client/node_modules/jake": { - "version": "10.9.4", - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "hub-client/node_modules/js-yaml": { "version": "4.1.1", "dev": true, @@ -1080,7 +1003,6 @@ "hub-client/node_modules/marked": { "version": "14.0.0", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -1296,6 +1218,23 @@ "dev": true, "license": "MIT" }, + "node_modules/@apideck/better-ajv-errors": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.7.tgz", + "integrity": "sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonpointer": "^5.0.1", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", @@ -1408,9 +1347,9 @@ "license": "MIT" }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "dev": true, "license": "MIT", "engines": { @@ -1423,6 +1362,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -1475,6 +1415,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", @@ -1512,6 +1465,83 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", + "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.29.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -1522,6 +1552,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", @@ -1554,6 +1598,19 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", @@ -1564,6 +1621,56 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -1592,6 +1699,21 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helpers": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", @@ -1621,26 +1743,27 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", "dependencies": { @@ -1650,1470 +1773,1467 @@ "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/standalone": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.29.2.tgz", - "integrity": "sha512-VSuvywmVRS8efooKrvJzs6BlVSxRvAdLeGrAKUrWoBx1fFBSeE/oBpUZCQ5BcprLyXy04W8skzz7JT8GqlNRJg==", + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", + "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", + "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0" } }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.29.0" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/accessibility": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", - "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.0.0" + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/core": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", - "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "dev": true, "license": "MIT", "dependencies": { - "@dnd-kit/accessibility": "^3.1.1", - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/sortable": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", - "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "dev": true, "license": "MIT", "dependencies": { - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@dnd-kit/core": "^6.3.0", - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/utilities": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", - "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0" + "@babel/core": "^7.12.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", - "cpu": [ - "loong64" - ], + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, "engines": { - "node": ">=18" - } + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", - "cpu": [ - "mips64el" - ], + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", - "cpu": [ - "riscv64" - ], + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", - "cpu": [ - "s390x" - ], + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@hono/node-server": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", - "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18.14.1" + "node": ">=6.9.0" }, "peerDependencies": { - "hono": "^4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", - "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", - "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=6.9.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "hasInstallScript": true, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=6.9.0" }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", - "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", - "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", - "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", - "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", - "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", - "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", - "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", - "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", - "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", - "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", - "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/preset-env": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.3.tgz", + "integrity": "sha512-ySZypNLAIH1ClygLDQzVMoGQRViATnkHkYYV6TcNDz+8+jwZCdsguGvsb3EY5d9wyWyhmF1iSuFM0Yh5XPnqSA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/compat-data": "^7.29.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", - "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@playwright/test": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", - "integrity": "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==", - "dev": true, - "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@quarto/annotated-qmd": { - "resolved": "ts-packages/annotated-qmd", - "link": true - }, - "node_modules/@quarto/hub-mcp": { - "resolved": "ts-packages/quarto-hub-mcp", - "link": true - }, - "node_modules/@quarto/pandoc-types": { - "resolved": "ts-packages/pandoc-types", - "link": true - }, - "node_modules/@quarto/quarto-automerge-schema": { - "resolved": "ts-packages/quarto-automerge-schema", - "link": true - }, - "node_modules/@quarto/quarto-sync-client": { - "resolved": "ts-packages/quarto-sync-client", - "link": true - }, - "node_modules/@quarto/sync-test-harness": { - "resolved": "ts-packages/sync-test-harness", - "link": true - }, - "node_modules/@quarto/trace-viewer": { - "resolved": "trace-viewer", - "link": true - }, - "node_modules/@react-oauth/google": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.13.4.tgz", - "integrity": "sha512-hGKyNEH+/PK8M0sFEuo3MAEk0txtHpgs94tDQit+s2LXg7b6z53NtzHfqDvoB2X8O6lGB+FRg80hY//X6hfD+w==", + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@revealjs/react": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@revealjs/react/-/react-0.2.0.tgz", - "integrity": "sha512-kIxl5rCttlVJFeSnWJostA80IbhuM5+GO2yjs6yHOpesyIuzpCZjsNjX1s+5bbb1BGwEIAbuE04KPLWxZR1XAw==", + "node_modules/@babel/standalone": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.29.2.tgz", + "integrity": "sha512-VSuvywmVRS8efooKrvJzs6BlVSxRvAdLeGrAKUrWoBx1fFBSeE/oBpUZCQ5BcprLyXy04W8skzz7JT8GqlNRJg==", "license": "MIT", - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18", - "reveal.js": ">=5" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", - "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", - "cpu": [ - "arm" - ], + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", - "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", - "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", - "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", - "cpu": [ - "x64" - ], + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", - "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ - "freebsd" + "darwin" ] }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", - "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", "cpu": [ "x64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", - "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", - "cpu": [ - "arm" - ], - "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ] }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", - "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", - "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", - "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", "cpu": [ - "arm64" + "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", - "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", "cpu": [ - "loong64" + "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ] }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", - "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", - "cpu": [ - "loong64" + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", - "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", - "cpu": [ - "ppc64" + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", - "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", + "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", + "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@dnd-kit/accessibility": "^3.1.1", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", + "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -3121,69 +3241,84 @@ "license": "MIT", "optional": true, "os": [ - "linux" - ] + "aix" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", - "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ - "riscv64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "android" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", - "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ - "riscv64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "android" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", - "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ - "s390x" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "android" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", - "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", - "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -3191,13 +3326,33 @@ "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", - "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -3205,27 +3360,33 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" - ] + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", - "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ - "arm64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "openharmony" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", - "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -3233,13 +3394,16 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", - "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -3247,13 +3411,101 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", - "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -3261,13 +3513,33 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", - "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -3275,699 +3547,3721 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", + "integrity": "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@quarto/annotated-qmd": { + "resolved": "ts-packages/annotated-qmd", + "link": true + }, + "node_modules/@quarto/hub-mcp": { + "resolved": "ts-packages/quarto-hub-mcp", + "link": true + }, + "node_modules/@quarto/pandoc-types": { + "resolved": "ts-packages/pandoc-types", + "link": true + }, + "node_modules/@quarto/quarto-automerge-schema": { + "resolved": "ts-packages/quarto-automerge-schema", + "link": true + }, + "node_modules/@quarto/quarto-sync-client": { + "resolved": "ts-packages/quarto-sync-client", + "link": true + }, + "node_modules/@quarto/sync-test-harness": { + "resolved": "ts-packages/sync-test-harness", + "link": true + }, + "node_modules/@quarto/trace-viewer": { + "resolved": "trace-viewer", + "link": true + }, + "node_modules/@react-oauth/google": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.13.4.tgz", + "integrity": "sha512-hGKyNEH+/PK8M0sFEuo3MAEk0txtHpgs94tDQit+s2LXg7b6z53NtzHfqDvoB2X8O6lGB+FRg80hY//X6hfD+w==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@revealjs/react": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@revealjs/react/-/react-0.2.0.tgz", + "integrity": "sha512-kIxl5rCttlVJFeSnWJostA80IbhuM5+GO2yjs6yHOpesyIuzpCZjsNjX1s+5bbb1BGwEIAbuE04KPLWxZR1XAw==", + "license": "MIT", + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18", + "reveal.js": ">=5" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__standalone": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__standalone/-/babel__standalone-7.1.9.tgz", + "integrity": "sha512-IcCNPLqpevUD7UpV8QB0uwQPOyoOKACFf0YtYWRHcmxcakaje4Q7dbG2+jMqxw/I8Zk0NHvEps66WwS7z/UaaA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.6", + "@babel/types": "^7.25.6", + "@types/babel__core": "^7.20.5", + "@types/babel__generator": "^7.6.8", + "@types/babel__template": "^7.4.4", + "@types/babel__traverse": "^7.20.6" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "license": "MIT" + }, + "node_modules/@types/morphdom": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/morphdom/-/morphdom-2.3.0.tgz", + "integrity": "sha512-xDWhsCHpQLCLKmJYjm2txI9VRU6mWuqOitkj+VNgb4SSu1jrPR/jgwPzKojQInM1AzSDiHwQ3ZenUygr50axsw==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz", + "integrity": "sha512-/6zU2FLGg0jsd+ePZcwHRy3+WpNTBBhDY56P4JTRqUN/Dp6CvOEa9HrikcQ4KfV2b2kAHUFB4dl1SuocWXSFEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.17", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.17", + "vitest": "4.0.17" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz", + "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz", + "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.17", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz", + "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz", + "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz", + "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.17", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz", + "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz", + "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.17", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", + "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", + "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^5.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001774", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", + "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, + "node_modules/cbor-x": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "license": "MIT", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fake-indexeddb": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.2.5.tgz", + "integrity": "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "license": "Apache-2.0" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-sha256": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", + "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", + "license": "Unlicense" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "license": "MIT" }, - "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", - "dev": true, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "picocolors": "1.1.1", - "pretty-format": "^27.0.2" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { - "node": ">=18" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "@adobe/css-tools": "^4.4.0", - "aria-query": "^5.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "picocolors": "^1.1.1", - "redent": "^3.0.0" + "is-callable": "^1.2.7" }, "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/@testing-library/react": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", - "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.5" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@testing-library/dom": "^10.0.0", - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "node": ">=10" } }, - "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=12", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "peer": true + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/babel__standalone": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__standalone/-/babel__standalone-7.1.9.tgz", - "integrity": "sha512-IcCNPLqpevUD7UpV8QB0uwQPOyoOKACFf0YtYWRHcmxcakaje4Q7dbG2+jMqxw/I8Zk0NHvEps66WwS7z/UaaA==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.6", - "@babel/types": "^7.25.6", - "@types/babel__core": "^7.20.5", - "@types/babel__generator": "^7.6.8", - "@types/babel__template": "^7.4.4", - "@types/babel__traverse": "^7.20.6" + "engines": { + "node": ">= 0.4" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, - "license": "MIT" - }, - "node_modules/@types/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", - "license": "MIT" - }, - "node_modules/@types/morphdom": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/morphdom/-/morphdom-2.3.0.tgz", - "integrity": "sha512-xDWhsCHpQLCLKmJYjm2txI9VRU6mWuqOitkj+VNgb4SSu1jrPR/jgwPzKojQInM1AzSDiHwQ3ZenUygr50axsw==", - "license": "MIT" + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } }, - "node_modules/@types/node": { - "version": "25.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", - "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "undici-types": "~7.16.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { - "csstype": "^3.2.2" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitejs/plugin-react": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", - "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/core": "^7.29.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-rc.3", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" - }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "node": ">=8" } }, - "node_modules/@vitest/coverage-v8": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz", - "integrity": "sha512-/6zU2FLGg0jsd+ePZcwHRy3+WpNTBBhDY56P4JTRqUN/Dp6CvOEa9HrikcQ4KfV2b2kAHUFB4dl1SuocWXSFEw==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { - "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.0.17", - "ast-v8-to-istanbul": "^0.3.10", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.2.0", - "magicast": "^0.5.1", - "obug": "^2.1.1", - "std-env": "^3.10.0", - "tinyrainbow": "^3.0.3" + "es-define-property": "^1.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "4.0.17", - "vitest": "4.0.17" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/expect": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz", - "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==", + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.17", - "@vitest/utils": "4.0.17", - "chai": "^6.2.1", - "tinyrainbow": "^3.0.3" + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/mocker": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz", - "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==", - "dev": true, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", - "dependencies": { - "@vitest/spy": "4.0.17", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz", - "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/runner": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz", - "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.17", - "pathe": "^2.0.3" + "function-bind": "^1.1.2" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hono": { + "version": "4.12.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", + "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" } }, - "node_modules/@vitest/snapshot": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz", - "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==", + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.17", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "whatwg-encoding": "^3.1.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=18" } }, - "node_modules/@vitest/spy": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz", - "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, - "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" - } + "license": "MIT" }, - "node_modules/@vitest/utils": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz", - "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==", - "dev": true, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.17", - "tinyrainbow": "^3.0.3" + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, "engines": { "node": ">= 14" } }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "agent-base": "^7.1.2", + "debug": "4" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 14" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/hub-client": { + "resolved": "hub-client", + "link": true + }, + "node_modules/hub-kanban": { + "resolved": "q2-demos/kanban", + "link": true + }, + "node_modules/hub-react-todo": { + "resolved": "q2-demos/hub-react-todo", + "link": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "license": "MIT", "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/idb": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz", + "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==", + "license": "ISC" + }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "license": "MIT" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">= 0.4" } }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 0.10" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", - "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^9.0.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", - "license": "MIT" - }, - "node_modules/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", - "license": "MIT", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">= 0.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, "license": "MIT", "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "has-bigints": "^1.0.2" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" + "hasown": "^2.0.2" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, "license": "MIT", "dependencies": { - "base-x": "^4.0.0" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bs58check": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", - "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "^1.2.0", - "bs58": "^5.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "is-extglob": "^2.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3975,771 +7269,766 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001774", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", - "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" + "license": "MIT" }, - "node_modules/cbor-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", - "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", - "hasInstallScript": true, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "node-gyp-build-optional-packages": "5.1.1" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, - "bin": { - "download-cbor-prebuilds": "bin/download-prebuilds.js" + "engines": { + "node": ">= 0.4" }, - "optionalDependencies": { - "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", - "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", - "@cbor-extract/cbor-extract-linux-x64": "2.2.0", - "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cbor-x": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", - "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, "license": "MIT", - "optionalDependencies": { - "cbor-extract": "^2.2.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=0.10.0" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 16" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "call-bound": "^1.0.3" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/color-convert": { + "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">= 12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=6.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, "license": "MIT", "dependencies": { - "object-assign": "^4", - "vary": "^1" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/css-line-break": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", - "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", - "license": "MIT", + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "utrie": "^1.0.2" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", - "dev": true, - "license": "MIT", + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" }, "engines": { - "node": ">=18" + "node": ">=10" } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/jose": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", + "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, "license": "MIT" }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { "node": ">=18" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "canvas": "^3.0.0" }, "peerDependenciesMeta": { - "supports-color": { + "canvas": { "optional": true } } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, "engines": { "node": ">=6" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, "engines": { "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/katex": { + "version": "0.16.28", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", + "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "commander": "^8.3.0" }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, "license": "MIT" }, - "node_modules/electron-to-chromium": { - "version": "1.5.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", - "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } + "license": "ISC" }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" + "bin": { + "lz-string": "bin/bin.js" } }, - "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.8" } }, - "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", - "dev": true, - "license": "Apache-2.0", + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": ">= 0.6" } }, - "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 18" + "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, - "node_modules/express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, "license": "MIT", - "dependencies": { - "ip-address": "10.1.0" - }, "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" + "node": ">=4" } }, - "node_modules/fake-indexeddb": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.2.5.tgz", - "integrity": "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==", + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "Apache-2.0", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=18" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "license": "Apache-2.0" - }, - "node_modules/fast-sha256": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", - "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", - "license": "Unlicense" - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "node": ">=16 || 14 >=14.17" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "node_modules/morphdom": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", + "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", "license": "MIT" }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "license": "MIT", - "engines": { - "node": ">= 0.8" + "optional": true + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, - "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=0.10.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -4748,739 +8037,969 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-proto": { + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/own-keys": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, "license": "MIT", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "entities": "^6.0.0" }, "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", - "engines": { - "node": ">= 0.4" - }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 14.16" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "devOptional": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/playwright": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", + "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "function-bind": "^1.1.2" + "playwright-core": "1.58.0" + }, + "bin": { + "playwright": "cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "license": "BSD-3-Clause", + "node_modules/playwright-core": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", + "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, "engines": { - "node": ">=12.0.0" + "node": ">=18" } }, - "node_modules/hono": { - "version": "4.12.7", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", - "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==", + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=16.9.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, "engines": { - "node": ">=18" + "node": ">= 0.4" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, - "license": "MIT" - }, - "node_modules/html2canvas": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", - "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "css-line-break": "^2.1.0", - "text-segmentation": "^1.0.3" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=8.0.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, "engines": { - "node": ">= 0.8" + "node": "^14.13.1 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 14" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">= 14" + "node": ">= 0.10" } }, - "node_modules/hub-client": { - "resolved": "hub-client", - "link": true - }, - "node_modules/hub-kanban": { - "resolved": "q2-demos/kanban", - "link": true - }, - "node_modules/hub-react-todo": { - "resolved": "q2-demos/hub-react-todo", - "link": true - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "side-channel": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/idb": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz", - "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==", - "license": "ISC" - }, - "node_modules/immutable": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", - "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", - "license": "MIT" - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "safe-buffer": "^5.1.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { - "node": ">= 12" + "node": ">= 0.6" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, "engines": { "node": ">= 0.10" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { - "is-extglob": "^2.1.1" + "scheduler": "^0.27.0" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "react": "^19.2.4" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, "license": "MIT" }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "node_modules/react-usestateref": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/react-usestateref/-/react-usestateref-1.0.9.tgz", + "integrity": "sha512-t8KLsI7oje0HzfzGhxFXzuwbf1z9vhBM1ptHLUIHhYqZDKFuI5tzdhEVxSNzUkYxwF8XdpOErzHlKxvP7sTERw==", + "license": "ISC", + "peerDependencies": { + "react": ">16.0.0" + } }, - "node_modules/isomorphic-ws": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "license": "MIT", - "peerDependencies": { - "ws": "*" + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "regenerate": "^1.4.2" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">= 0.4" }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jose": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", - "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" } }, - "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, "license": "MIT" }, - "node_modules/jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "cssstyle": "^4.2.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.5.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.16", - "parse5": "^7.2.1", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.1.1", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.1", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" + "jsesc": "~3.1.0" }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "peerDependencies": { - "canvas": "^3.0.0" + "bin": { + "resolve": "bin/resolve" }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reveal.js": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-6.0.0.tgz", + "integrity": "sha512-RayDr1FL3Jglnf6p9xHGJ0U18va96PiuLs/JHnd1cdDOXvC+3lsXKe6ujl7PX0pvnhNW2Tpqnr6PEKpJVO2exw==", + "license": "MIT", + "peer": true + }, + "node_modules/reveal.js-menu": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/reveal.js-menu/-/reveal.js-menu-2.1.0.tgz", + "integrity": "sha512-35zp4fHSMyWd15+3CvQ8LrpS+4Gj2qvlkxX3lo5LpITDe6ZkA4A9y1E5fE63YlQl5fp7W1mNgNJr4kCU0s14lA==", + "license": "MIT, Copyright (C) 2020 Greg Denehy" + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, "bin": { - "jsesc": "bin/jsesc" + "rimraf": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/rollup": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { - "json5": "lib/cli.js" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=6" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", + "fsevents": "~2.3.2" } }, - "node_modules/katex": { - "version": "0.16.28", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", - "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { - "commander": "^8.3.0" + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" }, - "bin": { - "katex": "cli.js" + "engines": { + "node": ">= 18" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "dev": true, "license": "MIT" }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "es-errors": "^1.3.0", + "isarray": "^2.0.5" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/math-intrinsics": { + "node_modules/safe-regex-test": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, "engines": { - "node": ">= 0.8" + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=v12.22.7" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "mime-db": "^1.54.0" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">=18" + "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" } }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" } }, - "node_modules/morphdom": { - "version": "2.7.8", - "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", - "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">= 0.4" } }, - "node_modules/negotiator": { + "node_modules/set-proto": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" } }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT", - "optional": true + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.1" + "shebang-regex": "^3.0.0" }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" + "engines": { + "node": ">=8" } }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, "engines": { "node": ">= 0.4" }, @@ -5488,649 +9007,738 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", "dependencies": { - "ee-first": "1.1.1" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { - "wrappy": "1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "dev": true, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { - "entities": "^6.0.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/smob": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", + "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20.0.0" } }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", "dev": true, - "license": "BlueOak-1.0.0", + "license": "BSD-3-Clause", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "whatwg-url": "^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 8" } }, - "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 14.16" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "devOptional": true, - "license": "MIT", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=0.10.0" } }, - "node_modules/pkce-challenge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", - "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "node_modules/source-map/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=16.20.0" + "dependencies": { + "punycode": "^2.1.0" } }, - "node_modules/playwright": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", - "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", + "node_modules/source-map/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true, - "license": "Apache-2.0", + "license": "BSD-2-Clause" + }, + "node_modules/source-map/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "license": "MIT", "dependencies": { - "playwright-core": "1.58.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "node_modules/playwright-core": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", - "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.8" } }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.4" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", - "license": "BSD-3-Clause", + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", "side-channel": "^1.1.0" }, "engines": { - "node": ">=0.6" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, "license": "MIT", "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", - "license": "MIT", + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, "license": "MIT", "dependencies": { - "scheduler": "^0.27.0" + "ansi-regex": "^6.0.1" }, - "peerDependencies": { - "react": "^19.2.4" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-usestateref": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/react-usestateref/-/react-usestateref-1.0.9.tgz", - "integrity": "sha512-t8KLsI7oje0HzfzGhxFXzuwbf1z9vhBM1ptHLUIHhYqZDKFuI5tzdhEVxSNzUkYxwF8XdpOErzHlKxvP7sTERw==", - "license": "ISC", - "peerDependencies": { - "react": ">16.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "node": ">=10" } }, - "node_modules/redent": { + "node_modules/strip-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "license": "MIT", "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "min-indent": "^1.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/resolve-pkg-maps": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/reveal.js": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-6.0.0.tgz", - "integrity": "sha512-RayDr1FL3Jglnf6p9xHGJ0U18va96PiuLs/JHnd1cdDOXvC+3lsXKe6ujl7PX0pvnhNW2Tpqnr6PEKpJVO2exw==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, "license": "MIT" }, - "node_modules/reveal.js-menu": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/reveal.js-menu/-/reveal.js-menu-2.1.0.tgz", - "integrity": "sha512-35zp4fHSMyWd15+3CvQ8LrpS+4Gj2qvlkxX3lo5LpITDe6ZkA4A9y1E5fE63YlQl5fp7W1mNgNJr4kCU0s14lA==", - "license": "MIT, Copyright (C) 2020 Greg Denehy" + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "glob": "^10.3.7" + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" }, - "bin": { - "rimraf": "dist/esm/bin.mjs" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rollup": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", - "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", + "node_modules/terser": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.2.tgz", + "integrity": "sha512-uxfo9fPcSgLDYob/w1FuL0c99MWiJDnv+5qXSQc5+Ki5NjVNsYi66INnMFBjf6uFz6OnX12piJQPF4IpjJTNTw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@types/estree": "1.0.8" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" }, "bin": { - "rollup": "dist/bin/rollup" + "terser": "bin/terser" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.55.1", - "@rollup/rollup-android-arm64": "4.55.1", - "@rollup/rollup-darwin-arm64": "4.55.1", - "@rollup/rollup-darwin-x64": "4.55.1", - "@rollup/rollup-freebsd-arm64": "4.55.1", - "@rollup/rollup-freebsd-x64": "4.55.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", - "@rollup/rollup-linux-arm-musleabihf": "4.55.1", - "@rollup/rollup-linux-arm64-gnu": "4.55.1", - "@rollup/rollup-linux-arm64-musl": "4.55.1", - "@rollup/rollup-linux-loong64-gnu": "4.55.1", - "@rollup/rollup-linux-loong64-musl": "4.55.1", - "@rollup/rollup-linux-ppc64-gnu": "4.55.1", - "@rollup/rollup-linux-ppc64-musl": "4.55.1", - "@rollup/rollup-linux-riscv64-gnu": "4.55.1", - "@rollup/rollup-linux-riscv64-musl": "4.55.1", - "@rollup/rollup-linux-s390x-gnu": "4.55.1", - "@rollup/rollup-linux-x64-gnu": "4.55.1", - "@rollup/rollup-linux-x64-musl": "4.55.1", - "@rollup/rollup-openbsd-x64": "4.55.1", - "@rollup/rollup-openharmony-arm64": "4.55.1", - "@rollup/rollup-win32-arm64-msvc": "4.55.1", - "@rollup/rollup-win32-ia32-msvc": "4.55.1", - "@rollup/rollup-win32-x64-gnu": "4.55.1", - "@rollup/rollup-win32-x64-msvc": "4.55.1", - "fsevents": "~2.3.2" + "node": ">=10" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" + "utrie": "^1.0.2" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { - "node": ">= 18" + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/sass": { - "version": "1.97.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", - "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, "license": "MIT", - "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.0.2", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, "engines": { "node": ">=14.0.0" - }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" } }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "xmlchars": "^2.2.0" + "tldts-core": "^6.1.86" }, - "engines": { - "node": ">=v12.22.7" + "bin": { + "tldts": "bin/cli.js" } }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, "license": "MIT" }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" }, "engines": { - "node": ">=10" + "node": ">=16" } }, - "node_modules/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" + "punycode": "^2.3.1" }, "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=18" } }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, "license": "MIT", "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" }, "engines": { - "node": ">= 18" + "node": ">=18.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "optionalDependencies": { + "fsevents": "~2.3.3" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" + "node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -6139,14 +9747,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -6155,16 +9769,52 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -6173,762 +9823,1028 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=4" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, - "engines": { - "node": ">=12" + "bin": { + "update-browserslist-db": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "base64-arraybuffer": "^1.0.2" } }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "ansi-regex": "^5.0.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=12" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/vite-plugin-pwa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz", + "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.10", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "node": ">=16.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^1.0.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "node_modules/vite-plugin-wasm": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.5.0.tgz", + "integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==", "dev": true, "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" + "peerDependencies": { + "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "node_modules/vitest": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz", + "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "js-tokens": "^9.0.1" + "@vitest/expect": "4.0.17", + "@vitest/mocker": "4.0.17", + "@vitest/pretty-format": "4.0.17", + "@vitest/runner": "4.0.17", + "@vitest/snapshot": "4.0.17", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.17", + "@vitest/browser-preview": "4.0.17", + "@vitest/browser-webdriverio": "4.0.17", + "@vitest/ui": "4.0.17", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/text-segmentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", - "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", - "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" + "node": ">=18" } }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, + "node_modules/web-tree-sitter": { + "version": "0.26.8", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.8.tgz", + "integrity": "sha512-4sUwi7ZyOrIk5KLgYLkc2A/F0LFMQnBhfb+2Cdl7ik4ePJ6JD+fk4ofI2sA5eGawBKBaK4Vntt7Ww5KcEsay4A==", "license": "MIT" }, - "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=12" } }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" + "iconv-lite": "0.6.3" }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", "engines": { - "node": ">=0.6" + "node": ">=18" } }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { - "tldts": "^6.1.32" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=16" + "node": ">= 8" } }, - "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.3.1" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" }, "engines": { - "node": ">=18" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tsx": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", - "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.27.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, "license": "MIT", "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "node": ">= 0.4" }, - "engines": { - "node": ">=14.17" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, - "license": "MIT" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "siginfo": "^2.0.0", + "stackback": "0.0.2" }, "bin": { - "update-browserslist-db": "cli.js" + "why-is-node-running": "cli.js" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "engines": { + "node": ">=8" } }, - "node_modules/utrie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", - "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "node_modules/workbox-background-sync": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz", + "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==", + "dev": true, "license": "MIT", "dependencies": { - "base64-arraybuffer": "^1.0.2" + "idb": "^7.0.1", + "workbox-core": "7.4.0" } }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "node_modules/workbox-background-sync/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/workbox-broadcast-update": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz", + "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==", + "dev": true, "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "dependencies": { + "workbox-core": "7.4.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/workbox-build": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz", + "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==", + "dev": true, "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^11.0.1", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.79.2", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.4.0", + "workbox-broadcast-update": "7.4.0", + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-google-analytics": "7.4.0", + "workbox-navigation-preload": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-range-requests": "7.4.0", + "workbox-recipes": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0", + "workbox-streams": "7.4.0", + "workbox-sw": "7.4.0", + "workbox-window": "7.4.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/workbox-build/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 0.8" + "node": ">=18" } }, - "node_modules/vite": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "node": ">= 10.0.0" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" }, "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { + "@types/babel__core": { "optional": true } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/workbox-build/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/workbox-build/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/workbox-build/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" }, "bin": { - "vite-node": "vite-node.mjs" + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "20 || >=22" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vite-plugin-wasm": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.5.0.tgz", - "integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==", + "node_modules/workbox-build/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, - "license": "MIT", - "peerDependencies": { - "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vitest": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz", - "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", + "node_modules/workbox-build/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/workbox-build/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.0.17", - "@vitest/mocker": "4.0.17", - "@vitest/pretty-format": "4.0.17", - "@vitest/runner": "4.0.17", - "@vitest/snapshot": "4.0.17", - "@vitest/spy": "4.0.17", - "@vitest/utils": "4.0.17", - "es-module-lexer": "^1.7.0", - "expect-type": "^1.2.2", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^3.10.0", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.0.3", - "vite": "^6.0.0 || ^7.0.0", - "why-is-node-running": "^2.3.0" + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/workbox-build/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" }, - "bin": { - "vitest": "vitest.mjs" + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.17", - "@vitest/browser-preview": "4.0.17", - "@vitest/browser-webdriverio": "4.0.17", - "@vitest/ui": "4.0.17", - "happy-dom": "*", - "jsdom": "*" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.80.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz", + "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==", "dev": true, "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" + "peer": true, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=18" + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/web-tree-sitter": { - "version": "0.26.8", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.8.tgz", - "integrity": "sha512-4sUwi7ZyOrIk5KLgYLkc2A/F0LFMQnBhfb+2Cdl7ik4ePJ6JD+fk4ofI2sA5eGawBKBaK4Vntt7Ww5KcEsay4A==", + "node_modules/workbox-cacheable-response": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz", + "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-core": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz", + "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==", + "dev": true, "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "node_modules/workbox-expiration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz", + "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.4.0" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "node_modules/workbox-expiration/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/workbox-google-analytics": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz", + "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==", "dev": true, "license": "MIT", "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" + "workbox-background-sync": "7.4.0", + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "node_modules/workbox-navigation-preload": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz", + "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "workbox-core": "7.4.0" } }, - "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "node_modules/workbox-precaching": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz", + "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", + "node_modules/workbox-range-requests": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz", + "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "workbox-core": "7.4.0" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "node_modules/workbox-recipes": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz", + "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==", "dev": true, "license": "MIT", "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz", + "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz", + "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-streams": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz", + "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz", + "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-window": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz", + "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.4.0" } }, "node_modules/wrap-ansi": { @@ -7043,6 +10959,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -7114,6 +11031,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } From ceaf0186c6e3878af51e53d72b9622cea32310d6 Mon Sep 17 00:00:00 2001 From: elliot Date: Fri, 1 May 2026 11:53:41 -0400 Subject: [PATCH 2/8] Add basic offline support with a service worker --- hub-client/OFFLINE.md | 95 + hub-client/package.json | 2 + hub-client/vite.config.ts | 56 + package-lock.json | 11579 ++++++++++++++++++++++++------------ 4 files changed, 7770 insertions(+), 3962 deletions(-) create mode 100644 hub-client/OFFLINE.md diff --git a/hub-client/OFFLINE.md b/hub-client/OFFLINE.md new file mode 100644 index 000000000..e41066e8b --- /dev/null +++ b/hub-client/OFFLINE.md @@ -0,0 +1,95 @@ +# Offline Support + +Quarto Hub includes offline support via Vite PWA plugin powered by Workbox. + +## How it works + +The service worker is automatically generated at build time by `vite-plugin-pwa` and provides: + +1. **App shell precaching**: HTML and icon are precached on first visit +2. **Runtime caching**: JS, CSS, and fonts are cached as they're loaded +3. **Automatic updates**: Service worker auto-updates when new versions are deployed +4. **Google Fonts caching**: External fonts are cached for offline use + +## Caching strategy + +### Precached (available immediately on first load) +Everything is precached during service worker installation (~44 MB total): +- All HTML pages (`index.html`, `debug.html`, `ast-renderer.html`) +- All JavaScript bundles (including 3MB+ main bundles) +- All CSS files +- All WASM files (including 32MB quarto parser + 2MB Automerge WASM) +- All local fonts (.woff, .woff2) +- Icons and SVG assets + +### Runtime cached (external resources) + +- **Google Fonts CSS** - `CacheFirst` + - Cached permanently once loaded + - 1-year expiration, max 10 entries + +- **Google Fonts files** - `CacheFirst` + - Cached permanently once loaded + - 1-year expiration, max 10 entries + +## Why precache everything? + +Service workers don't control a page until the **second navigation**. On first visit: +1. Page loads normally from network +2. Service worker installs in background +3. Service worker is "waiting" and doesn't intercept requests yet + +This means runtime caching (NetworkFirst, etc.) **doesn't work** until the second visit. + +By precaching all assets during service worker installation: +- ✅ First visit: installs in background while page loads +- ✅ Refresh (even offline): everything loads from cache immediately +- ✅ No "second visit" needed - works offline right away + +## Limitations + +This is **basic offline support** - it provides: +- ✅ App shell loads when offline (after first visit) +- ✅ Previously loaded pages/assets work offline +- ❌ No offline editing (requires server connection for Automerge sync) +- ❌ No background sync +- ❌ No push notifications + +## Development + +The service worker only registers in production builds. During development (`npm run dev`), it's disabled to avoid caching issues. + +## Testing offline behavior + +1. Build for production: `npm run build` +2. Serve the build: `npm run preview` +3. Open http://localhost:4173 in browser +4. Open DevTools → Application → Service Workers to verify registration +5. Navigate around the app to populate cache +6. Enable "Offline" mode in DevTools → Network tab +7. Reload the page - it should load from cache + +## Configuration + +PWA settings are in `vite.config.ts`: + +```typescript +VitePWA({ + registerType: 'autoUpdate', + workbox: { + globPatterns: ['**/*.{html,svg}'], + maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, + runtimeCaching: [/* ... */] + } +}) +``` + +## Cache management + +The service worker automatically: +- Updates when new versions are deployed +- Cleans up old caches +- Enforces size limits (max entries, max age) +- Handles cache storage quota exceeded errors + +No manual cache version bumping is required - Workbox handles versioning automatically. diff --git a/hub-client/package.json b/hub-client/package.json index 00d955e41..5ad57f119 100644 --- a/hub-client/package.json +++ b/hub-client/package.json @@ -74,8 +74,10 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.46.4", "vite": "^7.2.4", + "vite-plugin-pwa": "^1.2.0", "vite-plugin-wasm": "^3.5.0", "vitest": "^4.0.17", + "workbox-window": "^7.4.0", "ws": "^8.19.0", "yaml": "^2.8.2" } diff --git a/hub-client/vite.config.ts b/hub-client/vite.config.ts index f0f0b0fb5..47d5c84e3 100644 --- a/hub-client/vite.config.ts +++ b/hub-client/vite.config.ts @@ -3,6 +3,7 @@ import type { Plugin } from 'vite' import react from '@vitejs/plugin-react' import wasm from 'vite-plugin-wasm' import compression from 'compression' +import { VitePWA } from 'vite-plugin-pwa' import path from 'path' import { readFileSync } from 'fs' import { execSync } from 'child_process' @@ -88,6 +89,61 @@ export default defineConfig({ server.middlewares.use(middleware as any); }, }, + VitePWA({ + registerType: 'autoUpdate', + includeAssets: ['quarto-icon.svg'], + manifest: { + name: 'Quarto Hub', + short_name: 'Quarto Hub', + description: 'Collaborative editing for Quarto projects', + theme_color: '#447099', + icons: [ + { + src: 'quarto-icon.svg', + sizes: 'any', + type: 'image/svg+xml' + } + ] + }, + workbox: { + // Precache all static assets including JS/CSS bundles and WASM + globPatterns: ['**/*.{html,js,css,svg,woff,woff2,wasm}'], + // Increase limit to 35MB to include WASM files (largest is ~32MB) + maximumFileSizeToCacheInBytes: 35 * 1024 * 1024, + // Don't warn about large files - we know they're big + dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, + runtimeCaching: [ + { + urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i, + handler: 'CacheFirst', + options: { + cacheName: 'google-fonts-cache', + expiration: { + maxEntries: 10, + maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year + }, + cacheableResponse: { + statuses: [0, 200] + } + } + }, + { + urlPattern: /^https:\/\/fonts\.gstatic\.com\/.*/i, + handler: 'CacheFirst', + options: { + cacheName: 'google-fonts-static', + expiration: { + maxEntries: 10, + maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year + }, + cacheableResponse: { + statuses: [0, 200] + } + } + } + ] + } + }) ], define: { __GIT_COMMIT_HASH__: JSON.stringify(gitInfo.commitHash), diff --git a/package-lock.json b/package-lock.json index cff75e638..b5a098683 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ }, "hub-client": { "version": "0.0.0", + "hasInstallScript": true, "dependencies": { "@automerge/automerge-repo": "^2.5.1", "@automerge/automerge-repo-network-websocket": "^2.5.1", @@ -77,8 +78,10 @@ "typescript": "~5.9.3", "typescript-eslint": "^8.46.4", "vite": "^7.2.4", + "vite-plugin-pwa": "^1.2.0", "vite-plugin-wasm": "^3.5.0", "vitest": "^4.0.17", + "workbox-window": "^7.4.0", "ws": "^8.19.0", "yaml": "^2.8.2" } @@ -564,17 +567,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "hub-client/node_modules/acorn": { - "version": "8.15.0", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "hub-client/node_modules/acorn-jsx": { "version": "5.3.2", "dev": true, @@ -830,19 +822,6 @@ "node": ">=4.0" } }, - "hub-client/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "hub-client/node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, "hub-client/node_modules/fast-levenshtein": { "version": "2.0.6", "dev": true, @@ -1238,6 +1217,23 @@ "dev": true, "license": "MIT" }, + "node_modules/@apideck/better-ajv-errors": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.7.tgz", + "integrity": "sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonpointer": "^5.0.1", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", @@ -1350,9 +1346,9 @@ "license": "MIT" }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "dev": true, "license": "MIT", "engines": { @@ -1417,6 +1413,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", @@ -1454,6 +1463,66 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", + "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.29.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -1464,6 +1533,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", @@ -1496,6 +1579,19 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", @@ -1506,6 +1602,56 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -1534,6 +1680,21 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helpers": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", @@ -1563,10 +1724,27 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", "dependencies": { @@ -1576,13 +1754,13 @@ "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", "dependencies": { @@ -1592,1184 +1770,1202 @@ "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", + "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/standalone": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.29.2.tgz", - "integrity": "sha512-VSuvywmVRS8efooKrvJzs6BlVSxRvAdLeGrAKUrWoBx1fFBSeE/oBpUZCQ5BcprLyXy04W8skzz7JT8GqlNRJg==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/template": { + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.29.0" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/accessibility": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", - "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/core": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", - "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "dev": true, "license": "MIT", "dependencies": { - "@dnd-kit/accessibility": "^3.1.1", - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@babel/core": "^7.12.0" } }, - "node_modules/@dnd-kit/sortable": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", - "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", + "dev": true, "license": "MIT", "dependencies": { - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@dnd-kit/core": "^6.3.0", - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dnd-kit/utilities": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", - "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.0.0" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", - "cpu": [ - "loong64" - ], + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", - "cpu": [ - "mips64el" - ], + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", - "cpu": [ - "riscv64" - ], + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", - "cpu": [ - "s390x" - ], + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=18.14.1" + "node": ">=6.9.0" }, "peerDependencies": { - "hono": "^4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", - "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "dev": true, "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", - "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { - "node": ">=18" + "node": ">=6.9.0" }, "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } + "@babel/core": "^7.0.0" } }, - "node_modules/@napi-rs/keyring": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring/-/keyring-1.3.0.tgz", - "integrity": "sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 10" + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=6.9.0" }, - "optionalDependencies": { - "@napi-rs/keyring-darwin-arm64": "1.3.0", - "@napi-rs/keyring-darwin-x64": "1.3.0", - "@napi-rs/keyring-freebsd-x64": "1.3.0", - "@napi-rs/keyring-linux-arm-gnueabihf": "1.3.0", - "@napi-rs/keyring-linux-arm64-gnu": "1.3.0", - "@napi-rs/keyring-linux-arm64-musl": "1.3.0", - "@napi-rs/keyring-linux-riscv64-gnu": "1.3.0", - "@napi-rs/keyring-linux-x64-gnu": "1.3.0", - "@napi-rs/keyring-linux-x64-musl": "1.3.0", - "@napi-rs/keyring-win32-arm64-msvc": "1.3.0", - "@napi-rs/keyring-win32-ia32-msvc": "1.3.0", - "@napi-rs/keyring-win32-x64-msvc": "1.3.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-darwin-arm64": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-arm64/-/keyring-darwin-arm64-1.3.0.tgz", - "integrity": "sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-darwin-x64": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-x64/-/keyring-darwin-x64-1.3.0.tgz", - "integrity": "sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-freebsd-x64": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-freebsd-x64/-/keyring-freebsd-x64-1.3.0.tgz", - "integrity": "sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-arm-gnueabihf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm-gnueabihf/-/keyring-linux-arm-gnueabihf-1.3.0.tgz", - "integrity": "sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-arm64-gnu": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-gnu/-/keyring-linux-arm64-gnu-1.3.0.tgz", - "integrity": "sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-arm64-musl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-musl/-/keyring-linux-arm64-musl-1.3.0.tgz", - "integrity": "sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-riscv64-gnu": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-riscv64-gnu/-/keyring-linux-riscv64-gnu-1.3.0.tgz", - "integrity": "sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==", - "cpu": [ - "riscv64" - ], + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-x64-gnu": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-gnu/-/keyring-linux-x64-gnu-1.3.0.tgz", - "integrity": "sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-linux-x64-musl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-musl/-/keyring-linux-x64-musl-1.3.0.tgz", - "integrity": "sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@napi-rs/keyring-win32-arm64-msvc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-arm64-msvc/-/keyring-win32-arm64-msvc-1.3.0.tgz", - "integrity": "sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/preset-env": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.3.tgz", + "integrity": "sha512-ySZypNLAIH1ClygLDQzVMoGQRViATnkHkYYV6TcNDz+8+jwZCdsguGvsb3EY5d9wyWyhmF1iSuFM0Yh5XPnqSA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/compat-data": "^7.29.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@napi-rs/keyring-win32-ia32-msvc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-ia32-msvc/-/keyring-win32-ia32-msvc-1.3.0.tgz", - "integrity": "sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@napi-rs/keyring-win32-x64-msvc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-x64-msvc/-/keyring-win32-x64-msvc-1.3.0.tgz", - "integrity": "sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">= 10" + "node": ">=6.9.0" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@babel/standalone": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.29.2.tgz", + "integrity": "sha512-VSuvywmVRS8efooKrvJzs6BlVSxRvAdLeGrAKUrWoBx1fFBSeE/oBpUZCQ5BcprLyXy04W8skzz7JT8GqlNRJg==", "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=6.9.0" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "hasInstallScript": true, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", - "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", - "cpu": [ - "arm64" - ], + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=18" } }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", "cpu": [ "arm64" ], @@ -2777,19 +2973,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", - "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", "cpu": [ "x64" ], @@ -2797,314 +2986,249 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", - "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", "cpu": [ - "x64" + "arm" ], "license": "MIT", "optional": true, "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "linux" + ] }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", - "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", "cpu": [ - "arm" + "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", - "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", "cpu": [ - "arm" + "x64" ], "license": "MIT", "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", - "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", "cpu": [ - "arm64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" + ] + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], + "license": "MIT-0", "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=18" } }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", - "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", - "cpu": [ - "arm64" + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">= 10.0.0" + "node": ">=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", - "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", - "cpu": [ - "x64" + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", - "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", - "cpu": [ - "x64" + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">= 10.0.0" + "node": ">=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", - "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", - "cpu": [ - "arm64" + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } ], "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=18" } }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", - "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", - "cpu": [ - "ia32" - ], + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", + "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "tslib": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "react": ">=16.8.0" } }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", - "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", - "cpu": [ - "x64" - ], + "node_modules/@dnd-kit/core": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", + "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "@dnd-kit/accessibility": "^3.1.1", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, + "node_modules/@dnd-kit/sortable": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", + "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@playwright/test": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", - "integrity": "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==", - "dev": true, - "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.0" - }, - "bin": { - "playwright": "cli.js" + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@quarto/annotated-qmd": { - "resolved": "ts-packages/annotated-qmd", - "link": true - }, - "node_modules/@quarto/hub-mcp": { - "resolved": "ts-packages/quarto-hub-mcp", - "link": true - }, - "node_modules/@quarto/pandoc-types": { - "resolved": "ts-packages/pandoc-types", - "link": true - }, - "node_modules/@quarto/preview-renderer": { - "resolved": "ts-packages/preview-renderer", - "link": true - }, - "node_modules/@quarto/preview-runtime": { - "resolved": "ts-packages/preview-runtime", - "link": true - }, - "node_modules/@quarto/quarto-automerge-schema": { - "resolved": "ts-packages/quarto-automerge-schema", - "link": true - }, - "node_modules/@quarto/quarto-sync-client": { - "resolved": "ts-packages/quarto-sync-client", - "link": true - }, - "node_modules/@quarto/sync-test-harness": { - "resolved": "ts-packages/sync-test-harness", - "link": true - }, - "node_modules/@quarto/trace-viewer": { - "resolved": "trace-viewer", - "link": true - }, - "node_modules/@quarto/wasm-js-bridge": { - "resolved": "ts-packages/wasm-js-bridge", - "link": true - }, - "node_modules/@react-oauth/google": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.13.4.tgz", - "integrity": "sha512-hGKyNEH+/PK8M0sFEuo3MAEk0txtHpgs94tDQit+s2LXg7b6z53NtzHfqDvoB2X8O6lGB+FRg80hY//X6hfD+w==", - "license": "MIT", "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" } }, - "node_modules/@revealjs/react": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@revealjs/react/-/react-0.2.0.tgz", - "integrity": "sha512-kIxl5rCttlVJFeSnWJostA80IbhuM5+GO2yjs6yHOpesyIuzpCZjsNjX1s+5bbb1BGwEIAbuE04KPLWxZR1XAw==", + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, "peerDependencies": { - "react": ">=18", - "react-dom": ">=18", - "reveal.js": ">=5" + "react": ">=16.8.0" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", - "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -3113,12 +3237,15 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", - "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -3127,82 +3254,100 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", - "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "android" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", - "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", - "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "freebsd" - ] + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", - "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", - "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ - "arm" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", - "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -3211,12 +3356,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", - "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -3225,26 +3373,32 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", - "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ - "arm64" + "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", - "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -3253,26 +3407,32 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", - "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ - "loong64" + "mips64el" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", - "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -3281,68 +3441,83 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", - "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ - "ppc64" + "riscv64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", - "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ - "riscv64" + "s390x" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", - "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ - "riscv64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", - "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", "cpu": [ - "s390x" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", - "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -3350,27 +3525,33 @@ "license": "MIT", "optional": true, "os": [ - "linux" - ] + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", - "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", - "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -3379,12 +3560,15 @@ "optional": true, "os": [ "openbsd" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", - "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", "cpu": [ "arm64" ], @@ -3393,54 +3577,66 @@ "optional": true, "os": [ "openharmony" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", - "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" - ] + "sunos" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", - "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ - "ia32" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", - "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ - "x64" + "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", - "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -3449,810 +3645,3882 @@ "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" + "node_modules/@hono/node-server": { + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } }, - "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "license": "MIT", - "peer": true, + "license": "ISC", "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "picocolors": "1.1.1", - "pretty-format": "^27.0.2" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=18" + "node": ">=12" } }, - "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@adobe/css-tools": "^4.4.0", - "aria-query": "^5.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "picocolors": "^1.1.1", - "redent": "^3.0.0" - }, + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=6.0.0" } }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, - "node_modules/@testing-library/react": { - "version": "16.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", - "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.5" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@testing-library/dom": "^10.0.0", - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" }, "peerDependenciesMeta": { - "@types/react": { + "@cfworker/json-schema": { "optional": true }, - "@types/react-dom": { - "optional": true + "zod": { + "optional": false } } }, - "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", - "dev": true, + "node_modules/@napi-rs/keyring": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring/-/keyring-1.3.0.tgz", + "integrity": "sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==", "license": "MIT", "engines": { - "node": ">=12", - "npm": ">=6" + "node": ">= 10" }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/keyring-darwin-arm64": "1.3.0", + "@napi-rs/keyring-darwin-x64": "1.3.0", + "@napi-rs/keyring-freebsd-x64": "1.3.0", + "@napi-rs/keyring-linux-arm-gnueabihf": "1.3.0", + "@napi-rs/keyring-linux-arm64-gnu": "1.3.0", + "@napi-rs/keyring-linux-arm64-musl": "1.3.0", + "@napi-rs/keyring-linux-riscv64-gnu": "1.3.0", + "@napi-rs/keyring-linux-x64-gnu": "1.3.0", + "@napi-rs/keyring-linux-x64-musl": "1.3.0", + "@napi-rs/keyring-win32-arm64-msvc": "1.3.0", + "@napi-rs/keyring-win32-ia32-msvc": "1.3.0", + "@napi-rs/keyring-win32-x64-msvc": "1.3.0" } }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, + "node_modules/@napi-rs/keyring-darwin-arm64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-arm64/-/keyring-darwin-arm64-1.3.0.tgz", + "integrity": "sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "peer": true + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/@napi-rs/keyring-darwin-x64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-x64/-/keyring-darwin-x64-1.3.0.tgz", + "integrity": "sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "node_modules/@napi-rs/keyring-freebsd-x64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-freebsd-x64/-/keyring-freebsd-x64-1.3.0.tgz", + "integrity": "sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@types/babel__standalone": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__standalone/-/babel__standalone-7.1.9.tgz", - "integrity": "sha512-IcCNPLqpevUD7UpV8QB0uwQPOyoOKACFf0YtYWRHcmxcakaje4Q7dbG2+jMqxw/I8Zk0NHvEps66WwS7z/UaaA==", - "license": "MIT", + "node_modules/@napi-rs/keyring-linux-arm-gnueabihf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm-gnueabihf/-/keyring-linux-arm-gnueabihf-1.3.0.tgz", + "integrity": "sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-arm64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-gnu/-/keyring-linux-arm64-gnu-1.3.0.tgz", + "integrity": "sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-arm64-musl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-musl/-/keyring-linux-arm64-musl-1.3.0.tgz", + "integrity": "sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-riscv64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-riscv64-gnu/-/keyring-linux-riscv64-gnu-1.3.0.tgz", + "integrity": "sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-x64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-gnu/-/keyring-linux-x64-gnu-1.3.0.tgz", + "integrity": "sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-x64-musl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-musl/-/keyring-linux-x64-musl-1.3.0.tgz", + "integrity": "sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-arm64-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-arm64-msvc/-/keyring-win32-arm64-msvc-1.3.0.tgz", + "integrity": "sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-ia32-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-ia32-msvc/-/keyring-win32-ia32-msvc-1.3.0.tgz", + "integrity": "sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-x64-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-x64-msvc/-/keyring-win32-x64-msvc-1.3.0.tgz", + "integrity": "sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", + "integrity": "sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@quarto/annotated-qmd": { + "resolved": "ts-packages/annotated-qmd", + "link": true + }, + "node_modules/@quarto/hub-mcp": { + "resolved": "ts-packages/quarto-hub-mcp", + "link": true + }, + "node_modules/@quarto/pandoc-types": { + "resolved": "ts-packages/pandoc-types", + "link": true + }, + "node_modules/@quarto/preview-renderer": { + "resolved": "ts-packages/preview-renderer", + "link": true + }, + "node_modules/@quarto/preview-runtime": { + "resolved": "ts-packages/preview-runtime", + "link": true + }, + "node_modules/@quarto/quarto-automerge-schema": { + "resolved": "ts-packages/quarto-automerge-schema", + "link": true + }, + "node_modules/@quarto/quarto-sync-client": { + "resolved": "ts-packages/quarto-sync-client", + "link": true + }, + "node_modules/@quarto/sync-test-harness": { + "resolved": "ts-packages/sync-test-harness", + "link": true + }, + "node_modules/@quarto/trace-viewer": { + "resolved": "trace-viewer", + "link": true + }, + "node_modules/@quarto/wasm-js-bridge": { + "resolved": "ts-packages/wasm-js-bridge", + "link": true + }, + "node_modules/@react-oauth/google": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.13.4.tgz", + "integrity": "sha512-hGKyNEH+/PK8M0sFEuo3MAEk0txtHpgs94tDQit+s2LXg7b6z53NtzHfqDvoB2X8O6lGB+FRg80hY//X6hfD+w==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@revealjs/react": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@revealjs/react/-/react-0.2.0.tgz", + "integrity": "sha512-kIxl5rCttlVJFeSnWJostA80IbhuM5+GO2yjs6yHOpesyIuzpCZjsNjX1s+5bbb1BGwEIAbuE04KPLWxZR1XAw==", + "license": "MIT", + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18", + "reveal.js": ">=5" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", + "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", + "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", + "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", + "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", + "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", + "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", + "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", + "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", + "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", + "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", + "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", + "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", + "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", + "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", + "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", + "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", + "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", + "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", + "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", + "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", + "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", + "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", + "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", + "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", + "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__standalone": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__standalone/-/babel__standalone-7.1.9.tgz", + "integrity": "sha512-IcCNPLqpevUD7UpV8QB0uwQPOyoOKACFf0YtYWRHcmxcakaje4Q7dbG2+jMqxw/I8Zk0NHvEps66WwS7z/UaaA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.6", + "@babel/types": "^7.25.6", + "@types/babel__core": "^7.20.5", + "@types/babel__generator": "^7.6.8", + "@types/babel__template": "^7.4.4", + "@types/babel__traverse": "^7.20.6" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "license": "MIT" + }, + "node_modules/@types/morphdom": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/morphdom/-/morphdom-2.3.0.tgz", + "integrity": "sha512-xDWhsCHpQLCLKmJYjm2txI9VRU6mWuqOitkj+VNgb4SSu1jrPR/jgwPzKojQInM1AzSDiHwQ3ZenUygr50axsw==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz", + "integrity": "sha512-/6zU2FLGg0jsd+ePZcwHRy3+WpNTBBhDY56P4JTRqUN/Dp6CvOEa9HrikcQ4KfV2b2kAHUFB4dl1SuocWXSFEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.17", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.17", + "vitest": "4.0.17" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz", + "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz", + "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.17", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz", + "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz", + "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz", + "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.17", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz", + "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz", + "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.17", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", + "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", + "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^5.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001774", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", + "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, + "node_modules/cbor-x": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "license": "MIT", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "peer": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.6", - "@babel/types": "^7.25.6", - "@types/babel__core": "^7.20.5", - "@types/babel__generator": "^7.6.8", - "@types/babel__template": "^7.4.4", - "@types/babel__traverse": "^7.20.6" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/express-rate-limit": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", + "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fake-indexeddb": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.2.5.tgz", + "integrity": "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "license": "Apache-2.0" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-sha256": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", + "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", + "license": "Unlicense" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", "dev": true, "license": "MIT", - "dependencies": { - "@types/express": "*", - "@types/node": "*" + "engines": { + "node": ">= 0.4" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/@types/express": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", - "dev": true, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/serve-static": "^2" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", - "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", - "license": "MIT" - }, - "node_modules/@types/morphdom": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/morphdom/-/morphdom-2.3.0.tgz", - "integrity": "sha512-xDWhsCHpQLCLKmJYjm2txI9VRU6mWuqOitkj+VNgb4SSu1jrPR/jgwPzKojQInM1AzSDiHwQ3ZenUygr50axsw==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "25.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", - "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/@types/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { - "csstype": "^3.2.2" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "license": "ISC" }, - "node_modules/@types/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitejs/plugin-react": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", - "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.29.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-rc.3", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" + "dunder-proto": "^1.0.0" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 0.4" }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/coverage-v8": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz", - "integrity": "sha512-/6zU2FLGg0jsd+ePZcwHRy3+WpNTBBhDY56P4JTRqUN/Dp6CvOEa9HrikcQ4KfV2b2kAHUFB4dl1SuocWXSFEw==", - "dev": true, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.0.17", - "ast-v8-to-istanbul": "^0.3.10", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.2.0", - "magicast": "^0.5.1", - "obug": "^2.1.1", - "std-env": "^3.10.0", - "tinyrainbow": "^3.0.3" + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "4.0.17", - "vitest": "4.0.17" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/expect": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz", - "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.17", - "@vitest/utils": "4.0.17", - "chai": "^6.2.1", - "tinyrainbow": "^3.0.3" + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vitest/mocker": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz", - "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "@vitest/spy": "4.0.17", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0-0" + "function-bind": "^1.1.2" }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "engines": { + "node": ">= 0.4" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz", - "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==", + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hono": { + "version": "4.12.18", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.18.tgz", + "integrity": "sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "whatwg-encoding": "^3.1.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=18" } }, - "node_modules/@vitest/runner": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz", - "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, + "license": "MIT" + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.17", - "pathe": "^2.0.3" + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@vitest/snapshot": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz", - "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==", - "dev": true, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.17", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@vitest/spy": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz", - "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@vitest/utils": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz", - "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.17", - "tinyrainbow": "^3.0.3" + "agent-base": "^7.1.2", + "debug": "4" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 14" } }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "node_modules/hub-client": { + "resolved": "hub-client", + "link": true + }, + "node_modules/hub-kanban": { + "resolved": "q2-demos/kanban", + "link": true + }, + "node_modules/hub-react-todo": { + "resolved": "q2-demos/hub-react-todo", + "link": true + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "license": "MIT", "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "node_modules/idb": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz", + "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==", + "license": "ISC" + }, + "node_modules/immutable": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "license": "MIT" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14" + "node": ">=8" } }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 0.4" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/ip-address": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": ">= 12" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", - "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "dequal": "^2.0.3" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", - "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^9.0.1" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", - "license": "MIT" - }, - "node_modules/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", - "license": "MIT", + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">= 0.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, + "license": "MIT", "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, "license": "MIT", "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "license": "MIT", - "dependencies": { - "base-x": "^4.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/bs58check": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", - "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "^1.2.0", - "bs58": "^5.0.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", + "call-bound": "^1.0.3" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "is-extglob": "^2.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4260,2335 +7528,2457 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001774", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", - "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" + "license": "MIT" }, - "node_modules/cbor-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", - "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", - "hasInstallScript": true, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "node-gyp-build-optional-packages": "5.1.1" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, - "bin": { - "download-cbor-prebuilds": "bin/download-prebuilds.js" + "engines": { + "node": ">= 0.4" }, - "optionalDependencies": { - "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", - "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", - "@cbor-extract/cbor-extract-linux-x64": "2.2.0", - "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cbor-x": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", - "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, "license": "MIT", - "optionalDependencies": { - "cbor-extract": "^2.2.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 16" + "node": ">=0.10.0" } }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, "engines": { - "node": ">= 14.16.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "call-bound": "^1.0.3" }, "engines": { - "node": ">=7.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "mime-db": ">= 1.43.0 < 2" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.1.0", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.0.0" + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/compression/node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=6.6.0" + "node": ">=10" } }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "license": "MIT", + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "object-assign": "^4", - "vary": "^1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" }, "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/css-line-break": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", - "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "node_modules/jose": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", + "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, "license": "MIT" }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">=18" + "node": ">=6" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" + "universalify": "^2.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/katex": { + "version": "0.16.28", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", + "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], "license": "MIT", - "engines": { - "node": ">= 0.8" + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, - "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", - "license": "(MPL-2.0 OR Apache-2.0)", + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", "peer": true, - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" + "bin": { + "lz-string": "bin/bin.js" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "license": "Apache-2.0", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" + "semver": "^7.5.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", - "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", "engines": { - "node": ">=0.12" + "node": ">=18" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=4" } }, - "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" }, "engines": { - "node": ">=18" + "node": ">=16 || 14 >=14.17" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "node_modules/morphdom": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", + "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", "license": "MIT" }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", "license": "MIT", + "optional": true, "dependencies": { - "eventsource-parser": "^3.0.1" + "detect-libc": "^2.0.1" }, - "engines": { - "node": ">=18.0.0" + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" + "license": "MIT" + }, + "node_modules/oauth4webapi": { + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.6.tgz", + "integrity": "sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=0.10.0" } }, - "node_modules/express-rate-limit": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", - "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", - "dependencies": { - "ip-address": "^10.2.0" - }, "engines": { - "node": ">= 16" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fake-indexeddb": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.2.5.tgz", - "integrity": "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 0.4" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "license": "Apache-2.0" - }, - "node_modules/fast-sha256": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", - "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", - "license": "Unlicense" - }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.0.0" + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], "license": "MIT" }, - "node_modules/filelist": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", - "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", - "license": "Apache-2.0", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { - "minimatch": "^5.0.1" + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "wrappy": "1" } }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, "engines": { - "node": ">= 18.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, - "license": "ISC" + "license": "BlueOak-1.0.0" }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" + "entities": "^6.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">= 14.16" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "devOptional": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "node": ">=16.20.0" } }, - "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "node_modules/playwright": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", + "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", "dev": true, - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "playwright-core": "1.58.0" }, "bin": { - "glob": "dist/esm/bin.mjs" + "playwright": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/playwright-core": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", + "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/has-symbols": { + "node_modules/possible-typed-array-names": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/hono": { - "version": "4.12.18", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.18.tgz", - "integrity": "sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==", + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=16.9.0" + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "whatwg-encoding": "^3.1.1" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=18" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/html2canvas": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", - "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { - "css-line-break": "^2.1.0", - "text-segmentation": "^1.0.3" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.10" } }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/q2-preview-spa": { + "resolved": "q2-preview-spa", + "link": true + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" + "side-channel": "^1.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=0.6" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { - "node": ">= 14" + "node": ">= 0.6" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 0.10" } }, - "node_modules/hub-client": { - "resolved": "hub-client", - "link": true - }, - "node_modules/hub-kanban": { - "resolved": "q2-demos/kanban", - "link": true - }, - "node_modules/hub-react-todo": { - "resolved": "q2-demos/hub-react-todo", - "link": true - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/idb": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz", - "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==", - "license": "ISC" - }, - "node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", - "license": "MIT" - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", - "engines": { - "node": ">= 12" + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "node_modules/react-usestateref": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/react-usestateref/-/react-usestateref-1.0.9.tgz", + "integrity": "sha512-t8KLsI7oje0HzfzGhxFXzuwbf1z9vhBM1ptHLUIHhYqZDKFuI5tzdhEVxSNzUkYxwF8XdpOErzHlKxvP7sTERw==", + "license": "ISC", + "peerDependencies": { + "react": ">16.0.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/is-fullwidth-code-point": { + "node_modules/redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true, "license": "MIT" }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/isomorphic-ws": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, "license": "MIT", - "peerDependencies": { - "ws": "*" + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "jsesc": "~3.1.0" }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reveal.js": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-6.0.0.tgz", + "integrity": "sha512-RayDr1FL3Jglnf6p9xHGJ0U18va96PiuLs/JHnd1cdDOXvC+3lsXKe6ujl7PX0pvnhNW2Tpqnr6PEKpJVO2exw==", + "license": "MIT" + }, + "node_modules/reveal.js-menu": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/reveal.js-menu/-/reveal.js-menu-2.1.0.tgz", + "integrity": "sha512-35zp4fHSMyWd15+3CvQ8LrpS+4Gj2qvlkxX3lo5LpITDe6ZkA4A9y1E5fE63YlQl5fp7W1mNgNJr4kCU0s14lA==", + "license": "MIT, Copyright (C) 2020 Greg Denehy" + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "license": "Apache-2.0", + "node_modules/rollup": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", + "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", + "dev": true, + "license": "MIT", "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" + "@types/estree": "1.0.8" }, "bin": { - "jake": "bin/cli.js" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=10" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.4", + "@rollup/rollup-android-arm64": "4.60.4", + "@rollup/rollup-darwin-arm64": "4.60.4", + "@rollup/rollup-darwin-x64": "4.60.4", + "@rollup/rollup-freebsd-arm64": "4.60.4", + "@rollup/rollup-freebsd-x64": "4.60.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", + "@rollup/rollup-linux-arm-musleabihf": "4.60.4", + "@rollup/rollup-linux-arm64-gnu": "4.60.4", + "@rollup/rollup-linux-arm64-musl": "4.60.4", + "@rollup/rollup-linux-loong64-gnu": "4.60.4", + "@rollup/rollup-linux-loong64-musl": "4.60.4", + "@rollup/rollup-linux-ppc64-gnu": "4.60.4", + "@rollup/rollup-linux-ppc64-musl": "4.60.4", + "@rollup/rollup-linux-riscv64-gnu": "4.60.4", + "@rollup/rollup-linux-riscv64-musl": "4.60.4", + "@rollup/rollup-linux-s390x-gnu": "4.60.4", + "@rollup/rollup-linux-x64-gnu": "4.60.4", + "@rollup/rollup-linux-x64-musl": "4.60.4", + "@rollup/rollup-openbsd-x64": "4.60.4", + "@rollup/rollup-openharmony-arm64": "4.60.4", + "@rollup/rollup-win32-arm64-msvc": "4.60.4", + "@rollup/rollup-win32-ia32-msvc": "4.60.4", + "@rollup/rollup-win32-x64-gnu": "4.60.4", + "@rollup/rollup-win32-x64-msvc": "4.60.4", + "fsevents": "~2.3.2" } }, - "node_modules/jose": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", - "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, - "node_modules/jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", - "dev": true, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "license": "MIT", "dependencies": { - "cssstyle": "^4.2.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.5.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.16", - "parse5": "^7.2.1", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.1.1", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.1", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" }, - "engines": { - "node": ">=18" + "bin": { + "sass": "sass.js" }, - "peerDependencies": { - "canvas": "^3.0.0" + "engines": { + "node": ">=14.0.0" }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" }, "engines": { - "node": ">=6" + "node": ">=v12.22.7" } }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, - "license": "MIT", + "license": "ISC", "bin": { - "json5": "lib/cli.js" + "semver": "bin/semver.js" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/katex": { - "version": "0.16.28", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", - "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "commander": "^8.3.0" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, - "bin": { - "katex": "cli.js" + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "license": "ISC" + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", - "peer": true, - "bin": { - "lz-string": "bin/bin.js" + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/media-typer": { + "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { - "mime-db": "^1.54.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } + "license": "ISC" }, - "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "node_modules/smob": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", + "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=20.0.0" } }, - "node_modules/morphdom": { - "version": "2.7.8", - "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", - "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">= 8" } }, - "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT", - "optional": true - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "MIT" - }, - "node_modules/oauth4webapi": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.6.tgz", - "integrity": "sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "node_modules/source-map/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" + "punycode": "^2.1.0" } }, - "node_modules/on-headers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "node_modules/source-map/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "license": "BSD-2-Clause" }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", + "node_modules/source-map/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "license": "MIT", "dependencies": { - "wrappy": "1" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true, - "license": "BlueOak-1.0.0" + "license": "MIT" }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">= 14.16" + "node": ">=8" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "devOptional": true, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkce-challenge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", - "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/playwright": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", - "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "playwright-core": "1.58.0" - }, - "bin": { - "playwright": "cli.js" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, - "optionalDependencies": { - "fsevents": "2.3.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/playwright-core": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", - "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=18" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=4" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/q2-preview-spa": { - "resolved": "q2-preview-spa", - "link": true - }, - "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, + "license": "MIT", "engines": { - "node": ">=0.6" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, "license": "MIT", "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" + "min-indent": "^1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "js-tokens": "^9.0.1" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "react": "^19.2.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-usestateref": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/react-usestateref/-/react-usestateref-1.0.9.tgz", - "integrity": "sha512-t8KLsI7oje0HzfzGhxFXzuwbf1z9vhBM1ptHLUIHhYqZDKFuI5tzdhEVxSNzUkYxwF8XdpOErzHlKxvP7sTERw==", - "license": "ISC", - "peerDependencies": { - "react": ">16.0.0" + "node": ">=8" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, "engines": { - "node": ">= 14.18.0" + "node": ">=10" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "node_modules/terser": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.2.tgz", + "integrity": "sha512-uxfo9fPcSgLDYob/w1FuL0c99MWiJDnv+5qXSQc5+Ki5NjVNsYi66INnMFBjf6uFz6OnX12piJQPF4IpjJTNTw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" }, "engines": { - "node": ">=8" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, + "license": "MIT" + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "dependencies": { + "utrie": "^1.0.2" } }, - "node_modules/reveal.js": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-6.0.0.tgz", - "integrity": "sha512-RayDr1FL3Jglnf6p9xHGJ0U18va96PiuLs/JHnd1cdDOXvC+3lsXKe6ujl7PX0pvnhNW2Tpqnr6PEKpJVO2exw==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, "license": "MIT" }, - "node_modules/reveal.js-menu": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/reveal.js-menu/-/reveal.js-menu-2.1.0.tgz", - "integrity": "sha512-35zp4fHSMyWd15+3CvQ8LrpS+4Gj2qvlkxX3lo5LpITDe6ZkA4A9y1E5fE63YlQl5fp7W1mNgNJr4kCU0s14lA==", - "license": "MIT, Copyright (C) 2020 Greg Denehy" + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, - "node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "glob": "^10.3.7" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, - "bin": { - "rimraf": "dist/esm/bin.mjs" + "engines": { + "node": ">=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/rollup": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", - "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.4", - "@rollup/rollup-android-arm64": "4.60.4", - "@rollup/rollup-darwin-arm64": "4.60.4", - "@rollup/rollup-darwin-x64": "4.60.4", - "@rollup/rollup-freebsd-arm64": "4.60.4", - "@rollup/rollup-freebsd-x64": "4.60.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", - "@rollup/rollup-linux-arm-musleabihf": "4.60.4", - "@rollup/rollup-linux-arm64-gnu": "4.60.4", - "@rollup/rollup-linux-arm64-musl": "4.60.4", - "@rollup/rollup-linux-loong64-gnu": "4.60.4", - "@rollup/rollup-linux-loong64-musl": "4.60.4", - "@rollup/rollup-linux-ppc64-gnu": "4.60.4", - "@rollup/rollup-linux-ppc64-musl": "4.60.4", - "@rollup/rollup-linux-riscv64-gnu": "4.60.4", - "@rollup/rollup-linux-riscv64-musl": "4.60.4", - "@rollup/rollup-linux-s390x-gnu": "4.60.4", - "@rollup/rollup-linux-x64-gnu": "4.60.4", - "@rollup/rollup-linux-x64-musl": "4.60.4", - "@rollup/rollup-openbsd-x64": "4.60.4", - "@rollup/rollup-openharmony-arm64": "4.60.4", - "@rollup/rollup-win32-arm64-msvc": "4.60.4", - "@rollup/rollup-win32-ia32-msvc": "4.60.4", - "@rollup/rollup-win32-x64-gnu": "4.60.4", - "@rollup/rollup-win32-x64-msvc": "4.60.4", - "fsevents": "~2.3.2" + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" + "tldts-core": "^6.1.86" }, - "engines": { - "node": ">= 18" + "bin": { + "tldts": "bin/cli.js" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT" }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sass": { - "version": "1.97.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", - "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.0.2", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" + "tldts": "^6.1.32" }, "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" + "node": ">=16" } }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "xmlchars": "^2.2.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">=v12.22.7" + "node": ">=18" } }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, "bin": { - "semver": "bin/semver.js" + "tsx": "dist/cli.mjs" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" } }, - "node_modules/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - }, + "node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">= 18" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">= 0.6" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -6597,14 +9987,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -6613,790 +10008,1048 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=4" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, - "engines": { - "node": ">=12" + "bin": { + "update-browserslist-db": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "base64-arraybuffer": "^1.0.2" } }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", + "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=12" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/vite-plugin-pwa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz", + "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.10", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "node": ">=16.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^1.0.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "node_modules/vite-plugin-wasm": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.5.0.tgz", + "integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==", "dev": true, "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" + "peerDependencies": { + "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "node_modules/vitest": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz", + "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", "dev": true, "license": "MIT", "dependencies": { - "js-tokens": "^9.0.1" + "@vitest/expect": "4.0.17", + "@vitest/mocker": "4.0.17", + "@vitest/pretty-format": "4.0.17", + "@vitest/runner": "4.0.17", + "@vitest/snapshot": "4.0.17", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { - "url": "https://github.com/sponsors/antfu" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.17", + "@vitest/browser-preview": "4.0.17", + "@vitest/browser-webdriverio": "4.0.17", + "@vitest/ui": "4.0.17", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/text-segmentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", - "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", - "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" + "node": ">=18" } }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, + "node_modules/web-tree-sitter": { + "version": "0.26.8", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.8.tgz", + "integrity": "sha512-4sUwi7ZyOrIk5KLgYLkc2A/F0LFMQnBhfb+2Cdl7ik4ePJ6JD+fk4ofI2sA5eGawBKBaK4Vntt7Ww5KcEsay4A==", "license": "MIT" }, - "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=12" } }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" + "iconv-lite": "0.6.3" }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" }, - "bin": { - "tldts": "bin/cli.js" + "engines": { + "node": ">=18" } }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=0.6" + "node": ">= 8" } }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "tldts": "^6.1.32" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" }, "engines": { - "node": ">=16" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.3.1" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { - "node": ">=18" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tsx": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", - "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.27.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" }, "engines": { - "node": ">=18.0.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, "license": "MIT", "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "license": "Apache-2.0", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "why-is-node-running": "cli.js" }, "engines": { - "node": ">=14.17" + "node": ">=8" } }, - "node_modules/undici": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", - "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "node_modules/workbox-background-sync": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz", + "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==", "dev": true, "license": "MIT", - "engines": { - "node": ">=20.18.1" + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.4.0" } }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "node_modules/workbox-background-sync/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "node_modules/workbox-broadcast-update": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz", + "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-build": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz", + "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==", + "dev": true, "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^11.0.1", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.79.2", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.4.0", + "workbox-broadcast-update": "7.4.0", + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-google-analytics": "7.4.0", + "workbox-navigation-preload": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-range-requests": "7.4.0", + "workbox-recipes": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0", + "workbox-streams": "7.4.0", + "workbox-sw": "7.4.0", + "workbox-window": "7.4.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/workbox-build/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 0.8" + "node": ">=18" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "node_modules/workbox-build/node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" }, - "bin": { - "update-browserslist-db": "cli.js" + "engines": { + "node": ">= 10.0.0" }, "peerDependencies": { - "browserslist": ">= 4.21.0" + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } } }, - "node_modules/utrie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", - "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "node_modules/workbox-build/node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, "license": "MIT", "dependencies": { - "base64-arraybuffer": "^1.0.2" + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" } }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "node_modules/workbox-build/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/workbox-build/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": "18 || 20 || >=22" } }, - "node_modules/vite": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", - "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", + "node_modules/workbox-build/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", - "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "node_modules/workbox-build/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" }, "bin": { - "vite-node": "vite-node.mjs" + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "20 || >=22" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vite-plugin-wasm": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.5.0.tgz", - "integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==", + "node_modules/workbox-build/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, - "license": "MIT", - "peerDependencies": { - "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vitest": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz", - "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", + "node_modules/workbox-build/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/workbox-build/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.0.17", - "@vitest/mocker": "4.0.17", - "@vitest/pretty-format": "4.0.17", - "@vitest/runner": "4.0.17", - "@vitest/snapshot": "4.0.17", - "@vitest/spy": "4.0.17", - "@vitest/utils": "4.0.17", - "es-module-lexer": "^1.7.0", - "expect-type": "^1.2.2", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^3.10.0", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.0.3", - "vite": "^6.0.0 || ^7.0.0", - "why-is-node-running": "^2.3.0" + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/workbox-build/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" }, - "bin": { - "vitest": "vitest.mjs" + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.17", - "@vitest/browser-preview": "4.0.17", - "@vitest/browser-webdriverio": "4.0.17", - "@vitest/ui": "4.0.17", - "happy-dom": "*", - "jsdom": "*" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.80.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz", + "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==", "dev": true, "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=18" + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/web-tree-sitter": { - "version": "0.26.8", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.26.8.tgz", - "integrity": "sha512-4sUwi7ZyOrIk5KLgYLkc2A/F0LFMQnBhfb+2Cdl7ik4ePJ6JD+fk4ofI2sA5eGawBKBaK4Vntt7Ww5KcEsay4A==", + "node_modules/workbox-cacheable-response": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz", + "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-core": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz", + "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==", + "dev": true, "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "node_modules/workbox-expiration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz", + "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.4.0" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "node_modules/workbox-expiration/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/workbox-google-analytics": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz", + "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==", "dev": true, "license": "MIT", "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" + "workbox-background-sync": "7.4.0", + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "node_modules/workbox-navigation-preload": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz", + "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "workbox-core": "7.4.0" } }, - "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "node_modules/workbox-precaching": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz", + "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", + "node_modules/workbox-range-requests": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz", + "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "workbox-core": "7.4.0" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "node_modules/workbox-recipes": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz", + "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==", "dev": true, "license": "MIT", "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz", + "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz", + "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0" + } + }, + "node_modules/workbox-streams": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz", + "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz", + "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-window": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz", + "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.4.0" } }, "node_modules/wrap-ansi": { @@ -8021,9 +11674,11 @@ "dependencies": { "@quarto/preview-runtime": "*", "@quarto/quarto-automerge-schema": "*", + "@revealjs/react": "^0.2.0", "morphdom": "^2.7.8", "react": "^19.2.0", - "react-dom": "^19.2.0" + "react-dom": "^19.2.0", + "reveal.js": "^6.0.0" }, "devDependencies": { "@testing-library/jest-dom": "^6.6.3", From 013787cb70def2de6d02d4c68fe7666d5ad07b9d Mon Sep 17 00:00:00 2001 From: elliot Date: Tue, 9 Jun 2026 14:14:15 -0400 Subject: [PATCH 3/8] attempt undo rebase --- .beads/.gitignore | 6 + .beads/README.md | 19 + .beads/issues.jsonl | 446 +- .beads/metadata.json | 3 +- .braid-project | 1 + .braid/README.md | 38 + .braid/snapshot.jsonl | 1145 + .cargo/config.toml | 1 + .claude/rules/integration-tests.md | 94 + .claude/rules/wasm.md | 39 + .claude/rules/worktrees.md | 195 +- .claude/rules/xtask.md | 2 + .claude/skills/braid/SKILL.md | 26 + .claude/skills/investigate-beads/SKILL.md | 128 + .../references/plan-skeleton-template.md | 67 + .claude/skills/preview-render-parity/SKILL.md | 283 + .../skills/reader-expectations-prose/SKILL.md | 115 + .claude/skills/triage/SKILL.md | 121 + .../triage/references/triage-doc-template.md | 49 + .claude/skills/upgrade-cargo-deps/PINS.md | 130 + .claude/skills/upgrade-cargo-deps/SKILL.md | 315 + .config/nextest.toml | 39 + .github/workflows/hub-client-e2e.yml | 85 +- .github/workflows/test-suite.yml | 33 +- .github/workflows/ts-test-suite.yml | 11 +- .gitignore | 11 + .mcp.json | 4 +- .nvmrc | 1 + CLAUDE.md | 189 +- Cargo.lock | 1324 +- Cargo.toml | 36 +- README.md | 101 +- ...2026-04-28-ci-disk-space-and-profile-ci.md | 184 + .../2026-05-01-bd-f5yi-sidebar-after-fix.png | Bin 0 -> 531566 bytes .../native-1000.png | Bin 0 -> 104216 bytes .../native-1100.png | Bin 0 -> 105802 bytes .../native-1200.png | Bin 0 -> 106562 bytes .../native-1400.png | Bin 0 -> 106408 bytes .../native-1600.png | Bin 0 -> 109349 bytes .../native-767.png | Bin 0 -> 88537 bytes .../native-768.png | Bin 0 -> 95171 bytes .../native-800.png | Bin 0 -> 94962 bytes .../native-900.png | Bin 0 -> 96813 bytes .../post-fix-1200.png | Bin 0 -> 106562 bytes .../post-fix-800.png | Bin 0 -> 94013 bytes .../post-fix-900.png | Bin 0 -> 96041 bytes .../post-fix-992.png | Bin 0 -> 103793 bytes .../post-fix-hub-preview-1200.png | Bin 0 -> 108073 bytes claude-notes/architecture/01-pipeline.md | 186 + claude-notes/architecture/02-crates.md | 189 + .../architecture/03-hub-client-automerge.md | 150 + .../architecture/04-q2-preview-wasm.md | 106 + claude-notes/architecture/README.md | 92 + claude-notes/architecture/automerge.svg | 169 + claude-notes/architecture/crates.svg | 188 + claude-notes/architecture/pipeline.svg | 317 + claude-notes/architecture/q2-preview-wasm.svg | 146 + .../designs/attribution-encoding-contract.md | 129 + .../designs/body-link-resolution-contract.md | 162 + .../designs/document-profile-contract.md | 411 + .../sidebar-auto-expansion-contract.md | 158 + .../designs/wire-format-source-info-codes.md | 101 + .../instructions/auth-verification.md | 340 + .../instructions/hub-mcp-operator-runbook.md | 195 + .../instructions/performance-profiling.md | 39 + .../instructions/preview-spa-rebuild.md | 144 + claude-notes/instructions/replay-engine.md | 149 + claude-notes/instructions/testing.md | 79 +- claude-notes/issue-reports/152/exp-mixed.qmd | 5 + claude-notes/issue-reports/152/exp-prefix.qmd | 6 + claude-notes/issue-reports/152/exp-suffix.qmd | 5 + .../issue-reports/152/q236-repro-variants.qmd | 58 + claude-notes/issue-reports/152/q236-repro.qmd | 7 + claude-notes/issue-reports/152/q236-triage.md | 144 + claude-notes/issue-reports/152/repro.qmd | 5 + claude-notes/issue-reports/152/triage.md | 139 + claude-notes/issue-reports/161/repro.qmd | 3 + .../issue-reports/161/round-trip-1.qmd | 5 + claude-notes/issue-reports/161/triage.md | 135 + claude-notes/issue-reports/173/repro.qmd | 4 + claude-notes/issue-reports/173/repro.sh | 24 + claude-notes/issue-reports/173/triage.md | 148 + .../issue-reports/175/exp-empty-body-row.qmd | 4 + claude-notes/issue-reports/175/repro.qmd | 4 + claude-notes/issue-reports/175/triage.md | 173 + .../issue-reports/180/repro-figure-figure.qmd | 3 + .../issue-reports/180/repro-figure-para.qmd | 3 + .../issue-reports/180/repro-layout-div.qmd | 8 + .../180/repro-para-figure-OK.qmd | 3 + claude-notes/issue-reports/180/triage.md | 184 + .../issue-reports/181/exp-blank-lines.qmd | 7 + .../181/exp-fenced-code-in-bq.qmd | 5 + .../issue-reports/181/exp-no-blockquote.qmd | 3 + .../issue-reports/181/exp-only-math.qmd | 3 + claude-notes/issue-reports/181/repro.qmd | 5 + claude-notes/issue-reports/181/triage.md | 189 + .../issue-reports/182/repro-no-space.qmd | 1 + .../issue-reports/182/repro-with-space.qmd | 1 + claude-notes/issue-reports/182/triage.md | 189 + .../183/exp-single-codeblock.qmd | 6 + .../issue-reports/183/exp-two-paras.qmd | 6 + .../issue-reports/183/expected-output.qmd | 9 + .../issue-reports/183/observed-output.qmd | 9 + claude-notes/issue-reports/183/repro.qmd | 8 + claude-notes/issue-reports/183/triage.md | 250 + claude-notes/issue-reports/184/repro.qmd | 7 + claude-notes/issue-reports/184/triage.md | 101 + .../issue-reports/195/repro-list-table.qmd | 6 + .../issue-reports/195/repro-plain.qmd | 4 + claude-notes/issue-reports/195/triage.md | 207 + .../issue-reports/196/exp-bullet-list.qmd | 3 + .../issue-reports/196/exp-no-trailing-ws.qmd | 3 + .../issue-reports/196/exp-tab-on-blank.qmd | 3 + .../196/exp-trailing-ws-text.qmd | 3 + .../196/exp-two-trailing-spaces.qmd | 3 + claude-notes/issue-reports/196/repro.qmd | 3 + claude-notes/issue-reports/196/triage.md | 120 + claude-notes/issue-reports/201/repro.qmd | 1 + claude-notes/issue-reports/201/triage.md | 130 + claude-notes/issue-reports/205/repro.json | 1 + claude-notes/issue-reports/205/repro.qmd | 1 + claude-notes/issue-reports/205/triage.md | 223 + .../issue-reports/206/exp-blank-line.qmd | 6 + .../issue-reports/206/exp-caption-no-div.qmd | 4 + .../issue-reports/206/exp-heading-after.qmd | 4 + .../issue-reports/206/exp-heading-between.qmd | 6 + .../206/exp-no-div-just-colons.qmd | 4 + .../issue-reports/206/exp-para-after.qmd | 4 + claude-notes/issue-reports/206/repro.qmd | 5 + claude-notes/issue-reports/206/triage.md | 141 + claude-notes/issue-reports/222/repro.qmd | 1 + claude-notes/issue-reports/222/triage.md | 157 + .../plans/2026-04-23-website-project-epic.md | 878 + .../plans/2026-04-23-websites-phase-0.md | 641 + .../plans/2026-04-23-websites-phase-1.md | 829 + .../2026-04-24-include-expansion-merge.md | 483 + .../plans/2026-04-24-websites-phase-2.md | 1142 + .../plans/2026-04-24-websites-phase-3.md | 1149 + .../plans/2026-04-24-websites-phase-4.md | 877 + .../plans/2026-04-24-websites-phase-5.md | 1190 + .../plans/2026-04-24-websites-phase-6.md | 1154 + .../plans/2026-04-27-websites-phase-7.md | 1145 + .../plans/2026-04-27-websites-phase-8.md | 1507 + .../plans/2026-04-27-websites-phase-9.md | 1185 + ...6-04-29-bd-swpy-nav-href-relativization.md | 440 + .../plans/2026-04-29-sidebar-default-title.md | 334 + .../plans/2026-04-29-website-examples.md | 322 + .../2026-04-29-website-sidebar-layout.md | 353 + .../plans/2026-04-30-page-nav-q1-parity.md | 431 + ...4-30-sidebar-title-home-link-relativize.md | 416 + .../2026-04-30-sidebar-vertical-border.md | 313 + ...30-tree-sitter-backtick-paragraph-split.md | 238 + ...5-01-default-project-render-diagnostics.md | 304 + .../2026-05-01-default-project-theme-flush.md | 316 + ...2026-05-01-hub-client-website-render-ux.md | 403 + .../2026-05-01-website-link-navigation.md | 348 + .../2026-05-01-website-sidebar-breakpoints.md | 358 + .../plans/2026-05-03-project-resources.md | 680 + ...2026-05-03-publish-command-and-gh-pages.md | 1169 + .../plans/2026-05-03-replay-engine.md | 141 + .../plans/2026-05-03-trace-size-for-replay.md | 317 + .../2026-05-04-bootstrap-js-injection.md | 230 + ...26-05-04-cargo-dependency-upgrade-skill.md | 255 + .../2026-05-04-cargo-upgrade-execution.md | 107 + .../plans/2026-05-04-cargo-upgrade-survey.md | 116 + .../plans/2026-05-04-includes-feature.md | 527 + ...jupyter-kernelspec-discovery-and-errors.md | 231 + .../plans/2026-05-04-math-mode-handoff.md | 181 + claude-notes/plans/2026-05-04-math-mode.md | 842 + .../2026-05-04-q2-preview-plan-1-pipeline.md | 912 + ...04-q2-preview-plan-2a-iframe-foundation.md | 871 + ...4-q2-preview-plan-2b-builtin-components.md | 1466 + ...04-q2-preview-plan-3-filter-idempotence.md | 311 + ...-04-q2-preview-plan-4-source-info-types.md | 360 + ...026-05-04-q2-preview-plan-5-wire-format.md | 310 + ...5-04-q2-preview-plan-6-provenance-audit.md | 268 + ...04-q2-preview-plan-7-incremental-writer.md | 804 + ...4-q2-preview-plan-7a-filter-idempotence.md | 449 + ...-04-q2-preview-plan-8-include-roundtrip.md | 402 + .../plans/2026-05-04-vendored-deps-audit.md | 174 + ...5-doctemplate-diagnostics-quarto-render.md | 511 + ...5-05-hub-mcp-device-flow-implementation.md | 1827 + ...026-05-05-listings-L0-profile-extension.md | 896 + .../2026-05-05-listings-L1-autofill-stage.md | 950 + .../2026-05-05-listings-design-discussion.md | 989 + .../plans/2026-05-05-listings-epic.md | 863 + ...026-05-06-attribution-pipeline-flow-v2.svg | 320 + .../plans/2026-05-06-attribution-pipeline.md | 2340 + .../2026-05-06-listings-L2-data-model.md | 769 + ...026-05-06-listings-L3-resolve-transform.md | 1726 + ...26-05-06-listings-L5-categories-sidebar.md | 1350 + .../plans/2026-05-07-create-worktree-xtask.md | 453 + ...-07-debug-render-components-not-loading.md | 149 + .../plans/2026-05-07-listings-L6-dep-graph.md | 874 + ...26-05-07-listings-L7-postrender-upgrade.md | 1683 + ...2026-05-07-listings-L8-custom-templates.md | 1142 + ...-05-07-q2-preview-plan-2pre-restructure.md | 586 + ...026-05-07-render-components-live-reload.md | 219 + .../2026-05-08-listings-L11-close-out.md | 341 + .../plans/2026-05-08-listings-L9-rss-feeds.md | 2076 + ...q2-preview-plan-2c-customnode-rendering.md | 775 + ...05-10-q2-preview-plan-2d-body-container.md | 1017 + ...-q2-preview-plan-2e-q2-slides-migration.md | 289 + ...026-05-10-thread-user-grammars-renderer.md | 322 + .../2026-05-11-bq-multiline-in-list-item.md | 432 + .../2026-05-11-hub-client-decomposition.md | 1027 + ...6-05-11-implement-create-worktree-xtask.md | 2156 + .../plans/2026-05-11-q2-preview-epic.md | 789 + .../2026-05-11-vite-preview-for-e2e-tests.md | 129 + ...2026-05-12-displaymath-column-strip-fix.md | 248 + .../2026-05-13-q2-preview-attribution.md | 440 + .../plans/2026-05-13-q2-preview-phase-a.md | 500 + .../plans/2026-05-13-q2-preview-phase-b.md | 433 + .../plans/2026-05-13-q2-preview-phase-c.md | 407 + .../2026-05-14-attribution-auto-viewer.md | 524 + .../2026-05-14-issue-195-empty-list-items.md | 257 + ...-issue-196-list-continuation-regression.md | 95 + ...26-05-14-list-table-multiblock-cell-fix.md | 109 + ...-05-14-q-2-35-indented-code-block-error.md | 146 + ...-05-14-q-2-36-knitr-style-chunk-options.md | 191 + .../plans/2026-05-14-q2-preview-phase-d.md | 265 + .../plans/2026-05-14-q2-preview-phase-f.md | 497 + ...2026-05-15-attribution-lua-binding-plan.md | 431 + ...-05-15-fix-pipe-table-caption-collision.md | 127 + .../2026-05-15-issue-201-apostrophe-escape.md | 159 + .../plans/2026-05-15-quiet-default-logging.md | 237 + .../plans/2026-05-18-bare-lt-as-str.md | 367 + ...-05-18-q2-preview-project-replay-engine.md | 447 + ...5-19-bd-i6jy4-capture-driver-qmd-filter.md | 180 + ...2026-05-19-bd-tnm3k-single-file-preview.md | 132 + .../plans/2026-05-19-code-block-features.md | 813 + .../2026-05-20-auth-provider-interface.md | 650 + ...0-bd-6qbto-error-generation-utf8-safety.md | 205 + ...6-05-20-bd-8d6rk-navigation-diagnostics.md | 297 + ...5-20-bd-c05x6-body-link-source-location.md | 216 + ...05-20-bd-qor9a-metadata-path-resolution.md | 380 + .../plans/2026-05-20-brand-yml-support.md | 556 + ...2026-05-20-heading-in-list-item-dropped.md | 158 + ...-20-issue-222-deterministic-diagnostics.md | 132 + ...-20-preview-navbar-brand-artifacts-link.md | 257 + .../2026-05-20-render-no-project-skip-walk.md | 276 + ...26-05-20-render-truncates-source-images.md | 433 + ...26-05-20-table-default-rendering-parity.md | 350 + ...26-05-21-q2-preview-diagnostics-ariadne.md | 254 + ...26-05-21-q2-preview-diagnostics-surface.md | 615 + .../2026-05-21-q2-render-website-profile.md | 174 + ...05-21-resource-directory-recursive-copy.md | 249 + .../2026-05-21-resource-path-diagnostic.md | 247 + .../2026-05-21-resource-path-leading-slash.md | 162 + ...2026-05-22-callout-class-vocabulary-fix.md | 225 + .../plans/2026-05-22-diagnostic-coalescing.md | 263 + .../2026-05-22-engine-discovery-cache.md | 254 + .../plans/2026-05-22-error-docs-content.md | 184 + .../plans/2026-05-22-error-docs-foundation.md | 326 + .../plans/2026-05-22-error-docs-tooling.md | 244 + .../2026-05-22-error-docs-website-epic.md | 201 + .../plans/2026-05-22-pampa-hash-fileids.md | 282 + .../plans/2026-05-22-parallelize-pass-one.md | 510 + .../plans/2026-05-22-q2-render-json-errors.md | 628 + .../plans/2026-05-22-theme-diagnostic-epic.md | 126 + .../2026-05-22-theme-diagnostic-structured.md | 302 + .../2026-05-22-worktree-disk-reclamation.md | 182 + ...-inline-code-triple-asterisk-regression.md | 357 + .../2026-05-24-multiline-inline-code-spans.md | 655 + .../2026-05-27-multi-engine-execution.md | 672 + .../plans/2026-05-28-hub-mcp-loopback-pkce.md | 1191 + ...26-05-28-integration-test-consolidation.md | 316 + .../2026-05-28-mermaidjs-engine-design.md | 635 + ...-30-bd-1lpkx-star-emphasis-opening-mark.md | 171 + ...26-05-30-hub-path-traversal-containment.md | 316 + .../plans/2026-06-01-import-from-zip.md | 255 + .../plans/2026-06-01-parallelize-pass-two.md | 214 + .../plans/2026-06-01-render-perf-profiling.md | 180 + .../plans/2026-06-02-get-config-command.md | 273 + ...2026-06-02-render-error-warning-summary.md | 305 + .../2026-06-03-codeblock-trailing-margin.md | 178 + ...6-08-braid-0.3.0-features-for-migration.md | 151 + .../plans/2026-06-08-braid-migration.md | 275 + .../2026-06-08-revealjs-presentations.md | 646 + .../plans/2026-06-09-metadata-as-str-audit.md | 261 + ...026-06-09-named-footnote-ref-resolution.md | 248 + .../2026-06-09-revealjs-docs-and-examples.md | 277 + .../5qnj-trace-size-investigation/big.qmd | 243 + .../measurements.md | 225 + .../5qnj-trace-size-investigation/medium.qmd | 125 + .../5qnj-trace-size-investigation/tiny.qmd | 12 + .../bd-352bh-screenshot-ariadne-expanded.png | Bin 0 -> 610875 bytes .../bd-352bh-screenshot-ariadne-q120.png | Bin 0 -> 218506 bytes .../bd-b9kzg-screenshot-1-q13-4-body-link.png | Bin 0 -> 504519 bytes ...bd-b9kzg-screenshot-2-styled-collapsed.png | Bin 0 -> 508082 bytes .../bd-b9kzg-screenshot-3-styled-expanded.png | Bin 0 -> 557116 bytes .../repro-and-codepath.md | 112 + .../2026-05-05-editable-custom-nodes.md | 239 + ...-05-19-PreviewDocument-merge-resolution.md | 189 + .../2026-05-19-attribution-merge-briefing.md | 466 + .../2026-05-21-quarto-web-render-profile.md | 500 + ...-quarto-web-parallel-pass1-profile.json.gz | Bin 0 -> 465478 bytes ...-web-parallel-pass1-profile.json.syms.json | 1 + ...6-05-22-quarto-web-postfix-profile.json.gz | Bin 0 -> 64896 bytes ...-quarto-web-postfix-profile.json.syms.json | 1 + .../2026-05-24-tracing-envfilter-mismatch.md | 219 + .../2026-05-28-integration-test-bloat.md | 264 + .../research/commonmark-spec/README.md | 66 + .../commonmark-spec/examples-index.md | 664 + .../research/commonmark-spec/index.md | 52 + .../commonmark-spec/scripts/spec-example.sh | 61 + .../commonmark-spec/scripts/spec-section.sh | 89 + .../research/measurements/baseline-debug.log | 656 + .../measurements/baseline-release.log | 656 + .../controlled-baseline-debug.log | 655 + .../controlled-baseline-release.log | 655 + .../measurements/controlled-pilot-debug.log | 655 + .../measurements/controlled-pilot-release.log | 655 + .../measurements/pampa-pilot-debug.log | 655 + .../measurements/pampa-pilot-release.log | 655 + .../measurements/phase6-baseline-debug.log | 655 + .../measurements/phase6-baseline-release.log | 655 + .../measurements/phase6-rollout-debug.log | 655 + .../measurements/phase6-rollout-release.log | 655 + .../vendored-dependencies-inventory.md | 475 + crates/comrak-to-pandoc/Cargo.toml | 2 +- .../tests/{ => integration}/debug.rs | 2 - .../tests/{ => integration}/debug_comrak.rs | 2 - .../tests/{ => integration}/differential.rs | 0 .../tests/{ => integration}/generators.rs | 0 .../tests/integration/main.rs | 10 + .../{ => integration}/proptest_roundtrip.rs | 6 +- crates/pampa/Cargo.toml | 14 +- crates/pampa/README.md | 16 + .../pampa/resources/error-corpus/Q-2-12.json | 4 +- .../pampa/resources/error-corpus/Q-2-24.json | 16 +- .../pampa/resources/error-corpus/Q-2-35.json | 32 + .../pampa/resources/error-corpus/Q-2-36.json | 26 + .../pampa/resources/error-corpus/Q-2-37.json | 29 + .../pampa/resources/error-corpus/Q-2-38.json | 118 + .../error-corpus/_autogen-table.json | 3276 +- .../error-corpus/case-files/Q-2-24-simple.qmd | 1 - .../error-corpus/case-files/Q-2-35-basic.qmd | 5 + .../case-files/Q-2-35-indented-blockquote.qmd | 3 + .../case-files/Q-2-35-more-than-four.qmd | 5 + .../case-files/Q-2-35-tab-indent.qmd | 5 + .../case-files/Q-2-36-bare-label.qmd | 3 + .../case-files/Q-2-36-comma-and-kv.qmd | 3 + .../case-files/Q-2-36-comma-args.qmd | 3 + .../case-files/Q-2-37-after-scheme.qmd | 2 + .../case-files/Q-2-37-before-close-paren.qmd | 2 + .../case-files/Q-2-37-mid-destination.qmd | 2 + .../case-files/Q-2-38-eof-after-class.qmd | 1 + .../case-files/Q-2-38-eof-after-id.qmd | 1 + .../case-files/Q-2-38-eof-after-kv.qmd | 1 + .../Q-2-38-image-multi-line-eof.qmd | 2 + .../Q-2-38-multi-line-eof-class-and-kv.qmd | 3 + .../Q-2-38-multi-line-eof-two-classes.qmd | 3 + .../Q-2-38-multi-line-eof-two-kvs.qmd | 3 + .../case-files/Q-2-38-multi-line-eof.qmd | 2 + .../json/anchor-shorthand-06-empty.snap | 3 +- .../native/heading-and-plain-list-items.snap | 5 + .../native/heading-in-bullet-list-item.snap | 5 + .../native/heading-in-ordered-list-item.snap | 5 + ...ssue-206-fenced-div-close-after-table.snap | 6 + .../snapshots/native/list-table-basic.snap | 5 +- .../snapshots/native/list-table-colspan.snap | 5 +- .../native/list-table-with-alignments.snap | 5 +- .../native/list-table-with-caption.snap | 5 +- crates/pampa/src/attribution.rs | 70 + crates/pampa/src/config_json.rs | 387 + crates/pampa/src/json_filter.rs | 1 + crates/pampa/src/lib.rs | 4 + crates/pampa/src/lua/dofile_wasm.rs | 60 +- crates/pampa/src/lua/filter.rs | 38 +- crates/pampa/src/lua/filter_tests.rs | 2224 +- crates/pampa/src/lua/mod.rs | 3 +- crates/pampa/src/lua/quarto_api.rs | 138 + crates/pampa/src/lua/quarto_doc.rs | 55 + crates/pampa/src/lua/types.rs | 71 + crates/pampa/src/main.rs | 3 + crates/pampa/src/pandoc/treesitter.rs | 602 +- .../treesitter_utils/code_span_helpers.rs | 87 +- .../treesitter_utils/language_specifier.rs | 3 +- .../pandoc/treesitter_utils/postprocess.rs | 15 +- .../pandoc/treesitter_utils/text_helpers.rs | 112 +- crates/pampa/src/readers/qmd.rs | 17 +- .../pampa/src/readers/qmd_error_messages.rs | 62 +- crates/pampa/src/unified_filter.rs | 39 +- crates/pampa/src/wasm_entry_points/mod.rs | 1 + crates/pampa/src/writers/html.rs | 951 +- crates/pampa/src/writers/html_source.rs | 1 + crates/pampa/src/writers/json.rs | 175 + crates/pampa/src/writers/qmd.rs | 351 +- .../test-fixtures/schemas/definitions.yml | 43 + .../attribution_html_coalescing_test.rs | 429 + .../integration/attribution_json_wire_test.rs | 233 + .../{ => integration}/error_node_analysis.rs | 0 .../incremental_writer_investigation.rs | 0 .../incremental_writer_tests.rs | 0 .../inline_span_investigation.rs | 0 .../inline_splice_integration_tests.rs | 0 .../inline_splice_property_tests.rs | 0 .../inline_splice_safety_tests.rs | 0 .../{ => integration}/json_location_test.rs | 3 + .../json_reader_smoke_tests.rs | 0 crates/pampa/tests/integration/main.rs | 73 + .../qmd_writer_source_info.rs | 0 crates/pampa/tests/{ => integration}/test.rs | 35 +- .../{ => integration}/test_ansi_writer.rs | 0 .../test_attr_source_parsing.rs | 279 + .../test_attr_source_structure.rs | 0 .../tests/integration/test_bare_lt_str.rs | 179 + .../test_blockquote_multiline_attrs.rs | 155 + .../test_citeproc_integration.rs | 0 .../{ => integration}/test_cli_input_arg.rs | 0 .../test_code_block_attributes.rs | 38 +- .../tests/{ => integration}/test_code_span.rs | 0 .../test_diagnostic_determinism.rs | 63 + .../test_editorial_mark_spacing.rs | 0 .../integration/test_emphasis_opening_mark.rs | 66 + .../{ => integration}/test_error_corpus.rs | 4 +- .../integration/test_grid_table_error.rs | 146 + .../{ => integration}/test_hard_soft_break.rs | 0 .../test_html_attr_handling.rs | 0 .../test_inline_locations.rs | 0 .../test_json_div_transforms.rs | 145 +- .../{ => integration}/test_json_errors.rs | 0 .../{ => integration}/test_json_roundtrip.rs | 0 .../test_link_destination_linebreak.rs | 80 + .../{ => integration}/test_location_health.rs | 0 .../test_lua_attr_mutation.rs | 1 + .../test_lua_constructors.rs | 1 + .../tests/{ => integration}/test_lua_list.rs | 1 + .../tests/{ => integration}/test_lua_utils.rs | 1 + .../tests/{ => integration}/test_math_attr.rs | 0 .../tests/{ => integration}/test_meta.rs | 0 .../test_metadata_source_tracking.rs | 0 .../test_nested_yaml_serialization.rs | 0 .../test_ordered_list_formatting.rs | 0 .../test_rawblock_to_config_value.rs | 0 .../{ => integration}/test_section_divs.rs | 0 .../tests/{ => integration}/test_shortcode.rs | 0 .../test_template_integration.rs | 0 .../test_trailing_linebreak_commonmark.rs | 0 .../test_treesitter_coverage.rs | 0 .../test_treesitter_refactoring.rs | 93 + .../test_unclosed_attr_specifier.rs | 131 + .../test_unicode_error_offsets.rs | 0 .../test_unicode_whitespace.rs | 0 .../tests/{ => integration}/test_warnings.rs | 231 +- .../test_wasm_entrypoints.rs | 0 .../test_whitespace_re_compile_once.rs | 74 + .../test_yaml_tag_regression.rs | 0 .../test_yaml_to_config_value.rs | 0 .../markdown/bq-multiline-in-list-minus.qmd | 2 + .../bq-multiline-in-list-ordered-dot.qmd | 2 + .../bq-multiline-in-list-ordered-paren.qmd | 2 + .../markdown/bq-multiline-in-list-plus.qmd | 2 + .../markdown/bq-multiline-in-list-star.qmd | 2 + .../bq-multiline-in-list-then-paragraph.qmd | 4 + .../bq-multiline-in-list-three-lines.qmd | 3 + .../inline-code-multiline-absorbs-blocks.qmd | 3 + .../inline-code-multiline-blockquote-lazy.qmd | 2 + ...nline-code-multiline-blockquote-nested.qmd | 2 + .../inline-code-multiline-blockquote.qmd | 2 + .../inline-code-multiline-doubled-space.qmd | 2 + .../inline-code-multiline-list-loose.qmd | 4 + .../inline-code-multiline-list-nested.qmd | 3 + .../markdown/inline-code-multiline-list.qmd | 3 + .../markdown/inline-code-multiline-simple.qmd | 2 + .../inline-code-multiline-three-lines.qmd | 3 + .../markdown/inline-code-quad-star.qmd | 1 + .../markdown/inline-code-triple-star-only.qmd | 1 + .../inline-code-triple-star-prefix.qmd | 1 + .../inline-code-triple-star-suffix.qmd | 1 + .../inline-math-multiline-blockquote.qmd | 2 + .../markdown/inline-math-multiline-list.qmd | 2 + .../markdown/inline-math-multiline-simple.qmd | 2 + .../apostrophe_after_code_inline.qmd | 1 + .../qmd-json-qmd/apostrophe_after_emph.qmd | 1 + .../apostrophe_at_block_start.qmd | 1 + .../qmd-json-qmd/apostrophe_before_punct.qmd | 1 + .../qmd-json-qmd/apostrophe_before_space.qmd | 1 + .../attr_value_backslash_escaped_punct.qmd | 3 + .../qmd-json-qmd/attr_value_escaped_quote.qmd | 3 + .../attr_value_literal_backslash.qmd | 3 + .../qmd-json-qmd/bare_lt_eol.qmd | 1 + .../qmd-json-qmd/bare_lt_simple.qmd | 1 + .../qmd-json-qmd/bare_lt_unclosed_tag.qmd | 1 + .../code_span_then_html_with_space.qmd | 1 + .../qmd-json-qmd/codeblock_empty.qmd | 2 + .../codeblock_only_blank_lines.qmd | 4 + .../codeblock_trailing_double_newline.qmd | 5 + .../codeblock_trailing_newline.qmd | 4 + .../display_math_in_blockquote.qmd | 5 + .../display_math_in_blockquote_in_list.qmd | 3 + .../display_math_in_bq_list_bq.qmd | 3 + .../display_math_in_list_in_blockquote.qmd | 3 + .../display_math_in_nested_blockquote.qmd | 3 + .../emph_around_multiline_display_math.qmd | 4 + ...d_multiline_display_math_in_blockquote.qmd | 4 + .../qmd-json-qmd/empty_bullet_item_nested.qmd | 4 + .../qmd-json-qmd/empty_bullet_item_only.qmd | 1 + .../empty_bullet_item_trailing.qmd | 2 + .../empty_ordered_item_trailing.qmd | 2 + .../figure_implicit_then_figure.qmd | 3 + .../figure_implicit_then_para.qmd | 3 + .../qmd-json-qmd/inline_backslash_space.qmd | 1 + ...inline_backslash_space_paragraph_start.qmd | 1 + .../labeled_display_math_in_blockquote.qmd | 5 + ...abeled_display_math_top_level_indented.qmd | 4 + .../qmd-json-qmd/layout_div_subfigures.qmd | 8 + .../list_table_cell_para_then_codeblock.qmd | 8 + .../list_table_cell_single_codeblock.qmd | 6 + .../list_table_cell_two_paragraphs.qmd | 6 + .../qmd-json-qmd/list_table_empty_cell.qmd | 6 + .../list_table_empty_cell_with_attrs.qmd | 5 + .../qmd-json-qmd/pipe_table_empty_header.qmd | 4 + .../qmd-json-qmd/rawblock_html.qmd | 3 + .../qmd-json-qmd/rawblock_latex.qmd | 3 + .../table-caption-with-classes.qmd | 5 + .../qmd-json-qmd/table-caption-with-id.qmd | 5 + .../table-caption-with-keyval.qmd | 5 + .../table-caption-with-mixed-attrs.qmd | 5 + .../table_with_inline_nbsp_in_cell.qmd | 3 + .../native/heading-and-plain-list-items.qmd | 2 + .../native/heading-in-bullet-list-item.qmd | 1 + .../native/heading-in-ordered-list-item.qmd | 1 + ...issue-206-fenced-div-close-after-table.qmd | 5 + crates/perf-harness/Cargo.toml | 4 + crates/perf-harness/src/bin/parse_corpus.rs | 145 + .../perf-harness/src/bin/parse_qmd_to_ast.rs | 1 + .../apostrophe_quotes_test.rs | 0 .../attribute_ordering_test.rs | 0 .../{ => integration}/grid_tables_test.rs | 0 .../tests/integration/main.rs | 25 + .../tests/{ => integration}/q_2_11_test.rs | 0 .../tests/{ => integration}/q_2_12_test.rs | 0 .../tests/{ => integration}/q_2_13_test.rs | 0 .../tests/{ => integration}/q_2_15_test.rs | 0 .../tests/{ => integration}/q_2_16_test.rs | 0 .../tests/{ => integration}/q_2_17_test.rs | 0 .../tests/{ => integration}/q_2_18_test.rs | 0 .../tests/{ => integration}/q_2_19_test.rs | 0 .../tests/{ => integration}/q_2_20_test.rs | 0 .../tests/{ => integration}/q_2_21_test.rs | 0 .../tests/{ => integration}/q_2_22_test.rs | 0 .../tests/{ => integration}/q_2_23_test.rs | 0 .../tests/{ => integration}/q_2_24_test.rs | 0 .../tests/{ => integration}/q_2_25_test.rs | 0 .../tests/{ => integration}/q_2_26_test.rs | 0 .../tests/{ => integration}/q_2_28_test.rs | 0 .../tests/{ => integration}/q_2_5_test.rs | 0 crates/quarto-brand/Cargo.toml | 19 + crates/quarto-brand/src/error.rs | 19 + crates/quarto-brand/src/lib.rs | 30 + crates/quarto-brand/src/resolve.rs | 203 + crates/quarto-brand/src/types.rs | 574 + crates/quarto-brand/tests/fixtures/README.md | 18 + .../brand-yaml/kitchen-sink/_brand.yml | 52 + .../kitchen-sink/brand-typography.qmd | 38 + .../brand-yaml/monospace-colors/_brand.yml | 6 + .../monospace-colors/brand-typography.qmd | 30 + .../brand-yaml/palette-colors/_brand.yml | 18 + .../palette-colors/brand-typography.qmd | 32 + .../fixtures/use-brand/basic-brand/README.md | 3 + .../fixtures/use-brand/basic-brand/_brand.yml | 12 + .../basic-brand/fonts/custom-font.woff2 | 1 + .../fixtures/use-brand/basic-brand/logo.png | Bin 0 -> 1862 bytes .../use-brand/multi-file-brand/_brand.yml | 23 + .../use-brand/multi-file-brand/favicon.png | Bin 0 -> 1169 bytes .../multi-file-brand/fonts/brand-bold.woff2 | 1 + .../fonts/brand-regular.woff2 | 1 + .../fonts/unused-italic.woff2 | 1 + .../use-brand/multi-file-brand/logo.png | Bin 0 -> 1862 bytes .../multi-file-brand/unused-styles.css | 2 + .../use-brand/nested-brand/_brand.yml | 8 + .../nested-brand/images/extra-icon.png | 1 + .../use-brand/nested-brand/images/header.png | Bin 0 -> 2209 bytes .../use-brand/nested-brand/images/logo.png | Bin 0 -> 1862 bytes .../fixtures/use-brand/nested-brand/notes.txt | 1 + .../tests/integration/color_test.rs | 99 + .../tests/integration/logo_test.rs | 106 + crates/quarto-brand/tests/integration/main.rs | 9 + .../tests/integration/parse_test.rs | 116 + .../tests/integration/typography_test.rs | 121 + crates/quarto-citeproc/Cargo.toml | 2 +- .../{ => integration}/csl_conformance.rs | 0 .../tests/{ => integration}/error_tests.rs | 0 .../quarto-citeproc/tests/integration/main.rs | 7 + crates/quarto-config/src/lib.rs | 3 + crates/quarto-config/src/website.rs | 302 + crates/quarto-core/Cargo.toml | 61 +- crates/quarto-core/resources/styles.css | 94 +- crates/quarto-core/src/artifact.rs | 377 +- crates/quarto-core/src/attribution/builder.rs | 94 + .../quarto-core/src/attribution/git_blame.rs | 304 + crates/quarto-core/src/attribution/handle.rs | 124 + crates/quarto-core/src/attribution/mod.rs | 123 + crates/quarto-core/src/attribution/mode.rs | 40 + crates/quarto-core/src/attribution/palette.rs | 123 + .../src/attribution/pampa_bridge.rs | 101 + .../quarto-core/src/attribution/prebuilt.rs | 62 + crates/quarto-core/src/attribution/resolve.rs | 29 + crates/quarto-core/src/attribution/source.rs | 80 + crates/quarto-core/src/attribution/types.rs | 252 + crates/quarto-core/src/dependency.rs | 20 +- crates/quarto-core/src/document_profile.rs | 1655 + .../quarto-core/src/engine/capture_splice.rs | 612 + crates/quarto-core/src/engine/context.rs | 10 +- crates/quarto-core/src/engine/detection.rs | 263 +- crates/quarto-core/src/engine/fixture.rs | 447 + .../quarto-core/src/engine/jupyter/error.rs | 49 +- .../quarto-core/src/engine/jupyter/execute.rs | 4 + .../src/engine/jupyter/kernelspec.rs | 28 +- crates/quarto-core/src/engine/jupyter/mod.rs | 105 +- crates/quarto-core/src/engine/knitr/mod.rs | 4 +- .../src/engine/knitr/subprocess.rs | 46 + crates/quarto-core/src/engine/mod.rs | 37 +- .../quarto-core/src/engine/preview_record.rs | 484 + crates/quarto-core/src/engine/registry.rs | 44 +- crates/quarto-core/src/engine/replay.rs | 308 + crates/quarto-core/src/format.rs | 218 +- crates/quarto-core/src/get_config.rs | 71 + crates/quarto-core/src/lib.rs | 19 +- crates/quarto-core/src/output_sink.rs | 659 + crates/quarto-core/src/pipeline.rs | 1642 +- crates/quarto-core/src/project/cache_key.rs | 393 + .../src/project/dependency_graph.rs | 1070 + crates/quarto-core/src/project/discovery.rs | 587 + crates/quarto-core/src/project/index.rs | 167 + .../src/project/listing/binding.rs | 794 + .../quarto-core/src/project/listing/config.rs | 1345 + .../src/project/listing/feed/binding.rs | 1078 + .../src/project/listing/feed/complete.rs | 669 + .../src/project/listing/feed/link_inject.rs | 455 + .../src/project/listing/feed/mod.rs | 68 + .../src/project/listing/feed/reader_ext.rs | 573 + .../src/project/listing/feed/stage.rs | 1061 + .../listing/feed/templates/item.template | 10 + .../listing/feed/templates/postamble.template | 2 + .../listing/feed/templates/preamble.template | 22 + .../quarto-core/src/project/listing/filter.rs | 309 + .../src/project/listing/helpers.rs | 449 + .../quarto-core/src/project/listing/item.rs | 211 + crates/quarto-core/src/project/listing/mod.rs | 76 + .../src/project/listing/placeholders.rs | 311 + .../project/listing/post_render_upgrade.rs | 57 + .../listing/post_render_upgrade/reader.rs | 520 + .../listing/post_render_upgrade/substitute.rs | 1087 + .../quarto-core/src/project/listing/sort.rs | 257 + .../src/project/listing/templates.rs | 93 + .../listing/templates/item-default.template | 63 + .../listing/templates/item-grid.template | 67 + .../listing/templates/item-table.template | 1 + .../templates/listing-default.template | 5 + .../listing/templates/listing-grid.template | 5 + .../listing/templates/listing-table.template | 7 + .../src/{project.rs => project/mod.rs} | 249 +- .../quarto-core/src/project/orchestrator.rs | 1992 + .../quarto-core/src/project/pass2_renderer.rs | 1128 + .../quarto-core/src/project/profile_cache.rs | 453 + .../src/project/sidebar_membership.rs | 361 + .../quarto-core/src/project/website_config.rs | 200 + .../src/project/website_post_render.rs | 888 + crates/quarto-core/src/project_resources.rs | 1658 + crates/quarto-core/src/render.rs | 267 +- crates/quarto-core/src/render_to_file.rs | 650 +- crates/quarto-core/src/resource_resolver.rs | 700 + crates/quarto-core/src/resources.rs | 89 +- crates/quarto-core/src/revealjs/assemble.rs | 233 + crates/quarto-core/src/revealjs/columns.rs | 149 + crates/quarto-core/src/revealjs/footnotes.rs | 391 + crates/quarto-core/src/revealjs/mod.rs | 30 + crates/quarto-core/src/revealjs/slides.rs | 366 + crates/quarto-core/src/revealjs/transform.rs | 159 + crates/quarto-core/src/stage/context.rs | 231 +- crates/quarto-core/src/stage/data.rs | 80 +- crates/quarto-core/src/stage/error.rs | 18 + crates/quarto-core/src/stage/mod.rs | 14 +- crates/quarto-core/src/stage/observer.rs | 27 + .../src/stage/stages/apply_template.rs | 427 +- .../src/stage/stages/ast_transforms.rs | 73 +- .../src/stage/stages/attribution_generate.rs | 254 + .../src/stage/stages/bootstrap_js.rs | 574 + .../src/stage/stages/capture_splice.rs | 201 + .../src/stage/stages/clipboard_js.rs | 502 + .../src/stage/stages/code_highlight.rs | 20 +- .../src/stage/stages/compile_theme_css.rs | 784 +- .../src/stage/stages/document_profile.rs | 444 + .../src/stage/stages/engine_execution.rs | 1226 +- .../src/stage/stages/include_expansion.rs | 38 +- .../src/stage/stages/include_resolve.rs | 1128 + .../src/stage/stages/link_resolution.rs | 678 + .../src/stage/stages/listing_item_info.rs | 867 + .../quarto-core/src/stage/stages/math_js.rs | 1003 + .../src/stage/stages/metadata_merge.rs | 27 +- crates/quarto-core/src/stage/stages/mod.rs | 53 +- .../src/stage/stages/parse_document.rs | 1 + .../src/stage/stages/pre_engine_sugaring.rs | 2 + .../src/stage/stages/render_html.rs | 51 +- .../src/stage/stages/resource_report.rs | 279 + .../src/stage/stages/unwrap_profile.rs | 93 + .../src/stage/stages/user_filters.rs | 25 + crates/quarto-core/src/stage/trace.rs | 143 + crates/quarto-core/src/template.rs | 716 +- crates/quarto-core/src/theme_diagnostic.rs | 364 + crates/quarto-core/src/transform.rs | 12 + crates/quarto-core/src/transforms/appendix.rs | 45 +- .../src/transforms/attribution_generate.rs | 109 + .../src/transforms/attribution_render.rs | 352 + .../src/transforms/attribution_viewer.rs | 251 + crates/quarto-core/src/transforms/callout.rs | 20 +- .../src/transforms/callout_resolve.rs | 1176 +- .../src/transforms/categories_sidebar.rs | 970 + .../src/transforms/code_block_generate.rs | 848 + .../src/transforms/code_block_render.rs | 770 + crates/quarto-core/src/transforms/config.rs | 55 + .../src/transforms/footer_generate.rs | 194 +- .../src/transforms/footer_render.rs | 315 +- .../quarto-core/src/transforms/footnotes.rs | 127 +- .../src/transforms/link_rewrite.rs | 700 + .../src/transforms/listing_generate.rs | 505 + .../src/transforms/listing_render.rs | 1544 + .../src/transforms/metadata_normalize.rs | 8 +- crates/quarto-core/src/transforms/mod.rs | 46 +- .../src/transforms/navbar_generate.rs | 285 +- .../src/transforms/navbar_render.rs | 639 +- .../src/transforms/navigation_active.rs | 219 + .../src/transforms/navigation_enrich.rs | 206 + .../src/transforms/navigation_href.rs | 1450 + .../src/transforms/page_nav_generate.rs | 629 + .../src/transforms/page_nav_render.rs | 469 + .../src/transforms/resource_collector.rs | 221 +- .../src/transforms/sidebar_auto.rs | 722 + .../src/transforms/sidebar_generate.rs | 630 + .../src/transforms/sidebar_render.rs | 791 + .../src/transforms/table_bootstrap_class.rs | 324 + .../src/transforms/toc_generate.rs | 13 +- .../src/transforms/website_bootstrap_icons.rs | 135 + .../src/transforms/website_canonical_url.rs | 254 + .../src/transforms/website_favicon.rs | 370 + .../src/transforms/website_title_prefix.rs | 274 + .../tests/fixtures/attribution-blame/REGEN.md | 49 + .../tests/fixtures/attribution-blame/doc.qmd | 7 + .../attribution-blame/multi-commit.porcelain | 29 + .../attribution-blame/single-commit.porcelain | 13 + .../phase5-single-doc-baseline/doc.qmd | 7 + .../expected_hashes.txt | 128 + .../PRE_PHASE5_OUTPUT.md | 68 + .../phase5-website-baseline/_quarto.yml | 10 + .../phase5-website-baseline/about.qmd | 5 + .../phase5-website-baseline/docs/api.qmd | 5 + .../phase5-website-baseline/index.qmd | 5 + .../fixtures/websites/hub-smoke/_quarto.yml | 10 + .../fixtures/websites/hub-smoke/about.qmd | 8 + .../fixtures/websites/hub-smoke/index.qmd | 9 + .../websites/hub-smoke/posts/first.qmd | 10 + .../integration/artifact_scoping_pipeline.rs | 358 + .../attribution_baseline_snapshot.rs | 73 + .../attribution_chain_resolution.rs | 89 + .../tests/integration/attribution_cli.rs | 114 + .../tests/integration/attribution_generate.rs | 366 + .../tests/integration/attribution_gitblame.rs | 296 + .../tests/integration/attribution_render.rs | 426 + .../tests/integration/attribution_types.rs | 254 + .../tests/integration/attribution_viewer.rs | 327 + .../integration/attribution_wasm_invariant.rs | 206 + .../integration/bootstrap_js_pipeline.rs | 376 + .../tests/integration/brand_render.rs | 179 + .../{ => integration}/crossref_fixtures.rs | 0 .../integration/document_profile_pipeline.rs | 636 + .../tests/integration/engine_merge.rs | 135 + .../tests/integration/fail_fast.rs | 225 + .../tests/integration/get_config_merge.rs | 145 + .../integration/include_resolve_pipeline.rs | 234 + .../tests/integration/incremental_rebuild.rs | 920 + .../{ => integration}/jupyter_integration.rs | 0 .../integration/link_rewriting_pipeline.rs | 524 + .../tests/integration/listing_pipeline.rs | 887 + crates/quarto-core/tests/integration/main.rs | 43 + .../tests/integration/math_mode_pipeline.rs | 312 + .../integration/metadata_path_resolution.rs | 296 + .../integration/navbar_footer_pipeline.rs | 400 + .../tests/{ => integration}/navigation_e2e.rs | 11 +- .../{ => integration}/navigation_merge.rs | 0 .../integration/page_navigation_pipeline.rs | 609 + .../tests/integration/project_pipeline.rs | 805 + .../tests/integration/project_resources.rs | 895 + .../integration/render_page_in_project.rs | 1035 + .../render_preserves_source_files.rs | 142 + .../render_to_html_user_grammars.rs | 159 + .../tests/integration/replay_engine.rs | 264 + .../tests/integration/revealjs_features.rs | 447 + .../tests/integration/revealjs_format.rs | 206 + .../tests/integration/sidebar_pipeline.rs | 502 + ...ne_snapshot__attribution_off_baseline.snap | 19 + ...in_default_with_categories_cloud_mode.snap | 19 + ..._default_with_categories_default_mode.snap | 20 + ...fault_with_categories_unnumbered_mode.snap | 19 + ..._with_two_listings_aggregates_sidebar.snap | 12 + .../tests/integration/website_post_render.rs | 667 + .../tests/{ => integration}/error_tests.rs | 0 .../tests/{ => integration}/integration.rs | 0 crates/quarto-csl/tests/integration/main.rs | 7 + crates/quarto-doctemplate/Cargo.toml | 1 + crates/quarto-doctemplate/src/evaluator.rs | 121 +- crates/quarto-doctemplate/src/lib.rs | 3 +- crates/quarto-doctemplate/src/parser.rs | 47 +- crates/quarto-doctemplate/src/pipes.rs | 782 + crates/quarto-doctemplate/src/resolver.rs | 68 + .../{ => integration}/integration_tests.rs | 0 .../tests/integration/main.rs | 7 + .../{ => integration}/pandoc_equiv_tests.rs | 0 .../CONTRIBUTING-ERRORS.md | 2 +- crates/quarto-error-reporting/Cargo.toml | 9 + crates/quarto-error-reporting/README.md | 4 +- .../quarto-error-reporting/error_catalog.json | 478 +- .../schemas/json-diagnostic.json | 145 + .../schemas/json-pass1-failure.json | 173 + crates/quarto-error-reporting/src/builder.rs | 20 + crates/quarto-error-reporting/src/catalog.rs | 102 + crates/quarto-error-reporting/src/coalesce.rs | 461 + .../quarto-error-reporting/src/diagnostic.rs | 54 +- crates/quarto-error-reporting/src/json.rs | 480 + crates/quarto-error-reporting/src/lib.rs | 18 + .../tests/schema_drift.rs | 133 + .../tests/{ => integration}/all_languages.rs | 0 .../tests/{ => integration}/annotate.rs | 0 .../tests/{ => integration}/golden.rs | 2 +- .../tests/integration/main.rs | 11 + .../tests/{ => integration}/python_basic.rs | 0 .../snapshots/integration__golden__bash.snap} | 0 .../snapshots/integration__golden__css.snap} | 0 .../snapshots/integration__golden__html.snap} | 0 .../integration__golden__javascript.snap} | 0 ...ration__golden__javascript_jsx_alias.snap} | 0 .../snapshots/integration__golden__json.snap} | 0 .../integration__golden__julia.snap} | 0 .../snapshots/integration__golden__lua.snap} | 0 .../integration__golden__python.snap} | 0 .../snapshots/integration__golden__r.snap} | 0 .../snapshots/integration__golden__sql.snap} | 0 .../snapshots/integration__golden__tsx.snap} | 0 .../integration__golden__typescript.snap} | 0 ...tegration__golden__user_grammar_toml.snap} | 0 .../snapshots/integration__golden__yaml.snap} | 0 .../tests/{ => integration}/trait_provider.rs | 0 .../{ => integration}/user_grammar_toml.rs | 0 crates/quarto-hub/Cargo.toml | 13 +- crates/quarto-hub/src/auth.rs | 526 +- crates/quarto-hub/src/context.rs | 269 +- crates/quarto-hub/src/discovery.rs | 111 +- crates/quarto-hub/src/index.rs | 347 +- crates/quarto-hub/src/main.rs | 33 +- crates/quarto-hub/src/server.rs | 676 +- crates/quarto-hub/src/storage.rs | 20 + crates/quarto-hub/src/sync.rs | 209 +- crates/quarto-hub/src/sync_state.rs | 2 +- crates/quarto-hub/src/watch.rs | 333 +- crates/quarto-hub/tests/auth_bearer.rs | 1324 + crates/quarto-lsp-core/src/types.rs | 3 +- crates/quarto-lsp/tests/integration_test.rs | 21 +- crates/quarto-navigation/Cargo.toml | 1 + crates/quarto-navigation/src/footer.rs | 63 +- crates/quarto-navigation/src/item.rs | 125 +- crates/quarto-navigation/src/lib.rs | 7 + crates/quarto-navigation/src/navbar.rs | 114 +- crates/quarto-navigation/src/page_nav.rs | 152 + crates/quarto-navigation/src/render_html.rs | 1058 +- crates/quarto-navigation/src/sidebar.rs | 1749 + crates/quarto-parse-errors/Cargo.toml | 1 + .../src/error_generation.rs | 399 +- crates/quarto-parse-errors/src/lib.rs | 4 +- .../src/tree_sitter_log.rs | 27 +- crates/quarto-preview/Cargo.toml | 44 + crates/quarto-preview/build.rs | 118 + crates/quarto-preview/src/cache.rs | 537 + crates/quarto-preview/src/capture_driver.rs | 1042 + crates/quarto-preview/src/config.rs | 200 + crates/quarto-preview/src/deps.rs | 362 + crates/quarto-preview/src/diagnostics.rs | 317 + crates/quarto-preview/src/lib.rs | 377 + crates/quarto-preview/src/re_execute.rs | 512 + .../quarto-preview/tests/integration/boot.rs | 135 + .../tests/integration/cache_hit.rs | 148 + .../diagnostics_capture_failure.rs | 141 + .../tests/integration/diagnostics_endpoint.rs | 149 + .../tests/integration/eager_capture.rs | 205 + .../quarto-preview/tests/integration/main.rs | 12 + .../quarto-preview/tests/integration/smoke.rs | 98 + .../tests/integration/staleness.rs | 219 + crates/quarto-publish/Cargo.toml | 39 + crates/quarto-publish/src/cli.rs | 248 + crates/quarto-publish/src/common/errors.rs | 15 + crates/quarto-publish/src/common/git.rs | 387 + crates/quarto-publish/src/common/github.rs | 526 + crates/quarto-publish/src/common/mod.rs | 9 + .../quarto-publish/src/common/publish_yml.rs | 315 + crates/quarto-publish/src/common/wait.rs | 209 + crates/quarto-publish/src/config.rs | 146 + crates/quarto-publish/src/execute.rs | 416 + crates/quarto-publish/src/gh_pages/mod.rs | 11 + .../quarto-publish/src/gh_pages/provider.rs | 694 + crates/quarto-publish/src/host.rs | 402 + crates/quarto-publish/src/lib.rs | 28 + crates/quarto-publish/src/provider.rs | 380 + crates/quarto-publish/src/renderer.rs | 42 + crates/quarto-publish/src/types.rs | 453 + crates/quarto-publish/tests/gh_pages_e2e.rs | 586 + crates/quarto-sass/Cargo.toml | 11 +- crates/quarto-sass/build.rs | 20 +- crates/quarto-sass/src/brand_layer.rs | 609 + crates/quarto-sass/src/compile.rs | 231 + crates/quarto-sass/src/config.rs | 486 +- crates/quarto-sass/src/error.rs | 63 +- crates/quarto-sass/src/lib.rs | 5 +- crates/quarto-sass/src/themes.rs | 153 +- .../tests/integration/brand_compile_test.rs | 104 + .../tests/integration/brand_config_test.rs | 217 + .../tests/integration/brand_layer_test.rs | 365 + .../compile_all_themes_test.rs | 67 + .../{ => integration}/custom_theme_test.rs | 0 .../embedded_compile_test.rs | 0 crates/quarto-sass/tests/integration/main.rs | 12 + .../tests/{ => integration}/parity_test.rs | 0 crates/quarto-source-map/src/file_info.rs | 35 +- crates/quarto-source-map/src/source_info.rs | 27 + crates/quarto-system-runtime/Cargo.toml | 18 +- crates/quarto-system-runtime/src/traits.rs | 31 + crates/quarto-system-runtime/src/wasm.rs | 20 + crates/quarto-test/src/runner.rs | 8 + crates/quarto-test/src/spec.rs | 10 + crates/quarto-trace-server/src/lib.rs | 61 +- crates/quarto-trace/Cargo.toml | 2 + crates/quarto-trace/src/lib.rs | 149 +- crates/quarto-trace/src/read.rs | 147 +- crates/quarto-trace/src/write.rs | 138 +- crates/quarto-trace/tests/roundtrip.rs | 657 +- crates/quarto-util/src/lib.rs | 6 + crates/quarto-util/src/user_status.rs | 41 + crates/quarto-util/src/verbose.rs | 75 + crates/quarto-xml/src/parser.rs | 77 +- .../JSON-OUTPUT-SCHEMA.md | 2 +- crates/quarto-yaml-validation/src/error.rs | 4 +- .../comprehensive_schemas.rs | 12 +- .../tests/integration/main.rs | 10 + .../tests/{ => integration}/real_schemas.rs | 2 +- .../{ => integration}/schema_compilation.rs | 0 .../{ => integration}/schema_inheritance.rs | 0 .../validation_diagnostic.rs | 0 crates/quarto-yaml/src/lib.rs | 2 +- crates/quarto-yaml/src/parser.rs | 29 +- crates/quarto/Cargo.toml | 14 +- crates/quarto/src/commands/get_config.rs | 118 + crates/quarto/src/commands/hub.rs | 10 + crates/quarto/src/commands/mod.rs | 1 + crates/quarto/src/commands/preview.rs | 555 +- crates/quarto/src/commands/publish.rs | 425 +- crates/quarto/src/commands/render.rs | 1913 +- crates/quarto/src/main.rs | 293 +- .../tests/integration/attribution_cli_e2e.rs | 519 + .../tests/integration/get_config_cli.rs | 194 + .../quarto/tests/integration/json_errors.rs | 331 + crates/quarto/tests/integration/main.rs | 14 + .../quarto/tests/integration/preview_cli.rs | 77 + .../tests/integration/render_cli_e2e.rs | 794 + .../{ => integration}/render_integration.rs | 6 +- .../quarto/tests/integration/revealjs_cli.rs | 112 + .../tests/{ => integration}/smoke_all.rs | 0 .../tests/{ => integration}/trace_cli.rs | 8 +- .../includes/crossref/placeholder.png} | 0 .../tests/smoke-all/q2-debug/reactji.tsx | 87 + .../q2-debug/render-components-reactji.qmd | 18 + .../body-classes-full-layout-combo.qmd | 22 + .../q2-preview/body-classes-override.qmd | 18 + .../q2-preview/body-container-default.qmd | 17 + .../q2-preview/body-container-full-layout.qmd | 18 + .../body-container-minimal-title.qmd | 23 + .../q2-preview/body-container-minimal.qmd | 19 + .../tests/smoke-all/q2-preview/hero.png | Bin 0 -> 69 bytes .../smoke-all/q2-preview/image-with-attrs.qmd | 22 + .../q2-preview/multi-element-doc.qmd | 52 + .../multi-element-project/_quarto.yml | 2 + .../q2-preview/multi-element-project/hero.png | Bin 0 -> 69 bytes .../multi-element-project/index.qmd | 50 + .../multi-element-project/notes.qmd | 5 + .../q2-preview/title-block-date-no-author.qmd | 21 + .../q2-preview/title-block-default.qmd | 20 + .../smoke-all/q2-preview/title-block-full.qmd | 25 + .../q2-preview/title-block-multi-author.qmd | 22 + .../q2-preview/title-block-no-title.qmd | 18 + .../with-render-components/_quarto.yml | 2 + .../with-render-components/index.qmd | 27 + .../with-render-components/overrides.tsx | 28 + .../smoke-all/quarto-test/callouts-matrix.qmd | 118 + .../grammar/Cargo.toml | 2 +- crates/tree-sitter-qmd/CMakeLists.txt | 65 - crates/tree-sitter-qmd/CONTRIBUTING.md | 81 - crates/tree-sitter-qmd/Makefile | 5 - crates/tree-sitter-qmd/Package.resolved | 16 - crates/tree-sitter-qmd/Package.swift | 55 - crates/tree-sitter-qmd/README.md | 34 +- .../tree-sitter-qmd/README.tree-sitter-md.md | 81 - crates/tree-sitter-qmd/binding.gyp | 23 - .../bindings/go/binding_test.go | 22 - .../tree-sitter-qmd/bindings/go/markdown.go | 14 - .../bindings/go/markdown_inline.go | 14 - .../tree-sitter-qmd/bindings/node/binding.cc | 29 - .../bindings/node/binding_test.js | 16 - .../tree-sitter-qmd/bindings/node/index.d.ts | 30 - crates/tree-sitter-qmd/bindings/node/index.js | 8 - .../tree-sitter-qmd/bindings/node/inline.js | 1 - .../bindings/python/tests/test_binding.py | 17 - .../python/tree_sitter_markdown/__init__.py | 5 - .../python/tree_sitter_markdown/__init__.pyi | 3 - .../python/tree_sitter_markdown/binding.c | 35 - .../tree-sitter-qmd/bindings/rust/parser.rs | 65 +- .../tree-sitter-qmd/bindings/swift/.gitignore | 1 - .../TreeSitterMarkdownTests.swift | 20 - crates/tree-sitter-qmd/common/common.mak | 94 - crates/tree-sitter-qmd/go.mod | 9 - crates/tree-sitter-qmd/package-lock.json | 376 - crates/tree-sitter-qmd/package.json | 54 - crates/tree-sitter-qmd/pyproject.toml | 32 - crates/tree-sitter-qmd/scripts/build.js | 12 - crates/tree-sitter-qmd/scripts/test.js | 18 - crates/tree-sitter-qmd/setup.py | 62 - .../tree-sitter-markdown/CMakeLists.txt | 9 - .../tree-sitter-markdown/Makefile | 5 - .../__pycache__/migrate_tests.cpython-313.pyc | Bin 9612 -> 0 bytes .../bindings/c/tree-sitter-markdown.h | 16 - .../bindings/c/tree-sitter-markdown.pc.in | 11 - .../swift/TreeSitterMarkdown/markdown.h | 16 - .../tree-sitter-markdown/grammar.js | 161 +- .../tree-sitter-markdown/package.json | 8 - .../scripts/unicode-ranges.py | 15 +- .../tree-sitter-markdown/src/grammar.json | 132 +- .../tree-sitter-markdown/src/node-types.json | 46 +- .../tree-sitter-markdown/src/parser.c | 206015 ++++++++------- .../tree-sitter-markdown/src/scanner.c | 682 +- .../src/tree_sitter/array.h | 181 +- .../test/corpus/code_span.txt | 147 + .../test/corpus/grid_table.txt | 88 + .../test/corpus/inline-multiline-attrs.txt | 445 + .../tree-sitter-markdown/test/corpus/list.txt | 127 +- .../test/corpus/lt-as-str.txt | 73 + .../tree-sitter-markdown/test/corpus/math.txt | 50 + .../test/corpus/new-spec.txt | 22 +- .../test/corpus/paragraph.txt | 228 +- .../test/corpus/pipe_table.txt | 58 + .../test/corpus/po-as-str.txt | 72 + .../tree-sitter-markdown/test/corpus/qmd.txt | 118 +- crates/tree-sitter-qmd/tree-sitter.json | 22 +- crates/validate-yaml/README.md | 4 +- crates/wasm-quarto-hub-client/CLAUDE.md | 53 + crates/wasm-quarto-hub-client/Cargo.lock | 1835 +- crates/wasm-quarto-hub-client/Cargo.toml | 7 +- crates/wasm-quarto-hub-client/src/lib.rs | 1410 +- crates/xtask/Cargo.toml | 2 + crates/xtask/src/braid_snapshot.rs | 79 + crates/xtask/src/build_all.rs | 40 +- crates/xtask/src/build_q2_preview_spa.rs | 51 + crates/xtask/src/create_worktree.rs | 1432 + crates/xtask/src/lint/metadata_as_str.rs | 412 + crates/xtask/src/lint/mod.rs | 2 + crates/xtask/src/main.rs | 98 +- crates/xtask/src/switch_task.rs | 188 + crates/xtask/src/util.rs | 47 + crates/xtask/src/verify.rs | 130 +- dev-docs/testing.md | 17 +- docs/.gitignore | 1 + docs/_quarto.yml | 215 +- docs/authoring/markdown/elephant.png | Bin 0 -> 126124 bytes docs/authoring/markdown/index.qmd | 136 + docs/errors/README.md | 223 + docs/errors/cli/Q-7-1.qmd | 42 + docs/errors/cli/Q-7-2.qmd | 38 + docs/errors/cli/Q-7-3.qmd | 49 + docs/errors/cli/Q-7-4.qmd | 50 + docs/errors/cli/Q-7-5.qmd | 42 + docs/errors/cli/Q-7-6.qmd | 51 + docs/errors/cli/Q-7-7.qmd | 47 + docs/errors/cli/Q-7-8.qmd | 47 + docs/errors/index.qmd | 46 + docs/errors/internal/Q-0-1.qmd | 53 + docs/errors/internal/Q-0-99.qmd | 52 + docs/errors/listing/Q-12-1.qmd | 56 + docs/errors/listing/Q-12-10.qmd | 52 + docs/errors/listing/Q-12-11.qmd | 49 + docs/errors/listing/Q-12-12.qmd | 53 + docs/errors/listing/Q-12-13.qmd | 51 + docs/errors/listing/Q-12-14.qmd | 53 + docs/errors/listing/Q-12-15.qmd | 63 + docs/errors/listing/Q-12-16.qmd | 54 + docs/errors/listing/Q-12-2.qmd | 48 + docs/errors/listing/Q-12-3.qmd | 52 + docs/errors/listing/Q-12-4.qmd | 40 + docs/errors/listing/Q-12-5.qmd | 47 + docs/errors/listing/Q-12-6.qmd | 48 + docs/errors/listing/Q-12-7.qmd | 51 + docs/errors/listing/Q-12-8.qmd | 52 + docs/errors/listing/Q-12-9.qmd | 43 + docs/errors/lua/Q-11-1.qmd | 54 + docs/errors/markdown/Q-2-1.qmd | 59 + docs/errors/markdown/Q-2-10.qmd | 60 + docs/errors/markdown/Q-2-11.qmd | 49 + docs/errors/markdown/Q-2-12.qmd | 48 + docs/errors/markdown/Q-2-13.qmd | 43 + docs/errors/markdown/Q-2-14.qmd | 41 + docs/errors/markdown/Q-2-15.qmd | 46 + docs/errors/markdown/Q-2-16.qmd | 50 + docs/errors/markdown/Q-2-17.qmd | 46 + docs/errors/markdown/Q-2-18.qmd | 40 + docs/errors/markdown/Q-2-19.qmd | 47 + docs/errors/markdown/Q-2-2.qmd | 62 + docs/errors/markdown/Q-2-20.qmd | 43 + docs/errors/markdown/Q-2-21.qmd | 42 + docs/errors/markdown/Q-2-22.qmd | 42 + docs/errors/markdown/Q-2-23.qmd | 48 + docs/errors/markdown/Q-2-24.qmd | 50 + docs/errors/markdown/Q-2-25.qmd | 49 + docs/errors/markdown/Q-2-26.qmd | 43 + docs/errors/markdown/Q-2-27.qmd | 53 + docs/errors/markdown/Q-2-28.qmd | 48 + docs/errors/markdown/Q-2-29.qmd | 65 + docs/errors/markdown/Q-2-3.qmd | 56 + docs/errors/markdown/Q-2-30.qmd | 51 + docs/errors/markdown/Q-2-31.qmd | 45 + docs/errors/markdown/Q-2-32.qmd | 43 + docs/errors/markdown/Q-2-33.qmd | 48 + docs/errors/markdown/Q-2-34.qmd | 54 + docs/errors/markdown/Q-2-35.qmd | 60 + docs/errors/markdown/Q-2-39.qmd | 58 + docs/errors/markdown/Q-2-4.qmd | 51 + docs/errors/markdown/Q-2-5.qmd | 48 + docs/errors/markdown/Q-2-6.qmd | 46 + docs/errors/markdown/Q-2-7.qmd | 56 + docs/errors/markdown/Q-2-8.qmd | 37 + docs/errors/markdown/Q-2-9.qmd | 50 + docs/errors/navigation/Q-13-1.qmd | 50 + docs/errors/navigation/Q-13-2.qmd | 42 + docs/errors/navigation/Q-13-3.qmd | 42 + docs/errors/navigation/Q-13-4.qmd | 54 + docs/errors/navigation/Q-13-5.qmd | 50 + docs/errors/navigation/Q-13-6.qmd | 49 + docs/errors/navigation/Q-13-7.qmd | 47 + docs/errors/project/Q-5-1.qmd | 53 + docs/errors/project/Q-5-2.qmd | 45 + docs/errors/project/Q-5-3.qmd | 47 + docs/errors/template/Q-10-1.qmd | 50 + docs/errors/template/Q-10-2.qmd | 50 + docs/errors/template/Q-10-3.qmd | 50 + docs/errors/template/Q-10-4.qmd | 44 + docs/errors/template/Q-10-5.qmd | 50 + docs/errors/template/Q-10-6.qmd | 47 + docs/errors/template/Q-10-7.qmd | 45 + docs/errors/theme/Q-14-1.qmd | 52 + docs/errors/theme/Q-14-2.qmd | 53 + docs/errors/writer/Q-3-1.qmd | 52 + docs/errors/writer/Q-3-10.qmd | 64 + docs/errors/writer/Q-3-11.qmd | 46 + docs/errors/writer/Q-3-12.qmd | 50 + docs/errors/writer/Q-3-20.qmd | 53 + docs/errors/writer/Q-3-21.qmd | 51 + docs/errors/writer/Q-3-30.qmd | 48 + docs/errors/writer/Q-3-31.qmd | 51 + docs/errors/writer/Q-3-32.qmd | 47 + docs/errors/writer/Q-3-33.qmd | 53 + docs/errors/writer/Q-3-34.qmd | 44 + docs/errors/writer/Q-3-35.qmd | 45 + docs/errors/writer/Q-3-36.qmd | 46 + docs/errors/writer/Q-3-38.qmd | 47 + docs/errors/writer/Q-3-40.qmd | 50 + docs/errors/writer/Q-3-50.qmd | 43 + docs/errors/writer/Q-3-51.qmd | 41 + docs/errors/writer/Q-3-52.qmd | 39 + docs/errors/writer/Q-3-53.qmd | 41 + docs/errors/writer/Q-3-54.qmd | 44 + docs/errors/writer/Q-3-55.qmd | 40 + docs/errors/xml/Q-9-1.qmd | 51 + docs/errors/xml/Q-9-10.qmd | 48 + docs/errors/xml/Q-9-11.qmd | 47 + docs/errors/xml/Q-9-12.qmd | 51 + docs/errors/xml/Q-9-13.qmd | 47 + docs/errors/xml/Q-9-14.qmd | 47 + docs/errors/xml/Q-9-15.qmd | 48 + docs/errors/xml/Q-9-16.qmd | 47 + docs/errors/xml/Q-9-2.qmd | 48 + docs/errors/xml/Q-9-3.qmd | 51 + docs/errors/xml/Q-9-4.qmd | 49 + docs/errors/xml/Q-9-5.qmd | 48 + docs/errors/xml/Q-9-6.qmd | 44 + docs/errors/xml/Q-9-7.qmd | 47 + docs/errors/xml/Q-9-8.qmd | 46 + docs/errors/xml/Q-9-9.qmd | 47 + docs/errors/yaml/Q-1-1.qmd | 67 + docs/errors/yaml/Q-1-10.qmd | 97 + docs/errors/yaml/Q-1-11.qmd | 73 + docs/errors/yaml/Q-1-12.qmd | 58 + docs/errors/yaml/Q-1-13.qmd | 55 + docs/errors/yaml/Q-1-14.qmd | 60 + docs/errors/yaml/Q-1-15.qmd | 57 + docs/errors/yaml/Q-1-16.qmd | 52 + docs/errors/yaml/Q-1-17.qmd | 57 + docs/errors/yaml/Q-1-18.qmd | 59 + docs/errors/yaml/Q-1-19.qmd | 45 + docs/errors/yaml/Q-1-20.qmd | 68 + docs/errors/yaml/Q-1-21.qmd | 65 + docs/errors/yaml/Q-1-22.qmd | 55 + docs/errors/yaml/Q-1-23.qmd | 58 + docs/errors/yaml/Q-1-24.qmd | 51 + docs/errors/yaml/Q-1-25.qmd | 42 + docs/errors/yaml/Q-1-26.qmd | 52 + docs/errors/yaml/Q-1-27.qmd | 51 + docs/errors/yaml/Q-1-28.qmd | 68 + docs/errors/yaml/Q-1-29.qmd | 54 + docs/errors/yaml/Q-1-99.qmd | 59 + docs/guide/get-config.qmd | 85 + docs/guide/index.qmd | 15 + docs/guide/introduction.qmd | 5 + docs/guide/themes/brand.qmd | 170 + docs/index.qmd | 51 +- docs/presentations/revealjs/index.qmd | 265 + docs/quarto.png | Bin 0 -> 11810 bytes examples/README.md | 60 + examples/presentations/.gitignore | 6 + .../01-creating-slides/README.md | 30 + .../01-creating-slides/_quarto.yml | 2 + .../01-creating-slides/slides.qmd | 15 + examples/presentations/02-sections/README.md | 23 + .../presentations/02-sections/_quarto.yml | 2 + examples/presentations/02-sections/slides.qmd | 28 + examples/presentations/03-fragments/README.md | 25 + .../presentations/03-fragments/_quarto.yml | 2 + .../presentations/03-fragments/slides.qmd | 32 + .../04-incremental-lists/README.md | 23 + .../04-incremental-lists/_quarto.yml | 2 + .../04-incremental-lists/slides.qmd | 35 + examples/presentations/05-columns/README.md | 21 + examples/presentations/05-columns/_quarto.yml | 2 + examples/presentations/05-columns/slides.qmd | 21 + .../presentations/06-speaker-notes/README.md | 21 + .../06-speaker-notes/_quarto.yml | 2 + .../presentations/06-speaker-notes/slides.qmd | 14 + examples/presentations/07-asides/README.md | 19 + examples/presentations/07-asides/_quarto.yml | 2 + examples/presentations/07-asides/slides.qmd | 13 + examples/presentations/08-footnotes/README.md | 32 + .../presentations/08-footnotes/_quarto.yml | 2 + .../presentations/08-footnotes/slides.qmd | 19 + examples/presentations/README.md | 36 + examples/websites/.gitignore | 4 + examples/websites/01-minimal/.gitignore | 2 + examples/websites/01-minimal/README.md | 89 + examples/websites/01-minimal/_quarto.yml | 9 + examples/websites/01-minimal/about.qmd | 21 + examples/websites/01-minimal/index.qmd | 24 + examples/websites/02-auto-sidebar/README.md | 69 + examples/websites/02-auto-sidebar/_quarto.yml | 11 + examples/websites/02-auto-sidebar/index.qmd | 26 + .../02-auto-sidebar/posts/aardvark.qmd | 7 + .../02-auto-sidebar/posts/advanced-topics.qmd | 8 + .../02-auto-sidebar/posts/getting-started.qmd | 7 + .../posts/work-in-progress.qmd | 9 + .../websites/02-auto-sidebar/posts/zebra.qmd | 7 + examples/websites/03-nested-sidebar/README.md | 77 + .../websites/03-nested-sidebar/_quarto.yml | 26 + .../03-nested-sidebar/guide/first-steps.qmd | 8 + .../03-nested-sidebar/guide/index.qmd | 12 + .../03-nested-sidebar/guide/installation.qmd | 7 + .../03-nested-sidebar/guide/tuning.qmd | 10 + examples/websites/03-nested-sidebar/index.qmd | 29 + .../03-nested-sidebar/reference/api.qmd | 6 + .../03-nested-sidebar/reference/cli.qmd | 7 + .../03-nested-sidebar/reference/index.qmd | 8 + examples/websites/04-navbar-footer/README.md | 93 + .../websites/04-navbar-footer/_quarto.yml | 31 + examples/websites/04-navbar-footer/about.qmd | 12 + examples/websites/04-navbar-footer/index.qmd | 26 + .../04-navbar-footer/tools/converter.qmd | 9 + .../websites/04-navbar-footer/tools/index.qmd | 13 + .../websites/05-shared-resources/README.md | 92 + .../websites/05-shared-resources/_quarto.yml | 14 + .../websites/05-shared-resources/docs/api.qmd | 6 + .../docs/internals/architecture.qmd | 12 + .../websites/05-shared-resources/index.qmd | 25 + examples/websites/06-site-metadata/.gitignore | 2 + examples/websites/06-site-metadata/README.md | 95 + .../websites/06-site-metadata/_quarto.yml | 17 + examples/websites/06-site-metadata/api.qmd | 5 + .../websites/06-site-metadata/favicon.svg | 5 + examples/websites/06-site-metadata/guides.qmd | 8 + examples/websites/06-site-metadata/index.qmd | 21 + .../06-site-metadata/q1-site/api.html | 578 + .../06-site-metadata/q1-site/favicon.svg | 5 + .../06-site-metadata/q1-site/guides.html | 583 + .../06-site-metadata/q1-site/index.html | 585 + .../06-site-metadata/q1-site/robots.txt | 1 + .../06-site-metadata/q1-site/search.json | 32 + ...p-158031087360bce0ff56dc785ce39e06.min.css | 12 + .../site_libs/bootstrap/bootstrap-icons.css | 0 .../site_libs/bootstrap/bootstrap-icons.woff | Bin .../site_libs/bootstrap/bootstrap.min.js | 0 .../site_libs/clipboard/clipboard.min.js | 0 .../site_libs/quarto-html/anchor.min.js | 0 .../site_libs/quarto-html/popper.min.js | 0 ...hting-3aa970819e70fbc78806154e5a1fcd28.css | 0 .../q1-site/site_libs/quarto-html/quarto.js | 845 + .../site_libs/quarto-html/tabsets/tabsets.js | 0 .../q1-site}/site_libs/quarto-html/tippy.css | 0 .../site_libs/quarto-html/tippy.umd.min.js | 0 .../site_libs/quarto-nav/headroom.min.js | 0 .../site_libs/quarto-nav/quarto-nav.js | 0 .../quarto-search/autocomplete.umd.js | 0 .../site_libs/quarto-search/fuse.min.js | 0 .../site_libs/quarto-search/quarto-search.js | 1457 + .../06-site-metadata/q1-site/sitemap.xml | 15 + examples/websites/07-incremental/README.md | 122 + examples/websites/07-incremental/_quarto.yml | 15 + examples/websites/07-incremental/about.qmd | 13 + examples/websites/07-incremental/index.qmd | 29 + .../websites/07-incremental/posts/first.qmd | 6 + .../websites/07-incremental/posts/second.qmd | 6 + .../websites/07-incremental/posts/third.qmd | 6 + examples/websites/08-hub-preview/README.md | 127 + examples/websites/08-hub-preview/_quarto.yml | 11 + examples/websites/08-hub-preview/about.qmd | 12 + examples/websites/08-hub-preview/index.qmd | 18 + .../websites/08-hub-preview/posts/first.qmd | 8 + .../websites/08-hub-preview/posts/second.qmd | 7 + hub-client/README.md | 56 + hub-client/changelog.md | 66 + hub-client/e2e/helpers/previewExtraction.ts | 94 +- hub-client/e2e/helpers/projectFactory.ts | 103 +- hub-client/e2e/helpers/smokeAllAssertions.ts | 16 +- hub-client/e2e/helpers/smokeAllDiscovery.ts | 124 +- hub-client/e2e/helpers/testHooks.ts | 43 + hub-client/e2e/import-zip.spec.ts | 119 + hub-client/e2e/preview-extraction.spec.ts | 4 +- hub-client/e2e/project-loading.spec.ts | 7 +- .../e2e/q2-debug-render-components.spec.ts | 77 + .../fresh-setup-dark-chromium-linux.png | Bin 0 -> 32857 bytes .../fresh-setup-light-chromium-linux.png | Bin 0 -> 32664 bytes .../migration-dark-chromium-linux.png | Bin 0 -> 40110 bytes .../migration-error-dark-chromium-linux.png | Bin 0 -> 42422 bytes .../migration-error-light-chromium-linux.png | Bin 0 -> 42491 bytes .../migration-light-chromium-linux.png | Bin 0 -> 40032 bytes hub-client/e2e/share-link-project-set.spec.ts | 13 +- hub-client/e2e/smoke-all.spec.ts | 36 +- hub-client/e2e/theme-subdir-e2e.spec.ts | 4 +- hub-client/package.json | 15 +- hub-client/playwright.config.ts | 38 +- hub-client/public/q2-raw.html | 307 + .../ast-renderer.html => q2-debug.html} | 6 +- hub-client/q2-preview.html | 32 + hub-client/q2-raw.html | 69 + .../quarto-hub-sandboxed-preview/.gitignore | 27 + .../quarto-hub-sandboxed-preview/README.md | 41 + .../quarto-hub-sandboxed-preview/index.html | 16 + .../package-lock.json | 1982 + .../quarto-hub-sandboxed-preview/package.json | 25 + .../quarto-hub-sandboxed-preview/src/App.tsx | 63 + .../src/index.css | 13 + .../quarto-hub-sandboxed-preview/src/main.tsx | 10 + .../tsconfig.json | 25 + .../vite.config.ts | 35 + hub-client/src/App.tsx | 56 +- hub-client/src/__mocks__/userSettings.ts | 2 +- hub-client/src/ast-renderer-entry.tsx | 139 - hub-client/src/auth/AuthProvider.test.tsx | 42 + hub-client/src/auth/AuthProvider.tsx | 103 + .../src/auth/GoogleAuthProvider.test.tsx | 122 + hub-client/src/auth/GoogleAuthProvider.tsx | 60 + hub-client/src/auth/MockAuthProvider.tsx | 81 + hub-client/src/components/DevHarness.tsx | 2 +- hub-client/src/components/Editor.css | 29 + hub-client/src/components/Editor.tsx | 43 +- .../FileSidebar.integration.test.tsx | 2 +- hub-client/src/components/FileSidebar.tsx | 4 +- hub-client/src/components/OutlinePanel.tsx | 2 +- hub-client/src/components/ProjectSelector.css | 8 + .../ProjectSelector.import.test.tsx | 167 + hub-client/src/components/ProjectSelector.tsx | 143 +- hub-client/src/components/ProjectSetSetup.tsx | 2 +- hub-client/src/components/ReplayDrawer.css | 135 +- .../src/components/ReplayDrawer.test.tsx | 188 +- hub-client/src/components/ReplayDrawer.tsx | 107 +- .../src/components/ViewToggleControl.tsx | 24 +- .../src/components/auth/LoginScreen.test.tsx | 52 + .../src/components/auth/LoginScreen.tsx | 21 +- hub-client/src/components/render/Preview.tsx | 117 +- .../components/render/PreviewErrorOverlay.tsx | 64 - .../src/components/render/PreviewRouter.tsx | 44 +- .../render/ReactAstDebugRenderer.tsx | 606 - .../components/render/ReactAstRenderer.tsx | 344 - .../render/ReactAstSlideRenderer.test.tsx | 59 + .../render/ReactAstSlideRenderer.tsx | 184 +- .../src/components/render/ReactPreview.tsx | 261 +- .../render/ReactRenderer.integration.test.tsx | 355 + .../src/components/render/ReactRenderer.tsx | 113 +- .../render/RevealjsReactAstSlideRenderer.tsx | 3 +- .../src/components/render/getQ2Format.ts | 13 +- .../render/iframeMessageDispatch.test.ts | 263 + .../render/iframeMessageDispatch.ts | 125 + .../render/parity.integration.test.tsx | 79 + .../Q2DebugIframe.tsx} | 14 +- .../q2-debug/attribution.integration.test.tsx | 157 + .../components/render/q2-debug/components.tsx | 231 + .../render/q2-debug/dispatchers.tsx | 40 + .../src/components/render/q2-debug/entry.tsx | 168 + .../src/components/render/q2-debug/index.ts | 11 + .../q2-debug/q2-debug.integration.test.tsx | 267 + .../components/render/q2-debug/registry.ts | 24 + .../src/components/render/q2-debug/styles.ts | 19 + .../attribution.integration.test.tsx | 161 + .../components/render/q2-preview/entry.tsx | 7 + .../components/render/q2-raw/Q2RawIframe.tsx | 54 + hub-client/src/components/tabs/AboutTab.tsx | 2 +- hub-client/src/components/tabs/ProjectTab.tsx | 2 +- .../src/debug/hooks/useLocalProjects.ts | 2 +- .../src/debug/services/localProjects.ts | 2 +- hub-client/src/hooks/useAttribution.test.ts | 202 + hub-client/src/hooks/useAttribution.ts | 283 + .../{useAuth.test.ts => useAuth.test.tsx} | 145 +- hub-client/src/hooks/useAuth.ts | 67 +- hub-client/src/hooks/useAutomergeSync.test.ts | 8 +- hub-client/src/hooks/useAutomergeSync.ts | 4 +- hub-client/src/hooks/useCursorToSlide.ts | 5 +- .../src/hooks/useIframePostProcessor.ts | 7 +- hub-client/src/hooks/useIntelligence.ts | 2 +- hub-client/src/hooks/usePreference.test.tsx | 55 + hub-client/src/hooks/usePreference.ts | 30 +- hub-client/src/hooks/usePresence.test.ts | 2 +- hub-client/src/hooks/usePresence.ts | 2 +- hub-client/src/hooks/useProjectSet.ts | 2 +- hub-client/src/hooks/useReplayMode.test.ts | 4 +- hub-client/src/hooks/useReplayMode.ts | 8 +- hub-client/src/hooks/useSectionThumbnails.ts | 2 +- hub-client/src/hooks/useSelectionSync.ts | 4 +- hub-client/src/hooks/useSlideThumbnails.tsx | 5 +- hub-client/src/main.tsx | 24 +- .../assetManifestProject.wasm.test.ts | 204 + .../src/services/attribution-runs.test.ts | 172 + hub-client/src/services/attribution-runs.ts | 452 + hub-client/src/services/authService.test.ts | 18 +- hub-client/src/services/authService.ts | 16 +- .../customNodeWireFormatProject.wasm.test.ts | 104 + hub-client/src/services/debugApi.test.ts | 358 + hub-client/src/services/debugApi.ts | 318 + .../src/services/intelligenceService.ts | 8 +- hub-client/src/services/monacoProviders.ts | 2 +- hub-client/src/services/preferences/index.ts | 23 + hub-client/src/services/preferences/schema.ts | 5 + .../src/services/presenceService.test.ts | 9 +- hub-client/src/services/presenceService.ts | 2 +- hub-client/src/services/projectStorage.ts | 2 +- hub-client/src/services/resourceService.ts | 2 +- hub-client/src/services/smokeAll.wasm.test.ts | 16 +- hub-client/src/services/storage/utils.ts | 4 +- .../src/services/templateService.test.ts | 6 +- hub-client/src/services/templateService.ts | 2 +- hub-client/src/services/themeCss.wasm.test.ts | 7 +- .../services/themeFingerprint.wasm.test.ts | 175 + hub-client/src/services/tsxTranspiler.ts | 50 - .../services/userGrammarParity.wasm.test.ts | 16 +- hub-client/src/test-hooks.ts | 44 + hub-client/src/test-utils/index.ts | 20 +- hub-client/src/types/diagnostic.ts | 52 - .../src/utils/diagnosticToMonaco.test.ts | 4 +- hub-client/src/utils/diagnosticToMonaco.ts | 6 +- hub-client/src/utils/fileTree.ts | 2 +- hub-client/src/utils/palette.test.ts | 39 + hub-client/src/utils/palette.ts | 84 + hub-client/src/utils/pipelineKind.test.ts | 31 + hub-client/src/utils/pipelineKind.ts | 34 + hub-client/src/vite-env.d.ts | 11 + hub-client/vite.config.ts | 121 +- hub-client/vitest.config.ts | 6 + hub-client/vitest.integration.config.ts | 2 + hub-client/vitest.wasm.config.ts | 10 +- old-docs/.gitignore | 2 + old-docs/_quarto.yml | 49 + {docs => old-docs}/_site/about.html | 0 {docs => old-docs}/_site/index.html | 0 {docs => old-docs}/_site/search.json | 0 ...p-5b4ad623e5705c0698d39aec6f10cf02.min.css | 0 .../site_libs/bootstrap/bootstrap-icons.css | 2106 + .../site_libs/bootstrap/bootstrap-icons.woff | Bin 0 -> 180288 bytes .../site_libs/bootstrap/bootstrap.min.js | 7 + .../site_libs/clipboard/clipboard.min.js | 7 + .../_site/site_libs/quarto-html/anchor.min.js | 9 + .../site_libs/quarto-html/axe/axe-check.js | 0 .../_site/site_libs/quarto-html/popper.min.js | 6 + ...hting-3aa970819e70fbc78806154e5a1fcd28.css | 236 + .../_site/site_libs/quarto-html/quarto.js | 0 .../site_libs/quarto-html/tabsets/tabsets.js | 95 + .../_site/site_libs/quarto-html/tippy.css | 1 + .../site_libs/quarto-html/tippy.umd.min.js | 2 + .../site_libs/quarto-nav/headroom.min.js | 7 + .../_site/site_libs/quarto-nav/quarto-nav.js | 325 + .../quarto-search/autocomplete.umd.js | 3 + .../_site/site_libs/quarto-search/fuse.min.js | 9 + .../site_libs/quarto-search/quarto-search.js | 0 {docs => old-docs}/_site/styles.css | 0 .../_site/syntax/definition-lists.html | 0 {docs => old-docs}/_site/syntax/index.html | 0 old-docs/about.qmd | 5 + old-docs/authoring/attribution.qmd | 295 + old-docs/bug-reports.qmd | 94 + old-docs/index.qmd | 52 + {docs => old-docs}/library-docs/index.qmd | 0 .../rust/source-info/architecture.qmd | 0 .../library-docs/rust/source-info/index.qmd | 0 .../library-docs/rust/source-info/json.qmd | 0 .../typescript/annotated-qmd/index.qmd | 0 {docs => old-docs}/navigation.qmd | 108 +- old-docs/projects/resources.qmd | 124 + old-docs/q2-preview.qmd | 145 + .../quarto-hub/collaboration.qmd | 0 {docs => old-docs}/quarto-hub/files.qmd | 0 {docs => old-docs}/quarto-hub/index.qmd | 0 {docs => old-docs}/quarto-hub/preview.qmd | 0 {docs => old-docs}/quarto-hub/projects.qmd | 0 {docs => old-docs}/quarto-hub/templates.qmd | 0 {docs => old-docs}/quarto-hub/themes.qmd | 0 old-docs/styles.css | 1 + {docs => old-docs}/syntax/code_span.qmd | 0 .../syntax/definition-lists.qmd | 0 .../syntax/desugaring/definition-lists.qmd | 0 .../syntax/desugaring/editorial-marks.qmd | 0 .../syntax/desugaring/index.qmd | 0 .../syntax/desugaring/math-attributes.qmd | 0 .../syntax/desugaring/note-references.qmd | 0 .../syntax/desugaring/table-captions.qmd | 0 {docs => old-docs}/syntax/editorial-marks.qmd | 0 {docs => old-docs}/syntax/footnotes.qmd | 0 .../syntax/highlighting-filter.qmd | 0 {docs => old-docs}/syntax/index.qmd | 0 {docs => old-docs}/syntax/lists.qmd | 0 {docs => old-docs}/syntax/yaml-metadata.qmd | 0 {docs => old-docs}/writers/index.qmd | 0 {docs => old-docs}/writers/json.qmd | 0 {docs => old-docs}/writers/qmd.qmd | 0 package-lock.json | 1080 +- package.json | 7 + q2-preview-spa/.gitignore | 6 + q2-preview-spa/e2e/basic-preview.spec.ts | 192 + q2-preview-spa/e2e/chrome.spec.ts | 439 + q2-preview-spa/e2e/config-edits.spec.ts | 191 + q2-preview-spa/e2e/cross-page-nav.spec.ts | 268 + q2-preview-spa/e2e/dep-graph-filter.spec.ts | 143 + q2-preview-spa/e2e/diagnostics.spec.ts | 94 + q2-preview-spa/e2e/helpers/globalSetup.ts | 32 + q2-preview-spa/e2e/helpers/previewServer.ts | 282 + q2-preview-spa/e2e/include-shortcode.spec.ts | 171 + q2-preview-spa/e2e/static-resources.spec.ts | 145 + q2-preview-spa/index.html | 31 + q2-preview-spa/package.json | 37 + q2-preview-spa/playwright.config.ts | 36 + q2-preview-spa/q2-preview.html | 20 + .../src/PreviewApp.integration.test.tsx | 1122 + q2-preview-spa/src/PreviewApp.tsx | 889 + .../src/components/ForceRefreshButton.tsx | 58 + .../components/PreviewDiagnosticsOverlay.css | 229 + ...iewDiagnosticsOverlay.integration.test.tsx | 269 + .../components/PreviewDiagnosticsOverlay.tsx | 197 + .../StaleCaptureOverlay.integration.test.tsx | 101 + .../src/components/StaleCaptureOverlay.tsx | 135 + q2-preview-spa/src/main.tsx | 16 + q2-preview-spa/src/pickInitialPage.test.ts | 60 + q2-preview-spa/src/pickInitialPage.ts | 59 + q2-preview-spa/src/q2-preview-entry.tsx | 6 + q2-preview-spa/src/test-utils/setup.ts | 19 + q2-preview-spa/tsconfig.app.json | 26 + q2-preview-spa/tsconfig.json | 7 + q2-preview-spa/tsconfig.node.json | 24 + q2-preview-spa/vite.config.ts | 93 + q2-preview-spa/vitest.config.ts | 34 + q2-preview-spa/vitest.integration.config.ts | 29 + resources/attribution/README.md | 30 + resources/attribution/viewer.css | 49 + resources/attribution/viewer.js | 95 + resources/bootstrap-icons/README.md | 32 + resources/bootstrap-icons/bootstrap-icons.css | 2106 + .../bootstrap-icons/bootstrap-icons.woff | Bin 0 -> 180288 bytes resources/js/README.md | 32 + .../js/bootstrap/bootstrap.bundle.min.js | 7 + resources/js/clipboard/clipboard.min.js | 7 + resources/js/clipboard/code-copy-init.js | 97 + resources/listing/list.min.js | 2 + resources/listing/quarto-listing.js | 254 + resources/revealjs/LICENSE | 19 + resources/revealjs/README.md | 33 + resources/revealjs/quarto-reveal.css | 44 + resources/revealjs/reset.css | 1 + resources/revealjs/reveal.css | 1 + resources/revealjs/reveal.js | 40 + resources/revealjs/theme/white.css | 1 + .../scss/bootstrap/_bootstrap-rules.scss | 320 + resources/scss/html/templates/highlight.scss | 16 + rust-toolchain.toml | 11 +- scripts/measure-test-build.sh | 115 + scripts/upload-project.mjs | 464 + ts-packages/preview-renderer/package.json | 84 + .../preview-renderer/src/framework/Ast.tsx | 127 + .../framework/AttributionLookupContext.tsx | 47 + .../src/framework/RegistryContext.tsx | 22 + .../src/framework/attribution.styles.test.ts | 33 + .../src/framework/attribution.test.ts | 96 + .../src/framework/attribution.test.tsx | 60 + .../src/framework/attribution.tsx | 256 + .../src/framework/customNode.test.ts | 348 + .../src/framework/customNode.ts | 403 + .../src/framework/dispatch.tsx | 436 + .../preview-renderer/src/framework/index.ts | 19 + .../src/framework/meta.test.ts | 285 + .../preview-renderer/src/framework/meta.ts | 115 + .../src/framework/plainText.test.ts | 143 + .../src/framework/plainText.ts | 155 + .../preview-renderer/src/framework/types.ts | 185 + ts-packages/preview-renderer/src/global.d.ts | 33 + .../src/iframe}/DoubleBufferedIframe.tsx | 11 +- .../src/iframe}/MorphIframe.tsx | 11 +- .../Q2PreviewIframe.integration.test.tsx | 297 + .../src/iframe/Q2PreviewIframe.tsx | 246 + ts-packages/preview-renderer/src/index.ts | 26 + .../PreviewErrorOverlay.integration.test.tsx | 176 + .../src/overlays/PreviewErrorOverlay.tsx | 126 + .../src/overlays}/PreviewStaticInfoViews.tsx | 4 +- .../preview-renderer/src/placeholder.test.ts | 7 + .../src/q2-preview/AssetManifestContext.tsx | 22 + .../src/q2-preview/IncrementalContext.tsx | 25 + .../src/q2-preview/NoteNumberingContext.tsx | 25 + .../src/q2-preview/PreviewContext.tsx | 18 + .../PreviewDocument.integration.test.tsx | 589 + .../src/q2-preview/PreviewDocument.tsx | 295 + .../src/q2-preview/RevealDeck.tsx | 171 + .../src/q2-preview/assetWalker.test.ts | 236 + .../src/q2-preview/assetWalker.ts | 155 + .../src/q2-preview/blocks/BlockQuote.tsx | 6 + .../src/q2-preview/blocks/BulletList.tsx | 36 + .../src/q2-preview/blocks/CodeBlock.tsx | 221 + .../src/q2-preview/blocks/DefinitionList.tsx | 67 + .../src/q2-preview/blocks/Div.tsx | 80 + .../src/q2-preview/blocks/Figure.tsx | 59 + .../src/q2-preview/blocks/Header.tsx | 16 + .../src/q2-preview/blocks/HorizontalRule.tsx | 1 + .../src/q2-preview/blocks/LineBlock.tsx | 33 + .../src/q2-preview/blocks/OrderedList.tsx | 60 + .../src/q2-preview/blocks/Para.tsx | 4 + .../src/q2-preview/blocks/Plain.tsx | 6 + .../src/q2-preview/blocks/RawBlock.tsx | 19 + .../src/q2-preview/blocks/Table.tsx | 204 + .../src/q2-preview/blocks/index.ts | 14 + .../src/q2-preview/chromeSlots.tsx | 162 + .../custom-components.integration.test.tsx | 911 + .../src/q2-preview/custom/Callout.tsx | 236 + .../q2-preview/custom/CrossrefResolvedRef.tsx | 102 + .../src/q2-preview/custom/Equation.tsx | 146 + .../src/q2-preview/custom/Fallback.tsx | 48 + .../src/q2-preview/custom/FloatRefTarget.tsx | 170 + .../PreviewTitleBlock.integration.test.tsx | 292 + .../q2-preview/custom/PreviewTitleBlock.tsx | 116 + .../src/q2-preview/custom/Proof.tsx | 126 + .../src/q2-preview/custom/Theorem.tsx | 172 + .../src/q2-preview/custom/index.ts | 27 + .../src/q2-preview/dispatchers.tsx | 114 + .../src/q2-preview/entry.integration.test.tsx | 110 + .../preview-renderer/src/q2-preview/entry.tsx | 501 + .../preview-renderer/src/q2-preview/index.ts | 9 + .../src/q2-preview/inlines/Cite.tsx | 29 + .../src/q2-preview/inlines/Code.tsx | 12 + .../src/q2-preview/inlines/Emph.tsx | 4 + .../src/q2-preview/inlines/Image.tsx | 41 + .../src/q2-preview/inlines/LineBreak.tsx | 1 + .../src/q2-preview/inlines/Link.tsx | 14 + .../src/q2-preview/inlines/Math.tsx | 33 + .../src/q2-preview/inlines/Note.tsx | 43 + .../src/q2-preview/inlines/Quoted.tsx | 19 + .../src/q2-preview/inlines/RawInline.tsx | 16 + .../src/q2-preview/inlines/SmallCaps.tsx | 6 + .../src/q2-preview/inlines/SoftBreak.tsx | 3 + .../src/q2-preview/inlines/Space.tsx | 1 + .../src/q2-preview/inlines/Span.tsx | 13 + .../src/q2-preview/inlines/Str.tsx | 3 + .../src/q2-preview/inlines/Strikeout.tsx | 6 + .../src/q2-preview/inlines/Strong.tsx | 6 + .../src/q2-preview/inlines/Subscript.tsx | 6 + .../src/q2-preview/inlines/Superscript.tsx | 6 + .../src/q2-preview/inlines/Underline.tsx | 6 + .../src/q2-preview/inlines/index.ts | 20 + .../q2-preview.integration.test.tsx | 976 + .../src/q2-preview/quartoClasses.ts | 106 + .../src/q2-preview/registry.test.ts | 105 + .../src/q2-preview/registry.ts | 48 + .../src/q2-preview/theoremEnvs.ts | 26 + .../preview-renderer/src/q2-preview/utils.tsx | 212 + .../preview-renderer/src/test-utils/setup.ts | 30 + .../src/types/artifactPaths.ts | 14 + .../preview-renderer/src/types/diagnostic.ts | 93 + .../src/types/intelligence.ts | 0 .../src/types/project.test.ts | 0 .../preview-renderer}/src/types/project.ts | 0 .../preview-renderer/src/types/sourceInfo.ts | 51 + .../src/utils/atomicCustomNodes.ts | 27 + .../src/utils/componentPath.test.ts | 36 + .../src/utils/componentPath.ts | 32 + .../src/utils/customRegistry.test.ts | 51 + .../src/utils/customRegistry.ts | 20 + .../iframeLinkHandlers.integration.test.ts | 347 + .../src/utils/iframeLinkHandlers.ts | 194 + .../iframePostProcessor.integration.test.ts | 184 + .../src/utils/iframePostProcessor.test.ts | 142 + .../src/utils/iframePostProcessor.ts | 179 +- .../src/utils/sourceInfo.test.ts | 91 + .../preview-renderer/src/utils/sourceInfo.ts | 69 + .../src/utils/stripAnsi.test.ts | 0 .../preview-renderer}/src/utils/stripAnsi.ts | 0 .../src/utils/vfsPaths.test.ts | 75 + .../preview-renderer/src/utils/vfsPaths.ts | 81 + ts-packages/preview-renderer/tsconfig.json | 31 + ts-packages/preview-renderer/vitest.config.ts | 74 + .../vitest.integration.config.ts | 81 + ts-packages/preview-runtime/package.json | 56 + .../src}/automergeSync.test.ts | 39 +- .../preview-runtime/src}/automergeSync.ts | 61 +- ts-packages/preview-runtime/src/index.ts | 16 + .../preview-runtime/src/placeholder.test.ts | 7 + .../src/test-utils/mockSyncClient.ts | 0 .../src/test-utils/mockWasm.ts | 2 +- .../preview-runtime/src/test-utils/setup.ts | 18 + .../src/userGrammar/Cache.test.ts | 6 +- .../preview-runtime/src/userGrammar/Cache.ts | 4 +- .../src/userGrammar/Discovery.test.ts | 2 +- .../src/userGrammar/Discovery.ts | 0 .../src/userGrammar/Highlight.ts | 0 .../src/userGrammar/Highlight.wasm.test.ts | 7 +- .../preview-runtime/src/vite-shims.d.ts | 27 + .../src/wasm-quarto-hub-client.d.ts | 160 + .../preview-runtime/src}/wasmRenderer.test.ts | 0 .../preview-runtime/src}/wasmRenderer.ts | 264 +- ts-packages/preview-runtime/tsconfig.json | 28 + ts-packages/preview-runtime/vitest.config.ts | 39 + .../vitest.integration.config.ts | 33 + .../src/__tests__/migration.test.ts | 90 +- .../quarto-automerge-schema/src/index.ts | 56 +- ts-packages/quarto-hub-mcp/README.md | 241 + ts-packages/quarto-hub-mcp/package.json | 6 +- .../src/auth/auth-tools.test.ts | 799 + .../quarto-hub-mcp/src/auth/auth-tools.ts | 642 + .../quarto-hub-mcp/src/auth/browser.test.ts | 82 + .../quarto-hub-mcp/src/auth/browser.ts | 95 + .../src/auth/credential-store.test.ts | 539 + .../src/auth/credential-store.ts | 226 + .../quarto-hub-mcp/src/auth/loopback.test.ts | 155 + .../quarto-hub-mcp/src/auth/loopback.ts | 326 + .../src/auth/oauth-config.test.ts | 63 + .../quarto-hub-mcp/src/auth/oauth-config.ts | 96 + .../quarto-hub-mcp/src/auth/pkce.test.ts | 39 + ts-packages/quarto-hub-mcp/src/auth/pkce.ts | 30 + .../quarto-hub-mcp/src/auth/redact.test.ts | 33 + ts-packages/quarto-hub-mcp/src/auth/redact.ts | 22 + .../src/auth/refresh-manager.test.ts | 641 + .../src/auth/refresh-manager.ts | 256 + .../src/connection-manager.test.ts | 614 + .../quarto-hub-mcp/src/connection-manager.ts | 381 +- ts-packages/quarto-hub-mcp/src/index.test.ts | 43 + ts-packages/quarto-hub-mcp/src/index.ts | 198 +- ts-packages/quarto-hub-mcp/src/tools.ts | 39 +- ts-packages/quarto-sync-client/package.json | 4 +- .../src/NodeWebSocketClientAdapter.test.ts | 200 + .../src/NodeWebSocketClientAdapter.ts | 314 + .../quarto-sync-client/src/client.test.ts | 177 +- ts-packages/quarto-sync-client/src/client.ts | 121 +- .../quarto-sync-client/src/import-zip.test.ts | 249 + .../quarto-sync-client/src/import-zip.ts | 185 + ts-packages/quarto-sync-client/src/index.ts | 16 + .../src/storage-adapter.test.ts | 80 + .../quarto-sync-client/src/storage-adapter.ts | 81 + ts-packages/quarto-sync-client/src/types.ts | 38 +- ts-packages/wasm-js-bridge/package.json | 22 + .../wasm-js-bridge/src}/cache.d.ts | 0 .../wasm-js-bridge/src}/cache.js | 0 .../wasm-js-bridge/src}/cache.test.ts | 0 .../wasm-js-bridge/src}/fetch.js | 0 .../wasm-js-bridge/src}/sass.d.ts | 0 .../wasm-js-bridge/src}/sass.js | 0 ts-packages/wasm-js-bridge/src/sass.test.ts | 29 + .../wasm-js-bridge/src}/template.js | 0 1786 files changed, 385420 insertions(+), 108508 deletions(-) create mode 100644 .braid-project create mode 100644 .braid/README.md create mode 100644 .braid/snapshot.jsonl create mode 100644 .claude/rules/integration-tests.md create mode 100644 .claude/skills/braid/SKILL.md create mode 100644 .claude/skills/investigate-beads/SKILL.md create mode 100644 .claude/skills/investigate-beads/references/plan-skeleton-template.md create mode 100644 .claude/skills/preview-render-parity/SKILL.md create mode 100644 .claude/skills/reader-expectations-prose/SKILL.md create mode 100644 .claude/skills/triage/SKILL.md create mode 100644 .claude/skills/triage/references/triage-doc-template.md create mode 100644 .claude/skills/upgrade-cargo-deps/PINS.md create mode 100644 .claude/skills/upgrade-cargo-deps/SKILL.md create mode 100644 .config/nextest.toml create mode 100644 .nvmrc create mode 100644 claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md create mode 100644 claude-notes/2026-05-01-bd-f5yi-sidebar-after-fix.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-1000.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-1100.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-1200.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-1400.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-1600.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-767.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-768.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-800.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/native-900.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/post-fix-1200.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/post-fix-800.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/post-fix-900.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/post-fix-992.png create mode 100644 claude-notes/2026-05-01-sidebar-breakpoints/post-fix-hub-preview-1200.png create mode 100644 claude-notes/architecture/01-pipeline.md create mode 100644 claude-notes/architecture/02-crates.md create mode 100644 claude-notes/architecture/03-hub-client-automerge.md create mode 100644 claude-notes/architecture/04-q2-preview-wasm.md create mode 100644 claude-notes/architecture/README.md create mode 100644 claude-notes/architecture/automerge.svg create mode 100644 claude-notes/architecture/crates.svg create mode 100644 claude-notes/architecture/pipeline.svg create mode 100644 claude-notes/architecture/q2-preview-wasm.svg create mode 100644 claude-notes/designs/attribution-encoding-contract.md create mode 100644 claude-notes/designs/body-link-resolution-contract.md create mode 100644 claude-notes/designs/document-profile-contract.md create mode 100644 claude-notes/designs/sidebar-auto-expansion-contract.md create mode 100644 claude-notes/designs/wire-format-source-info-codes.md create mode 100644 claude-notes/instructions/auth-verification.md create mode 100644 claude-notes/instructions/hub-mcp-operator-runbook.md create mode 100644 claude-notes/instructions/preview-spa-rebuild.md create mode 100644 claude-notes/instructions/replay-engine.md create mode 100644 claude-notes/issue-reports/152/exp-mixed.qmd create mode 100644 claude-notes/issue-reports/152/exp-prefix.qmd create mode 100644 claude-notes/issue-reports/152/exp-suffix.qmd create mode 100644 claude-notes/issue-reports/152/q236-repro-variants.qmd create mode 100644 claude-notes/issue-reports/152/q236-repro.qmd create mode 100644 claude-notes/issue-reports/152/q236-triage.md create mode 100644 claude-notes/issue-reports/152/repro.qmd create mode 100644 claude-notes/issue-reports/152/triage.md create mode 100644 claude-notes/issue-reports/161/repro.qmd create mode 100644 claude-notes/issue-reports/161/round-trip-1.qmd create mode 100644 claude-notes/issue-reports/161/triage.md create mode 100644 claude-notes/issue-reports/173/repro.qmd create mode 100755 claude-notes/issue-reports/173/repro.sh create mode 100644 claude-notes/issue-reports/173/triage.md create mode 100644 claude-notes/issue-reports/175/exp-empty-body-row.qmd create mode 100644 claude-notes/issue-reports/175/repro.qmd create mode 100644 claude-notes/issue-reports/175/triage.md create mode 100644 claude-notes/issue-reports/180/repro-figure-figure.qmd create mode 100644 claude-notes/issue-reports/180/repro-figure-para.qmd create mode 100644 claude-notes/issue-reports/180/repro-layout-div.qmd create mode 100644 claude-notes/issue-reports/180/repro-para-figure-OK.qmd create mode 100644 claude-notes/issue-reports/180/triage.md create mode 100644 claude-notes/issue-reports/181/exp-blank-lines.qmd create mode 100644 claude-notes/issue-reports/181/exp-fenced-code-in-bq.qmd create mode 100644 claude-notes/issue-reports/181/exp-no-blockquote.qmd create mode 100644 claude-notes/issue-reports/181/exp-only-math.qmd create mode 100644 claude-notes/issue-reports/181/repro.qmd create mode 100644 claude-notes/issue-reports/181/triage.md create mode 100644 claude-notes/issue-reports/182/repro-no-space.qmd create mode 100644 claude-notes/issue-reports/182/repro-with-space.qmd create mode 100644 claude-notes/issue-reports/182/triage.md create mode 100644 claude-notes/issue-reports/183/exp-single-codeblock.qmd create mode 100644 claude-notes/issue-reports/183/exp-two-paras.qmd create mode 100644 claude-notes/issue-reports/183/expected-output.qmd create mode 100644 claude-notes/issue-reports/183/observed-output.qmd create mode 100644 claude-notes/issue-reports/183/repro.qmd create mode 100644 claude-notes/issue-reports/183/triage.md create mode 100644 claude-notes/issue-reports/184/repro.qmd create mode 100644 claude-notes/issue-reports/184/triage.md create mode 100644 claude-notes/issue-reports/195/repro-list-table.qmd create mode 100644 claude-notes/issue-reports/195/repro-plain.qmd create mode 100644 claude-notes/issue-reports/195/triage.md create mode 100644 claude-notes/issue-reports/196/exp-bullet-list.qmd create mode 100644 claude-notes/issue-reports/196/exp-no-trailing-ws.qmd create mode 100644 claude-notes/issue-reports/196/exp-tab-on-blank.qmd create mode 100644 claude-notes/issue-reports/196/exp-trailing-ws-text.qmd create mode 100644 claude-notes/issue-reports/196/exp-two-trailing-spaces.qmd create mode 100644 claude-notes/issue-reports/196/repro.qmd create mode 100644 claude-notes/issue-reports/196/triage.md create mode 100644 claude-notes/issue-reports/201/repro.qmd create mode 100644 claude-notes/issue-reports/201/triage.md create mode 100644 claude-notes/issue-reports/205/repro.json create mode 100644 claude-notes/issue-reports/205/repro.qmd create mode 100644 claude-notes/issue-reports/205/triage.md create mode 100644 claude-notes/issue-reports/206/exp-blank-line.qmd create mode 100644 claude-notes/issue-reports/206/exp-caption-no-div.qmd create mode 100644 claude-notes/issue-reports/206/exp-heading-after.qmd create mode 100644 claude-notes/issue-reports/206/exp-heading-between.qmd create mode 100644 claude-notes/issue-reports/206/exp-no-div-just-colons.qmd create mode 100644 claude-notes/issue-reports/206/exp-para-after.qmd create mode 100644 claude-notes/issue-reports/206/repro.qmd create mode 100644 claude-notes/issue-reports/206/triage.md create mode 100644 claude-notes/issue-reports/222/repro.qmd create mode 100644 claude-notes/issue-reports/222/triage.md create mode 100644 claude-notes/plans/2026-04-23-website-project-epic.md create mode 100644 claude-notes/plans/2026-04-23-websites-phase-0.md create mode 100644 claude-notes/plans/2026-04-23-websites-phase-1.md create mode 100644 claude-notes/plans/2026-04-24-include-expansion-merge.md create mode 100644 claude-notes/plans/2026-04-24-websites-phase-2.md create mode 100644 claude-notes/plans/2026-04-24-websites-phase-3.md create mode 100644 claude-notes/plans/2026-04-24-websites-phase-4.md create mode 100644 claude-notes/plans/2026-04-24-websites-phase-5.md create mode 100644 claude-notes/plans/2026-04-24-websites-phase-6.md create mode 100644 claude-notes/plans/2026-04-27-websites-phase-7.md create mode 100644 claude-notes/plans/2026-04-27-websites-phase-8.md create mode 100644 claude-notes/plans/2026-04-27-websites-phase-9.md create mode 100644 claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md create mode 100644 claude-notes/plans/2026-04-29-sidebar-default-title.md create mode 100644 claude-notes/plans/2026-04-29-website-examples.md create mode 100644 claude-notes/plans/2026-04-29-website-sidebar-layout.md create mode 100644 claude-notes/plans/2026-04-30-page-nav-q1-parity.md create mode 100644 claude-notes/plans/2026-04-30-sidebar-title-home-link-relativize.md create mode 100644 claude-notes/plans/2026-04-30-sidebar-vertical-border.md create mode 100644 claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md create mode 100644 claude-notes/plans/2026-05-01-default-project-render-diagnostics.md create mode 100644 claude-notes/plans/2026-05-01-default-project-theme-flush.md create mode 100644 claude-notes/plans/2026-05-01-hub-client-website-render-ux.md create mode 100644 claude-notes/plans/2026-05-01-website-link-navigation.md create mode 100644 claude-notes/plans/2026-05-01-website-sidebar-breakpoints.md create mode 100644 claude-notes/plans/2026-05-03-project-resources.md create mode 100644 claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md create mode 100644 claude-notes/plans/2026-05-03-replay-engine.md create mode 100644 claude-notes/plans/2026-05-03-trace-size-for-replay.md create mode 100644 claude-notes/plans/2026-05-04-bootstrap-js-injection.md create mode 100644 claude-notes/plans/2026-05-04-cargo-dependency-upgrade-skill.md create mode 100644 claude-notes/plans/2026-05-04-cargo-upgrade-execution.md create mode 100644 claude-notes/plans/2026-05-04-cargo-upgrade-survey.md create mode 100644 claude-notes/plans/2026-05-04-includes-feature.md create mode 100644 claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md create mode 100644 claude-notes/plans/2026-05-04-math-mode-handoff.md create mode 100644 claude-notes/plans/2026-05-04-math-mode.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-1-pipeline.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-2a-iframe-foundation.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-2b-builtin-components.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-3-filter-idempotence.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-4-source-info-types.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-5-wire-format.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-7-incremental-writer.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-7a-filter-idempotence.md create mode 100644 claude-notes/plans/2026-05-04-q2-preview-plan-8-include-roundtrip.md create mode 100644 claude-notes/plans/2026-05-04-vendored-deps-audit.md create mode 100644 claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md create mode 100644 claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md create mode 100644 claude-notes/plans/2026-05-05-listings-L0-profile-extension.md create mode 100644 claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md create mode 100644 claude-notes/plans/2026-05-05-listings-design-discussion.md create mode 100644 claude-notes/plans/2026-05-05-listings-epic.md create mode 100644 claude-notes/plans/2026-05-06-attribution-pipeline-flow-v2.svg create mode 100644 claude-notes/plans/2026-05-06-attribution-pipeline.md create mode 100644 claude-notes/plans/2026-05-06-listings-L2-data-model.md create mode 100644 claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md create mode 100644 claude-notes/plans/2026-05-06-listings-L5-categories-sidebar.md create mode 100644 claude-notes/plans/2026-05-07-create-worktree-xtask.md create mode 100644 claude-notes/plans/2026-05-07-debug-render-components-not-loading.md create mode 100644 claude-notes/plans/2026-05-07-listings-L6-dep-graph.md create mode 100644 claude-notes/plans/2026-05-07-listings-L7-postrender-upgrade.md create mode 100644 claude-notes/plans/2026-05-07-listings-L8-custom-templates.md create mode 100644 claude-notes/plans/2026-05-07-q2-preview-plan-2pre-restructure.md create mode 100644 claude-notes/plans/2026-05-07-render-components-live-reload.md create mode 100644 claude-notes/plans/2026-05-08-listings-L11-close-out.md create mode 100644 claude-notes/plans/2026-05-08-listings-L9-rss-feeds.md create mode 100644 claude-notes/plans/2026-05-09-q2-preview-plan-2c-customnode-rendering.md create mode 100644 claude-notes/plans/2026-05-10-q2-preview-plan-2d-body-container.md create mode 100644 claude-notes/plans/2026-05-10-q2-preview-plan-2e-q2-slides-migration.md create mode 100644 claude-notes/plans/2026-05-10-thread-user-grammars-renderer.md create mode 100644 claude-notes/plans/2026-05-11-bq-multiline-in-list-item.md create mode 100644 claude-notes/plans/2026-05-11-hub-client-decomposition.md create mode 100644 claude-notes/plans/2026-05-11-implement-create-worktree-xtask.md create mode 100644 claude-notes/plans/2026-05-11-q2-preview-epic.md create mode 100644 claude-notes/plans/2026-05-11-vite-preview-for-e2e-tests.md create mode 100644 claude-notes/plans/2026-05-12-displaymath-column-strip-fix.md create mode 100644 claude-notes/plans/2026-05-13-q2-preview-attribution.md create mode 100644 claude-notes/plans/2026-05-13-q2-preview-phase-a.md create mode 100644 claude-notes/plans/2026-05-13-q2-preview-phase-b.md create mode 100644 claude-notes/plans/2026-05-13-q2-preview-phase-c.md create mode 100644 claude-notes/plans/2026-05-14-attribution-auto-viewer.md create mode 100644 claude-notes/plans/2026-05-14-issue-195-empty-list-items.md create mode 100644 claude-notes/plans/2026-05-14-issue-196-list-continuation-regression.md create mode 100644 claude-notes/plans/2026-05-14-list-table-multiblock-cell-fix.md create mode 100644 claude-notes/plans/2026-05-14-q-2-35-indented-code-block-error.md create mode 100644 claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md create mode 100644 claude-notes/plans/2026-05-14-q2-preview-phase-d.md create mode 100644 claude-notes/plans/2026-05-14-q2-preview-phase-f.md create mode 100644 claude-notes/plans/2026-05-15-attribution-lua-binding-plan.md create mode 100644 claude-notes/plans/2026-05-15-fix-pipe-table-caption-collision.md create mode 100644 claude-notes/plans/2026-05-15-issue-201-apostrophe-escape.md create mode 100644 claude-notes/plans/2026-05-15-quiet-default-logging.md create mode 100644 claude-notes/plans/2026-05-18-bare-lt-as-str.md create mode 100644 claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md create mode 100644 claude-notes/plans/2026-05-19-bd-i6jy4-capture-driver-qmd-filter.md create mode 100644 claude-notes/plans/2026-05-19-bd-tnm3k-single-file-preview.md create mode 100644 claude-notes/plans/2026-05-19-code-block-features.md create mode 100644 claude-notes/plans/2026-05-20-auth-provider-interface.md create mode 100644 claude-notes/plans/2026-05-20-bd-6qbto-error-generation-utf8-safety.md create mode 100644 claude-notes/plans/2026-05-20-bd-8d6rk-navigation-diagnostics.md create mode 100644 claude-notes/plans/2026-05-20-bd-c05x6-body-link-source-location.md create mode 100644 claude-notes/plans/2026-05-20-bd-qor9a-metadata-path-resolution.md create mode 100644 claude-notes/plans/2026-05-20-brand-yml-support.md create mode 100644 claude-notes/plans/2026-05-20-heading-in-list-item-dropped.md create mode 100644 claude-notes/plans/2026-05-20-issue-222-deterministic-diagnostics.md create mode 100644 claude-notes/plans/2026-05-20-preview-navbar-brand-artifacts-link.md create mode 100644 claude-notes/plans/2026-05-20-render-no-project-skip-walk.md create mode 100644 claude-notes/plans/2026-05-20-render-truncates-source-images.md create mode 100644 claude-notes/plans/2026-05-20-table-default-rendering-parity.md create mode 100644 claude-notes/plans/2026-05-21-q2-preview-diagnostics-ariadne.md create mode 100644 claude-notes/plans/2026-05-21-q2-preview-diagnostics-surface.md create mode 100644 claude-notes/plans/2026-05-21-q2-render-website-profile.md create mode 100644 claude-notes/plans/2026-05-21-resource-directory-recursive-copy.md create mode 100644 claude-notes/plans/2026-05-21-resource-path-diagnostic.md create mode 100644 claude-notes/plans/2026-05-21-resource-path-leading-slash.md create mode 100644 claude-notes/plans/2026-05-22-callout-class-vocabulary-fix.md create mode 100644 claude-notes/plans/2026-05-22-diagnostic-coalescing.md create mode 100644 claude-notes/plans/2026-05-22-engine-discovery-cache.md create mode 100644 claude-notes/plans/2026-05-22-error-docs-content.md create mode 100644 claude-notes/plans/2026-05-22-error-docs-foundation.md create mode 100644 claude-notes/plans/2026-05-22-error-docs-tooling.md create mode 100644 claude-notes/plans/2026-05-22-error-docs-website-epic.md create mode 100644 claude-notes/plans/2026-05-22-pampa-hash-fileids.md create mode 100644 claude-notes/plans/2026-05-22-parallelize-pass-one.md create mode 100644 claude-notes/plans/2026-05-22-q2-render-json-errors.md create mode 100644 claude-notes/plans/2026-05-22-theme-diagnostic-epic.md create mode 100644 claude-notes/plans/2026-05-22-theme-diagnostic-structured.md create mode 100644 claude-notes/plans/2026-05-22-worktree-disk-reclamation.md create mode 100644 claude-notes/plans/2026-05-24-inline-code-triple-asterisk-regression.md create mode 100644 claude-notes/plans/2026-05-24-multiline-inline-code-spans.md create mode 100644 claude-notes/plans/2026-05-27-multi-engine-execution.md create mode 100644 claude-notes/plans/2026-05-28-hub-mcp-loopback-pkce.md create mode 100644 claude-notes/plans/2026-05-28-integration-test-consolidation.md create mode 100644 claude-notes/plans/2026-05-28-mermaidjs-engine-design.md create mode 100644 claude-notes/plans/2026-05-30-bd-1lpkx-star-emphasis-opening-mark.md create mode 100644 claude-notes/plans/2026-05-30-hub-path-traversal-containment.md create mode 100644 claude-notes/plans/2026-06-01-import-from-zip.md create mode 100644 claude-notes/plans/2026-06-01-parallelize-pass-two.md create mode 100644 claude-notes/plans/2026-06-01-render-perf-profiling.md create mode 100644 claude-notes/plans/2026-06-02-get-config-command.md create mode 100644 claude-notes/plans/2026-06-02-render-error-warning-summary.md create mode 100644 claude-notes/plans/2026-06-03-codeblock-trailing-margin.md create mode 100644 claude-notes/plans/2026-06-08-braid-0.3.0-features-for-migration.md create mode 100644 claude-notes/plans/2026-06-08-braid-migration.md create mode 100644 claude-notes/plans/2026-06-08-revealjs-presentations.md create mode 100644 claude-notes/plans/2026-06-09-metadata-as-str-audit.md create mode 100644 claude-notes/plans/2026-06-09-named-footnote-ref-resolution.md create mode 100644 claude-notes/plans/2026-06-09-revealjs-docs-and-examples.md create mode 100644 claude-notes/plans/5qnj-trace-size-investigation/big.qmd create mode 100644 claude-notes/plans/5qnj-trace-size-investigation/measurements.md create mode 100644 claude-notes/plans/5qnj-trace-size-investigation/medium.qmd create mode 100644 claude-notes/plans/5qnj-trace-size-investigation/tiny.qmd create mode 100644 claude-notes/plans/bd-352bh-screenshot-ariadne-expanded.png create mode 100644 claude-notes/plans/bd-352bh-screenshot-ariadne-q120.png create mode 100644 claude-notes/plans/bd-b9kzg-screenshot-1-q13-4-body-link.png create mode 100644 claude-notes/plans/bd-b9kzg-screenshot-2-styled-collapsed.png create mode 100644 claude-notes/plans/bd-b9kzg-screenshot-3-styled-expanded.png create mode 100644 claude-notes/plans/thread-user-grammars-renderer-investigation/repro-and-codepath.md create mode 100644 claude-notes/research/2026-05-05-editable-custom-nodes.md create mode 100644 claude-notes/research/2026-05-19-PreviewDocument-merge-resolution.md create mode 100644 claude-notes/research/2026-05-19-attribution-merge-briefing.md create mode 100644 claude-notes/research/2026-05-21-quarto-web-render-profile.md create mode 100644 claude-notes/research/2026-05-22-quarto-web-parallel-pass1-profile.json.gz create mode 100644 claude-notes/research/2026-05-22-quarto-web-parallel-pass1-profile.json.syms.json create mode 100644 claude-notes/research/2026-05-22-quarto-web-postfix-profile.json.gz create mode 100644 claude-notes/research/2026-05-22-quarto-web-postfix-profile.json.syms.json create mode 100644 claude-notes/research/2026-05-24-tracing-envfilter-mismatch.md create mode 100644 claude-notes/research/2026-05-28-integration-test-bloat.md create mode 100644 claude-notes/research/commonmark-spec/README.md create mode 100644 claude-notes/research/commonmark-spec/examples-index.md create mode 100644 claude-notes/research/commonmark-spec/index.md create mode 100755 claude-notes/research/commonmark-spec/scripts/spec-example.sh create mode 100755 claude-notes/research/commonmark-spec/scripts/spec-section.sh create mode 100644 claude-notes/research/measurements/baseline-debug.log create mode 100644 claude-notes/research/measurements/baseline-release.log create mode 100644 claude-notes/research/measurements/controlled-baseline-debug.log create mode 100644 claude-notes/research/measurements/controlled-baseline-release.log create mode 100644 claude-notes/research/measurements/controlled-pilot-debug.log create mode 100644 claude-notes/research/measurements/controlled-pilot-release.log create mode 100644 claude-notes/research/measurements/pampa-pilot-debug.log create mode 100644 claude-notes/research/measurements/pampa-pilot-release.log create mode 100644 claude-notes/research/measurements/phase6-baseline-debug.log create mode 100644 claude-notes/research/measurements/phase6-baseline-release.log create mode 100644 claude-notes/research/measurements/phase6-rollout-debug.log create mode 100644 claude-notes/research/measurements/phase6-rollout-release.log create mode 100644 claude-notes/research/vendored-dependencies-inventory.md rename crates/comrak-to-pandoc/tests/{ => integration}/debug.rs (99%) rename crates/comrak-to-pandoc/tests/{ => integration}/debug_comrak.rs (99%) rename crates/comrak-to-pandoc/tests/{ => integration}/differential.rs (100%) rename crates/comrak-to-pandoc/tests/{ => integration}/generators.rs (100%) create mode 100644 crates/comrak-to-pandoc/tests/integration/main.rs rename crates/comrak-to-pandoc/tests/{ => integration}/proptest_roundtrip.rs (98%) create mode 100644 crates/pampa/resources/error-corpus/Q-2-35.json create mode 100644 crates/pampa/resources/error-corpus/Q-2-36.json create mode 100644 crates/pampa/resources/error-corpus/Q-2-37.json create mode 100644 crates/pampa/resources/error-corpus/Q-2-38.json delete mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-24-simple.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-35-basic.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-35-indented-blockquote.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-35-more-than-four.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-35-tab-indent.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-36-bare-label.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-36-comma-and-kv.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-36-comma-args.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-37-after-scheme.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-37-before-close-paren.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-37-mid-destination.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-eof-after-class.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-eof-after-id.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-eof-after-kv.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-image-multi-line-eof.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-multi-line-eof-class-and-kv.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-multi-line-eof-two-classes.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-multi-line-eof-two-kvs.qmd create mode 100644 crates/pampa/resources/error-corpus/case-files/Q-2-38-multi-line-eof.qmd create mode 100644 crates/pampa/snapshots/native/heading-and-plain-list-items.snap create mode 100644 crates/pampa/snapshots/native/heading-in-bullet-list-item.snap create mode 100644 crates/pampa/snapshots/native/heading-in-ordered-list-item.snap create mode 100644 crates/pampa/snapshots/native/issue-206-fenced-div-close-after-table.snap create mode 100644 crates/pampa/src/attribution.rs create mode 100644 crates/pampa/src/config_json.rs create mode 100644 crates/pampa/tests/integration/attribution_html_coalescing_test.rs create mode 100644 crates/pampa/tests/integration/attribution_json_wire_test.rs rename crates/pampa/tests/{ => integration}/error_node_analysis.rs (100%) rename crates/pampa/tests/{ => integration}/incremental_writer_investigation.rs (100%) rename crates/pampa/tests/{ => integration}/incremental_writer_tests.rs (100%) rename crates/pampa/tests/{ => integration}/inline_span_investigation.rs (100%) rename crates/pampa/tests/{ => integration}/inline_splice_integration_tests.rs (100%) rename crates/pampa/tests/{ => integration}/inline_splice_property_tests.rs (100%) rename crates/pampa/tests/{ => integration}/inline_splice_safety_tests.rs (100%) rename crates/pampa/tests/{ => integration}/json_location_test.rs (97%) rename crates/pampa/tests/{ => integration}/json_reader_smoke_tests.rs (100%) create mode 100644 crates/pampa/tests/integration/main.rs rename crates/pampa/tests/{ => integration}/qmd_writer_source_info.rs (100%) rename crates/pampa/tests/{ => integration}/test.rs (96%) rename crates/pampa/tests/{ => integration}/test_ansi_writer.rs (100%) rename crates/pampa/tests/{ => integration}/test_attr_source_parsing.rs (84%) rename crates/pampa/tests/{ => integration}/test_attr_source_structure.rs (100%) create mode 100644 crates/pampa/tests/integration/test_bare_lt_str.rs create mode 100644 crates/pampa/tests/integration/test_blockquote_multiline_attrs.rs rename crates/pampa/tests/{ => integration}/test_citeproc_integration.rs (100%) rename crates/pampa/tests/{ => integration}/test_cli_input_arg.rs (100%) rename crates/pampa/tests/{ => integration}/test_code_block_attributes.rs (81%) rename crates/pampa/tests/{ => integration}/test_code_span.rs (100%) create mode 100644 crates/pampa/tests/integration/test_diagnostic_determinism.rs rename crates/pampa/tests/{ => integration}/test_editorial_mark_spacing.rs (100%) create mode 100644 crates/pampa/tests/integration/test_emphasis_opening_mark.rs rename crates/pampa/tests/{ => integration}/test_error_corpus.rs (99%) create mode 100644 crates/pampa/tests/integration/test_grid_table_error.rs rename crates/pampa/tests/{ => integration}/test_hard_soft_break.rs (100%) rename crates/pampa/tests/{ => integration}/test_html_attr_handling.rs (100%) rename crates/pampa/tests/{ => integration}/test_inline_locations.rs (100%) rename crates/pampa/tests/{ => integration}/test_json_div_transforms.rs (55%) rename crates/pampa/tests/{ => integration}/test_json_errors.rs (100%) rename crates/pampa/tests/{ => integration}/test_json_roundtrip.rs (100%) create mode 100644 crates/pampa/tests/integration/test_link_destination_linebreak.rs rename crates/pampa/tests/{ => integration}/test_location_health.rs (100%) rename crates/pampa/tests/{ => integration}/test_lua_attr_mutation.rs (99%) rename crates/pampa/tests/{ => integration}/test_lua_constructors.rs (99%) rename crates/pampa/tests/{ => integration}/test_lua_list.rs (99%) rename crates/pampa/tests/{ => integration}/test_lua_utils.rs (99%) rename crates/pampa/tests/{ => integration}/test_math_attr.rs (100%) rename crates/pampa/tests/{ => integration}/test_meta.rs (100%) rename crates/pampa/tests/{ => integration}/test_metadata_source_tracking.rs (100%) rename crates/pampa/tests/{ => integration}/test_nested_yaml_serialization.rs (100%) rename crates/pampa/tests/{ => integration}/test_ordered_list_formatting.rs (100%) rename crates/pampa/tests/{ => integration}/test_rawblock_to_config_value.rs (100%) rename crates/pampa/tests/{ => integration}/test_section_divs.rs (100%) rename crates/pampa/tests/{ => integration}/test_shortcode.rs (100%) rename crates/pampa/tests/{ => integration}/test_template_integration.rs (100%) rename crates/pampa/tests/{ => integration}/test_trailing_linebreak_commonmark.rs (100%) rename crates/pampa/tests/{ => integration}/test_treesitter_coverage.rs (100%) rename crates/pampa/tests/{ => integration}/test_treesitter_refactoring.rs (97%) create mode 100644 crates/pampa/tests/integration/test_unclosed_attr_specifier.rs rename crates/pampa/tests/{ => integration}/test_unicode_error_offsets.rs (100%) rename crates/pampa/tests/{ => integration}/test_unicode_whitespace.rs (100%) rename crates/pampa/tests/{ => integration}/test_warnings.rs (63%) rename crates/pampa/tests/{ => integration}/test_wasm_entrypoints.rs (100%) create mode 100644 crates/pampa/tests/integration/test_whitespace_re_compile_once.rs rename crates/pampa/tests/{ => integration}/test_yaml_tag_regression.rs (100%) rename crates/pampa/tests/{ => integration}/test_yaml_to_config_value.rs (100%) create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-minus.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-ordered-dot.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-ordered-paren.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-plus.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-star.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-then-paragraph.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/bq-multiline-in-list-three-lines.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-absorbs-blocks.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-blockquote-lazy.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-blockquote-nested.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-blockquote.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-doubled-space.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-list-loose.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-list-nested.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-list.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-simple.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-multiline-three-lines.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-quad-star.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-triple-star-only.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-triple-star-prefix.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-code-triple-star-suffix.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-math-multiline-blockquote.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-math-multiline-list.qmd create mode 100644 crates/pampa/tests/pandoc-match-corpus/markdown/inline-math-multiline-simple.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_after_code_inline.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_after_emph.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_at_block_start.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_before_punct.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_before_space.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/attr_value_backslash_escaped_punct.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/attr_value_escaped_quote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/attr_value_literal_backslash.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/bare_lt_eol.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/bare_lt_simple.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/bare_lt_unclosed_tag.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/code_span_then_html_with_space.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/codeblock_empty.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/codeblock_only_blank_lines.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/codeblock_trailing_double_newline.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/codeblock_trailing_newline.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/display_math_in_blockquote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/display_math_in_blockquote_in_list.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/display_math_in_bq_list_bq.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/display_math_in_list_in_blockquote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/display_math_in_nested_blockquote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/emph_around_multiline_display_math.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/emph_around_multiline_display_math_in_blockquote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_bullet_item_nested.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_bullet_item_only.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_bullet_item_trailing.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_ordered_item_trailing.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/figure_implicit_then_figure.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/figure_implicit_then_para.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/inline_backslash_space.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/inline_backslash_space_paragraph_start.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/labeled_display_math_in_blockquote.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/labeled_display_math_top_level_indented.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/layout_div_subfigures.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/list_table_cell_para_then_codeblock.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/list_table_cell_single_codeblock.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/list_table_cell_two_paragraphs.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/list_table_empty_cell.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/list_table_empty_cell_with_attrs.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/pipe_table_empty_header.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/rawblock_html.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/rawblock_latex.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/table-caption-with-classes.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/table-caption-with-id.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/table-caption-with-keyval.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/table-caption-with-mixed-attrs.qmd create mode 100644 crates/pampa/tests/roundtrip_tests/qmd-json-qmd/table_with_inline_nbsp_in_cell.qmd create mode 100644 crates/pampa/tests/snapshots/native/heading-and-plain-list-items.qmd create mode 100644 crates/pampa/tests/snapshots/native/heading-in-bullet-list-item.qmd create mode 100644 crates/pampa/tests/snapshots/native/heading-in-ordered-list-item.qmd create mode 100644 crates/pampa/tests/snapshots/native/issue-206-fenced-div-close-after-table.qmd create mode 100644 crates/perf-harness/src/bin/parse_corpus.rs rename crates/qmd-syntax-helper/tests/{ => integration}/apostrophe_quotes_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/attribute_ordering_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/grid_tables_test.rs (100%) create mode 100644 crates/qmd-syntax-helper/tests/integration/main.rs rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_11_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_12_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_13_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_15_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_16_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_17_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_18_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_19_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_20_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_21_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_22_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_23_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_24_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_25_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_26_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_28_test.rs (100%) rename crates/qmd-syntax-helper/tests/{ => integration}/q_2_5_test.rs (100%) create mode 100644 crates/quarto-brand/Cargo.toml create mode 100644 crates/quarto-brand/src/error.rs create mode 100644 crates/quarto-brand/src/lib.rs create mode 100644 crates/quarto-brand/src/resolve.rs create mode 100644 crates/quarto-brand/src/types.rs create mode 100644 crates/quarto-brand/tests/fixtures/README.md create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/kitchen-sink/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/kitchen-sink/brand-typography.qmd create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/monospace-colors/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/monospace-colors/brand-typography.qmd create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/palette-colors/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/brand-yaml/palette-colors/brand-typography.qmd create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/basic-brand/README.md create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/basic-brand/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/basic-brand/fonts/custom-font.woff2 create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/basic-brand/logo.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/favicon.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/fonts/brand-bold.woff2 create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/fonts/brand-regular.woff2 create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/fonts/unused-italic.woff2 create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/logo.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/multi-file-brand/unused-styles.css create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/nested-brand/_brand.yml create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/nested-brand/images/extra-icon.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/nested-brand/images/header.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/nested-brand/images/logo.png create mode 100644 crates/quarto-brand/tests/fixtures/use-brand/nested-brand/notes.txt create mode 100644 crates/quarto-brand/tests/integration/color_test.rs create mode 100644 crates/quarto-brand/tests/integration/logo_test.rs create mode 100644 crates/quarto-brand/tests/integration/main.rs create mode 100644 crates/quarto-brand/tests/integration/parse_test.rs create mode 100644 crates/quarto-brand/tests/integration/typography_test.rs rename crates/quarto-citeproc/tests/{ => integration}/csl_conformance.rs (100%) rename crates/quarto-citeproc/tests/{ => integration}/error_tests.rs (100%) create mode 100644 crates/quarto-citeproc/tests/integration/main.rs create mode 100644 crates/quarto-config/src/website.rs create mode 100644 crates/quarto-core/src/attribution/builder.rs create mode 100644 crates/quarto-core/src/attribution/git_blame.rs create mode 100644 crates/quarto-core/src/attribution/handle.rs create mode 100644 crates/quarto-core/src/attribution/mod.rs create mode 100644 crates/quarto-core/src/attribution/mode.rs create mode 100644 crates/quarto-core/src/attribution/palette.rs create mode 100644 crates/quarto-core/src/attribution/pampa_bridge.rs create mode 100644 crates/quarto-core/src/attribution/prebuilt.rs create mode 100644 crates/quarto-core/src/attribution/resolve.rs create mode 100644 crates/quarto-core/src/attribution/source.rs create mode 100644 crates/quarto-core/src/attribution/types.rs create mode 100644 crates/quarto-core/src/document_profile.rs create mode 100644 crates/quarto-core/src/engine/capture_splice.rs create mode 100644 crates/quarto-core/src/engine/fixture.rs create mode 100644 crates/quarto-core/src/engine/preview_record.rs create mode 100644 crates/quarto-core/src/engine/replay.rs create mode 100644 crates/quarto-core/src/get_config.rs create mode 100644 crates/quarto-core/src/output_sink.rs create mode 100644 crates/quarto-core/src/project/cache_key.rs create mode 100644 crates/quarto-core/src/project/dependency_graph.rs create mode 100644 crates/quarto-core/src/project/discovery.rs create mode 100644 crates/quarto-core/src/project/index.rs create mode 100644 crates/quarto-core/src/project/listing/binding.rs create mode 100644 crates/quarto-core/src/project/listing/config.rs create mode 100644 crates/quarto-core/src/project/listing/feed/binding.rs create mode 100644 crates/quarto-core/src/project/listing/feed/complete.rs create mode 100644 crates/quarto-core/src/project/listing/feed/link_inject.rs create mode 100644 crates/quarto-core/src/project/listing/feed/mod.rs create mode 100644 crates/quarto-core/src/project/listing/feed/reader_ext.rs create mode 100644 crates/quarto-core/src/project/listing/feed/stage.rs create mode 100644 crates/quarto-core/src/project/listing/feed/templates/item.template create mode 100644 crates/quarto-core/src/project/listing/feed/templates/postamble.template create mode 100644 crates/quarto-core/src/project/listing/feed/templates/preamble.template create mode 100644 crates/quarto-core/src/project/listing/filter.rs create mode 100644 crates/quarto-core/src/project/listing/helpers.rs create mode 100644 crates/quarto-core/src/project/listing/item.rs create mode 100644 crates/quarto-core/src/project/listing/mod.rs create mode 100644 crates/quarto-core/src/project/listing/placeholders.rs create mode 100644 crates/quarto-core/src/project/listing/post_render_upgrade.rs create mode 100644 crates/quarto-core/src/project/listing/post_render_upgrade/reader.rs create mode 100644 crates/quarto-core/src/project/listing/post_render_upgrade/substitute.rs create mode 100644 crates/quarto-core/src/project/listing/sort.rs create mode 100644 crates/quarto-core/src/project/listing/templates.rs create mode 100644 crates/quarto-core/src/project/listing/templates/item-default.template create mode 100644 crates/quarto-core/src/project/listing/templates/item-grid.template create mode 100644 crates/quarto-core/src/project/listing/templates/item-table.template create mode 100644 crates/quarto-core/src/project/listing/templates/listing-default.template create mode 100644 crates/quarto-core/src/project/listing/templates/listing-grid.template create mode 100644 crates/quarto-core/src/project/listing/templates/listing-table.template rename crates/quarto-core/src/{project.rs => project/mod.rs} (85%) create mode 100644 crates/quarto-core/src/project/orchestrator.rs create mode 100644 crates/quarto-core/src/project/pass2_renderer.rs create mode 100644 crates/quarto-core/src/project/profile_cache.rs create mode 100644 crates/quarto-core/src/project/sidebar_membership.rs create mode 100644 crates/quarto-core/src/project/website_config.rs create mode 100644 crates/quarto-core/src/project/website_post_render.rs create mode 100644 crates/quarto-core/src/project_resources.rs create mode 100644 crates/quarto-core/src/resource_resolver.rs create mode 100644 crates/quarto-core/src/revealjs/assemble.rs create mode 100644 crates/quarto-core/src/revealjs/columns.rs create mode 100644 crates/quarto-core/src/revealjs/footnotes.rs create mode 100644 crates/quarto-core/src/revealjs/mod.rs create mode 100644 crates/quarto-core/src/revealjs/slides.rs create mode 100644 crates/quarto-core/src/revealjs/transform.rs create mode 100644 crates/quarto-core/src/stage/stages/attribution_generate.rs create mode 100644 crates/quarto-core/src/stage/stages/bootstrap_js.rs create mode 100644 crates/quarto-core/src/stage/stages/capture_splice.rs create mode 100644 crates/quarto-core/src/stage/stages/clipboard_js.rs create mode 100644 crates/quarto-core/src/stage/stages/document_profile.rs create mode 100644 crates/quarto-core/src/stage/stages/include_resolve.rs create mode 100644 crates/quarto-core/src/stage/stages/link_resolution.rs create mode 100644 crates/quarto-core/src/stage/stages/listing_item_info.rs create mode 100644 crates/quarto-core/src/stage/stages/math_js.rs create mode 100644 crates/quarto-core/src/stage/stages/resource_report.rs create mode 100644 crates/quarto-core/src/stage/stages/unwrap_profile.rs create mode 100644 crates/quarto-core/src/theme_diagnostic.rs create mode 100644 crates/quarto-core/src/transforms/attribution_generate.rs create mode 100644 crates/quarto-core/src/transforms/attribution_render.rs create mode 100644 crates/quarto-core/src/transforms/attribution_viewer.rs create mode 100644 crates/quarto-core/src/transforms/categories_sidebar.rs create mode 100644 crates/quarto-core/src/transforms/code_block_generate.rs create mode 100644 crates/quarto-core/src/transforms/code_block_render.rs create mode 100644 crates/quarto-core/src/transforms/link_rewrite.rs create mode 100644 crates/quarto-core/src/transforms/listing_generate.rs create mode 100644 crates/quarto-core/src/transforms/listing_render.rs create mode 100644 crates/quarto-core/src/transforms/navigation_active.rs create mode 100644 crates/quarto-core/src/transforms/navigation_enrich.rs create mode 100644 crates/quarto-core/src/transforms/navigation_href.rs create mode 100644 crates/quarto-core/src/transforms/page_nav_generate.rs create mode 100644 crates/quarto-core/src/transforms/page_nav_render.rs create mode 100644 crates/quarto-core/src/transforms/sidebar_auto.rs create mode 100644 crates/quarto-core/src/transforms/sidebar_generate.rs create mode 100644 crates/quarto-core/src/transforms/sidebar_render.rs create mode 100644 crates/quarto-core/src/transforms/table_bootstrap_class.rs create mode 100644 crates/quarto-core/src/transforms/website_bootstrap_icons.rs create mode 100644 crates/quarto-core/src/transforms/website_canonical_url.rs create mode 100644 crates/quarto-core/src/transforms/website_favicon.rs create mode 100644 crates/quarto-core/src/transforms/website_title_prefix.rs create mode 100644 crates/quarto-core/tests/fixtures/attribution-blame/REGEN.md create mode 100644 crates/quarto-core/tests/fixtures/attribution-blame/doc.qmd create mode 100644 crates/quarto-core/tests/fixtures/attribution-blame/multi-commit.porcelain create mode 100644 crates/quarto-core/tests/fixtures/attribution-blame/single-commit.porcelain create mode 100644 crates/quarto-core/tests/fixtures/phase5-single-doc-baseline/doc.qmd create mode 100644 crates/quarto-core/tests/fixtures/phase5-single-doc-baseline/expected_hashes.txt create mode 100644 crates/quarto-core/tests/fixtures/phase5-website-baseline/PRE_PHASE5_OUTPUT.md create mode 100644 crates/quarto-core/tests/fixtures/phase5-website-baseline/_quarto.yml create mode 100644 crates/quarto-core/tests/fixtures/phase5-website-baseline/about.qmd create mode 100644 crates/quarto-core/tests/fixtures/phase5-website-baseline/docs/api.qmd create mode 100644 crates/quarto-core/tests/fixtures/phase5-website-baseline/index.qmd create mode 100644 crates/quarto-core/tests/fixtures/websites/hub-smoke/_quarto.yml create mode 100644 crates/quarto-core/tests/fixtures/websites/hub-smoke/about.qmd create mode 100644 crates/quarto-core/tests/fixtures/websites/hub-smoke/index.qmd create mode 100644 crates/quarto-core/tests/fixtures/websites/hub-smoke/posts/first.qmd create mode 100644 crates/quarto-core/tests/integration/artifact_scoping_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/attribution_baseline_snapshot.rs create mode 100644 crates/quarto-core/tests/integration/attribution_chain_resolution.rs create mode 100644 crates/quarto-core/tests/integration/attribution_cli.rs create mode 100644 crates/quarto-core/tests/integration/attribution_generate.rs create mode 100644 crates/quarto-core/tests/integration/attribution_gitblame.rs create mode 100644 crates/quarto-core/tests/integration/attribution_render.rs create mode 100644 crates/quarto-core/tests/integration/attribution_types.rs create mode 100644 crates/quarto-core/tests/integration/attribution_viewer.rs create mode 100644 crates/quarto-core/tests/integration/attribution_wasm_invariant.rs create mode 100644 crates/quarto-core/tests/integration/bootstrap_js_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/brand_render.rs rename crates/quarto-core/tests/{ => integration}/crossref_fixtures.rs (100%) create mode 100644 crates/quarto-core/tests/integration/document_profile_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/engine_merge.rs create mode 100644 crates/quarto-core/tests/integration/fail_fast.rs create mode 100644 crates/quarto-core/tests/integration/get_config_merge.rs create mode 100644 crates/quarto-core/tests/integration/include_resolve_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/incremental_rebuild.rs rename crates/quarto-core/tests/{ => integration}/jupyter_integration.rs (100%) create mode 100644 crates/quarto-core/tests/integration/link_rewriting_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/listing_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/main.rs create mode 100644 crates/quarto-core/tests/integration/math_mode_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/metadata_path_resolution.rs create mode 100644 crates/quarto-core/tests/integration/navbar_footer_pipeline.rs rename crates/quarto-core/tests/{ => integration}/navigation_e2e.rs (96%) rename crates/quarto-core/tests/{ => integration}/navigation_merge.rs (100%) create mode 100644 crates/quarto-core/tests/integration/page_navigation_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/project_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/project_resources.rs create mode 100644 crates/quarto-core/tests/integration/render_page_in_project.rs create mode 100644 crates/quarto-core/tests/integration/render_preserves_source_files.rs create mode 100644 crates/quarto-core/tests/integration/render_to_html_user_grammars.rs create mode 100644 crates/quarto-core/tests/integration/replay_engine.rs create mode 100644 crates/quarto-core/tests/integration/revealjs_features.rs create mode 100644 crates/quarto-core/tests/integration/revealjs_format.rs create mode 100644 crates/quarto-core/tests/integration/sidebar_pipeline.rs create mode 100644 crates/quarto-core/tests/integration/snapshots/integration__attribution_baseline_snapshot__attribution_off_baseline.snap create mode 100644 crates/quarto-core/tests/integration/snapshots/integration__listing_pipeline__snapshot_builtin_default_with_categories_cloud_mode.snap create mode 100644 crates/quarto-core/tests/integration/snapshots/integration__listing_pipeline__snapshot_builtin_default_with_categories_default_mode.snap create mode 100644 crates/quarto-core/tests/integration/snapshots/integration__listing_pipeline__snapshot_builtin_default_with_categories_unnumbered_mode.snap create mode 100644 crates/quarto-core/tests/integration/snapshots/integration__listing_pipeline__snapshot_page_with_two_listings_aggregates_sidebar.snap create mode 100644 crates/quarto-core/tests/integration/website_post_render.rs rename crates/quarto-csl/tests/{ => integration}/error_tests.rs (100%) rename crates/quarto-csl/tests/{ => integration}/integration.rs (100%) create mode 100644 crates/quarto-csl/tests/integration/main.rs create mode 100644 crates/quarto-doctemplate/src/pipes.rs rename crates/quarto-doctemplate/tests/{ => integration}/integration_tests.rs (100%) create mode 100644 crates/quarto-doctemplate/tests/integration/main.rs rename crates/quarto-doctemplate/tests/{ => integration}/pandoc_equiv_tests.rs (100%) create mode 100644 crates/quarto-error-reporting/schemas/json-diagnostic.json create mode 100644 crates/quarto-error-reporting/schemas/json-pass1-failure.json create mode 100644 crates/quarto-error-reporting/src/coalesce.rs create mode 100644 crates/quarto-error-reporting/src/json.rs create mode 100644 crates/quarto-error-reporting/tests/schema_drift.rs rename crates/quarto-highlight/tests/{ => integration}/all_languages.rs (100%) rename crates/quarto-highlight/tests/{ => integration}/annotate.rs (100%) rename crates/quarto-highlight/tests/{ => integration}/golden.rs (97%) create mode 100644 crates/quarto-highlight/tests/integration/main.rs rename crates/quarto-highlight/tests/{ => integration}/python_basic.rs (100%) rename crates/quarto-highlight/tests/{snapshots/golden__bash.snap => integration/snapshots/integration__golden__bash.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__css.snap => integration/snapshots/integration__golden__css.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__html.snap => integration/snapshots/integration__golden__html.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__javascript.snap => integration/snapshots/integration__golden__javascript.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__javascript_jsx_alias.snap => integration/snapshots/integration__golden__javascript_jsx_alias.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__json.snap => integration/snapshots/integration__golden__json.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__julia.snap => integration/snapshots/integration__golden__julia.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__lua.snap => integration/snapshots/integration__golden__lua.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__python.snap => integration/snapshots/integration__golden__python.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__r.snap => integration/snapshots/integration__golden__r.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__sql.snap => integration/snapshots/integration__golden__sql.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__tsx.snap => integration/snapshots/integration__golden__tsx.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__typescript.snap => integration/snapshots/integration__golden__typescript.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__user_grammar_toml.snap => integration/snapshots/integration__golden__user_grammar_toml.snap} (100%) rename crates/quarto-highlight/tests/{snapshots/golden__yaml.snap => integration/snapshots/integration__golden__yaml.snap} (100%) rename crates/quarto-highlight/tests/{ => integration}/trait_provider.rs (100%) rename crates/quarto-highlight/tests/{ => integration}/user_grammar_toml.rs (100%) create mode 100644 crates/quarto-hub/tests/auth_bearer.rs create mode 100644 crates/quarto-navigation/src/page_nav.rs create mode 100644 crates/quarto-navigation/src/sidebar.rs create mode 100644 crates/quarto-preview/Cargo.toml create mode 100644 crates/quarto-preview/build.rs create mode 100644 crates/quarto-preview/src/cache.rs create mode 100644 crates/quarto-preview/src/capture_driver.rs create mode 100644 crates/quarto-preview/src/config.rs create mode 100644 crates/quarto-preview/src/deps.rs create mode 100644 crates/quarto-preview/src/diagnostics.rs create mode 100644 crates/quarto-preview/src/lib.rs create mode 100644 crates/quarto-preview/src/re_execute.rs create mode 100644 crates/quarto-preview/tests/integration/boot.rs create mode 100644 crates/quarto-preview/tests/integration/cache_hit.rs create mode 100644 crates/quarto-preview/tests/integration/diagnostics_capture_failure.rs create mode 100644 crates/quarto-preview/tests/integration/diagnostics_endpoint.rs create mode 100644 crates/quarto-preview/tests/integration/eager_capture.rs create mode 100644 crates/quarto-preview/tests/integration/main.rs create mode 100644 crates/quarto-preview/tests/integration/smoke.rs create mode 100644 crates/quarto-preview/tests/integration/staleness.rs create mode 100644 crates/quarto-publish/Cargo.toml create mode 100644 crates/quarto-publish/src/cli.rs create mode 100644 crates/quarto-publish/src/common/errors.rs create mode 100644 crates/quarto-publish/src/common/git.rs create mode 100644 crates/quarto-publish/src/common/github.rs create mode 100644 crates/quarto-publish/src/common/mod.rs create mode 100644 crates/quarto-publish/src/common/publish_yml.rs create mode 100644 crates/quarto-publish/src/common/wait.rs create mode 100644 crates/quarto-publish/src/config.rs create mode 100644 crates/quarto-publish/src/execute.rs create mode 100644 crates/quarto-publish/src/gh_pages/mod.rs create mode 100644 crates/quarto-publish/src/gh_pages/provider.rs create mode 100644 crates/quarto-publish/src/host.rs create mode 100644 crates/quarto-publish/src/lib.rs create mode 100644 crates/quarto-publish/src/provider.rs create mode 100644 crates/quarto-publish/src/renderer.rs create mode 100644 crates/quarto-publish/src/types.rs create mode 100644 crates/quarto-publish/tests/gh_pages_e2e.rs create mode 100644 crates/quarto-sass/src/brand_layer.rs create mode 100644 crates/quarto-sass/tests/integration/brand_compile_test.rs create mode 100644 crates/quarto-sass/tests/integration/brand_config_test.rs create mode 100644 crates/quarto-sass/tests/integration/brand_layer_test.rs rename crates/quarto-sass/tests/{ => integration}/compile_all_themes_test.rs (67%) rename crates/quarto-sass/tests/{ => integration}/custom_theme_test.rs (100%) rename crates/quarto-sass/tests/{ => integration}/embedded_compile_test.rs (100%) create mode 100644 crates/quarto-sass/tests/integration/main.rs rename crates/quarto-sass/tests/{ => integration}/parity_test.rs (100%) create mode 100644 crates/quarto-util/src/user_status.rs create mode 100644 crates/quarto-util/src/verbose.rs rename crates/quarto-yaml-validation/tests/{ => integration}/comprehensive_schemas.rs (92%) create mode 100644 crates/quarto-yaml-validation/tests/integration/main.rs rename crates/quarto-yaml-validation/tests/{ => integration}/real_schemas.rs (98%) rename crates/quarto-yaml-validation/tests/{ => integration}/schema_compilation.rs (100%) rename crates/quarto-yaml-validation/tests/{ => integration}/schema_inheritance.rs (100%) rename crates/quarto-yaml-validation/tests/{ => integration}/validation_diagnostic.rs (100%) create mode 100644 crates/quarto/src/commands/get_config.rs create mode 100644 crates/quarto/tests/integration/attribution_cli_e2e.rs create mode 100644 crates/quarto/tests/integration/get_config_cli.rs create mode 100644 crates/quarto/tests/integration/json_errors.rs create mode 100644 crates/quarto/tests/integration/main.rs create mode 100644 crates/quarto/tests/integration/preview_cli.rs create mode 100644 crates/quarto/tests/integration/render_cli_e2e.rs rename crates/quarto/tests/{ => integration}/render_integration.rs (98%) create mode 100644 crates/quarto/tests/integration/revealjs_cli.rs rename crates/quarto/tests/{ => integration}/smoke_all.rs (100%) rename crates/quarto/tests/{ => integration}/trace_cli.rs (94%) rename crates/{tree-sitter-qmd/bindings/python/tree_sitter_markdown/py.typed => quarto/tests/smoke-all/includes/crossref/placeholder.png} (100%) create mode 100644 crates/quarto/tests/smoke-all/q2-debug/reactji.tsx create mode 100644 crates/quarto/tests/smoke-all/q2-debug/render-components-reactji.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-classes-full-layout-combo.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-classes-override.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-container-default.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-container-full-layout.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-container-minimal-title.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/body-container-minimal.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/hero.png create mode 100644 crates/quarto/tests/smoke-all/q2-preview/image-with-attrs.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/multi-element-doc.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/multi-element-project/_quarto.yml create mode 100644 crates/quarto/tests/smoke-all/q2-preview/multi-element-project/hero.png create mode 100644 crates/quarto/tests/smoke-all/q2-preview/multi-element-project/index.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/multi-element-project/notes.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/title-block-date-no-author.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/title-block-default.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/title-block-full.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/title-block-multi-author.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/title-block-no-title.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/with-render-components/_quarto.yml create mode 100644 crates/quarto/tests/smoke-all/q2-preview/with-render-components/index.qmd create mode 100644 crates/quarto/tests/smoke-all/q2-preview/with-render-components/overrides.tsx create mode 100644 crates/quarto/tests/smoke-all/quarto-test/callouts-matrix.qmd delete mode 100644 crates/tree-sitter-qmd/CMakeLists.txt delete mode 100644 crates/tree-sitter-qmd/CONTRIBUTING.md delete mode 100644 crates/tree-sitter-qmd/Makefile delete mode 100644 crates/tree-sitter-qmd/Package.resolved delete mode 100644 crates/tree-sitter-qmd/Package.swift delete mode 100644 crates/tree-sitter-qmd/README.tree-sitter-md.md delete mode 100644 crates/tree-sitter-qmd/binding.gyp delete mode 100644 crates/tree-sitter-qmd/bindings/go/binding_test.go delete mode 100644 crates/tree-sitter-qmd/bindings/go/markdown.go delete mode 100644 crates/tree-sitter-qmd/bindings/go/markdown_inline.go delete mode 100644 crates/tree-sitter-qmd/bindings/node/binding.cc delete mode 100644 crates/tree-sitter-qmd/bindings/node/binding_test.js delete mode 100644 crates/tree-sitter-qmd/bindings/node/index.d.ts delete mode 100644 crates/tree-sitter-qmd/bindings/node/index.js delete mode 100644 crates/tree-sitter-qmd/bindings/node/inline.js delete mode 100644 crates/tree-sitter-qmd/bindings/python/tests/test_binding.py delete mode 100644 crates/tree-sitter-qmd/bindings/python/tree_sitter_markdown/__init__.py delete mode 100644 crates/tree-sitter-qmd/bindings/python/tree_sitter_markdown/__init__.pyi delete mode 100644 crates/tree-sitter-qmd/bindings/python/tree_sitter_markdown/binding.c delete mode 100644 crates/tree-sitter-qmd/bindings/swift/.gitignore delete mode 100644 crates/tree-sitter-qmd/bindings/swift/TreeSitterMarkdownTests/TreeSitterMarkdownTests.swift delete mode 100644 crates/tree-sitter-qmd/common/common.mak delete mode 100644 crates/tree-sitter-qmd/go.mod delete mode 100644 crates/tree-sitter-qmd/package-lock.json delete mode 100644 crates/tree-sitter-qmd/package.json delete mode 100644 crates/tree-sitter-qmd/pyproject.toml delete mode 100755 crates/tree-sitter-qmd/scripts/build.js delete mode 100755 crates/tree-sitter-qmd/scripts/test.js delete mode 100644 crates/tree-sitter-qmd/setup.py delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/CMakeLists.txt delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/Makefile delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/__pycache__/migrate_tests.cpython-313.pyc delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/bindings/c/tree-sitter-markdown.h delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/bindings/c/tree-sitter-markdown.pc.in delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/bindings/swift/TreeSitterMarkdown/markdown.h delete mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/package.json create mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/grid_table.txt create mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/inline-multiline-attrs.txt create mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/lt-as-str.txt create mode 100644 crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/po-as-str.txt create mode 100644 crates/wasm-quarto-hub-client/CLAUDE.md create mode 100644 crates/xtask/src/braid_snapshot.rs create mode 100644 crates/xtask/src/build_q2_preview_spa.rs create mode 100644 crates/xtask/src/create_worktree.rs create mode 100644 crates/xtask/src/lint/metadata_as_str.rs create mode 100644 crates/xtask/src/switch_task.rs create mode 100644 crates/xtask/src/util.rs create mode 100644 docs/authoring/markdown/elephant.png create mode 100644 docs/authoring/markdown/index.qmd create mode 100644 docs/errors/README.md create mode 100644 docs/errors/cli/Q-7-1.qmd create mode 100644 docs/errors/cli/Q-7-2.qmd create mode 100644 docs/errors/cli/Q-7-3.qmd create mode 100644 docs/errors/cli/Q-7-4.qmd create mode 100644 docs/errors/cli/Q-7-5.qmd create mode 100644 docs/errors/cli/Q-7-6.qmd create mode 100644 docs/errors/cli/Q-7-7.qmd create mode 100644 docs/errors/cli/Q-7-8.qmd create mode 100644 docs/errors/index.qmd create mode 100644 docs/errors/internal/Q-0-1.qmd create mode 100644 docs/errors/internal/Q-0-99.qmd create mode 100644 docs/errors/listing/Q-12-1.qmd create mode 100644 docs/errors/listing/Q-12-10.qmd create mode 100644 docs/errors/listing/Q-12-11.qmd create mode 100644 docs/errors/listing/Q-12-12.qmd create mode 100644 docs/errors/listing/Q-12-13.qmd create mode 100644 docs/errors/listing/Q-12-14.qmd create mode 100644 docs/errors/listing/Q-12-15.qmd create mode 100644 docs/errors/listing/Q-12-16.qmd create mode 100644 docs/errors/listing/Q-12-2.qmd create mode 100644 docs/errors/listing/Q-12-3.qmd create mode 100644 docs/errors/listing/Q-12-4.qmd create mode 100644 docs/errors/listing/Q-12-5.qmd create mode 100644 docs/errors/listing/Q-12-6.qmd create mode 100644 docs/errors/listing/Q-12-7.qmd create mode 100644 docs/errors/listing/Q-12-8.qmd create mode 100644 docs/errors/listing/Q-12-9.qmd create mode 100644 docs/errors/lua/Q-11-1.qmd create mode 100644 docs/errors/markdown/Q-2-1.qmd create mode 100644 docs/errors/markdown/Q-2-10.qmd create mode 100644 docs/errors/markdown/Q-2-11.qmd create mode 100644 docs/errors/markdown/Q-2-12.qmd create mode 100644 docs/errors/markdown/Q-2-13.qmd create mode 100644 docs/errors/markdown/Q-2-14.qmd create mode 100644 docs/errors/markdown/Q-2-15.qmd create mode 100644 docs/errors/markdown/Q-2-16.qmd create mode 100644 docs/errors/markdown/Q-2-17.qmd create mode 100644 docs/errors/markdown/Q-2-18.qmd create mode 100644 docs/errors/markdown/Q-2-19.qmd create mode 100644 docs/errors/markdown/Q-2-2.qmd create mode 100644 docs/errors/markdown/Q-2-20.qmd create mode 100644 docs/errors/markdown/Q-2-21.qmd create mode 100644 docs/errors/markdown/Q-2-22.qmd create mode 100644 docs/errors/markdown/Q-2-23.qmd create mode 100644 docs/errors/markdown/Q-2-24.qmd create mode 100644 docs/errors/markdown/Q-2-25.qmd create mode 100644 docs/errors/markdown/Q-2-26.qmd create mode 100644 docs/errors/markdown/Q-2-27.qmd create mode 100644 docs/errors/markdown/Q-2-28.qmd create mode 100644 docs/errors/markdown/Q-2-29.qmd create mode 100644 docs/errors/markdown/Q-2-3.qmd create mode 100644 docs/errors/markdown/Q-2-30.qmd create mode 100644 docs/errors/markdown/Q-2-31.qmd create mode 100644 docs/errors/markdown/Q-2-32.qmd create mode 100644 docs/errors/markdown/Q-2-33.qmd create mode 100644 docs/errors/markdown/Q-2-34.qmd create mode 100644 docs/errors/markdown/Q-2-35.qmd create mode 100644 docs/errors/markdown/Q-2-39.qmd create mode 100644 docs/errors/markdown/Q-2-4.qmd create mode 100644 docs/errors/markdown/Q-2-5.qmd create mode 100644 docs/errors/markdown/Q-2-6.qmd create mode 100644 docs/errors/markdown/Q-2-7.qmd create mode 100644 docs/errors/markdown/Q-2-8.qmd create mode 100644 docs/errors/markdown/Q-2-9.qmd create mode 100644 docs/errors/navigation/Q-13-1.qmd create mode 100644 docs/errors/navigation/Q-13-2.qmd create mode 100644 docs/errors/navigation/Q-13-3.qmd create mode 100644 docs/errors/navigation/Q-13-4.qmd create mode 100644 docs/errors/navigation/Q-13-5.qmd create mode 100644 docs/errors/navigation/Q-13-6.qmd create mode 100644 docs/errors/navigation/Q-13-7.qmd create mode 100644 docs/errors/project/Q-5-1.qmd create mode 100644 docs/errors/project/Q-5-2.qmd create mode 100644 docs/errors/project/Q-5-3.qmd create mode 100644 docs/errors/template/Q-10-1.qmd create mode 100644 docs/errors/template/Q-10-2.qmd create mode 100644 docs/errors/template/Q-10-3.qmd create mode 100644 docs/errors/template/Q-10-4.qmd create mode 100644 docs/errors/template/Q-10-5.qmd create mode 100644 docs/errors/template/Q-10-6.qmd create mode 100644 docs/errors/template/Q-10-7.qmd create mode 100644 docs/errors/theme/Q-14-1.qmd create mode 100644 docs/errors/theme/Q-14-2.qmd create mode 100644 docs/errors/writer/Q-3-1.qmd create mode 100644 docs/errors/writer/Q-3-10.qmd create mode 100644 docs/errors/writer/Q-3-11.qmd create mode 100644 docs/errors/writer/Q-3-12.qmd create mode 100644 docs/errors/writer/Q-3-20.qmd create mode 100644 docs/errors/writer/Q-3-21.qmd create mode 100644 docs/errors/writer/Q-3-30.qmd create mode 100644 docs/errors/writer/Q-3-31.qmd create mode 100644 docs/errors/writer/Q-3-32.qmd create mode 100644 docs/errors/writer/Q-3-33.qmd create mode 100644 docs/errors/writer/Q-3-34.qmd create mode 100644 docs/errors/writer/Q-3-35.qmd create mode 100644 docs/errors/writer/Q-3-36.qmd create mode 100644 docs/errors/writer/Q-3-38.qmd create mode 100644 docs/errors/writer/Q-3-40.qmd create mode 100644 docs/errors/writer/Q-3-50.qmd create mode 100644 docs/errors/writer/Q-3-51.qmd create mode 100644 docs/errors/writer/Q-3-52.qmd create mode 100644 docs/errors/writer/Q-3-53.qmd create mode 100644 docs/errors/writer/Q-3-54.qmd create mode 100644 docs/errors/writer/Q-3-55.qmd create mode 100644 docs/errors/xml/Q-9-1.qmd create mode 100644 docs/errors/xml/Q-9-10.qmd create mode 100644 docs/errors/xml/Q-9-11.qmd create mode 100644 docs/errors/xml/Q-9-12.qmd create mode 100644 docs/errors/xml/Q-9-13.qmd create mode 100644 docs/errors/xml/Q-9-14.qmd create mode 100644 docs/errors/xml/Q-9-15.qmd create mode 100644 docs/errors/xml/Q-9-16.qmd create mode 100644 docs/errors/xml/Q-9-2.qmd create mode 100644 docs/errors/xml/Q-9-3.qmd create mode 100644 docs/errors/xml/Q-9-4.qmd create mode 100644 docs/errors/xml/Q-9-5.qmd create mode 100644 docs/errors/xml/Q-9-6.qmd create mode 100644 docs/errors/xml/Q-9-7.qmd create mode 100644 docs/errors/xml/Q-9-8.qmd create mode 100644 docs/errors/xml/Q-9-9.qmd create mode 100644 docs/errors/yaml/Q-1-1.qmd create mode 100644 docs/errors/yaml/Q-1-10.qmd create mode 100644 docs/errors/yaml/Q-1-11.qmd create mode 100644 docs/errors/yaml/Q-1-12.qmd create mode 100644 docs/errors/yaml/Q-1-13.qmd create mode 100644 docs/errors/yaml/Q-1-14.qmd create mode 100644 docs/errors/yaml/Q-1-15.qmd create mode 100644 docs/errors/yaml/Q-1-16.qmd create mode 100644 docs/errors/yaml/Q-1-17.qmd create mode 100644 docs/errors/yaml/Q-1-18.qmd create mode 100644 docs/errors/yaml/Q-1-19.qmd create mode 100644 docs/errors/yaml/Q-1-20.qmd create mode 100644 docs/errors/yaml/Q-1-21.qmd create mode 100644 docs/errors/yaml/Q-1-22.qmd create mode 100644 docs/errors/yaml/Q-1-23.qmd create mode 100644 docs/errors/yaml/Q-1-24.qmd create mode 100644 docs/errors/yaml/Q-1-25.qmd create mode 100644 docs/errors/yaml/Q-1-26.qmd create mode 100644 docs/errors/yaml/Q-1-27.qmd create mode 100644 docs/errors/yaml/Q-1-28.qmd create mode 100644 docs/errors/yaml/Q-1-29.qmd create mode 100644 docs/errors/yaml/Q-1-99.qmd create mode 100644 docs/guide/get-config.qmd create mode 100644 docs/guide/index.qmd create mode 100644 docs/guide/introduction.qmd create mode 100644 docs/guide/themes/brand.qmd create mode 100644 docs/presentations/revealjs/index.qmd create mode 100644 docs/quarto.png create mode 100644 examples/README.md create mode 100644 examples/presentations/.gitignore create mode 100644 examples/presentations/01-creating-slides/README.md create mode 100644 examples/presentations/01-creating-slides/_quarto.yml create mode 100644 examples/presentations/01-creating-slides/slides.qmd create mode 100644 examples/presentations/02-sections/README.md create mode 100644 examples/presentations/02-sections/_quarto.yml create mode 100644 examples/presentations/02-sections/slides.qmd create mode 100644 examples/presentations/03-fragments/README.md create mode 100644 examples/presentations/03-fragments/_quarto.yml create mode 100644 examples/presentations/03-fragments/slides.qmd create mode 100644 examples/presentations/04-incremental-lists/README.md create mode 100644 examples/presentations/04-incremental-lists/_quarto.yml create mode 100644 examples/presentations/04-incremental-lists/slides.qmd create mode 100644 examples/presentations/05-columns/README.md create mode 100644 examples/presentations/05-columns/_quarto.yml create mode 100644 examples/presentations/05-columns/slides.qmd create mode 100644 examples/presentations/06-speaker-notes/README.md create mode 100644 examples/presentations/06-speaker-notes/_quarto.yml create mode 100644 examples/presentations/06-speaker-notes/slides.qmd create mode 100644 examples/presentations/07-asides/README.md create mode 100644 examples/presentations/07-asides/_quarto.yml create mode 100644 examples/presentations/07-asides/slides.qmd create mode 100644 examples/presentations/08-footnotes/README.md create mode 100644 examples/presentations/08-footnotes/_quarto.yml create mode 100644 examples/presentations/08-footnotes/slides.qmd create mode 100644 examples/presentations/README.md create mode 100644 examples/websites/.gitignore create mode 100644 examples/websites/01-minimal/.gitignore create mode 100644 examples/websites/01-minimal/README.md create mode 100644 examples/websites/01-minimal/_quarto.yml create mode 100644 examples/websites/01-minimal/about.qmd create mode 100644 examples/websites/01-minimal/index.qmd create mode 100644 examples/websites/02-auto-sidebar/README.md create mode 100644 examples/websites/02-auto-sidebar/_quarto.yml create mode 100644 examples/websites/02-auto-sidebar/index.qmd create mode 100644 examples/websites/02-auto-sidebar/posts/aardvark.qmd create mode 100644 examples/websites/02-auto-sidebar/posts/advanced-topics.qmd create mode 100644 examples/websites/02-auto-sidebar/posts/getting-started.qmd create mode 100644 examples/websites/02-auto-sidebar/posts/work-in-progress.qmd create mode 100644 examples/websites/02-auto-sidebar/posts/zebra.qmd create mode 100644 examples/websites/03-nested-sidebar/README.md create mode 100644 examples/websites/03-nested-sidebar/_quarto.yml create mode 100644 examples/websites/03-nested-sidebar/guide/first-steps.qmd create mode 100644 examples/websites/03-nested-sidebar/guide/index.qmd create mode 100644 examples/websites/03-nested-sidebar/guide/installation.qmd create mode 100644 examples/websites/03-nested-sidebar/guide/tuning.qmd create mode 100644 examples/websites/03-nested-sidebar/index.qmd create mode 100644 examples/websites/03-nested-sidebar/reference/api.qmd create mode 100644 examples/websites/03-nested-sidebar/reference/cli.qmd create mode 100644 examples/websites/03-nested-sidebar/reference/index.qmd create mode 100644 examples/websites/04-navbar-footer/README.md create mode 100644 examples/websites/04-navbar-footer/_quarto.yml create mode 100644 examples/websites/04-navbar-footer/about.qmd create mode 100644 examples/websites/04-navbar-footer/index.qmd create mode 100644 examples/websites/04-navbar-footer/tools/converter.qmd create mode 100644 examples/websites/04-navbar-footer/tools/index.qmd create mode 100644 examples/websites/05-shared-resources/README.md create mode 100644 examples/websites/05-shared-resources/_quarto.yml create mode 100644 examples/websites/05-shared-resources/docs/api.qmd create mode 100644 examples/websites/05-shared-resources/docs/internals/architecture.qmd create mode 100644 examples/websites/05-shared-resources/index.qmd create mode 100644 examples/websites/06-site-metadata/.gitignore create mode 100644 examples/websites/06-site-metadata/README.md create mode 100644 examples/websites/06-site-metadata/_quarto.yml create mode 100644 examples/websites/06-site-metadata/api.qmd create mode 100644 examples/websites/06-site-metadata/favicon.svg create mode 100644 examples/websites/06-site-metadata/guides.qmd create mode 100644 examples/websites/06-site-metadata/index.qmd create mode 100644 examples/websites/06-site-metadata/q1-site/api.html create mode 100644 examples/websites/06-site-metadata/q1-site/favicon.svg create mode 100644 examples/websites/06-site-metadata/q1-site/guides.html create mode 100644 examples/websites/06-site-metadata/q1-site/index.html create mode 100644 examples/websites/06-site-metadata/q1-site/robots.txt create mode 100644 examples/websites/06-site-metadata/q1-site/search.json create mode 100644 examples/websites/06-site-metadata/q1-site/site_libs/bootstrap/bootstrap-158031087360bce0ff56dc785ce39e06.min.css rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/bootstrap/bootstrap-icons.css (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/bootstrap/bootstrap-icons.woff (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/bootstrap/bootstrap.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/clipboard/clipboard.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/anchor.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/popper.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/quarto-syntax-highlighting-3aa970819e70fbc78806154e5a1fcd28.css (100%) create mode 100644 examples/websites/06-site-metadata/q1-site/site_libs/quarto-html/quarto.js rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/tabsets/tabsets.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/tippy.css (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-html/tippy.umd.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-nav/headroom.min.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-nav/quarto-nav.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-search/autocomplete.umd.js (100%) rename {docs/_site => examples/websites/06-site-metadata/q1-site}/site_libs/quarto-search/fuse.min.js (100%) create mode 100644 examples/websites/06-site-metadata/q1-site/site_libs/quarto-search/quarto-search.js create mode 100644 examples/websites/06-site-metadata/q1-site/sitemap.xml create mode 100644 examples/websites/07-incremental/README.md create mode 100644 examples/websites/07-incremental/_quarto.yml create mode 100644 examples/websites/07-incremental/about.qmd create mode 100644 examples/websites/07-incremental/index.qmd create mode 100644 examples/websites/07-incremental/posts/first.qmd create mode 100644 examples/websites/07-incremental/posts/second.qmd create mode 100644 examples/websites/07-incremental/posts/third.qmd create mode 100644 examples/websites/08-hub-preview/README.md create mode 100644 examples/websites/08-hub-preview/_quarto.yml create mode 100644 examples/websites/08-hub-preview/about.qmd create mode 100644 examples/websites/08-hub-preview/index.qmd create mode 100644 examples/websites/08-hub-preview/posts/first.qmd create mode 100644 examples/websites/08-hub-preview/posts/second.qmd create mode 100644 hub-client/e2e/helpers/testHooks.ts create mode 100644 hub-client/e2e/import-zip.spec.ts create mode 100644 hub-client/e2e/q2-debug-render-components.spec.ts create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/fresh-setup-dark-chromium-linux.png create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/fresh-setup-light-chromium-linux.png create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/migration-dark-chromium-linux.png create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/migration-error-dark-chromium-linux.png create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/migration-error-light-chromium-linux.png create mode 100644 hub-client/e2e/setup-screens.visual.spec.ts-snapshots/migration-light-chromium-linux.png create mode 100644 hub-client/public/q2-raw.html rename hub-client/{public/ast-renderer.html => q2-debug.html} (82%) create mode 100644 hub-client/q2-preview.html create mode 100644 hub-client/q2-raw.html create mode 100644 hub-client/quarto-hub-sandboxed-preview/.gitignore create mode 100644 hub-client/quarto-hub-sandboxed-preview/README.md create mode 100644 hub-client/quarto-hub-sandboxed-preview/index.html create mode 100644 hub-client/quarto-hub-sandboxed-preview/package-lock.json create mode 100644 hub-client/quarto-hub-sandboxed-preview/package.json create mode 100644 hub-client/quarto-hub-sandboxed-preview/src/App.tsx create mode 100644 hub-client/quarto-hub-sandboxed-preview/src/index.css create mode 100644 hub-client/quarto-hub-sandboxed-preview/src/main.tsx create mode 100644 hub-client/quarto-hub-sandboxed-preview/tsconfig.json create mode 100644 hub-client/quarto-hub-sandboxed-preview/vite.config.ts delete mode 100644 hub-client/src/ast-renderer-entry.tsx create mode 100644 hub-client/src/auth/AuthProvider.test.tsx create mode 100644 hub-client/src/auth/AuthProvider.tsx create mode 100644 hub-client/src/auth/GoogleAuthProvider.test.tsx create mode 100644 hub-client/src/auth/GoogleAuthProvider.tsx create mode 100644 hub-client/src/auth/MockAuthProvider.tsx create mode 100644 hub-client/src/components/ProjectSelector.import.test.tsx create mode 100644 hub-client/src/components/auth/LoginScreen.test.tsx delete mode 100644 hub-client/src/components/render/PreviewErrorOverlay.tsx delete mode 100644 hub-client/src/components/render/ReactAstDebugRenderer.tsx delete mode 100644 hub-client/src/components/render/ReactAstRenderer.tsx create mode 100644 hub-client/src/components/render/ReactAstSlideRenderer.test.tsx create mode 100644 hub-client/src/components/render/ReactRenderer.integration.test.tsx create mode 100644 hub-client/src/components/render/iframeMessageDispatch.test.ts create mode 100644 hub-client/src/components/render/iframeMessageDispatch.ts create mode 100644 hub-client/src/components/render/parity.integration.test.tsx rename hub-client/src/components/render/{AstIframe.tsx => q2-debug/Q2DebugIframe.tsx} (86%) create mode 100644 hub-client/src/components/render/q2-debug/attribution.integration.test.tsx create mode 100644 hub-client/src/components/render/q2-debug/components.tsx create mode 100644 hub-client/src/components/render/q2-debug/dispatchers.tsx create mode 100644 hub-client/src/components/render/q2-debug/entry.tsx create mode 100644 hub-client/src/components/render/q2-debug/index.ts create mode 100644 hub-client/src/components/render/q2-debug/q2-debug.integration.test.tsx create mode 100644 hub-client/src/components/render/q2-debug/registry.ts create mode 100644 hub-client/src/components/render/q2-debug/styles.ts create mode 100644 hub-client/src/components/render/q2-preview/attribution.integration.test.tsx create mode 100644 hub-client/src/components/render/q2-preview/entry.tsx create mode 100644 hub-client/src/components/render/q2-raw/Q2RawIframe.tsx create mode 100644 hub-client/src/hooks/useAttribution.test.ts create mode 100644 hub-client/src/hooks/useAttribution.ts rename hub-client/src/hooks/{useAuth.test.ts => useAuth.test.tsx} (72%) create mode 100644 hub-client/src/hooks/usePreference.test.tsx create mode 100644 hub-client/src/services/assetManifestProject.wasm.test.ts create mode 100644 hub-client/src/services/attribution-runs.test.ts create mode 100644 hub-client/src/services/attribution-runs.ts create mode 100644 hub-client/src/services/customNodeWireFormatProject.wasm.test.ts create mode 100644 hub-client/src/services/debugApi.test.ts create mode 100644 hub-client/src/services/debugApi.ts create mode 100644 hub-client/src/services/themeFingerprint.wasm.test.ts create mode 100644 hub-client/src/test-hooks.ts delete mode 100644 hub-client/src/types/diagnostic.ts create mode 100644 hub-client/src/utils/palette.test.ts create mode 100644 hub-client/src/utils/palette.ts create mode 100644 hub-client/src/utils/pipelineKind.test.ts create mode 100644 hub-client/src/utils/pipelineKind.ts create mode 100644 old-docs/.gitignore create mode 100644 old-docs/_quarto.yml rename {docs => old-docs}/_site/about.html (100%) rename {docs => old-docs}/_site/index.html (100%) rename {docs => old-docs}/_site/search.json (100%) rename {docs => old-docs}/_site/site_libs/bootstrap/bootstrap-5b4ad623e5705c0698d39aec6f10cf02.min.css (100%) create mode 100644 old-docs/_site/site_libs/bootstrap/bootstrap-icons.css create mode 100644 old-docs/_site/site_libs/bootstrap/bootstrap-icons.woff create mode 100644 old-docs/_site/site_libs/bootstrap/bootstrap.min.js create mode 100644 old-docs/_site/site_libs/clipboard/clipboard.min.js create mode 100644 old-docs/_site/site_libs/quarto-html/anchor.min.js rename {docs => old-docs}/_site/site_libs/quarto-html/axe/axe-check.js (100%) create mode 100644 old-docs/_site/site_libs/quarto-html/popper.min.js create mode 100644 old-docs/_site/site_libs/quarto-html/quarto-syntax-highlighting-3aa970819e70fbc78806154e5a1fcd28.css rename {docs => old-docs}/_site/site_libs/quarto-html/quarto.js (100%) create mode 100644 old-docs/_site/site_libs/quarto-html/tabsets/tabsets.js create mode 100644 old-docs/_site/site_libs/quarto-html/tippy.css create mode 100644 old-docs/_site/site_libs/quarto-html/tippy.umd.min.js create mode 100644 old-docs/_site/site_libs/quarto-nav/headroom.min.js create mode 100644 old-docs/_site/site_libs/quarto-nav/quarto-nav.js create mode 100644 old-docs/_site/site_libs/quarto-search/autocomplete.umd.js create mode 100644 old-docs/_site/site_libs/quarto-search/fuse.min.js rename {docs => old-docs}/_site/site_libs/quarto-search/quarto-search.js (100%) rename {docs => old-docs}/_site/styles.css (100%) rename {docs => old-docs}/_site/syntax/definition-lists.html (100%) rename {docs => old-docs}/_site/syntax/index.html (100%) create mode 100644 old-docs/about.qmd create mode 100644 old-docs/authoring/attribution.qmd create mode 100644 old-docs/bug-reports.qmd create mode 100644 old-docs/index.qmd rename {docs => old-docs}/library-docs/index.qmd (100%) rename {docs => old-docs}/library-docs/rust/source-info/architecture.qmd (100%) rename {docs => old-docs}/library-docs/rust/source-info/index.qmd (100%) rename {docs => old-docs}/library-docs/rust/source-info/json.qmd (100%) rename {docs => old-docs}/library-docs/typescript/annotated-qmd/index.qmd (100%) rename {docs => old-docs}/navigation.qmd (67%) create mode 100644 old-docs/projects/resources.qmd create mode 100644 old-docs/q2-preview.qmd rename {docs => old-docs}/quarto-hub/collaboration.qmd (100%) rename {docs => old-docs}/quarto-hub/files.qmd (100%) rename {docs => old-docs}/quarto-hub/index.qmd (100%) rename {docs => old-docs}/quarto-hub/preview.qmd (100%) rename {docs => old-docs}/quarto-hub/projects.qmd (100%) rename {docs => old-docs}/quarto-hub/templates.qmd (100%) rename {docs => old-docs}/quarto-hub/themes.qmd (100%) create mode 100644 old-docs/styles.css rename {docs => old-docs}/syntax/code_span.qmd (100%) rename {docs => old-docs}/syntax/definition-lists.qmd (100%) rename {docs => old-docs}/syntax/desugaring/definition-lists.qmd (100%) rename {docs => old-docs}/syntax/desugaring/editorial-marks.qmd (100%) rename {docs => old-docs}/syntax/desugaring/index.qmd (100%) rename {docs => old-docs}/syntax/desugaring/math-attributes.qmd (100%) rename {docs => old-docs}/syntax/desugaring/note-references.qmd (100%) rename {docs => old-docs}/syntax/desugaring/table-captions.qmd (100%) rename {docs => old-docs}/syntax/editorial-marks.qmd (100%) rename {docs => old-docs}/syntax/footnotes.qmd (100%) rename {docs => old-docs}/syntax/highlighting-filter.qmd (100%) rename {docs => old-docs}/syntax/index.qmd (100%) rename {docs => old-docs}/syntax/lists.qmd (100%) rename {docs => old-docs}/syntax/yaml-metadata.qmd (100%) rename {docs => old-docs}/writers/index.qmd (100%) rename {docs => old-docs}/writers/json.qmd (100%) rename {docs => old-docs}/writers/qmd.qmd (100%) create mode 100644 q2-preview-spa/.gitignore create mode 100644 q2-preview-spa/e2e/basic-preview.spec.ts create mode 100644 q2-preview-spa/e2e/chrome.spec.ts create mode 100644 q2-preview-spa/e2e/config-edits.spec.ts create mode 100644 q2-preview-spa/e2e/cross-page-nav.spec.ts create mode 100644 q2-preview-spa/e2e/dep-graph-filter.spec.ts create mode 100644 q2-preview-spa/e2e/diagnostics.spec.ts create mode 100644 q2-preview-spa/e2e/helpers/globalSetup.ts create mode 100644 q2-preview-spa/e2e/helpers/previewServer.ts create mode 100644 q2-preview-spa/e2e/include-shortcode.spec.ts create mode 100644 q2-preview-spa/e2e/static-resources.spec.ts create mode 100644 q2-preview-spa/index.html create mode 100644 q2-preview-spa/package.json create mode 100644 q2-preview-spa/playwright.config.ts create mode 100644 q2-preview-spa/q2-preview.html create mode 100644 q2-preview-spa/src/PreviewApp.integration.test.tsx create mode 100644 q2-preview-spa/src/PreviewApp.tsx create mode 100644 q2-preview-spa/src/components/ForceRefreshButton.tsx create mode 100644 q2-preview-spa/src/components/PreviewDiagnosticsOverlay.css create mode 100644 q2-preview-spa/src/components/PreviewDiagnosticsOverlay.integration.test.tsx create mode 100644 q2-preview-spa/src/components/PreviewDiagnosticsOverlay.tsx create mode 100644 q2-preview-spa/src/components/StaleCaptureOverlay.integration.test.tsx create mode 100644 q2-preview-spa/src/components/StaleCaptureOverlay.tsx create mode 100644 q2-preview-spa/src/main.tsx create mode 100644 q2-preview-spa/src/pickInitialPage.test.ts create mode 100644 q2-preview-spa/src/pickInitialPage.ts create mode 100644 q2-preview-spa/src/q2-preview-entry.tsx create mode 100644 q2-preview-spa/src/test-utils/setup.ts create mode 100644 q2-preview-spa/tsconfig.app.json create mode 100644 q2-preview-spa/tsconfig.json create mode 100644 q2-preview-spa/tsconfig.node.json create mode 100644 q2-preview-spa/vite.config.ts create mode 100644 q2-preview-spa/vitest.config.ts create mode 100644 q2-preview-spa/vitest.integration.config.ts create mode 100644 resources/attribution/README.md create mode 100644 resources/attribution/viewer.css create mode 100644 resources/attribution/viewer.js create mode 100644 resources/bootstrap-icons/README.md create mode 100644 resources/bootstrap-icons/bootstrap-icons.css create mode 100644 resources/bootstrap-icons/bootstrap-icons.woff create mode 100644 resources/js/README.md create mode 100644 resources/js/bootstrap/bootstrap.bundle.min.js create mode 100644 resources/js/clipboard/clipboard.min.js create mode 100644 resources/js/clipboard/code-copy-init.js create mode 100644 resources/listing/list.min.js create mode 100644 resources/listing/quarto-listing.js create mode 100644 resources/revealjs/LICENSE create mode 100644 resources/revealjs/README.md create mode 100644 resources/revealjs/quarto-reveal.css create mode 100644 resources/revealjs/reset.css create mode 100644 resources/revealjs/reveal.css create mode 100644 resources/revealjs/reveal.js create mode 100644 resources/revealjs/theme/white.css create mode 100755 scripts/measure-test-build.sh create mode 100644 scripts/upload-project.mjs create mode 100644 ts-packages/preview-renderer/package.json create mode 100644 ts-packages/preview-renderer/src/framework/Ast.tsx create mode 100644 ts-packages/preview-renderer/src/framework/AttributionLookupContext.tsx create mode 100644 ts-packages/preview-renderer/src/framework/RegistryContext.tsx create mode 100644 ts-packages/preview-renderer/src/framework/attribution.styles.test.ts create mode 100644 ts-packages/preview-renderer/src/framework/attribution.test.ts create mode 100644 ts-packages/preview-renderer/src/framework/attribution.test.tsx create mode 100644 ts-packages/preview-renderer/src/framework/attribution.tsx create mode 100644 ts-packages/preview-renderer/src/framework/customNode.test.ts create mode 100644 ts-packages/preview-renderer/src/framework/customNode.ts create mode 100644 ts-packages/preview-renderer/src/framework/dispatch.tsx create mode 100644 ts-packages/preview-renderer/src/framework/index.ts create mode 100644 ts-packages/preview-renderer/src/framework/meta.test.ts create mode 100644 ts-packages/preview-renderer/src/framework/meta.ts create mode 100644 ts-packages/preview-renderer/src/framework/plainText.test.ts create mode 100644 ts-packages/preview-renderer/src/framework/plainText.ts create mode 100644 ts-packages/preview-renderer/src/framework/types.ts create mode 100644 ts-packages/preview-renderer/src/global.d.ts rename {hub-client/src/components/render => ts-packages/preview-renderer/src/iframe}/DoubleBufferedIframe.tsx (96%) rename {hub-client/src/components/render => ts-packages/preview-renderer/src/iframe}/MorphIframe.tsx (97%) create mode 100644 ts-packages/preview-renderer/src/iframe/Q2PreviewIframe.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/iframe/Q2PreviewIframe.tsx create mode 100644 ts-packages/preview-renderer/src/index.ts create mode 100644 ts-packages/preview-renderer/src/overlays/PreviewErrorOverlay.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/overlays/PreviewErrorOverlay.tsx rename {hub-client/src/components/render => ts-packages/preview-renderer/src/overlays}/PreviewStaticInfoViews.tsx (95%) create mode 100644 ts-packages/preview-renderer/src/placeholder.test.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/AssetManifestContext.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/IncrementalContext.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/NoteNumberingContext.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/PreviewContext.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/PreviewDocument.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/PreviewDocument.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/RevealDeck.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/assetWalker.test.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/assetWalker.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/BlockQuote.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/BulletList.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/DefinitionList.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Div.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Figure.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Header.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/HorizontalRule.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/LineBlock.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/OrderedList.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Para.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Plain.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/RawBlock.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/Table.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/blocks/index.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/chromeSlots.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom-components.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/Callout.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/CrossrefResolvedRef.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/Equation.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/Fallback.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/FloatRefTarget.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/PreviewTitleBlock.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/PreviewTitleBlock.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/Proof.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/Theorem.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/custom/index.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/dispatchers.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/entry.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/entry.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/index.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Cite.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Code.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Emph.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Image.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/LineBreak.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Link.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Math.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Note.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Quoted.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/RawInline.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/SmallCaps.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/SoftBreak.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Space.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Span.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Str.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Strikeout.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Strong.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Subscript.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Superscript.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/Underline.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/inlines/index.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/q2-preview.integration.test.tsx create mode 100644 ts-packages/preview-renderer/src/q2-preview/quartoClasses.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/registry.test.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/registry.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/theoremEnvs.ts create mode 100644 ts-packages/preview-renderer/src/q2-preview/utils.tsx create mode 100644 ts-packages/preview-renderer/src/test-utils/setup.ts create mode 100644 ts-packages/preview-renderer/src/types/artifactPaths.ts create mode 100644 ts-packages/preview-renderer/src/types/diagnostic.ts rename {hub-client => ts-packages/preview-renderer}/src/types/intelligence.ts (100%) rename {hub-client => ts-packages/preview-renderer}/src/types/project.test.ts (100%) rename {hub-client => ts-packages/preview-renderer}/src/types/project.ts (100%) create mode 100644 ts-packages/preview-renderer/src/types/sourceInfo.ts create mode 100644 ts-packages/preview-renderer/src/utils/atomicCustomNodes.ts create mode 100644 ts-packages/preview-renderer/src/utils/componentPath.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/componentPath.ts create mode 100644 ts-packages/preview-renderer/src/utils/customRegistry.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/customRegistry.ts create mode 100644 ts-packages/preview-renderer/src/utils/iframeLinkHandlers.integration.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/iframeLinkHandlers.ts create mode 100644 ts-packages/preview-renderer/src/utils/iframePostProcessor.integration.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/iframePostProcessor.test.ts rename {hub-client => ts-packages/preview-renderer}/src/utils/iframePostProcessor.ts (57%) create mode 100644 ts-packages/preview-renderer/src/utils/sourceInfo.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/sourceInfo.ts rename {hub-client => ts-packages/preview-renderer}/src/utils/stripAnsi.test.ts (100%) rename {hub-client => ts-packages/preview-renderer}/src/utils/stripAnsi.ts (100%) create mode 100644 ts-packages/preview-renderer/src/utils/vfsPaths.test.ts create mode 100644 ts-packages/preview-renderer/src/utils/vfsPaths.ts create mode 100644 ts-packages/preview-renderer/tsconfig.json create mode 100644 ts-packages/preview-renderer/vitest.config.ts create mode 100644 ts-packages/preview-renderer/vitest.integration.config.ts create mode 100644 ts-packages/preview-runtime/package.json rename {hub-client/src/services => ts-packages/preview-runtime/src}/automergeSync.test.ts (92%) rename {hub-client/src/services => ts-packages/preview-runtime/src}/automergeSync.ts (80%) create mode 100644 ts-packages/preview-runtime/src/index.ts create mode 100644 ts-packages/preview-runtime/src/placeholder.test.ts rename {hub-client => ts-packages/preview-runtime}/src/test-utils/mockSyncClient.ts (100%) rename {hub-client => ts-packages/preview-runtime}/src/test-utils/mockWasm.ts (98%) create mode 100644 ts-packages/preview-runtime/src/test-utils/setup.ts rename hub-client/src/services/userGrammarCache.test.ts => ts-packages/preview-runtime/src/userGrammar/Cache.test.ts (98%) rename hub-client/src/services/userGrammarCache.ts => ts-packages/preview-runtime/src/userGrammar/Cache.ts (98%) rename hub-client/src/services/userGrammarDiscovery.test.ts => ts-packages/preview-runtime/src/userGrammar/Discovery.test.ts (98%) rename hub-client/src/services/userGrammarDiscovery.ts => ts-packages/preview-runtime/src/userGrammar/Discovery.ts (100%) rename hub-client/src/services/userGrammarHighlight.ts => ts-packages/preview-runtime/src/userGrammar/Highlight.ts (100%) rename hub-client/src/services/userGrammarHighlight.wasm.test.ts => ts-packages/preview-runtime/src/userGrammar/Highlight.wasm.test.ts (94%) create mode 100644 ts-packages/preview-runtime/src/vite-shims.d.ts create mode 100644 ts-packages/preview-runtime/src/wasm-quarto-hub-client.d.ts rename {hub-client/src/services => ts-packages/preview-runtime/src}/wasmRenderer.test.ts (100%) rename {hub-client/src/services => ts-packages/preview-runtime/src}/wasmRenderer.ts (73%) create mode 100644 ts-packages/preview-runtime/tsconfig.json create mode 100644 ts-packages/preview-runtime/vitest.config.ts create mode 100644 ts-packages/preview-runtime/vitest.integration.config.ts create mode 100644 ts-packages/quarto-hub-mcp/README.md create mode 100644 ts-packages/quarto-hub-mcp/src/auth/auth-tools.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/auth-tools.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/browser.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/browser.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/credential-store.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/credential-store.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/loopback.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/loopback.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/oauth-config.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/oauth-config.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/pkce.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/pkce.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/redact.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/redact.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/refresh-manager.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/auth/refresh-manager.ts create mode 100644 ts-packages/quarto-hub-mcp/src/connection-manager.test.ts create mode 100644 ts-packages/quarto-hub-mcp/src/index.test.ts create mode 100644 ts-packages/quarto-sync-client/src/NodeWebSocketClientAdapter.test.ts create mode 100644 ts-packages/quarto-sync-client/src/NodeWebSocketClientAdapter.ts create mode 100644 ts-packages/quarto-sync-client/src/import-zip.test.ts create mode 100644 ts-packages/quarto-sync-client/src/import-zip.ts create mode 100644 ts-packages/quarto-sync-client/src/storage-adapter.test.ts create mode 100644 ts-packages/quarto-sync-client/src/storage-adapter.ts create mode 100644 ts-packages/wasm-js-bridge/package.json rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/cache.d.ts (100%) rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/cache.js (100%) rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/cache.test.ts (100%) rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/fetch.js (100%) rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/sass.d.ts (100%) rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/sass.js (100%) create mode 100644 ts-packages/wasm-js-bridge/src/sass.test.ts rename {hub-client/src/wasm-js-bridge => ts-packages/wasm-js-bridge/src}/template.js (100%) diff --git a/.beads/.gitignore b/.beads/.gitignore index bed8c9191..d8d86cf33 100644 --- a/.beads/.gitignore +++ b/.beads/.gitignore @@ -13,6 +13,9 @@ last-touched # Local history backups .br_history/ +# Recovery snapshots from br operations +.br_recovery/ + # Sync state .sync.lock sync_base.jsonl @@ -40,5 +43,8 @@ redirect # Migration artifacts *.migrated +# br operation backups (e.g. issues.jsonl.orig left behind by older br runs) +*.orig + # Local version marker .local_version diff --git a/.beads/README.md b/.beads/README.md index 9e5d1945d..93b9b9b3f 100644 --- a/.beads/README.md +++ b/.beads/README.md @@ -1,3 +1,22 @@ +> # ⛔ FROZEN — migrated to braid (2026-06-08) +> +> **This project no longer uses beads.** Issue tracking moved to **braid** on +> 2026-06-08. `.beads/` is kept only as a **read-only historical archive** (and +> the rollback source of last resort). Every `bd-XXXX` id was preserved in the +> migration, so source references stay valid. +> +> **Do NOT run `br` write commands here** (`br create`/`update`/`close`/`sync`). +> Use **braid** instead — run `braid agents-info` or the `/braid` skill for +> usage, and see `CLAUDE.md` § WORK TRACKING. +> +> Migration record: `claude-notes/plans/2026-06-08-braid-migration.md`. +> The `.beads/issues.jsonl` in this directory is the frozen final beads state; +> the live tracker is the braid skein (backup snapshot at `.braid/snapshot.jsonl`). +> +> *(The original beads boilerplate below is retained for historical context.)* + +--- + # Beads - AI-Native Issue Tracking Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code. diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 56f3f679b..327ef5778 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,101 +1,539 @@ -{"id":"bd-0gsj","title":"Fix CRLF handling in tree-sitter-qmd grammar.js for pipe tables","description":"Tree-sitter grammar at crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js parses pipe tables incorrectly when input uses CRLF line endings. With LF input, the pipe table closes at the blank line and following content becomes a separate block. With CRLF input, the table absorbs the following paragraph as a malformed body row. Bug propagates through pampa end-to-end: rendered Pandoc AST is structurally wrong for any Windows user with core.autocrlf=true (default) authoring a pipe table followed by a paragraph. Affects all output formats (HTML, PDF, Word) since Pandoc AST is upstream of every writer. Surfaced 2026-04-24 during PR 109 Windows verification as 5 failing pipe-table corpus tests; investigation in bd-ntnx classified it as a real grammar bug, not a corpus formatting issue. Full reproducer and observed parse trees in the design field. Cross-reference q2-windows-verify-tests memory note for related Windows CRLF failures.","design":"Reproducer. Two layers, both diagnostic. Layer 1 tests grammar.js directly. Layer 2 tests the full pampa pipeline that real users hit. Fixtures live in the tree-sitter-markdown directory so tree-sitter parse picks up the configured grammar without an init-config step.\n\nLayer 1 (grammar.js):\n\nprintf \"before\\r\\n\\r\\n| a | b |\\r\\n|---|---|\\r\\n| 1 | 2 |\\r\\n\\r\\nafter\\r\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd\nprintf \"before\\n\\n| a | b |\\n|---|---|\\n| 1 | 2 |\\n\\nafter\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd\ncd crates/tree-sitter-qmd/tree-sitter-markdown\ntree-sitter parse test-crlf.qmd > test-crlf.parse\ntree-sitter parse test-lf.qmd > test-lf.parse\ndiff test-crlf.parse test-lf.parse\n\nLayer 2 (pampa end-to-end):\n\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd > pampa-crlf.out\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd > pampa-lf.out\ndiff pampa-crlf.out pampa-lf.out\n\nObserved parse trees from Layer 1 on this branch (fix/windows-tree-sitter-crlf at 80f07171). Both trees agree on the prefix, so the divergence is the trailing block:\n\nLF (correct, table closes at the blank line):\n pipe_table [2, 0] - [5, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pandoc_paragraph [6, 0] - [7, 0]\n pandoc_str [6, 0] - [6, 5]\n\nCRLF (buggy, table absorbs following paragraph):\n pipe_table [2, 0] - [7, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pipe_table_row [6, 0] - [6, 5] <- SPURIOUS, should be a separate paragraph\n pipe_table_cell [6, 0] - [6, 5]\n pandoc_str [6, 0] - [6, 5]\n\nObserved Pandoc AST from Layer 2 (pampa default -t native), confirming the bug propagates past pampa input handling:\n\nLF: [Para [Str \"before\"], Table ... [body row [1,2]], Para [Str \"after\"]]\nCRLF: [Para [Str \"before\"], Table ... [body rows [1,2] AND [Plain \"after\"]]] <- no trailing Para\n\nConfirms pampa does NOT normalize line endings before feeding the grammar. End-user impact: any qmd document with CRLF endings, a pipe table, and following content produces structurally wrong output in every writer that consumes Pandoc AST.\n\nOpen design questions for the fix.\n\n1. Locate the bug in grammar.js. Likely candidates: newline character classes that match only \\n, or the external scanner (scanner.cc) handling of block boundary detection. Read both grammar.js and any external scanner before patching. Tree-sitter-markdown forks vary on this — confirm what our fork does versus what works.\n\n2. Upstream vs local fix. This grammar is forked from MDeiml/tree-sitter-markdown (or whichever upstream we track — confirm in tree-sitter.json or README). If upstream already fixes this, cherry-pick. If not, patch locally and consider an upstream PR.\n\n3. Test-corpus line-ending policy after the fix. Two viable strategies:\n a. Keep test/corpus/*.txt files materialized as CRLF on Windows checkout and rely on the fixed grammar to parse them identically. Tests then exercise CRLF on Windows and LF on Linux, which is useful coverage but creates a small risk that future grammar changes regress CRLF handling silently when only Linux CI runs.\n b. Pin test/corpus/*.txt to LF via .gitattributes (eol=lf for that subdirectory only) and add a separate Windows-only regression test that re-creates the fixtures with CRLF and asserts the parse trees match. More explicit, less coverage drift.\n\n The choice depends on whether we expect frequent grammar changes and whether ubuntu-only CI is sustainable. Recommend deciding before landing the grammar fix.\n\n4. Audit other CRLF patterns. The 5 failing pipe-table tests are the surface; there may be other constructs whose grammar paths assume \\n only. Grep grammar.js (and scanner.cc if present) for \\n usages and audit each one.\n\nReference. Investigation history and original framing in bd-ntnx (closed). Memory note q2-windows-verify-tests catalogues related Windows CRLF failures.","acceptance_criteria":"tree-sitter parse on matched CRLF and LF qmd inputs produces identical S-expression trees for pipe-table fixtures (Layer 1 reproducer diff is empty). pampa default native output is identical for the same matched inputs (Layer 2 reproducer diff is empty). All 5 originally-failing pipe-table tests under cd crates/tree-sitter-qmd/tree-sitter-markdown && tree-sitter test pass on Windows: Example 201 (GFM), Pipe table can precede content (two variants), Pipe table can follow content, Pipe table with blank-line caption. cargo xtask verify step 4 (tree-sitter test) passes on Windows. cargo nextest run --workspace and cargo xtask verify continue to pass on Linux CI (no regression). Decision recorded in commit message or PR description for upstream-vs-local fix and for test-corpus line-ending policy. Audit findings recorded for any other CRLF patterns discovered in grammar.js or scanner.cc. q2-windows-verify-tests memory note updated with PR link and resolution.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv","updated_at":"2026-04-29T16:25:17.790938600Z","external_ref":"https://github.com/quarto-dev/q2/issues/138","source_repo":".","compaction_level":0,"original_size":0,"labels":["tree-sitter","windows"],"dependencies":[{"issue_id":"bd-0gsj","depends_on_id":"bd-ntnx","type":"discovered-from","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv","metadata":"{}","thread_id":""}],"comments":[{"id":15,"issue_id":"bd-0gsj","author":"cderv","text":"PR #139 opened (https://github.com/quarto-dev/q2/pull/139). Layer 1 + Layer 2 reproducer diffs empty post-fix. tree-sitter test on Windows: 451/451 (was 446/451). Decision: local fix, not upstream — typo introduced on this fork in 79489c4e. Decision: no .gitattributes change for test corpus — fixed grammar parses LF and CRLF identically, so existing corpus tests both modes (LF on Linux, CRLF on Windows checkout). Audit: line 2259 was the only outlier; all other newline checks in scanner.c use paired '\\n' || '\\r'. Added Rust regression test pipe_table_crlf_matches_lf for cross-platform coverage.","created_at":"2026-04-28T15:37:36Z"},{"id":16,"issue_id":"bd-0gsj","author":"cderv","text":"Tomorrow's verification (next session pickup): (1) check PR #139 CI status — gh pr checks 139 --repo quarto-dev/q2; (2) if green, merge; (3) on merge, close bd-0gsj with PR link as the close reason; (4) flush and commit accumulated .beads/issues.jsonl from main repo (this session created bd-vxl8 and bd-picv, plus comments on bd-238o, bd-3pe8, bd-0gsj); (5) update q2-windows-verify-tests memory note status to fully resolved.","created_at":"2026-04-28T16:05:51Z"},{"id":18,"issue_id":"bd-0gsj","author":"cderv","text":"CRLF parity check landed in commit 8f61f587 on branch fix/windows-tree-sitter-crlf (PR #139). cargo xtask verify step 4 now re-runs tree-sitter test against a CRLF-converted corpus copy; 451/451 pass, regression-tested by reverting scanner.c (446/451, build fails). Awaiting PR merge to close.","created_at":"2026-04-29T16:25:17Z"}]} +{"id":"bd-068k","title":"Phase 0: quarto-publish crate scaffold + provider trait","description":"Phase 0 of bd-t3ny. Build the quarto-publish crate skeleton: types, PublishProvider trait (prepare/commit/verify), PublishHost, PublishRenderer, ProviderRegistry, NativeHost, CLI argument validation, and wire into crates/quarto/src/commands/publish.rs (replacing NotImplemented stub).\n\nProvider impls in this phase: gh-pages registered with prepare/commit unimplemented!() — tests exercise registry lookup and CLI dispatch only.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md (Phase 0 section)","status":"completed","priority":1,"issue_type":"task","created_at":"2026-05-03T14:37:32.946678Z","created_by":"cscheid","updated_at":"2026-05-03T14:57:58.079046Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-068k","depends_on_id":"bd-t3ny","type":"parent-child","created_at":"2026-05-03T14:37:32.946678Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0a3b","title":"Cargo: upgrade rand v0.9.4 → v0.10.1","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.9.4 is range-pinned in workspace; latest is 0.10.1. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.920222Z","created_by":"cscheid","updated_at":"2026-05-04T19:06:15.700658Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-0a3b","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.024220Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0fd0","title":"Lua filter injection slot between generate and render transforms","description":"Today, UserFiltersStage::pre() runs before AstTransformsStage and ::post() runs after. There is no Lua filter slot interleaved between generate-style transforms (NavbarGenerate, SidebarGenerate, ListingGenerate, etc.) and their render-side counterparts inside AstTransformsStage, so user filters cannot mutate resolved navigation/listings data before HTML emission.\n\nStrawman: split build_transform_pipeline (crates/quarto-core/src/pipeline.rs) into build_generate_transforms() and build_render_transforms() with a configurable user-filter bridge in between. The L3 listing transforms, navbar generate, sidebar generate, etc., become the first consumers.\n\nSource-code TODO markers should land at:\n- crates/quarto-core/src/pipeline.rs (NAVIGATION PHASE comment block)\n- crates/quarto-core/src/transforms/navbar_generate.rs (existing precedent with the same latent assumption)\n- crates/quarto-core/src/transforms/listing_generate.rs (added during L3)\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D2/D13 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T18:26:18.595826Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:18.595826Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0fd0","depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:18.595826Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0gkh3","title":"Phase 6 — hub-mcp refresh-on-401 (RefreshManager)","description":"New module ts-packages/quarto-hub-mcp/src/auth/refresh-manager.ts wrapping CredentialStore + oauth4webapi refresh-token grant.\n\nBehaviour fixed by empirical verification 2026-05-19: Google does NOT rotate refresh tokens for Limited-Input-Devices clients, so the persistence rule is keep-prior-on-missing. Defensive test still covers the rotated-refresh-token case.\n\nConcurrent-callers coalesce via in-flight-promise mutex; invalid_grant from Google triggers CredentialStore.clear() + typed ReauthRequired naming authenticate_start.\n\nPlan §Phase 6: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:14.252095Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:14.252095Z","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0gkh3","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:14.252095Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-0gsj","title":"Fix CRLF handling in tree-sitter-qmd grammar.js for pipe tables","description":"Tree-sitter grammar at crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js parses pipe tables incorrectly when input uses CRLF line endings. With LF input, the pipe table closes at the blank line and following content becomes a separate block. With CRLF input, the table absorbs the following paragraph as a malformed body row. Bug propagates through pampa end-to-end: rendered Pandoc AST is structurally wrong for any Windows user with core.autocrlf=true (default) authoring a pipe table followed by a paragraph. Affects all output formats (HTML, PDF, Word) since Pandoc AST is upstream of every writer. Surfaced 2026-04-24 during PR 109 Windows verification as 5 failing pipe-table corpus tests; investigation in bd-ntnx classified it as a real grammar bug, not a corpus formatting issue. Full reproducer and observed parse trees in the design field. Cross-reference q2-windows-verify-tests memory note for related Windows CRLF failures.","design":"Reproducer. Two layers, both diagnostic. Layer 1 tests grammar.js directly. Layer 2 tests the full pampa pipeline that real users hit. Fixtures live in the tree-sitter-markdown directory so tree-sitter parse picks up the configured grammar without an init-config step.\n\nLayer 1 (grammar.js):\n\nprintf \"before\\r\\n\\r\\n| a | b |\\r\\n|---|---|\\r\\n| 1 | 2 |\\r\\n\\r\\nafter\\r\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd\nprintf \"before\\n\\n| a | b |\\n|---|---|\\n| 1 | 2 |\\n\\nafter\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd\ncd crates/tree-sitter-qmd/tree-sitter-markdown\ntree-sitter parse test-crlf.qmd > test-crlf.parse\ntree-sitter parse test-lf.qmd > test-lf.parse\ndiff test-crlf.parse test-lf.parse\n\nLayer 2 (pampa end-to-end):\n\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd > pampa-crlf.out\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd > pampa-lf.out\ndiff pampa-crlf.out pampa-lf.out\n\nObserved parse trees from Layer 1 on this branch (fix/windows-tree-sitter-crlf at 80f07171). Both trees agree on the prefix, so the divergence is the trailing block:\n\nLF (correct, table closes at the blank line):\n pipe_table [2, 0] - [5, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pandoc_paragraph [6, 0] - [7, 0]\n pandoc_str [6, 0] - [6, 5]\n\nCRLF (buggy, table absorbs following paragraph):\n pipe_table [2, 0] - [7, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pipe_table_row [6, 0] - [6, 5] <- SPURIOUS, should be a separate paragraph\n pipe_table_cell [6, 0] - [6, 5]\n pandoc_str [6, 0] - [6, 5]\n\nObserved Pandoc AST from Layer 2 (pampa default -t native), confirming the bug propagates past pampa input handling:\n\nLF: [Para [Str \"before\"], Table ... [body row [1,2]], Para [Str \"after\"]]\nCRLF: [Para [Str \"before\"], Table ... [body rows [1,2] AND [Plain \"after\"]]] <- no trailing Para\n\nConfirms pampa does NOT normalize line endings before feeding the grammar. End-user impact: any qmd document with CRLF endings, a pipe table, and following content produces structurally wrong output in every writer that consumes Pandoc AST.\n\nOpen design questions for the fix.\n\n1. Locate the bug in grammar.js. Likely candidates: newline character classes that match only \\n, or the external scanner (scanner.cc) handling of block boundary detection. Read both grammar.js and any external scanner before patching. Tree-sitter-markdown forks vary on this — confirm what our fork does versus what works.\n\n2. Upstream vs local fix. This grammar is forked from MDeiml/tree-sitter-markdown (or whichever upstream we track — confirm in tree-sitter.json or README). If upstream already fixes this, cherry-pick. If not, patch locally and consider an upstream PR.\n\n3. Test-corpus line-ending policy after the fix. Two viable strategies:\n a. Keep test/corpus/*.txt files materialized as CRLF on Windows checkout and rely on the fixed grammar to parse them identically. Tests then exercise CRLF on Windows and LF on Linux, which is useful coverage but creates a small risk that future grammar changes regress CRLF handling silently when only Linux CI runs.\n b. Pin test/corpus/*.txt to LF via .gitattributes (eol=lf for that subdirectory only) and add a separate Windows-only regression test that re-creates the fixtures with CRLF and asserts the parse trees match. More explicit, less coverage drift.\n\n The choice depends on whether we expect frequent grammar changes and whether ubuntu-only CI is sustainable. Recommend deciding before landing the grammar fix.\n\n4. Audit other CRLF patterns. The 5 failing pipe-table tests are the surface; there may be other constructs whose grammar paths assume \\n only. Grep grammar.js (and scanner.cc if present) for \\n usages and audit each one.\n\nReference. Investigation history and original framing in bd-ntnx (closed). Memory note q2-windows-verify-tests catalogues related Windows CRLF failures.","acceptance_criteria":"tree-sitter parse on matched CRLF and LF qmd inputs produces identical S-expression trees for pipe-table fixtures (Layer 1 reproducer diff is empty). pampa default native output is identical for the same matched inputs (Layer 2 reproducer diff is empty). All 5 originally-failing pipe-table tests under cd crates/tree-sitter-qmd/tree-sitter-markdown && tree-sitter test pass on Windows: Example 201 (GFM), Pipe table can precede content (two variants), Pipe table can follow content, Pipe table with blank-line caption. cargo xtask verify step 4 (tree-sitter test) passes on Windows. cargo nextest run --workspace and cargo xtask verify continue to pass on Linux CI (no regression). Decision recorded in commit message or PR description for upstream-vs-local fix and for test-corpus line-ending policy. Audit findings recorded for any other CRLF patterns discovered in grammar.js or scanner.cc. q2-windows-verify-tests memory note updated with PR link and resolution.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv","updated_at":"2026-05-04T13:45:00.482193500Z","closed_at":"2026-05-04T13:45:00.481818100Z","close_reason":"PR #139 merged 2026-04-30: fixed CRLF pipe-table line ending in scanner.c (typo fix at line 2259), added Rust regression test and xtask CRLF parity check","external_ref":"https://github.com/quarto-dev/q2/issues/138","source_repo":".","compaction_level":0,"original_size":0,"labels":["tree-sitter","windows"],"dependencies":[{"issue_id":"bd-0gsj","depends_on_id":"bd-ntnx","type":"discovered-from","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv","metadata":"{}","thread_id":""}],"comments":[{"id":15,"issue_id":"bd-0gsj","author":"cderv","text":"PR #139 opened (https://github.com/quarto-dev/q2/pull/139). Layer 1 + Layer 2 reproducer diffs empty post-fix. tree-sitter test on Windows: 451/451 (was 446/451). Decision: local fix, not upstream — typo introduced on this fork in 79489c4e. Decision: no .gitattributes change for test corpus — fixed grammar parses LF and CRLF identically, so existing corpus tests both modes (LF on Linux, CRLF on Windows checkout). Audit: line 2259 was the only outlier; all other newline checks in scanner.c use paired '\\n' || '\\r'. Added Rust regression test pipe_table_crlf_matches_lf for cross-platform coverage.","created_at":"2026-04-28T15:37:36Z"},{"id":16,"issue_id":"bd-0gsj","author":"cderv","text":"Tomorrow's verification (next session pickup): (1) check PR #139 CI status — gh pr checks 139 --repo quarto-dev/q2; (2) if green, merge; (3) on merge, close bd-0gsj with PR link as the close reason; (4) flush and commit accumulated .beads/issues.jsonl from main repo (this session created bd-vxl8 and bd-picv, plus comments on bd-238o, bd-3pe8, bd-0gsj); (5) update q2-windows-verify-tests memory note status to fully resolved.","created_at":"2026-04-28T16:05:51Z"},{"id":18,"issue_id":"bd-0gsj","author":"cderv","text":"CRLF parity check landed in commit 8f61f587 on branch fix/windows-tree-sitter-crlf (PR #139). cargo xtask verify step 4 now re-runs tree-sitter test against a CRLF-converted corpus copy; 451/451 pass, regression-tested by reverting scanner.c (446/451, build fails). Awaiting PR merge to close.","created_at":"2026-04-29T16:25:17Z"}]} +{"id":"bd-0jyl","title":"Source-info threading through listing markdown re-parse","description":"L3's ListingRenderTransform invokes pampa::readers::qmd::read on doctemplate output to obtain Pandoc blocks, then discards the fresh SourceContext. Diagnostics from that re-parse are collapsed into a single Q-12-10 host-page warning naming the listing id and first message — not threaded back to the host page's SourceContext.\n\nFor a proper design, a way is needed to merge the fresh SourceContext from the re-parse into the host page's SourceContext, *and* preserve the chain 'host YAML key → template substitution → markdown span' through to the diagnostic. Likely cuts across quarto-source-map, quarto-doctemplate, and the diagnostic-builder layer. Worth its own design session.\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D3 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T18:26:24.690377Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:24.690377Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0jyl","depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:24.690377Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0mji","title":"Phase D follow-up: SPA render-event hook + dep-graph filter regression tests","description":"Two related affordances needed once Phase D's dep-graph filter for re-render is implemented:\n\n1. **SPA render-event hook.** PreviewApp's render useEffect re-fires for every contentTick bump. Today this is invisible at the DOM when neither active-page content nor merged metadata change. A small test-only counter (window.__renderTicks or similar) would let Playwright assert 'this edit did/didn't trigger a re-render' for cases where the rendered output is identical.\n\n2. **Dep-graph filter regression tests.** Once Phase D filters re-renders against ProjectDependencyGraph, we need:\n - Active page re-renders when an edited sibling IS a dependency (positive case).\n - Active page does NOT re-render when an edited sibling is NOT a dependency (negative case — the savings).\n\nReframes the deferred Phase B.4 plan acceptance criterion 3 ('editing an unrelated sibling re-renders the active page only when there's a dep edge'). In Phase B the contract was relaxed to 'always re-renders' because no filter exists; Phase D restores the original strict contract.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4 (deferred criterion 3).","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid","updated_at":"2026-05-14T19:25:36.371752Z","closed_at":"2026-05-14T19:25:36.371611Z","close_reason":"Both items resolved: (1) window.__renderTicks render-event hook landed in D.3 (bd-kw93.9, commit 1ddcbeaf); (2) dep-graph filter regression tests landed in D.6 (bd-kw93.12, commit 7310d44b) — negative case in dep-graph-filter.spec.ts, positive case in the existing include-shortcode.spec.ts (Phase B.3).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0mji","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-0mji","depends_on_id":"bd-mrx1","type":"discovered-from","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0pic6","title":"Support theme: {light, dark} dark-mode config (object form)","description":"TS Quarto supports a YAML-object form for 'theme:' in format.html, with 'light' and 'dark' keys whose values are theme-name + scss-file lists:\n\n format:\n html:\n theme:\n light: [cosmo, theme.scss]\n dark: [cosmo, theme-dark.scss]\n\nQ2 currently rejects this: 'Invalid theme configuration: theme must be a string or array of strings'. quarto-web uses this form, so it's the next blocker after bd-47w7o for a full quarto-web render.\n\nDiscovered after bd-47w7o (directory-resource recursive copy) landed and the render progressed past resource copying. To investigate: find where theme parsing happens in Q2 (search for 'Invalid theme configuration'), check TS Quarto behavior at external-sources/quarto-cli (light/dark theme spec), design the parsing + rendering path. The render-side work likely interacts with the existing SCSS resolution pipeline. Likely larger than a one-shot fix; may want a plan doc when picked up.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-21T21:51:40.488001Z","created_by":"cscheid","updated_at":"2026-05-21T21:51:40.488001Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0pic6","depends_on_id":"bd-47w7o","type":"discovered-from","created_at":"2026-05-21T21:51:40.488001Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0pm7a","title":"fix(preview): iframe src must be relative to support subpath deployment","description":"Q2DebugIframe and Q2PreviewIframe hard-code src='/q2-debug.html' and src='/q2-preview.html' (root-absolute). Vite is configured with base: './' so the rest of the build uses relative URLs. Locally and in Playwright the app is served at the host root, so the two are indistinguishable; when deployed under a subpath the iframe src resolves to the wrong origin path and the iframe loads a 404 / SPA shell, leaving the preview blank. Fix: drop the leading slash in both files.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T11:56:32.004803Z","created_by":"shikokuchuo","updated_at":"2026-05-21T12:11:14.743822Z","closed_at":"2026-05-21T12:11:14.743764Z","close_reason":"Dropped the leading slash on both iframe srcs (commit 843cd7c3). Subpath deployment verified locally.","source_repo":"kyoto","compaction_level":0,"original_size":0} +{"id":"bd-0tr6","title":"Website projects epic: multi-page sites with sidebars, shared resources, and hub-client integration","description":"Design and implement multi-page website projects for Quarto 2. Covers: typed static-document snapshots (PageSnapshot/DocumentProfile working name), pipeline resumability, ProjectType trait, website sidebars, scoped/relocatable artifact stores (site_libs), cross-doc link rewriting, sitemap/favicon/site-url, incremental rebuilds, and hub-client project rendering.\n\nMVP scope explicitly excludes: search, listings/RSS, aliases, announcements, analytics, 404, reader-mode, repo-actions, breadcrumbs, book project type, quarto preview, freeze.\n\nPlan: claude-notes/plans/2026-04-23-website-project-epic.md\n\nDesign decisions from initial conversation:\n- Snapshot is a typed serializable value produced at a pipeline checkpoint after MetadataMergeStage; downstream code consumes Vec; user filters read but do not mutate.\n- Pipeline stages up to snapshot are resumable (cloneable) to avoid redundant execution across pass 1 (snapshot sweep) and pass 2 (per-file render).\n- ProjectType trait introduced now (website, default). Single-document renders go through DefaultProjectType.\n- Artifact stores scope-aware (Page vs Project) and relocatable; single-doc = project with implicit _quarto.yml.\n- Hub-client caches project nav state; renders active page with cached state. Design must leave room for Q2 'quarto preview' which will be a local hub-client instance.\n- Naming TBD in Phase 0 (DocumentProfile working name; user dislikes Page*/Metadata*).","status":"open","priority":1,"issue_type":"epic","created_at":"2026-04-23T18:42:28.206394Z","created_by":"cscheid","updated_at":"2026-04-23T18:42:28.206394Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-0ufq5","title":"Phase 2 — Hub middleware: Bearer extraction + audience allowlist + CSRF/Origin gating","description":"Land Bearer-auth support in crates/quarto-hub alongside the existing cookie path. TDD: write the 30-test set in crates/quarto-hub/tests/auth_bearer.rs first, then implement.\n\nTouch points: auth.rs (audience config, OidcClaims migration, azp/iat checks), server.rs (cookie extraction, Authenticated extractor, CSRF + WS-Origin gating).\n\nDual-credential 400 rule and full OIDC §3.1.3.7 azp logic are required. Sibling bug bd-XXXX tracks the dual-credential CVE test specifically.\n\nPlan §Phase 2: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-20T14:26:56.463684Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:38.345334Z","closed_at":"2026-05-20T21:22:38.345295Z","close_reason":"Phase 2 landed. AuthConfig.additional_audiences plumbed, OidcClaims gained aud/azp/iat, build_auth_state_from_parts added, extract_credential + CredentialKind + dual-credential 400 in server.rs, Authenticated carries credential_kind, CSRF/WS-Origin gated, audit emission via tracing::event!. 33 new integration tests + 7 lib tests pass; cargo xtask verify --skip-hub-build clean. See plan.","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0ufq5","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:26:56.463684Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-0wyo","title":"Server-precomputed other_metadata_html for default listing","description":"Q1's item-default.ejs.md iterates over fields *not* in the curated set ('title','image','image-alt','date','author','subtitle','description','reading-time','categories') and emits a per such field. This is dynamic in EJS — there is no equivalent in doctemplate without server-side precomputation.\n\nL3 v1 ships the default listing with curated-fields-only output. This issue picks up the gap by adding an other_metadata_html string to the per-item TemplateValue::Map binding, computed server-side in the listing render transform. The built-in item-default.template gets one more interpolation site: $item.other-metadata-html$.\n\nSource-code TODO marker lands in crates/quarto-core/src/project/listing/templates/item-default.template at the otherFields gap location (added during L3).\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D15 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-06T18:26:31.323613Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:31.323613Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0wyo","depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:31.323613Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-0xmt","title":"Phase A.0: Lift WASM JS bridge to @quarto/wasm-js-bridge workspace package","description":"Move hub-client/src/wasm-js-bridge/ to a new @quarto/wasm-js-bridge workspace package. Wire hub-client + q2-preview-spa + preview-renderer test configs to alias /src/wasm-js-bridge -> the package's src. Removes the cross-platform symlink/duplication risk for Phase A.3. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.0.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-13T16:53:11.353454Z","created_by":"cscheid","updated_at":"2026-05-13T17:07:44.781502Z","closed_at":"2026-05-13T17:07:44.781355Z","close_reason":"Bridge files moved to @quarto/wasm-js-bridge workspace package; consumers alias /src/wasm-js-bridge. Verified end-to-end (sass compile through bridge proven by hub-client test:wasm; cargo xtask verify 11/11). Commits ea1bb889 + changelog 043f65e1.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-0xmt","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:11.353454Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-1066","title":"HTML comments lost during incremental writes","description":"HTML comments (<\\!-- ... -->) are dropped from the Pandoc AST during parsing. tree-sitter parses them as 'comment' nodes which become IntermediateUnknown and are silently removed. This causes comments to be lost when the incremental writer rewrites blocks containing comments. Block-level standalone comments survive as empty Para blocks (preserved via source spans on KeepBefore), but inline comments within paragraphs are completely gone.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-02-09T15:35:05.022976Z","created_by":"cscheid","updated_at":"2026-02-09T15:35:05.022976Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-11a1","title":"Automerge-backed project set storage","description":"Replace per-browser IndexedDB project list with a synced Automerge document. See claude-notes/plans/2026-03-31-automerge-project-set.md","status":"open","priority":1,"issue_type":"epic","created_at":"2026-03-31T20:37:29.036441Z","created_by":"cscheid","updated_at":"2026-03-31T20:37:29.036441Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-128x","title":"Slide renderer crashes on empty slides document","description":"When a document has format: q2-slides but no slide content (no headers, no title), parseSlides() returns an empty array. SlideAst then calls renderSlide(slides[0]) which is undefined, crashing on slide.type access. The fix should handle the empty slides case gracefully by showing an empty/placeholder slide. Plan: claude-notes/plans/2026-02-26-empty-slides-crash.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T15:13:14.778662Z","created_by":"cscheid","updated_at":"2026-02-26T16:34:51.200462Z","closed_at":"2026-02-26T16:34:51.200439Z","close_reason":"Fixed: guard renderSlide call and hide nav controls when slides array is empty","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-129m3","title":"Provenance follow-up: ValueSource anchor stamping for meta/var shortcodes","description":"Wires up the AnchorRole::ValueSource role (already defined in Plan 4's enum) so that meta/var shortcode resolutions carry a typed anchor pointing at where the value was defined (e.g., a key in _metadata.yml).\n\n**Today (Plan 4 + Plan 6 baseline):**\n- {{< meta footer >}} -> Generated { by: shortcode(\"meta\"), from: [Invocation -> token_si] }\n\n**After this issue:**\n- {{< meta footer >}} -> Generated { by: shortcode(\"meta\"), from: [Invocation -> token_si, ValueSource -> metadata_yml_si] }\n\nThe writer (Plan 7) keeps consulting invocation_anchor() only; ValueSource is diagnostic-only (\"hover the resolved value to see where it was defined\"). Doesn't affect round-tripping or attribution.\n\n**Blocker:** the metadata loader doesn't expose per-key source-info on merged metadata today. Each YAML key has source_info at parse time, but the merge step strips it. Threading it through requires extending the metadata value types to keep source_info alive past the merge.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-4-source-info-types.md §\"Deferred anchor role\"\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §\"ValueSource follow-up\"\n\n**Compatibility:** pure addition. AnchorRole::ValueSource already exists in Plan 4's enum from day 1. Plan 6's stamper gains conditional ValueSource emission for meta/var shortcodes whose values came from outside the active document.\n\n**Effort:** smaller than the Dispatch follow-up — self-contained (metadata loader + Plan 6 stamper). No new infrastructure crates.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T22:37:02.608131Z","created_by":"gordon","updated_at":"2026-05-21T22:37:02.608131Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["follow-up","provenance"]} +{"id":"bd-12fpz","title":"D4/D5: HTML writer emits odd/even and header row classes","description":"## What\n\n`write_table_row` in `crates/pampa/src/writers/html.rs:1490` emits bare `` for every row. Pandoc's reference HTML writer (which Q1 inherits) adds:\n\n- `` on header (thead) rows.\n- `` / `` alternating on body rows.\n\n## Fix\n\nPass row index + is_header from the table-writing loop into `write_table_row` (it already gets `is_header`); add the class accordingly.\n\n## Tests (TDD)\n\nSnapshot test on a 3-row table (1 header + 2 body) showing:\n- header row: ``\n- first body row: ``\n- second body row: ``\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D4, D5 sections — bundled because they share the same writer code path)","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T20:55:24.955808Z","created_by":"cscheid","updated_at":"2026-05-20T21:31:14.339774Z","closed_at":"2026-05-20T21:31:14.339617Z","close_reason":"Implemented in this commit: row classes (header/odd/even) emitted.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-12fpz","depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:24.955808Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-12vrr","title":"Callout default-title synthesizer + popup-menu callout-type switching (Plan 6 §B)","description":"Plan 6's audit identified crates/quarto-core/src/transforms/callout_resolve.rs:267 (default callout title 'Note'/'Tip'/'Warning'/...) as an AST synthesizer that today emits SourceInfo::default(). To bring it into the Generated shape Plan 6 establishes, it needs: (a) a new By::callout() constructor in quarto-source-map, (b) an atomicity decision (is_atomic_kind), (c) the fix at callout_resolve.rs:267, (d) a per-transform test. Deferred from Plan 6 because it was not enumerated in the plan body and requires the new By constructor + atomicity decision.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-22T16:19:01.484116Z","created_by":"gordon","updated_at":"2026-05-22T16:45:31.449690Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-12vrr","depends_on_id":"bd-129m3","type":"related","created_at":"2026-05-22T16:19:13.342003Z","created_by":"gordon","metadata":"{}","thread_id":""}],"comments":[{"id":27,"issue_id":"bd-12vrr","author":"Gordon Woodhull","text":"Why this matters beyond the audit fix: the React preview needs a UI affordance to **switch callout type** (Note → Tip → Warning → Important → Caution) via a popup menu on the callout block. For that to round-trip cleanly through Plan 7's writer, the default-title text (\"Note\", \"Tip\", …) must NOT be treated as user-editable Original content — otherwise typing-as-edit semantics would force the writer to materialize \"Note\" as literal text into source, even when the user only wanted to swap the type via the menu.\n\nThe `Generated { by: callout(), … }` stamping + the atomicity decision determine:\n\n1. **React-side**: whether the title region is gated read-only via Plan 2A's atomic check (so the user can't accidentally type into it; the menu is the only path to mutation).\n2. **Writer-side**: how a menu-driven type change serializes. The menu rewrites the Callout CustomNode's `plain_data` (e.g. `{\"type\": \"tip\"}`) and leaves the title-Generated either re-synthesized on next pipeline run or replaced with a fresh Generated whose `by.data` reflects the new type. Plan 7's let-user-win path handles the CustomNode rewrite naturally; the title region soft-drops on direct edits (Q-3-42-style).\n\nRecommend `is_atomic_kind = true` for `By::callout()`'s title-synthesizer use so the title is non-editable text and only menu-driven type changes mutate it. The popup-menu component lives in hub-client's React framework registry (post-Plan 2B); this beads owns the Rust-side provenance support that makes the round-trip behave.\n","created_at":"2026-05-22T16:45:31Z"}]} {"id":"bd-140x","title":"Contribute samod fix upstream with pure-rust reproduction test","description":"Cherry-pick the NotFound race condition fix (431333f) from quarto branch to main on cscheid/samod fork, and write a pure-rust integration test in samod-core/tests/ that reproduces the bug independently of quarto-hub. The test should demonstrate that a document synced from a client to a DontAnnounce server is dropped during handle_load when pending_sync_messages are ignored. PR target: alexjg/samod.","status":"open","priority":1,"issue_type":"task","created_at":"2026-03-04T00:58:02.303737Z","created_by":"cscheid","updated_at":"2026-03-04T00:58:02.303737Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-14rer","title":"ExecuteResult.filters set by Knitr engine is never consumed downstream","description":"Workspace-wide grep for `result.filters` / `ExecuteResult.*filters` returns hits in tests, the Knitr write site, extension parsing, and a comment in capture-splice — but no production consumer.\n\nConcretely:\n- crates/quarto-core/src/engine/knitr/mod.rs:215 sets `filters: result.filters` from the R subprocess output (test fixture asserts `vec![\"rmarkdown/pagebreak.lua\"]`, knitr/types.rs:281).\n- crates/quarto-core/src/filter_resolve.rs only resolves filters from YAML `filters:` document metadata, not from ExecuteResult.filters.\n\nSo Knitr's pagebreak filter is silently dropped today. This also blocks any future engine (like a mermaid Lua-filter approach) that wants to declare filters dynamically.\n\nDecision needed: wire ExecuteResult.filters into the resolver, or remove the field if the architectural direction is different (e.g. all engine-side filters should be expressed as AST transforms instead).\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G1.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-28T13:45:45.986759Z","created_by":"cscheid","updated_at":"2026-05-28T13:45:45.986759Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-14rer","depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:45.986759Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-159sr","title":"Verify @tip-foo crossref of callouts still works after class-vocabulary alignment","description":"The callout class-vocabulary fix (2026-05-22) reshaped\n\\`CalloutResolveTransform\\` output and added a defense-in-depth\nminimal-normalization. \\`CalloutTransform\\` still writes the\ncrossref triple (\\`ref_type\\`, \\`kind\\`, \\`identifier\\`) into\n\\`plain_data\\` for callouts whose id classifies (\\`callout.rs:236-241\\`),\nand the resolver now suppresses the screen-reader span when\n\\`ref_type\\` is present (correct behavior — the crossref-rendered\nprefix announces the type instead).\n\nVerify end-to-end:\n\n1. Render a doc with \\`::: {#tip-foo .callout-tip}\\` and \\`@tip-foo\\`\n elsewhere in the body.\n2. Check the rendered HTML:\n - The callout shows the type's display name (\\\"Tip\\\") in its\n title (default-injected, since no user title).\n - The body's \\`@tip-foo\\` resolves to the crossref-rendered text\n (e.g. \\\"Tip 1\\\" or whatever the locale specifies).\n - The hyperlink target is the callout's outer div id (#tip-foo).\n3. Confirm no screen-reader-only span is emitted on the callout\n (crossref prefix replaces it).\n4. Add a smoke-all fixture under \\`crates/quarto/tests/smoke-all/\\`\n if one doesn't already exist for this pattern.\n\nTracking item carried over from the 2026-05-22 plan's follow-up\nsection. P1 because a regression would silently break a feature\nsome users rely on.","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-26T13:44:11.453179Z","created_by":"gordon","updated_at":"2026-05-26T13:44:11.453179Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-15dw","title":"Navbar icon-only item enrichment tie-break","description":"Phase 3 enrichment fills navbar item.text from profile title only when text is None. An item that supplies icon but no text (common for social links) currently stays text-less. Confirmed intentional. Revisit if users ask for auto-text from titles even for icon-only items. See 2026-04-24-websites-phase-3.md §Follow-up beads.","status":"open","priority":4,"issue_type":"task","created_at":"2026-04-24T19:43:02.249186Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:02.249186Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-15dw","depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:43:02.249186Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-18wn","title":"Fix file-locking test failures in quarto-hub on Windows","description":"2 storage tests fail because Windows uses mandatory file locking vs Unix advisory. File::create fails with sharing violation before try_lock_exclusive runs. Fix: use OpenOptions::new().write(true).create(true) instead of File::create, or map sharing violation error to HubAlreadyRunning. Affects test_storage_manager_prevents_double_lock and test_storage_manager_standalone_prevents_double_lock.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-03-20T13:36:06.424470600Z","created_by":"cderv","updated_at":"2026-03-20T13:36:06.424470600Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-195t","title":"Lua attribute-mutation: proxy tables so cb.attr.attributes[k]=v persists","description":"Quarto 2's Lua bridge returns fresh copies of `cb.attr` (and of `cb.attr.attributes`) on every read. In-place mutation like `cb.attr.attributes[\"k\"] = v` — the idiomatic Pandoc-Lua pattern — silently hits an ephemeral copy and is discarded. Surfaced while exercising Phase 3.5's filter-authored spans fixture (04-filter-authored-spans); the workaround there rebuilds the whole Attr with pandoc.Attr(...) and assigns as one value. Before we document the Lua-filter path to syntax highlighting as a user-facing feature, the idiomatic pattern must persist. See claude-notes/plans/2026-04-20-syntax-highlighting-phase-3.5.md 'Follow-up task: Lua attribute-mutation proxy'. Plan: claude-notes/plans/2026-04-21-lua-attr-mutation-proxy.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-21T17:19:19.121444Z","created_by":"cscheid","updated_at":"2026-04-21T17:19:19.121444Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1c6x","title":"Incremental writer panics when original QMD lacks trailing newline","description":"The incremental writer (incremental_write_qmd WASM entry point) panics with 'byte index out of bounds' when the original QMD text doesn't end with a newline. The QMD reader internally pads input with \\n, producing source spans for the padded input, but incremental_write receives the unpadded string. Triggered by changing kanban card status when synced document text doesn't end with \\n. Plan: claude-notes/plans/2026-02-11-incremental-writer-trailing-newline-bug.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-02-11T20:48:21.313234Z","created_by":"cscheid","updated_at":"2026-02-11T21:07:59.477860Z","closed_at":"2026-02-11T21:07:59.477843Z","close_reason":"Fixed: added ensure_trailing_newline normalization in incremental_write and compute_incremental_edits. The QMD reader internally pads input with newline, so source spans reference the padded length. The incremental writer now pads its input to match, then strips the padding from results. 6 new tests added, all 6408 workspace tests pass.","source_repo":".","compaction_level":0,"original_size":0} -{"id":"bd-1d3e","title":"Fix CRLF test failures in quarto-doctemplate on Windows","description":"8 tests fail because template files are checked out as CRLF on Windows but tests compare against LF strings. Options: .gitattributes to force LF on template files, normalize CRLF in compile_from_file at parser.rs:225, or normalize in test assertions. Affects test_partial_resolution and 7 pandoc_equiv_tests.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-03-20T13:35:56.689880800Z","created_by":"cderv","updated_at":"2026-03-20T13:35:56.689880800Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1d3e","title":"Fix CRLF test failures in quarto-doctemplate on Windows","description":"8 tests fail because template files are checked out as CRLF on Windows but tests compare against LF strings. Options: .gitattributes to force LF on template files, normalize CRLF in compile_from_file at parser.rs:225, or normalize in test assertions. Affects test_partial_resolution and 7 pandoc_equiv_tests.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-03-20T13:35:56.689880800Z","created_by":"cderv","updated_at":"2026-05-05T16:08:19.594867400Z","external_ref":"https://github.com/quarto-dev/q2/issues/157","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1d6io","title":"annotated-qmd: source-tracking off-by-one in regenerated examples","description":"Two TS tests in ts-packages/annotated-qmd fail after regenerating example JSONs with the current pampa writer:\n\n1. substring-invariant.test.ts: 'substring invariant - links.qmd: inline code' — expects substring(125, 133) to be '`x = 5`' but gets ' `x = 5`' (extra leading space).\n2. block-types.test.ts: 'div-attrs.json - Div with attributes conversion' — key source text ' custom-key' has a leading space; the assertion 'should be a valid attribute key' fails because the substring extracted from source includes a preceding space.\n\nBoth fail in the same shape on the surface: the writer-recorded start offset for these tokens is 1 character too early, capturing the preceding whitespace. Whether they share a single root cause has not been confirmed.\n\n## Why this surfaces now (not on main)\n\nThe failures only surface when example fixtures (ts-packages/annotated-qmd/examples/*.json) are regenerated against the current pampa. The committed fixtures (regenerated 2025-10-24, commit 2b2337be by Carlos) predate the pampa changes that introduced the offset drift. cargo nextest run --workspace doesn't touch the fixtures — they're inert JSON loaded by the TS test suite (loadExample(...) in test/document-converter.test.ts and others) — so main's CI has been green throughout while the underlying writer behavior drifted.\n\nPlan 7f Phase 5 (wire-format rename attrS->a, sourceInfoPool->p) requires regenerating the fixtures because the TS code post-rename reads inline.a / astContext.p — old-format fixtures (attrS, sourceInfoPool) would be unreadable. Regeneration is a Phase-5 necessity. The regenerated fixtures capture current pampa writer behavior, including the off-by-one, and that's what trips these tests.\n\nPhase 5 itself only renamed JSON keys — no offset computation was touched. So Phase 5 is the messenger, not the cause.\n\n## Suspected commit for failure #1 (inline code) — NOT CONFIRMED\n\nPlausible candidate: commit 38e889ad (Carlos, 2026-05-24, 'tree-sitter qmd: allow line breaks inside inline code spans and inline math (bd-ilv8p)'). The commit substantially reworked code-span tokenization in the tree-sitter scanner + grammar — SOFT_LINE_ENDING absorb logic, pandoc_soft_break aliasing, an extract_code_span_text helper. It's the only recent commit between 2b2337be (2025-10-24) and HEAD that touches code-span tokenization.\n\nHypothesis: the rework widened the pandoc_code_span tree-sitter node by one byte to the left, to include the preceding-space character. Since Inline::Code's source_info is computed via node_source_info_with_context(node, context) at crates/pampa/src/pandoc/treesitter_utils/code_span_helpers.rs:171 — taking the whole node's byte range — that left-edge widening shows up directly as a 1-char-wider Code source range.\n\nNOT YET BISECTED. The hypothesis is consistent with the failure shape but a clean bisect would confirm or refute it.\n\n## Suspected commit for failure #2 (div key-source) — UNKNOWN\n\nThe div-attrs failure is in a different code path (attribute key-source recording during div parsing). The \"leading space byte gets included\" pattern matches surface-level, but I have NOT verified that this is the same code path or the same root cause. It could be:\n* the same scanner-side absorb pattern leaking into adjacent attr/key-source tokens, OR\n* a separate regression introduced by a different commit, OR\n* older than 2025-10-24 and only now visible because the regenerated fixture happens to record a real source range where the old fixture had something stale.\n\nA clean bisect against the example regen is the cheapest way to find out.\n\n## Repro\n\n cd ts-packages/annotated-qmd\n npm test\n\nFailures: 2 of 156 tests fail. The other 154 pass — including substring-invariant tests on Str / Space / Header / BulletList / ordered-list / link target / link text — which means the off-by-one is not pervasive; it's localized to specific token boundaries.\n\n## Fix direction\n\n1. Bisect each failure independently against the example fixture regen. Use a known-good baseline of pampa from 2025-10-24 (around commit 2b2337be) and walk forward.\n2. If failure #1 lands on 38e889ad, audit pandoc_code_span node-range computation in the scanner — likely the absorb-leading-space behavior needs to start the node at the opening backtick.\n3. If failure #2 lands on a different commit (likely), the fix is independent.\n4. Add a CI lane that regenerates the annotated-qmd example fixtures (or at minimum diffs the writer output against them) so the next time a tree-sitter scanner change drifts the output, this catches at the PR level instead of accumulating until the next forced regen.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-06-01T15:58:10.144959Z","created_by":"gordon","updated_at":"2026-06-01T18:26:49.621585Z","source_repo":".","compaction_level":0,"original_size":0,"comments":[{"id":29,"issue_id":"bd-1d6io","author":"Gordon Woodhull","text":"Investigation complete (worktree bd-1d6io, plan: claude-notes/plans/2026-06-01-bd-1d6io-investigation.md). VERDICT: ready — two distinct scanner-side bugs, both accidental leading-whitespace absorption; Rust writers correct. #1 (inline code): REGRESSION in 2025-10-30/31 inline-parser rewrite (good@2b2337be r:[126,133]; bad@5cc1a849 'code spans'); CODE_SPAN_START token absorbs preceding inline whitespace; 38e889ad REFUTED (parent 5d35218d already bad). #2 (div custom-key): ORIGINAL DEFECT since >=2025-08-06; 2nd+ key_value_key/KEY_SPECIFIER token absorbs inter-pair space; committed [252,262] never matched live pampa even at fixture birth d6230301 (live [251,262]). CI stayed green: insta json snapshots lack inline-Code/multi-kv cases; pandoc-match-corpus is source-range-blind; annotated-qmd JSON is static/hand-regenerated and inert to nextest. FIX: scanner fixes both tokens; add CI-resident byte-offset regression tests (TDD); add xtask verify guard diffing live writer over examples/*.qmd vs committed JSON.","created_at":"2026-06-01T18:26:49Z"}]} +{"id":"bd-1e6a5","title":"AttrSourceInfo: caption-attr merge into table breaks positional alignment","description":"When the qmd parser merges caption attributes into a table's Attr at:\n\n- crates/pampa/src/pandoc/treesitter_utils/section.rs:85-113\n- crates/pampa/src/pandoc/treesitter_utils/postprocess.rs:1483-1496\n\nit calls table.attr.2.insert(k, v) and table.attr_source.attributes.push(...). If a caption attribute key already exists on the table (e.g. both have id or class), LinkedHashMap::insert updates the existing entry in place while push always appends — leaving attr.2.len() and attr_source.attributes.len() out of sync. The positional alignment AttrSourceInfo.attributes[i] = (key_src, val_src) for the i-th entry in Attr.2 is broken whenever caption + table attribute keys overlap.\n\n**Discovered while reviewing Plan 6's theorem.rs::extract_name_attr fix** (claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet). Plan 6 mitigates with a runtime guard but the underlying bug pre-dates Plan 6.\n\n**Fix sketch:**\nFor each (k, v, key_src, val_src) being merged:\n- If table.attr.2.contains_key(&k), find its position, overwrite both attr.2's value AND attr_source.attributes[pos] in lockstep.\n- Else, append to both.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet (positional-alignment safeguards)\n- crates/quarto-pandoc-types/src/attr.rs:27-32 (AttrSourceInfo definition)","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-22T06:44:51.585690Z","created_by":"gordon","updated_at":"2026-05-22T06:44:51.585690Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","provenance"]} +{"id":"bd-1elkd","title":"Brand-aware favicon: read logo.small from _brand.yml when website.favicon unset","description":"Q1 falls back to brand.light.favicon when website.favicon is unset. Now that Q2 has Brand data via quarto-brand, wire it into the favicon emission path. Brand::favicon() already returns the small logo's path. Likely closes bd-97yc. Q1 reference: external-sources/quarto-cli/src/project/types/website/website.ts:185-205.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:07.428762Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:07.428762Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1elkd","depends_on_id":"bd-97yc","type":"related","created_at":"2026-05-21T02:31:07.428762Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-1g5f","title":"Make default sync server configurable via environment variable","description":"Allow build-time configuration of the default Automerge sync server URL via VITE_DEFAULT_SYNC_SERVER environment variable. Currently hardcoded to wss://sync.automerge.org in routing.ts and ProjectSelector.tsx. Needed for internal deployments with private sync servers so beta users don't have to manually enter a custom URL.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-04T21:26:45.230188Z","created_by":"cscheid","updated_at":"2026-02-04T21:48:29.989386Z","closed_at":"2026-02-04T21:48:29.989369Z","close_reason":"Implemented: DEFAULT_SYNC_SERVER now reads from import.meta.env.VITE_DEFAULT_SYNC_SERVER with fallback. Commit 3ed1c1bf.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1hdz","title":"Title-prefix home-page carve-out (Q1 stem==index parity)","description":"Q1 only injects website.title as pagetitle for the home page (stem == \"index\" && offset === \".\") when both title and pagetitle are absent. Phase 7 takes the broader \"any untitled page falls back to website title\" rule (Decision 4). Revisit if a real fixture surfaces a problem. Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.707126Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1hdz","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-1hdz","depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-1hwd","title":"Phase 5: Inline splicing for incremental writer","description":"Implement inline-level splicing in the incremental writer. When a reconciliation plan involves changes that neither add nor remove nodes that create newline characters (SoftBreak, LineBreak), indentation boundaries are preserved and inline changes can be spliced without rewriting the entire indentation boundary. This is a critical optimization for the common case of text edits within paragraphs inside lists and block quotes. Plan: claude-notes/plans/2026-02-10-inline-splicing.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-10T15:09:50.520536Z","created_by":"cscheid","updated_at":"2026-02-10T16:37:28.833053Z","closed_at":"2026-02-10T16:37:28.833034Z","close_reason":"Implemented inline splicing for incremental writer. All phases complete (5a-5g): safety checks, source span utilities, inline coarsening/assembly, comprehensive property tests, integration. 124 tests across 4 test files. 6394 workspace tests pass.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1hwd","depends_on_id":"bd-2t4o","type":"discovered-from","created_at":"2026-02-10T15:09:50.520536Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-1inj0","title":"Provenance follow-up: code-block decoration synthesizers (Plan 6 §C)","description":"Plan 6's audit identified crates/quarto-core/src/transforms/code_block_generate.rs and code_block_render.rs as a smaller audit pass for code-block decoration synthesizers (filename labels, captions). Deferred from Plan 6 because scope was bounded to the explicitly-enumerated transforms. Likely needs a By::code_block_chrome() (or similar) constructor and a small set of per-transform tests.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-22T16:19:08.284554Z","created_by":"gordon","updated_at":"2026-05-22T16:19:13.446418Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1inj0","depends_on_id":"bd-129m3","type":"related","created_at":"2026-05-22T16:19:13.446359Z","created_by":"gordon","metadata":"{}","thread_id":""}]} +{"id":"bd-1jnb","title":"q2-demos vite build fails: imports /src/wasm-js-bridge/cache.js","description":"The vite build of q2-demos/hub-react-todo and q2-demos/kanban fails with:\n\n [vite]: Rollup failed to resolve import \"/src/wasm-js-bridge/cache.js\"\n from \"crates/wasm-quarto-hub-client/pkg/wasm_quarto_hub_client.js\"\n\nThe wasm-bindgen-generated JS glue references an absolute path that\nresolves correctly when vite roots at hub-client/ (which has\nsrc/wasm-js-bridge/cache.js), but the demos do not have that file.\n\nThe demos likely need either:\n - their own copy of the cache.js bridge module, or\n - vite alias config that resolves the path to hub-client's copy, or\n - the wasm crate's #[wasm_bindgen(module = \"...\")] path changed to\n something portable.\n\nSurfaced while getting the Hub-Client E2E Tests workflow to run on CI\n(branch chore/e2e-ci). The workflow now builds only ts-packages +\nhub-client to avoid this failure; the demos remain broken at build\ntime. See claude-notes/ for session notes if needed.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-10T23:16:12.128803Z","created_by":"gordon","updated_at":"2026-05-10T23:16:12.128803Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1kly","title":"Complete FootnotesTransform for reference-location: block/section","description":"FootnotesTransform at crates/quarto-core/src/transforms/footnotes.rs:99-105 currently no-ops for reference-location: block and section, leaving raw Inline::Note nodes in the AST with a stale comment claiming \"Pandoc handles this\". pampa's HTML writer (crates/pampa/src/writers/html.rs:806-817) also doesn't handle them correctly — it emits [N] where N is the length of the note content array, not a sequential number, with a TODO acknowledging the gap.\n\nNeither layer numbers Notes correctly for these configs. The work is missing in both places.\n\nThe proper fix is to extend FootnotesTransform to handle block/section: number all Notes in document order (already done for document-mode) and emit per-block or per-section footnote sections at the right boundary instead of a single document-end section.\n\nDiscovered while reviewing q2-preview Plan 2B (claude-notes/plans/2026-05-04-q2-preview-plan-2b-builtin-components.md) — q2-preview's Note.tsx falls back to JS-side numbering with body-in-tooltip rendering for these configs as a temporary v1 measure. When this beads is closed and the upstream transform handles all four reference-location values uniformly, q2-preview's Note.tsx fallback can be deleted.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-09T20:40:28.166910Z","created_by":"gordon","updated_at":"2026-05-09T20:40:28.166910Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1kor9","title":"Implement callout output for non-HTML formats: revealjs, typst, latex","description":"TS Quarto's \\`customnodes/callout.lua\\` registers per-format\nrenderers for Bootstrap HTML, EPUB/RevealJS, GitHub Markdown,\nLaTeX, Typst, and a default fallback (\\`callout.lua:135-220\\`).\n\nq2 currently only wires up the Bootstrap HTML renderer via\n\\`CalloutResolveTransform\\`. Other formats either render callouts\nas plain Div blocks (no styling) or aren't supported at all.\n\nOut of scope for the 2026-05-22 class-vocabulary alignment; tracked\nas a follow-up. Each format will likely want its own dedicated\nresolve-like transform.\n\nReference: \\`/Users/gordon/src/quarto-cli/src/resources/filters/\ncustomnodes/callout.lua:130-220\\`.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-26T13:44:16.175550Z","created_by":"gordon","updated_at":"2026-05-26T13:44:16.175550Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1kvf","title":"Incremental writer loses blank line between front matter and first block","description":"When toggling a checkbox via the React todo demo, the blank line between the YAML front matter closing --- and the first div (::: {#todo}) disappears. Root cause: metadata_structurally_equal() uses ConfigValue PartialEq which includes source_info, causing false inequality between re-parsed original and JSON-deserialized new AST. Secondary latent bug: the metadata rewrite path doesn't emit the gap separator. Plan: claude-notes/plans/2026-02-08-incremental-writer-metadata-gap.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-08T16:08:02.508695Z","created_by":"cscheid","updated_at":"2026-02-08T16:30:27.327884Z","closed_at":"2026-02-08T16:30:27.327868Z","close_reason":"Fixed: content-only metadata comparison + gap preservation on rewrite","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","incremental-writer"]} +{"id":"bd-1mbj","title":"build_q2_preview_transform_pipeline_is_subset_of_html drift: HTML pipeline gained listing-* stages not in q2-preview subset","description":"Test at crates/quarto-core/src/pipeline.rs:1942 fails on feature/q2-preview-work HEAD. The HTML pipeline added listing-generate, listing-render, categories-sidebar, listing-feed-stage, listing-feed-link stages without updating the q2-preview subset (or the test). Surfaced during Plan 2A item 11 implementation; pre-existing on the branch (verified by stashing 2A changes — failure persists). Decide: include these in q2-preview's subset, exclude them by name in the assertion, or update the test's expected subset.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-09T16:21:16.410360Z","created_by":"gordon","updated_at":"2026-05-09T18:11:42.819490Z","closed_at":"2026-05-09T18:11:42.819459Z","close_reason":"Fixed by 0887a3fa (refactor q2-preview pipeline to deny-list construction) — listing-* stages now flow into q2-preview by default since the subset is HTML-pipeline minus an explicit exclusion list, not a hand-maintained allow-list. The test was deleted with the assertion infrastructure.","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","plan2a-discovered"]} {"id":"bd-1oxt","title":"Project ZIP export from hub-client","description":"Add exportProjectAsZip() to quarto-sync-client that walks all project files and returns a Uint8Array of ZIP bytes. Add an Export ZIP button to the PROJECT tab in hub-client. See plan: claude-notes/plans/2026-02-11-project-zip-export.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-11T19:56:41.539365Z","created_by":"cscheid","updated_at":"2026-02-11T19:56:41.539365Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["hub-client","quarto-sync-client"]} +{"id":"bd-1pwy8","title":"Wire SassError::UnknownTheme through the structured diagnostic system","description":"Follow-up discovered after the bd-l26u6 epic merged. SassError::UnknownTheme (raised by BuiltInTheme::from_str when a theme name is not recognized) still surfaces as the span-less, code-less 'Error: SASS error / Unknown theme: default' line — the theme_diagnostic fallback path.\n\nReproducer: q2 render external-sources/quarto-web — emits both Q-14-1 (coalesced, from _quarto.yml:686) AND the bare 'Unknown theme: default' line (from docs/output-formats/html-themes.qmd:11, which has 'theme: default' in its document frontmatter).\n\nFix follows the bd-pgczr pattern:\n- Add location: Option to SassError::UnknownTheme.\n- Add SassError::with_location(self, SourceInfo) -> Self helper so the next variant migration is trivial.\n- Propagate value.source_info.clone() at the ThemeSpec::parse call sites in extract_theme_specs (crates/quarto-sass/src/config.rs:455, :465).\n- Allocate Q-14-2 'Unknown theme name' in error_catalog.json under the existing 'theme' subsystem.\n- Extend theme_diagnostic::sass_error_to_parse_error to render UnknownTheme as a structured DiagnosticMessage with Q-14-2 + source span.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T15:40:16.192572Z","created_by":"cscheid","updated_at":"2026-05-22T16:00:33.283018Z","closed_at":"2026-05-22T16:00:33.282854Z","close_reason":"UnknownTheme now flows through quarto-error-reporting as Q-14-2. Verified end-to-end: pandas-acting-on-data.qmd:7:12 'default' produces a proper ariadne block. No more plain-text SASS error fallback in quarto-web.","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","theme"],"dependencies":[{"issue_id":"bd-1pwy8","depends_on_id":"bd-l26u6","type":"related","created_at":"2026-05-22T15:40:16.192572Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-1qk5","title":"Inline grammar: post-codespan apostrophe trips Q-2-7 (Unclosed Single Quote)","description":"The inline grammar's smart-quote rule treats `'` immediately after a\nclosing-backtick (code span boundary) as an *opening* single quote,\neven when followed by letters as in a possessive. Real Pandoc treats\nthe same construct as a possessive and emits no error. As a result,\ncommon technical writing patterns trip Q-2-7:\n\n `setAst`'s callback → FAIL (Q-2-7)\n `Para`'s rendering → FAIL\n `framework/Ast.tsx`'s → FAIL\n ``'s → FAIL (the angle brackets are not the\n trigger — backticks alone suffice)\n\nThis has tripped the changelogRender.wasm.test.ts at least twice:\n- 0c78b1a4 (2026-05-08): \"fix(hub-client): rewrite changelog 2026-05-08\n entry to clear Q-2-7 parse error\" — diagnosis blamed `` HTML-\n like content; the angle brackets are coincidental.\n- d7d7e063 (2026-05-10): same trigger pattern in Plan 2B Phase 1/2\n changelog entries; rewrote in plain prose.\n\n## Empirical scope\n\n| Pattern | Result | Why |\n|------------------------------------|--------|----------------------------------|\n| `` `code`'s gate `` | FAIL | post-codespan `'` promoted |\n| `` `code`'foo bar `` | FAIL | same |\n| `` `code` 's gate `` | FAIL | whitespace between doesn't help |\n| `` `code`\\'s gate `` | PASS | escaped apostrophe |\n| `` word's gate `` | PASS | letter-letter → possessive |\n| `` `code`'s and `other`'s pair `` | PASS | two opens form a balanced pair |\n| `` `code`'s and word's pair `` | FAIL | only one promoted-to-opening |\n\nReproducer: see /tmp/q27[a-e].qmd patterns in the discovery session\nor just `printf \"x \\\\\\`code\\\\\\`'s\\\\n\" | cargo run --bin pampa -- -t json -i -`.\n\n## Proper fix\n\nIn `tree-sitter-markdown-inline`'s grammar, extend the rule for\nopening single quote so a `'` immediately after a closing-backtick\n(or, more generally, after any inline-end token) is treated as a\npossessive when the next character is a letter — same heuristic\nthat already saves `word's`. Pandoc proper does this; the smart-\nquote algorithm there is \"an apostrophe between letters or after a\nmarkup boundary that resolves to letters is a possessive.\"\n\nAfter regenerate + build, add a test case to the inline grammar's\ntest corpus and a passing case to resources/error-corpus\ndemonstrating that `` `code`'s `` no longer fires Q-2-7.\n\n## Workarounds available today\n\n1. Pair them deliberately within the same block (two close-backtick\n apostrophes form a smart-quote pair).\n2. Backslash-escape: `` `code`\\'s ``.\n3. Rephrase to put the apostrophe inside a word (`the setAst\n callback's behavior`).\n4. bd-kk0a's writer-side escape (separate issue, AST→qmd direction).\n\n## Related\n\n- bd-kk0a: writer-side escape for unbalanced apostrophes in JSON\n → qmd round-trip. Option-4-of-this-issue (parser fix) would\n obviate part of bd-kk0a's escape work.\n- crates/pampa/snapshots/error-corpus/text/006.snap, 009.snap:\n current Q-2-7 examples for the parser-state mapping table at\n resources/error-corpus/_autogen-table.json:18686.\n- Discovery transcript: changelog Q-2-7 thread in\n feature/q2-preview implementation session 2026-05-10.","notes":"Pandoc-comparison findings posted to GH #221 (https://github.com/quarto-dev/q2/issues/221): symmetric notAfterString/notBeforeAlphanum predicates + speculative-balance fallback. Pandoc shares the same fundamental ambiguity but doesn't error — silently mis-quotes. Proposed fix scope: 'be at least as good as Pandoc' on the scope-table cases; a stricter fix (bias open-after-inline-end toward apostrophe) is harder design work.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-10T06:44:33.152101Z","created_by":"gordon","updated_at":"2026-05-20T21:13:53.979030Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1qk5","depends_on_id":"bd-kk0a","type":"related","created_at":"2026-05-10T06:44:33.152101Z","created_by":"gordon","metadata":"{}","thread_id":""}]} {"id":"bd-1s21","title":"Span writer: drop {} for empty attributes, use [ ] for empty span","description":"Change the QMD writer so that a Span with empty content and empty attributes is written as '[ ]' (space between brackets) instead of '[]{}'. This improves readability for the checkbox use case in hub-react-todo.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-08T15:37:32.152755Z","created_by":"cscheid","updated_at":"2026-02-08T15:45:48.708881Z","closed_at":"2026-02-08T15:45:48.708865Z","close_reason":"Implemented: spans with empty attrs drop {}, empty span writes as [ ]. All 6247 tests pass.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1tl09","title":"Code-block decorations (filename, copy, fold, line-numbers, annotations, preview)","description":"Port Quarto 1's code-block decorations to Quarto 2 using the existing Generate/Render transform pattern. One format-agnostic CodeBlockGenerateTransform extracts a typed CodeBlockDecoration from the AST; one CodeBlockRenderTransform per format emits the format-specific markup.\n\nFeatures in scope (sized as phases in the plan):\n1. Filename header ({r filename=\"x.R\"})\n2. Code copy button (clipboard.js + scaffold)\n3. Code folding ({code-fold: true|show},
)\n4. Line numbers ({code-line-numbers: true|\"3,5-7\"})\n5. Code preview iframe ({code-preview=\"foo.qmd\"})\n6. Code annotations (# markers + following ordered list)\n\nArchitecture, phase breakdown, open questions, and Q1 audit summary in:\n claude-notes/plans/2026-05-19-code-block-features.md\n\nOut of scope (separate plans): LaTeX/PDF rendering, Reveal.js-specific line-number ranges, annotation tooltip interaction modes.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-19T19:28:00.077936Z","created_by":"cscheid","updated_at":"2026-05-19T19:28:00.077936Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1ui2","title":"Suppress auto-generated header IDs in QMD writer roundtrips","description":"Headers like '## project {.a-class}' roundtrip as '## project {#project .a-class}', adding an auto-generated ID that wasn't in the source. Similarly, '## project' becomes '## project {#project}'. The writer should detect auto-generated IDs (AttrSourceInfo.id is None) and omit them when they match what auto_generated_id() would produce. Plan: claude-notes/plans/2026-02-10-suppress-auto-header-ids.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-02-11T15:07:48.060023Z","created_by":"cscheid","updated_at":"2026-02-11T16:05:08.293864Z","closed_at":"2026-02-11T16:05:08.293837Z","close_reason":"Implemented. Auto-generated header IDs are now suppressed in QMD writer output. All 6394 workspace tests pass.","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1uky","title":"New file templates from project _quarto-hub-templates directory","description":"Allow users to create new files from project-specific templates stored in _quarto-hub-templates directory. Templates are .qmd files with template-name metadata. The New File dialog shows a dropdown selector populated from available templates.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-12T20:19:14.894114Z","created_by":"cscheid","updated_at":"2026-02-12T20:19:14.894114Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1ul3","title":"Apply assert_filtered_subset drift helper to build_analysis_transform_pipeline","description":"Plan 1 (`claude-notes/plans/2026-05-04-q2-preview-plan-1-pipeline.md` §\"Resolved decisions / Drift-protection test\") originally promised a follow-up applying `assert_filtered_subset` to `build_analysis_transform_pipeline`. Scope has narrowed since that promise.\n\n## Background\n\nThe original drift helper (`assert_filtered_subset` in commit 60658a4e) was removed when q2-preview's pipeline was flipped to deny-list construction (`build_q2_preview_transform_pipeline` is now `build_transform_pipeline` filtered by `Q2_PREVIEW_TRANSFORM_EXCLUDED`; `build_q2_preview_pipeline_stages` is similarly built from the HTML stage list with `Q2_PREVIEW_STAGE_EXCLUDED`). The drift mode the helper guarded against is now impossible by construction for q2-preview.\n\n`build_analysis_transform_pipeline` (`crates/quarto-core/src/pipeline.rs:470`) is a different beast: a hand-written 6-transform sequence (sugar transforms + `crossref-index`) — *not* a deny-list of the full HTML transforms. Today it is protected only by:\n- the doc-comment at `pipeline.rs:454-469` (\"**Deliberately omitted**\" rationale),\n- a hand-rolled ordering test (`test_build_analysis_transform_pipeline_ordering`, `pipeline.rs:1392`) that asserts sparse position relations.\n\nBecause it's a hand-written allow-list (not a deny-list), the full HTML pipeline can grow new transforms relevant to outline analysis without anyone noticing — there's no test that fires when that happens.\n\n## Work\n\nThis issue is now exclusively about the analysis pipeline. Two paths:\n\n**Path A (cheaper)** — add a `seq_diff_eq` / `assert_seq_diff_eq` helper to the test module, expressing the analysis pipeline as `build_transform_pipeline` *minus* the exclusions documented at `pipeline.rs:454-469`. This treats the analysis pipeline as a deny-list at test time even though the runtime construction stays as an explicit allow-list.\n\n**Path B (more work, more upside)** — flip `build_analysis_transform_pipeline` itself to deny-list construction (mirroring what was just done to q2-preview), with `ANALYSIS_TRANSFORM_EXCLUDED` as a `const &[&str]`. The unknown-name validator pattern (see q2-preview tests in `pipeline.rs`) replaces the assertion. This makes drift impossible by construction.\n\nPath B is preferred if the analysis pipeline really does want to be defined relative to the HTML pipeline (today it skips render-shape transforms, which is an HTML-pipeline-relative concept). Path A is the right choice if there's reason to keep analysis as a hand-written allow-list (e.g. its 6-transform shape is small enough that listing them is clearer than subtracting from HTML's 30+).\n\nThe doc-comment at `pipeline.rs:454-469` enumerates the deliberate omissions; the exclusion-list candidates are derivable from it. Verify each name against actual `Transform::name()` strings — the unknown-name validator catches typos / renames.\n\n## Acceptance\n\nEither:\n- (Path A) New test in the `tests` module calls a deny-list-style assertion on `build_analysis_transform_pipeline`. Adding a new transform to `build_transform_pipeline` that isn't documented as either included or excluded in analysis trips the test.\n- (Path B) `build_analysis_transform_pipeline` rewritten as `build_transform_pipeline(...).retain_excluding(ANALYSIS_TRANSFORM_EXCLUDED)`. Existing `test_build_analysis_transform_pipeline_ordering` either becomes redundant (deny-list construction preserves order trivially) or stays for the cross-relation check. Unknown-name validator added.\n\n## Notes\n\nThe naming question — if Path A is chosen and a helper is added: `assert_seq_diff_eq` was discussed (sequence difference `A - B = C` is the formal operation). See conversation around the deny-list flip for the naming rationale.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-08T01:29:14.526011Z","created_by":"gordon","updated_at":"2026-05-09T17:46:11.628226Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1vlw8","title":"Implement quarto use brand scaffolding command","description":"Q1 has 'quarto use brand' at src/command/use/commands/brand.ts that scaffolds a _brand.yml. Q2's quarto-project-create crate is the analogous home. Low priority — manual editing works fine.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-21T02:31:31.081057Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.081057Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1wxq","title":"Diagnostic popups clipped by navbar when near top/bottom of editor","description":"Monaco diagnostic hover popups get clipped by the top navbar (and potentially the bottom edge) because the editor container uses overflow:hidden. When a diagnostic appears on a line near the top of the editor, the hover popup extends above the editor-main container and gets cut off. The fix should ensure the popup is shifted vertically to stay within visible bounds, rather than changing z-order.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-02-11T17:59:16.576579Z","created_by":"cscheid","updated_at":"2026-02-11T17:59:16.576579Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-1xf5","title":"hub-client WASM: implement dynamic tree-sitter grammar loading","description":"The native CLI render path supports user-supplied tree-sitter grammars\n(drop a .wasm + highlights.scm into _quarto/grammars//) via\ntree_sitter::WasmStore + wasmtime. The WASM/hub-client render path does\nnot, because wasmtime can't be embedded inside a wasm32-unknown-unknown\nbinary.\n\nDesign references (both checked in under claude-notes/research/):\n - syntax-highlighting-dynamic-grammars.md — outlines the browser-side\n approach: integrate web-tree-sitter via wasm-bindgen JS interop so\n the same .wasm grammar files load dynamically in the browser.\n - syntax-highlighting-wasm-compatibility.md — sibling audit confirming\n that tree-sitter-highlight itself compiles cleanly on\n wasm32-unknown-unknown (so bundling built-in grammars is fine; only\n dynamic user-grammar loading needs the JS-interop route).\n\nSurfaced while getting the Hub-Client E2E Tests workflow to run on CI\n(branch chore/e2e-ci). The smoke-all fixture\nhighlighting/03-user-grammar/03-user-grammar-toml.qmd passes in native\nCLI but fails in WASM (no TOML highlighting markup in rendered HTML).\nThe hub-client e2e workflow currently skips this fixture via\nSKIP_WASM_UNSUPPORTED in hub-client/e2e/helpers/smokeAllDiscovery.ts.","status":"tombstone","priority":3,"issue_type":"feature","created_at":"2026-05-11T01:01:44.327289Z","created_by":"gordon","updated_at":"2026-05-12T18:27:06.292263Z","close_reason":"Duplicate of bd-izfv (Phase 9 follow-up: thread user_grammars through RenderToHtmlRenderer). bd-izfv already has a worktree, plan doc, and code-path analysis at .worktrees/bd-izfv-thread-user-grammars/claude-notes/plans/2026-05-10-thread-user-grammars-renderer.md describing the exact same failure mode (project-render path drops user_grammars; fix site is the let _ = user_grammars at crates/wasm-quarto-hub-client/src/lib.rs:1443 and RenderContext construction at crates/quarto-core/src/project/pass2_renderer.rs:336). My earlier framing of bd-1xf5 was wrong: WASM does support user grammars on the single-file path; bd-izfv is the project-path threading gap.","source_repo":".","deleted_at":"2026-05-12T18:27:06.292256Z","deleted_by":"gordon","delete_reason":"delete","original_type":"feature","compaction_level":0,"original_size":0} +{"id":"bd-1xph","title":"Tree-sitter splits paragraph at line starting with * (emphasis or strong)","description":"Same class as bd-af1e. The scanner's line-break handler at scanner.c:2286-2291 and 2371-2376 excludes '*' from soft-line-break candidates whenever it appears at the start of a continuation line. But '*' only opens a block in specific contexts:\n- '* ' followed by space → list marker\n- '*** ' or longer with whitespace/eol → thematic break\n- otherwise → inline emphasis ('*emph*') or strong ('**strong**'), which should soft-break\n\nVerified pampa-vs-pandoc divergence:\n foo bar\n *emph* baz → pampa: 2 paragraphs, pandoc: 1 with SoftBreak + Emph\n **strong** baz → pampa: 2 paragraphs, pandoc: 1 with SoftBreak + Strong\n\nWhy this matters (severity sibling of bd-af1e): the asterisk IS the syntax for inline emphasis/strong. A user CANNOT work around the bug with backslash escaping (\\\\*emph\\\\* renders literally as '*emph*'). Underscore alternatives (_emph_, __strong__) work correctly already because '_' is not in the exclusion list, but many users prefer asterisks.\n\nBy contrast, '-', '+', '#', and digits at line start CAN be worked around via backslash escape (\\\\-text, \\\\#hashtag, \\\\123abc render as plain text starting with the punctuation), so we are deferring those.\n\nFix approach (same as bd-af1e — peek-count): when first_lookahead == '*', advance through consecutive asterisks. Then check what follows:\n- whitespace/eol after a single '*' → list marker (interrupt)\n- whitespace/eol after 3+ '*' → thematic break (interrupt) \n- anything else → inline (allow soft break)\n\nReference implementation: bd-af1e fix in scanner.c:2263-2308 (commit 274547af). The peek-without-mark_end + STATE_MATCHING-fallback pattern from that fix should generalize directly. See claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md.\n\nTest the fix doesn't break: '* item' (list opens), '*** ' (thematic break), '**foo**' at line start (inline strong), and '*foo*' / '**foo**' as continuation lines (soft break).","status":"closed","priority":1,"issue_type":"bug","assignee":"cscheid","created_at":"2026-04-30T18:45:50.725551Z","created_by":"cscheid","updated_at":"2026-04-30T18:56:04.698163Z","closed_at":"2026-04-30T18:56:04.698013Z","close_reason":"Fixed: extended bd-af1e peek-count pattern to '*' at line start. Single '*' followed by ws/eol → list marker (interrupt); >=3 '*' followed by ws/eol → thematic break (interrupt); otherwise inline emph/strong → soft break. Tree-sitter test 462/462 pass; workspace 8125/8125 pass; pampa output matches pandoc.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-1xph","depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:45:50.725551Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-205v6","title":"Flaky proptest: reconciliation_preserves_structure_full_ast","description":"On 2026-05-26, while running cargo xtask verify on the CoarsenedEntry self-contained refactor (commit pending on feature/provenance), the proptest property_tests::reconciliation_preserves_structure_full_ast in quarto-ast-reconcile failed with shrunken input cc 8f798bbfabf9a12269dc90aa13188f685afe8cbf6f4acb2da01f9bff1af93158. The failure was reproducible with the saved regression seed but did not reproduce with fresh seeds (re-running cargo nextest without the proptest-regressions/lib.txt file passed 9656/9656). Test passed against unmodified feature/provenance HEAD as well. Not caused by the pending refactor — the only code changes in that session are in pampa and quarto-error-reporting, neither of which is exercised by apply_reconciliation. The failing message: 'Result should be structurally equal to after' at crates/quarto-ast-reconcile/src/lib.rs:1242. Need to investigate: (1) regenerate the saved seed and inspect the AST shape; (2) determine whether the shape exposes a real apply_reconciliation bug or whether the structural_eq_blocks comparison has a false-negative; (3) commit the regression seed once the bug is fixed (or after determining it's expected behavior with an updated assertion).","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-26T12:01:51.810903Z","created_by":"gordon","updated_at":"2026-05-26T12:01:51.810903Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-217g","title":"Build headless sync testing infrastructure in quarto-sync-client","description":"Extend quarto-sync-client with a headless test harness for programmatic sync server testing. Should support: (1) creating projects against a sync server URL without a browser, (2) disconnect/reconnect cycles, (3) verifying document presence and content after reconnection, (4) starting/stopping hub and TS sync servers programmatically, (5) protocol-level tracing for debugging. This pays dividends for every future sync-related bug or feature. Plan: claude-notes/plans/2026-03-03-hub-sync-missing-docs.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-03T23:05:32.421813Z","created_by":"cscheid","updated_at":"2026-03-03T23:05:32.421813Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-217g","depends_on_id":"bd-33qc","type":"related","created_at":"2026-03-03T23:05:32.421813Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-21gu","title":"qmd writer: missing @ escape in link text causes citation re-parse","description":"From issue #150 (item 1): When a link text contains an escaped @ like `[\\@jjallaire](url)`, the qmd writer outputs the link text without re-escaping the @. Round-tripping turns the Str into a Cite. Repro:\n\n printf 'See [\\\\@jjallaire](https://github.com/jjallaire/) for details.\\n' | cargo run --bin pampa -- -t qmd\n See [@jjallaire](https://github.com/jjallaire/) for details.\n\nReporter notes there are likely other cases where escaping is needed; this is the one they saw. Plan in claude-notes/plans/ to follow.","notes":"Plan: claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md\nRoot cause: crates/pampa/src/writers/qmd.rs:1226 escape_markdown omits @\nFix: lookahead-based escape of @ when followed by alnum/_/{\nBug also reproduces outside link context (any Str starting with @).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T00:01:48.216570Z","created_by":"cscheid","updated_at":"2026-05-01T00:32:59.278601Z","closed_at":"2026-05-01T00:32:59.278440Z","close_reason":"Fixed in escape_markdown: always escape @ in Str bodies. Phase 2 audit of writer-escape gaps also identified { and } as same class; both fixed in this change. Position-dependent escapes (:, unbalanced ' \", line-start list markers 1./-/+) deferred to bd-kk0a. See claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-21q16","title":"Spike: explore contenteditable patterns for q2-preview Pandoc/Quarto React components","description":"Investigation/spike. Survey idiomatic React approaches for making text-bearing Pandoc/Quarto element components in ts-packages/preview-renderer (Str, Para, Header, Strong, etc.) editable via contenteditable. Initial scope: every element with text. Deliverable: a research note in claude-notes/research/ with 2-4 concrete approaches (with pros/cons), a small proof-of-concept on one approach, and a recommendation. Branch: feature/contenteditable-spike.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-22T05:53:04.231514Z","created_by":"gordon","updated_at":"2026-05-22T05:53:18.549583Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-233j","title":"Hub-Client E2E logs are flooded with YAMLWarning [TAG_RESOLVE_FAILED] !str","description":"Playwright e2e runs produce hundreds of warnings of the form:\n\n (node:NNNNN) [TAG_RESOLVE_FAILED] YAMLWarning: Unresolved tag: !str at line 14, column 12:\n - [!str \"
 tags is ApplyTemplateStage, which q2-preview already excludes. Net effect: on native q2-preview these stages register JS artifacts that nothing reads.\n\nQuestion: should Q2_PREVIEW_STAGE_EXCLUDED also list 'bootstrap-js' and 'clipboard-js'?\n\nFor exclusion:\n- Matches the WASM HTML pipeline.\n- Removes orphan artifact registration on native q2-preview.\n\nAgainst:\n- The deny-list framing at pipeline.rs:1170 says q2-preview opts a stage out only when there's a concrete reason. These stages are deterministic and harmless; the case for excluding them is tidiness, not correctness.\n- If a future non-iframe q2-preview renderer wants to consume those artifacts, the exclusion would have to be undone.\n\nContext: surfaced during Plan 3 (idempotence verification) review on 2026-05-20. Plan 3's hash test is unaffected either way — these stages don't write to the hashed surface — so this is filed separately rather than bundled into Plan 3.\n\nReferences:\n- crates/quarto-core/src/pipeline.rs:355 — Q2_PREVIEW_STAGE_EXCLUDED\n- crates/quarto-core/src/stage/stages/bootstrap_js.rs:48-55\n- crates/quarto-core/src/stage/stages/clipboard_js.rs:45\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-21T16:49:30.611239Z","created_by":"gordon","updated_at":"2026-05-21T16:49:30.611239Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-2c8rg","title":"D2: HTML table emits Bootstrap 'caption-top table' classes","description":"## What\n\nEvery `Block::Table` should have CSS classes `caption-top` and `table` in its rendered HTML output (matches Quarto 1 / Bootstrap convention).\n\n## Approach (chosen in plan)\n\nNew pipeline stage `HtmlTableClassTransform` in `crates/quarto-core/src/stage/stages/` that augments `Block::Table.attr.1` (class vec) with `caption-top` and `table` if missing. Stage runs only for HTML output formats; preserves round-trip qmd writer (writer does not see Quarto-added classes since classes are added post-AST sanitization for HTML output only).\n\nRationale for stage (vs writer hack): preserves separation of concerns — HTML writer renders what's in the AST; format-specific class augmentation happens in a stage. Mirrors TS Quarto's `quarto-bootstrap-table.lua` filter pattern.\n\n## Tests (TDD)\n\n1. Unit test on the transform: input table with no classes → output has `caption-top table`. Running transform twice doesn't duplicate (idempotent).\n2. Unit test: input table with existing `my-class` → output has `my-class caption-top table` (preserves user classes, dedupes).\n3. End-to-end render test against `tables.qmd` fixture → produced HTML contains ``.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D2 section)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-20T20:54:58.806604Z","created_by":"cscheid","updated_at":"2026-05-20T21:18:46.028499Z","closed_at":"2026-05-20T21:18:46.028305Z","close_reason":"Implemented in 987bdc9f via TableBootstrapClassTransform in FINALIZATION phase. Q1 markup parity for 
classes achieved (still needs Bootstrap CSS — D7).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2c8rg","depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:54:58.806604Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-2ercw","title":"whitespace_re regex recompiles per inline-processing call in native_visitor","description":"crates/pampa/src/pandoc/treesitter.rs:606 declares `let whitespace_re: Lazy = Lazy::new(|| Regex::new(r\"\\s+\").unwrap());` as a FUNCTION-LOCAL. The Lazy wrapper is pointless when local — a fresh Lazy is built (and \\s+ recompiled on first touch) on every call to this per-node inline-processing function.\n\nEvidence: samply profile of full q2 render of claude-notes/qmd-plans (565 files) attributes ~5% of ALL samples to the Thompson NFA compiler / Utf8State construction (regex::Regex::new), 100% under native_visitor's closure. See claude-notes/plans/2026-06-01-render-perf-profiling.md.\n\nFix: hoist to a module-level static (LazyLock or once_cell Lazy). Must land before any Pass-2 parallelization, otherwise every worker thread recompiles it per node.\n\nTDD: add a regression guard (e.g. a test/bench asserting the regex is shared / compiled once, or a micro-benchmark over the corpus). Verify end-to-end via q2 render wall-time before/after.","notes":"FIXED. Hoisted whitespace_re to module-level static WHITESPACE_RE in crates/pampa/src/pandoc/treesitter.rs. Added regression test test_whitespace_re_compile_once (asserts \\s+ compiles <=1x via WHITESPACE_RE_COMPILE_COUNT). Buggy compiled \\s+ 20806x over the 565-file corpus; fixed compiles 1x.\n\nPerf (median-of-5, release): isolated parse path -11.5% serial (2822->2496ms), -9.9% at 16 threads (391.6->352.7ms). End-to-end q2 render ~-24% (4720->3540ms) — render parses each file twice (Pass1 profile + Pass2 render) so the per-parse cost is paid 2x. Profile: regex-compile self-time 14.27%->0.02%, total CPU samples -17%.\n\nBonus finding: parse path parallelizes 7.1x on 16 threads with zero lock contention — confirms bd-3gj56 (parallelize Pass 2) is unblocked post-#247. Results in claude-notes/plans/2026-06-01-render-perf-profiling.md.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-06-01T14:45:03.449547Z","created_by":"cscheid","updated_at":"2026-06-01T15:13:56.742855Z","closed_at":"2026-06-01T15:13:56.742722Z","close_reason":"Hoisted whitespace_re to module static; regression test + perf-harness driver added; ~24% end-to-end render speedup, regex-compile self-time 14.3%->0.02%. Full cargo xtask verify green.","source_repo":".","compaction_level":0,"original_size":0,"labels":["perf"]} {"id":"bd-2gc9","title":"Nested tight lists incorrectly marked as loose (Para instead of Plain)","description":"In process_list() at crates/pampa/src/pandoc/treesitter.rs:183-192, multi-block list items with at least one paragraph are unconditionally marked as loose. This is wrong: a list item containing [Paragraph, BulletList] (e.g., '* foo\\n * bar') has no blank line between blocks and should remain tight. The CommonMark spec says a list is loose only when items are separated by blank lines or contain two block elements WITH A BLANK LINE between them.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-13T22:49:14.652871Z","created_by":"cscheid","updated_at":"2026-02-13T23:05:58.650439Z","closed_at":"2026-02-13T23:05:58.650417Z","close_reason":"Fixed: detect blank lines via tree-sitter block_continuation spans in process_list_item, propagate through IntermediateListItem","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2gkx","title":"Kanban: New card creation button with form","description":"Add a 'New Card' button that opens a form with: title (required), type dropdown (feature/milestone/bug/task), optional deadline with date picker, optional status. Default creation date to today. Extend addCard() in astHelpers.ts to support deadline and status. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-11T18:32:46.896753Z","created_by":"cscheid","updated_at":"2026-02-11T18:39:33.119846Z","closed_at":"2026-02-11T18:39:33.119829Z","close_reason":"Implemented - new card form with type, status, and deadline","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2h6x","title":"Slide thumbnails show in outline pane for non-slide documents","description":"The useSlideThumbnails hook runs unconditionally for all documents, generating thumbnails even for regular HTML documents. PreviewRouter detects format: q2-slides but doesn't communicate the format back to Editor.tsx. Fix: add onFormatChange callback from PreviewRouter so Editor can conditionally generate thumbnails. Plan: claude-notes/plans/2026-02-26-slide-thumbnails-conditional.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-26T15:04:39.650792Z","created_by":"cscheid","updated_at":"2026-02-26T15:10:26.512270Z","closed_at":"2026-02-26T15:10:26.512246Z","close_reason":"Fixed: slide thumbnails now conditional on format: q2-slides","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-2jwk","title":"Example Quarto 2 website projects for end-to-end feature testing","description":"Created 8 example Quarto 2 website projects under examples/websites/ that exercise each feature from the website epic (bd-0tr6). Each project demonstrates one aspect (sidebar manual/auto/nested, navbar+footer, shared site_libs/, site-metadata, incremental rebuilds, hub preview) with a README plus prose embedded in the qmd files. User-driven, not wired into CI. Plan: claude-notes/plans/2026-04-29-website-examples.md. Closed in commit 3629169b. Surfaced bd-swpy (closed by aa50d29e).","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid","updated_at":"2026-04-29T15:12:10.360266Z","closed_at":"2026-04-29T14:17:12.186716Z","close_reason":"All eight example projects built and verified end-to-end via 'q2 render' (08-hub-preview is a manual browser recipe). Surfaced bd-swpy (sidebar/navbar/footer href non-relativization in subdirectories). Plan: claude-notes/plans/2026-04-29-website-examples.md.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2jwk","depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-2jwk","depends_on_id":"bd-tr81","type":"related","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-2kt7f","title":"annotated-qmd: source-tracking off-by-one in regenerated examples","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-06-01T15:58:16.516338Z","created_by":"gordon","updated_at":"2026-06-01T15:58:39.818426Z","closed_at":"2026-06-01T15:58:39.818407Z","close_reason":"Duplicate of bd-1d6io","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2mxo","title":"Metadata materialization drops source_info provenance","description":"MergedConfig::materialize() in quarto-config/src/materialize.rs loses source provenance that pampa's YAML parser correctly provides:\n- Map container source_info replaced with heuristic/default (lines ~121-161)\n- Map entry key_source always set to SourceInfo::default() (line ~132)\n- Array container source_info uses only last item (lines ~109-113)\n\nScalar values are preserved correctly. Affects error reporting for any metadata-related diagnostics after the merge stage. The code has an explicit comment acknowledging the key_source loss: 'We lose key source info during materialization.'\n\nPre-existing since commit 955bc326 (2025-12-07, 'config merging in'). Not blocking Plan 0 but degrades the YAML frontmatter Concat piece in the QMD writer's SourceInfo output.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-20T15:52:16.644685Z","created_by":"gordon","updated_at":"2026-04-20T15:52:16.644685Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-2njja","title":"Upgrade @playwright/test to >=1.60.0 and drop the Node 24.15.0 pin","description":"The Hub-Client E2E workflow currently pins Node to 24.15.0 (PR #249) to dodge a yauzl extraction-hang regression in Node >=24.16 that hangs 'playwright install chromium' at 100% with Playwright <1.60. The CORRECT, durable fix is to upgrade @playwright/test from ^1.50.0 (locked 1.58.0) to >=1.60.0, which contains the upstream fix (microsoft/playwright#40747, issue #40724) and is compatible with Node 24.16+/26.\n\nScope:\n- Bump @playwright/test to ^1.60.0 in hub-client/package.json; refresh package-lock.json.\n- Remove the 'node-version: 24.15.0' pin in .github/workflows/hub-client-e2e.yml (restore to '24' and delete the explanatory comment).\n- Chromium goes 145 -> 148 (1.59=147), so the pixel-comparison VISUAL-REGRESSION baselines will shift. Regenerate them via the workflow_dispatch 'recreate-all-snapshots' path (baselines must be generated on the Linux runner, not locally) and review the snapshot diffs per the CLAUDE.md snapshot-review rules.\n- Verify a full green e2e run (functional + visual) before merge.\n\nRefs: PR #249 (interim pin), microsoft/playwright#40724 / #40747.","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-01T15:37:57.663402Z","created_by":"gordon","updated_at":"2026-06-01T15:37:57.663402Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2olu","title":"Hub MCP Server: automerge project access for AI agents","description":"Design and implement an MCP server that allows AI coding agents (Claude Code, Codex, etc.) to read and write files in Quarto Hub projects via automerge sync, without requiring filesystem access. Plan: claude-notes/plans/2026-03-13-hub-mcp-server-design.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-03-13T23:38:33.161278Z","created_by":"cscheid","updated_at":"2026-03-13T23:38:33.161278Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-2qjnd","title":"Listing config: parse_sort scalar arm should accept PandocInlines via as_plain_text","description":"Q2's listing parse_sort (crates/quarto-core/src/project/listing/config.rs:692) has inconsistent handling between its scalar and array arms:\n\n- Scalar arm matches only ConfigValueKind::Scalar(Yaml::String(s)) — fails on PandocInlines.\n- Array arm uses .as_plain_text() — handles PandocInlines fine.\n\nRepro: in a listing block, write 'sort: code' (unquoted). Q2 metadata parsing turns it into PandocInlines('code'), parse_sort falls through to the _ arm, and emits Q-12-3 'sort: must be a string, array of strings, or false'. Workaround: 'sort: [code]' uses the array path and works.\n\nFix: change line 695 from 'ConfigValueKind::Scalar(Yaml::String(s)) => vec![parse_one_sort_key(s)]' to use 'value.as_plain_text()' like the array branch.\n\nDiscovered while authoring docs/errors/index.qmd as part of bd-nvlxn (error-docs foundation, parent bd-94x8a). The workaround in that file should be removed once this is fixed.\n\nRelated: sort-ui only accepts boolean in Q2 (line 452); Q1's 'list of allowed sort fields' form is not implemented. That's a separate feature gap, not this bug.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-22T19:15:20.730868Z","created_by":"cscheid","updated_at":"2026-05-22T19:15:20.730868Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","listing"],"dependencies":[{"issue_id":"bd-2qjnd","depends_on_id":"bd-nvlxn","type":"discovered-from","created_at":"2026-05-22T19:15:20.730868Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-2quy","title":"[websites] Audit Stage<->RenderContext bridge completeness","description":"During Phase 2, AstTransformsStage was missing 'project_index' in its StageContext->RenderContext bridge, silently disabling the sidebar Render-step .qmd->.html rewrite. Integration tests caught it; unit tests (which built their own RenderContext) did not. Audit the bridge code to verify every field that exists on both sides is transferred correctly — and consider structural guards (e.g. a test that compares field sets, or a derive-style helper to replace manual field-by-field copying).","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T17:52:49.777311Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:49.777311Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2quy","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:49.777311Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-2rbk","title":"Improve pampa test skip behavior when Pandoc is absent","description":"4 pampa tests hard-assert instead of gracefully skipping when Pandoc is not available. Should use test skip or conditional compilation so cargo xtask test runs cleanly without Pandoc. Low priority since pampa is currently excluded from Windows test compilation due to v8.","status":"open","priority":3,"issue_type":"task","created_at":"2026-03-20T13:36:13.451656600Z","created_by":"cderv","updated_at":"2026-03-20T13:36:13.451656600Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-2rv8","title":"Hub-client console debug API (window.quartoDebug for read/write/rerender)","description":"Enabler ticket. Add a window-global debug API to hub-client so an agent (or developer) can read/write project files and trigger renders from the DevTools console without going through the menu UI.\n\nSketched surface:\n window.quartoDebug = {\n project: () => ProjectInfo,\n listFiles: () => string[],\n readFile: (path: string) => string,\n writeFile: (path: string, contents: string) => Promise,\n rerender: () => Promise,\n getActiveFile: () => string,\n setActiveFile: (path: string) => void,\n lastRenderResponse: () => unknown,\n vfsList: (prefix?: string) => string[],\n vfsRead: (path: string) => Uint8Array | null,\n };\n\nConstraints:\n- writeFile goes through the same Automerge mutation path the editor uses, so sync is exercised.\n- Dev-only by default (import.meta.env.DEV) with an opt-in escape hatch for prod debugging — see Q5 in plan.\n- Don't bypass auth / project ownership.\n- Confirmed greenfield: no existing window.* assignments in hub-client/src/.\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Enabler section). Suggested to land first since it speeds up debugging the other three children.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-01T13:58:38.836884Z","created_by":"cscheid","updated_at":"2026-05-01T13:58:38.836884Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2rv8","depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:38.836884Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-2s6j","title":"Kanban: Horizontal rows instead of columns","description":"Change the board layout from vertical status columns to horizontal rows. Each status group becomes a full-width row with cards flowing left-to-right. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-11T18:32:33.985420Z","created_by":"cscheid","updated_at":"2026-02-11T18:34:29.136267Z","closed_at":"2026-02-11T18:34:29.136249Z","close_reason":"Implemented - board now uses horizontal rows","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2t4o","title":"Incremental QMD writer for localized AST-to-string updates","description":"Design and implement an incremental writer for pampa that converts localized AST changes into localized string edits. When an AST node changes, only the corresponding portion of the QMD string should be rewritten, preserving the rest of the original source text. Key challenge: markdown's indentation-sensitive constructs (block quotes, lists) mean inner node source spans are non-contiguous, requiring a 'loosened incrementality' approach.","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-07T18:27:04.058233Z","created_by":"cscheid","updated_at":"2026-02-07T18:27:04.058233Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2t4o","depends_on_id":"bd-3lsb","type":"discovered-from","created_at":"2026-02-07T18:27:04.058233Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-2vl0","title":"L9 follow-up: Q-12-15 dedup (per-project, not per-host)","description":"v1 emits Q-12-15 once per ListingFeedStageTransform invocation (= once per host page that has feeds configured + missing site-url). For a project with N feed-configured hosts, the user sees N Q-12-15 warnings. Consolidate to once per project — track an already_warned: bool on a project-scoped state, or dedupe via ctx.diagnostics post-hoc.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:33:37.197930Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:37.197930Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-2vl0","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:37.197930Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-2w80","title":"Investigate CSL manifest test failure after rebase","description":"quarto-citeproc::csl_conformance::csl_validate_manifest fails. Was previously resolved as stale artifact but reappeared after rebasing windows-and-improvement on main. May be a lockfile mismatch that needs regeneration or a genuine regression from main.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-03-20T13:36:09.944920300Z","created_by":"cderv","updated_at":"2026-03-20T13:36:09.944920300Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-2x4l","title":"Kanban demo app (hub + incremental writer)","description":"Minimal Kanban-style project tool backed by QMD files, demonstrating bidirectional editing via React components + incremental writer. Each card = level-2 header + body. React provides views (board, milestones) while the document stays human-readable. Plan: claude-notes/plans/2026-02-10-kanban-demo.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-10T20:54:43.438414Z","created_by":"cscheid","updated_at":"2026-02-10T20:54:43.438414Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["demo","hub"]} {"id":"bd-31lk","title":"Div transforms (definition-list, list-table) not applied to JSON input","description":"The transform_definition_list_div and transform_list_table_div transforms are applied in postprocess() which is only called from the qmd reader path. When the input format is json, the code bypasses postprocess() and these transforms are never applied. This means divs with 'definition-list' or 'list-table' classes are not converted to their proper AST representations when processing JSON input.\n\nPlan: claude-notes/plans/2026-02-05-div-transforms-json-input.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-05T14:54:35.844209Z","created_by":"cscheid","updated_at":"2026-02-05T21:16:48.523250Z","closed_at":"2026-02-05T21:16:48.523226Z","close_reason":"Fixed: Added transform_divs() function and applied it in the JSON reader. Tests added and passing.","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-33qc","title":"Hub sync server loses documents on project creation","description":"When using the hub binary as a standalone automerge sync server, newly created projects lose some automerge documents on reconnection. Creating a project in hub-client and then reconnecting shows missing file documents. This does not happen with the TypeScript automerge-repo-sync-server. Likely root cause: samod Repo::create() returns before storage I/O completes, and there is no flush/drain API to wait for pending writes. Plan: claude-notes/plans/2026-03-03-hub-sync-missing-docs.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-03-03T23:05:26.668905Z","created_by":"cscheid","updated_at":"2026-03-03T23:05:26.668905Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-34wy","title":"Phase 2: Fork runtimelib and add venv-aware kernelspec discovery","description":"Fork runtimed/runtimelib to cscheid/runtimelib at the v2.0.0 tag. Add data_dirs_with_jupyter_paths() that augments data_dirs() with paths from ask_jupyter() (jupyter --paths --json). Add list_kernelspecs_with_jupyter_paths() and update find_kernelspec to use it. Extend RuntimeError::KernelNotFound with searched_paths: Vec. Match upstream conventions (cfg-gating, thiserror style, tests parallel to test_list_kernelspec_jsons).\n\nTDD per CLAUDE.md: failing test first for each behaviour.\n\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 2)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T15:49:47.470140Z","created_by":"cscheid","updated_at":"2026-05-04T16:08:33.192757Z","closed_at":"2026-05-04T16:08:33.192617Z","close_reason":"Fork branch feat/venv-kernelspec-discovery in cscheid/runtimed at commit 6647651. Added data_dirs_with_jupyter_paths(), list_kernelspecs_with_jupyter_paths(), find_kernelspec_with_jupyter_paths(), extended RuntimeError::KernelNotFound with searched_paths: Vec. 18 tests pass (10 baseline + 8 new). cargo fmt --check and cargo clippy -- -D warnings clean. Branch not pushed yet (per CLAUDE.md no-push policy).","source_repo":".","compaction_level":0,"original_size":0,"labels":["feature","jupyter"],"dependencies":[{"issue_id":"bd-34wy","depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:47.470140Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-352bh","title":"q2 preview diagnostics overlay: include ariadne source-context snippet (bd-b9kzg follow-up)","description":"Today's PreviewDiagnosticsOverlay shows the compact one-line summary for each warning (Line N: [code] title - problem). User asks for the rich ariadne-rendered source-context snippet (matching hub-client's overlay screenshot) so the preview surface looks like the q2 render stdout output.\n\nPath: DiagnosticMessage::to_text(Some(&source_context)) produces the snippet today (see ParseError::render in crates/quarto-core/src/error.rs:32-38). Pass-1 failures already flow through to the overlay via failure.error → result.error → overlay
. Warnings don't carry a rendered text yet — the JsonDiagnostic transport shape (lifted into quarto-error-reporting/src/json.rs under bd-b9kzg) doesn't have a field for it.\n\nScope:\n(1) Add rendered: Option to JsonDiagnostic and populate in diagnostic_to_json by calling diag.to_text(Some(ctx)).\n(2) Mirror the field on the TS Diagnostic interface.\n(3) Update PreviewDiagnosticsOverlay to render rendered as a 
 (with stripAnsi) when present, keeping the compact list as fallback for diagnostics without locations / source context.\n(4) End-to-end verify against docs/ — the [Q-13-4] body-link warning should look like the user's q2 render stdout output, with the ╭─[ ... ]─╯ box around the offending line.\n\nPlan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-ariadne.md (to be drafted).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid","updated_at":"2026-05-21T19:04:06.677144Z","closed_at":"2026-05-21T19:04:06.676974Z","close_reason":"Implemented: ariadne source-context snippets now render in the q2-preview overlay, matching the user's reference image and q2 render stdout output. Added rendered: Option to JsonDiagnostic (populated server-side via diag.to_text(Some(ctx))), mirrored on TS Diagnostic interface, branched PreviewDiagnosticsOverlay to render 
{stripAnsi(d.rendered)} for located diagnostics with the compact line as fallback. End-to-end verified against docs/ for both [Q-13-4] body-link and [Q-1-20] metadata-as-markdown warnings. cargo xtask verify 12/12 green. Merged to main as commit 2911db60. Plan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-ariadne.md","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-352bh","depends_on_id":"bd-b9kzg","type":"discovered-from","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-352bh","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-36fr9","title":"Provenance follow-up: Dispatch anchor for Lua-handler filter & shortcode","description":"Extends the provenance-epic AnchorRole enum with `Dispatch`, used to point at Lua source for filter-kind and Lua-handler-shortcode-kind Generated nodes.\n\n**Today (Plan 4 baseline):**\n- filter:    Generated { by: filter{filter_path, line}, from: [] }  -- path/line in by.data\n- shortcode (Lua handler): Generated { by: shortcode{name, lua_path, lua_line}, from: [Invocation -> token_si] }\n\n**After this issue:**\n- filter:    Generated { by: filter{}, from: [Dispatch -> lua_si] }\n- shortcode (Lua handler): Generated { by: shortcode{name}, from: [Invocation -> token_si, Dispatch -> lua_si] }\n\nThe writer (Plan 7) keeps consulting invocation_anchor() only; Dispatch is diagnostic-only (\"which Lua handler resolved this\").\n\n**Blocker:** requires registering Lua filter files in SourceContext so they get FileIds. Touches:\n- Lua engine (mlua bridge)\n- SourceContext (file registry / interning)\n- Diagnostic machinery (reconcile with existing per-Lua-file diagnostics)\n- Cache-key surface (Lua files become cache input)\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-4-source-info-types.md §\"Deferred anchor role\"\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §\"Dispatch follow-up\"\n\n**Compatibility:** pure addition. AnchorRole gains Dispatch; by.data shrinks for filter/Lua-shortcode kinds. Anchor list shape unchanged.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T22:36:48.538531Z","created_by":"gordon","updated_at":"2026-05-21T22:36:48.538531Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["follow-up","provenance"]}
+{"id":"bd-399t","title":"Docs callout: L7 listings preview is CLI-only (engine-rendered)","description":"When the user-facing docs site under `docs/` becomes a real published site, add a callout to the listings reference page documenting L7's bracketing-rule-3 behavior:\n\n> Engine-rendered previews are available in `quarto render` only. In interactive environments, listings show static-AST previews — set `description:` and `image:` explicitly if you need a specific preview to appear during preview.\n\nWording is locked in the L7 plan (`claude-notes/plans/2026-05-07-listings-L7-postrender-upgrade.md` §D13) and the listings epic plan (`claude-notes/plans/2026-05-05-listings-epic.md` §L7 §\"Bracketing rules\" rule 3). The future docs work copies it verbatim.\n\nFiled at L7 close-out per the L7 plan §\"Filing reminder\" follow-up #6.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-07T19:51:23.473994Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:23.473994Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-399t","depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:23.473994Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-3a0o","title":"Surface a diagnostic for unresolved nav-dependency declarations","description":"Decision 12 says: 'A nav-dependency that does not resolve to a project document emits a diagnostic warning at graph-build time and is dropped.' The graph builder today silently drops the edge (see crates/quarto-core/src/project/dependency_graph.rs:155-167 comment). compute_augmented_render_set passes a graph_diags Vec but does not propagate it. Wire it through summary.project_diagnostics and add an integration test that asserts the warning appears. Test 57 currently verifies render-proceeds half only.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:56.192415Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3a0o","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-3a0o","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-3aga","title":"Hub: optional local project watching (standalone sync server mode)","description":"Make local project watching optional so hub can run as a standalone sync server without a local Quarto project. The hub binary should default to no local project (sync-only), while quarto hub should default to watching the current project. Plan: claude-notes/plans/2026-03-03-hub-no-local-watch.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-03-03T17:17:34.628633Z","created_by":"cscheid","updated_at":"2026-03-03T17:36:24.629683Z","closed_at":"2026-03-03T17:36:24.629667Z","close_reason":"Implemented: StorageManager::new_standalone(), optional project_root, CLI flags (--project/--no-project/--data-dir), all tests passing (6502/6502)","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3aolj","title":"AttrSourceInfo: duplicate-key handling breaks positional alignment with Attr.2","description":"When the qmd parser sees an attribute list with a duplicate key like {foo=1 foo=2}, the construction loop in crates/pampa/src/pandoc/treesitter_utils/commonmark_attribute.rs:41-49 calls:\n\n- attr.2.insert(key, value) -- LinkedHashMap::insert on a duplicate key UPDATES the existing entry in place without growing the map.\n- attr_source.attributes.push(...) -- always appends.\n\nAfter processing {foo=1 foo=2}, attr.2.len() == 1 but attr_source.attributes.len() == 2. The positional alignment AttrSourceInfo.attributes[i] = (key_src, val_src) for the i-th entry in Attr.2 is broken.\n\n**Discovered while reviewing Plan 6's theorem.rs::extract_name_attr fix** (claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet), which indexes attr_source.attributes by the position of name in attr.2. Plan 6 mitigates with a runtime length-check guard and falls back to SourceInfo::default() when alignment is broken — but the underlying bug pre-dates Plan 6 and affects any future caller that relies on the invariant.\n\n**Fix options:**\n1. On duplicate keys, also overwrite attr_source.attributes[existing_idx] instead of pushing a new entry. Preserves alignment; loses the first key's source location (consistent with LinkedHashMap's value-overwrite behavior).\n2. Reject duplicate keys at parse time with a diagnostic. More invasive; changes user-facing behavior.\n3. Change attr.2 to allow duplicate keys (Vec<(String, String)>). Largest change; affects every consumer of Attr.\n\nOption 1 is the minimum-blast-radius fix; Plan 6's guard handles the symptom either way.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet (positional-alignment safeguards)\n- crates/quarto-pandoc-types/src/attr.rs:27-32 (AttrSourceInfo definition)","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-22T06:44:43.151226Z","created_by":"gordon","updated_at":"2026-05-22T06:44:43.151226Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","provenance"]}
+{"id":"bd-3az78","title":"refactor canonicalize_within_project to take Option<&SourceInfo>","description":"Plan 7f Phase 6.5 follow-up. Today's signature requires a SourceInfo, forcing Engine/Lua-filter resource-entry resolution (crates/quarto-core/src/project_resources.rs:541) to pass a sentinel `By::unknown()` value because those entries genuinely have no YAML source location. The receiver only uses the source location for diagnostic-span rendering, which already degrades gracefully. Refactoring the signature to `Option<&SourceInfo>` removes the sentinel from the call site and lets the receiver decide explicitly how to handle `None` for span-less diagnostics.","status":"open","priority":3,"issue_type":"task","created_at":"2026-06-01T18:26:14.218956Z","created_by":"gordon","updated_at":"2026-06-01T18:26:14.218956Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3az78","depends_on_id":"bd-1ngyy","type":"discovered-from","created_at":"2026-06-01T18:26:14.218956Z","created_by":"gordon","metadata":"{}","thread_id":""}]}
 {"id":"bd-3c6e","title":"Pipeline execution tracing","description":"Add ability to trace and inspect the state of the rendering pipeline at each step. Extend PipelineObserver with data-bearing callbacks, implement concrete trace observers (summary, JSON), add CLI/YAML/env activation. Plan: claude-notes/plans/2026-04-13-pipeline-tracing.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-13T20:37:52.537535Z","created_by":"cscheid","updated_at":"2026-04-13T21:18:02.143957Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3c6e","depends_on_id":"bd-ft03","type":"blocks","created_at":"2026-04-13T21:18:02.143227Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-3cus","title":"Pre-fill new file dialog with current file's directory path","description":"When opening the new file dialog via the '+ New' button, pre-fill the filename field with the directory path of the currently active file. For example, if the user is editing 'docs/chapter1.qmd', the filename field should show 'docs/' so they only need to type the new filename. Files at the root level should not pre-fill anything.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-02-04T17:04:35.946556Z","created_by":"cscheid","updated_at":"2026-02-04T17:06:06.266467Z","closed_at":"2026-02-04T17:06:06.266419Z","close_reason":"Implemented: handleNewFile in Editor.tsx now extracts directory prefix from currentFile.path and passes it as initialFilename to NewFileDialog","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3day","title":"customRegistry accumulator bug in ast-renderer-entry.tsx loses earlier-loaded user TSX exports","description":"In hub-client/src/ast-renderer-entry.tsx:72, the loadCustomComponents loop does: customRegistry = { ...componentRegistry, ...module } — overwriting customRegistry with the static componentRegistry plus only the current module's exports. Each iteration loses earlier modules' contributions. Should be: customRegistry = { ...customRegistry, ...module }. Affects multi-file render-components configurations where users split overrides across simple.tsx + html.tsx + comment.tsx etc. — only the last-loaded file's exports survive. The render_components.qmd docs describe the intended behavior correctly. q2-preview's entry (Plan 2A) will mirror the pattern but fix this bug; this issue tracks back-porting the fix to q2-debug.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T21:39:36.019777Z","created_by":"gordon","updated_at":"2026-05-08T19:39:59.708377Z","closed_at":"2026-05-08T19:39:59.708358Z","close_reason":"Fixed in 1e5a930f on branch bugfix/react-components-not-loading (q2-debug back-port of the customRegistry accumulator fix)","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3f1z9","title":"Preview navbar brand link points to artifacts VFS root and dead-ends iframe","description":"Bug placeholder","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:07:30.585480Z","created_by":"cscheid","updated_at":"2026-05-20T14:07:49.477814Z","closed_at":"2026-05-20T14:07:49.477621Z","close_reason":"Duplicate of bd-ql55q (first create attempt was a fallback placeholder)","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3f1z9","depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-20T14:07:30.585480Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-3flm","title":"Make cargo xtask verify match CI checks","description":"cargo xtask verify passes locally but CI fails because verify doesn't set RUSTFLAGS=\"-D warnings\", doesn't run custom lints, and doesn't run tree-sitter grammar tests. See plan: claude-notes/plans/2026-03-09-xtask-verify-ci-parity.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-03-09T17:05:42.756553Z","created_by":"cscheid","updated_at":"2026-03-09T17:19:16.101527Z","closed_at":"2026-03-09T17:19:16.101508Z","close_reason":"All work items complete: removed unused trim_prefix_suffix feature, added -D warnings/lint/tree-sitter steps to xtask verify","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3fwnh","title":"q2-preview SPA boot fails: samod findDoc(indexDocId) times out at 5s","description":"**Reproducer:**\n1. `cargo build --bin q2`\n2. `./target/debug/q2 preview .qmd`\n3. Open the printed URL in a browser.\n4. SPA displays \"Initializing q2-preview\" for ~5 seconds, then PreviewDiagnosticsOverlay shows:\n   `Document automerge: is unavailable`\n5. Boot state goes to `'error'` so the rendered content never appears.\n\nReproduces with any fixture (verified with callouts-matrix.qmd and basic-render.qmd, different doc ids each time). Hard refresh + restart of the server do not help.\n\n**Investigation so far:**\n\n- `/health` correctly returns the fresh `index_document_id` matching the one the SPA later tries to subscribe to (verified with curl).\n- HTTP-level WS upgrade succeeds (`curl -H \"Upgrade: websocket\" /ws` returns 101 Switching Protocols with a valid Sec-WebSocket-Accept).\n- The 5-second timeout in PreviewApp.tsx:505 (`connect(wsUrl, indexDocId, undefined, undefined, undefined, 5000)`) is firing on every cold load. The comment at lines 500-504 acknowledges this race was already mitigated once.\n- onError handler at PreviewApp.tsx:494-497 sets `boot: 'error'`, so the SPA shows the error screen instead of the rendered content.\n\n**Likely layer:** the samod protocol exchange ON TOP of the WS — peer announcement / sync messages aren't flowing within the 5s budget. Stack on this branch:\n- Server: Rust `samod = 0.9.0` (quarto-dev/samod q2 branch) in quarto-hub.\n- Client: JS `@automerge/automerge-repo@2.5.1` + `@quarto/quarto-sync-client` (workspace package).\n\n**History:** commit 2541f228 (\"Fix race condition in automerge sync causing document unavailable errors\") fixed an earlier instance by adding `waitForPeer()`. The 5s extra timeout in PreviewApp was the second mitigation. The race is still winning at boot on at least one developer's machine consistently.\n\n**Discovered during:** Phase 6 verification of the callout class-vocabulary fix\n(claude-notes/plans/2026-05-22-callout-class-vocabulary-fix.md). Unrelated to\nthat work — callout HTML render path verifies fine through\n`cargo run --bin q2 -- render `.\n\n**Possible next steps:**\n- Add samod-protocol-level logging on both sides during the first 5s of a fresh q2 preview session to see what messages (if any) traverse the WS after the upgrade.\n- Check whether samod 0.9.0 vs automerge-repo 2.5.1 have a protocol-version mismatch.\n- Try clearing IndexedDB on the SPA origin — might rule out any client-side storage layer interaction.\n- Bisect commits to wasm-quarto-hub-client / quarto-hub / quarto-preview / samod-related files in the past 3 weeks.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-26T12:38:32.512565Z","created_by":"gordon","updated_at":"2026-05-26T12:38:32.512565Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3gej","title":"Fix TOCTOU race in JupyterDaemon::get_or_start_session","description":"**Location:** `crates/quarto-core/src/engine/jupyter/daemon.rs:74-85`\n\n**Race:** `get_or_start_session` reads `self.sessions` under a read lock, drops the lock, then calls `start_kernel(&key).await?` (which takes the write lock at lines 197-199 and inserts). Between the two lock acquisitions, a second concurrent caller for the same `(kernel_name, working_dir)` key can pass the same `contains_key` check and also enter `start_kernel`. The second `start_kernel` overwrites the first's entry in the sessions map, leaking a kernel subprocess (the first kernel's handle is dropped without shutdown).\n\n**Mitigation today:** the render pipeline runs single-threaded (`pollster::block_on`, `?Send` async), so no two callers race in practice.\n\n**When it surfaces:** as soon as parallelism is added — `rayon`-per-worker is foreshadowed in `crates/quarto-core/src/project/orchestrator.rs` docstrings (\"a future rayon + pollster-per-worker parallelism path\"). Also surfaces under any future async runtime that schedules tasks across threads.\n\n**Fix sketch:** acquire the write lock first, re-check `contains_key` under the write lock, and either return the cached session or insert a placeholder before calling `start_kernel`. The standard \\\"upgrade and re-check\\\" pattern, equivalent to `entry().or_insert_with(...)`.\n\n**Discovered:** during the TS engine extensions plan-review session on 2026-04-28. The TS engine work explicitly chose a different concurrency strategy (harness-side idempotency on repeat \\`LoadEngine\\`/\\`LaunchEngine\\`) precisely so it wouldn't inherit this pattern. See claude-notes/plans/2026-04-16-plan1a-protocol-and-core.md \\\"Race-free init via harness idempotency\\\" and the corresponding section in claude-notes/plans/2026-04-16-plan1b-engine-host-deno.md.\n\n**Related:** lines 244-260 and 263-270 in the same file have the same shape but each takes the write lock atomically, so they are not racy. Only `get_or_start_session` at lines 74-85 needs fixing.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-05T13:48:20.303702Z","created_by":"gordon","updated_at":"2026-05-05T13:48:20.303702Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3gj56","title":"Parallelize Pass-2 render loop (orchestrator.rs) with rayon","description":"Pass 2 (qmd->HTML render-to-file) is a serial for-loop at crates/quarto-core/src/project/orchestrator.rs:1013, awaiting each page sequentially on the main thread. It is ~98% of full-project render wall time (Pass 1 is already parallel: perf.pass1 docs=565 threads_used=16 wall_ms=19).\n\nEvidence: samply profile of q2 render of claude-notes/qmd-plans — main q2 thread holds 93% of samples, 16 quarto-pass1 workers idle (6.9% combined). See claude-notes/plans/2026-06-01-render-perf-profiling.md.\n\nThe locale-lock that previously blocked MT scaling (bd-b7eb7) is FIXED by PR #247 (verified: lock waits dropped 77% -> 0.65% in the profile). Parallelism is now unblocked.\n\nInfrastructure already laid for this: pass2_renderer.rs:73 names 'a future rayon-per-worker parallelism path', the Pass2Renderer trait is ?Send, per-render args are Arc-wrapped. Main obstacle: the &mut self.project_artifacts accumulator (each page drains project-scoped artifacts into it) — needs per-worker accumulators merged at end. Must preserve deterministic output ordering and fail-fast semantics. Land bd-2ercw (regex recompile fix) first.","notes":"IMPLEMENTED (pending full verify + commit). Approach: Pass2Renderer::render_batch trait method, default serial (WASM/tests untouched, no Send bounds); RenderToFileRenderer overrides with rayon fan-out. Refined per-worker -> PER-DOCUMENT artifact stores merged in doc order = exact serial parity for conflict attribution. ProjectPipeline::with_jobs(n) for test-pinned parallelism; worker_count() shared with Pass 1 (QUARTO_JOBS, cap 16). perf.pass2 gauge added.\n\nResults (qmd-plans 565 files, release, median-of-5): end-to-end 3650ms(j=1) -> 500ms(j=16) = 7.3x; Pass-2 itself 3551 -> 446ms (~8x). Byte-equivalence: diff -r of serial vs 16-thread _site IDENTICAL (571 files). Tests: pass_two_preserves_input_order, pass_two_parallel_matches_serial (byte-exact), pass_two_parallel_renders_all_pages; deliberate-break sanity confirmed order guard bites. All 2163 quarto-core tests pass. Plan: claude-notes/plans/2026-06-01-parallelize-pass-two.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-06-01T14:45:12.317267Z","created_by":"cscheid","updated_at":"2026-06-01T16:40:40.581728Z","closed_at":"2026-06-01T16:40:40.581595Z","close_reason":"Pass-2 parallelized via rayon (render_batch trait method, native override, per-doc artifact stores merged in doc order). 7.3x end-to-end / ~8x Pass-2 on 16 threads; serial vs parallel _site byte-identical (571 files). 3 correctness tests + deliberate-break sanity; full cargo xtask verify green. Deferred (optional follow-up): a deterministic Pass-2-failure fixture for fail-fast/panic-isolation tests — hard to construct (parse errors fail in Pass 1); the AtomicBool/catch_unwind logic mirrors Pass 1's tested pattern.","source_repo":".","compaction_level":0,"original_size":0,"labels":["perf"],"dependencies":[{"issue_id":"bd-3gj56","depends_on_id":"bd-2ercw","type":"blocks","created_at":"2026-06-01T14:45:12.317267Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-3gtn","title":"WASM artifact flush overwrites user uploads with empty bytes for resource images","description":"**Discovered during**: q2-preview Plan 2A review (2026-05-07).\n\n## The bug\n\n`crates/wasm-quarto-hub-client/src/lib.rs:1208-1214` (single-doc render path) and `:1364-1369` (project render path) loop over `ctx.artifacts` and write each artifact's content to VFS:\n\n```rust\nfor (_key, artifact) in ctx.artifacts.iter() {\n    if let Some(artifact_path) = &artifact.path {\n        let vfs_path = resolver.on_disk_path_for(artifact.scope, artifact_path);\n        runtime.add_file(&vfs_path, artifact.content.clone());\n    }\n}\n```\n\nThere is no guard against empty content. `ResourceCollectorTransform` (in `crates/quarto-core/src/transforms/resource_collector.rs:65-71`) produces artifact entries via `Artifact::from_path(...)`, which sets `content: Vec::new()` (`crates/quarto-core/src/artifact.rs:108-116`). The artifact's `path` field is `base_dir.join(url)` — typically absolute in WASM context.\n\n`Path::join` semantics: an absolute second argument replaces the first. So `vfs_root.join(\"/project/hero.png\")` collapses to `/project/hero.png`, which is also where `automergeSync` (in `hub-client/src/services/automergeSync.ts:84,87`) wrote the user's image bytes via `vfsAddFile` / `vfsAddBinaryFile`.\n\n**Result**: the flush overwrites the user's upload with empty bytes on every render that references the image.\n\n## How it surfaces\n\nToday, in HTML preview, embedded images may appear broken on second-and-subsequent renders. Hasn't been widely reported — possibly because users don't often embed local images, or because path semantics in some cases avoid the collision (the bug is conditional on whether `ctx.document.input` is absolute or relative; both occur depending on how JS calls the WASM entry).\n\nFor q2-preview (Plan 2A), the iframe rewriter explicitly relies on the user's upload bytes being present. Without the fix, q2-preview renders with embedded images would produce empty data: URIs after the first render.\n\n## Fix\n\nAdd an `is_empty()` guard to both flush loops:\n\n```rust\nfor (_key, artifact) in ctx.artifacts.iter() {\n    if let Some(artifact_path) = &artifact.path {\n        if !artifact.content.is_empty() {\n            let vfs_path = resolver.on_disk_path_for(artifact.scope, artifact_path);\n            runtime.add_file(&vfs_path, artifact.content.clone());\n        }\n    }\n}\n```\n\nThis preserves manifest semantics for `ResourceCollectorTransform` (the entries still exist in `ctx.artifacts` for downstream consumers like `ResourceReportStage`) while preventing the overwrite. Theme CSS / icon CSS / fonts (which use `Artifact::from_bytes` with real content) keep flushing correctly.\n\n## Tests\n\n- Strengthen the website-fixture test in `crates/quarto-core/tests/render_page_in_project.rs::website_q2_preview_renders_through_orchestrator`: pre-populate VFS at the user's expected upload path with non-empty bytes, run the render, assert bytes are unchanged. (Today's test asserts only that the manifest entry exists.)\n- Add a similar regression test for `RenderToHtmlRenderer` if not already present.\n\n## Plan references\n\n- Plan 2A §\"Risk areas → Empty-content artifact overwrite (latent bug discovered during plan review)\" — `claude-notes/plans/2026-05-04-q2-preview-plan-2a-iframe-foundation.md`\n- Plan 1 §\"Multi-plan contract: page-scoped image artifacts\" — `claude-notes/plans/2026-05-04-q2-preview-plan-1-pipeline.md`\n- Plan 1 §Test plan, \"Website fixture with embedded image\" — references this issue for the deferred 6th assertion (bytes survive render).","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T13:14:56.576599Z","created_by":"gordon","updated_at":"2026-05-10T07:15:15.347294Z","closed_at":"2026-05-10T07:15:15.347266Z","close_reason":"Fixed in c8a684bd on feature/q2-preview: empty-content guard added to both WASM flush loops. Test in assetManifestProject.wasm.test.ts walks through bug-then-fix with binary upload BEFORE render in its natural lifecycle.","source_repo":".","compaction_level":0,"original_size":0,"labels":["q2-preview"]}
+{"id":"bd-3izo3","title":"Plan 7 Phase 8 e2e: Playwright matrix for incremental-write round-trips","description":"Deferred from the Plan 7 session that landed Phases 4-7 + the WASM-level wrapper test. The Rust-side soft-drop matrix is already covered in crates/pampa/src/writers/incremental.rs; this ticket tracks the *delivery* coverage at the browser surface.\n\nScenarios (one Playwright spec each):\n\nHub-client (e2e/):\n- Sectionized doc + edit one paragraph round-trip (section structure preserved in saved qmd)\n- Single-inline shortcode + edit different paragraph (shortcode preserved verbatim)\n- Multi-inline shortcode + edit different paragraph in same Para (shortcode appears once via dedupe)\n- Edit resolved shortcode title → Q-3-42 surfaced + doc byte-equal to no-op\n- Edit inside synthesized footnotes container → Q-3-43 surfaced + container regenerates\n\nSPA (q2-preview-spa/e2e/):\n- Project + edit paragraph round-trip\n- Single-file mode (bd-tnm3k path) + edit paragraph round-trip\n- Edit shortcode → Q-3-42 surfaces in DiagnosticStrip\n- Mixed atomic + non-atomic edit → non-atomic applies, atomic preserved\n- Content-match echo-prevention: induce echo loop (write → samod echo → fnv1aHex match in lastEmittedRef), assert exactly one render bumps __renderTicks after the edit; assert an interleaved unrelated file still re-renders\n\nEach spec needs a tempdir fixture + spawned hub/preview server; the existing hub-client e2e/ and q2-preview-spa/e2e/ infra (helpers/previewServer.ts pattern) is the model.\n\nRun gate: cargo xtask verify --e2e (currently optional in CI, not blocking). Should stay --e2e-gated to avoid taxing every PR.\n\nReferences:\n- Plan 7: claude-notes/plans/2026-05-04-q2-preview-plan-7-incremental-writer.md §Phase 8\n- Phase 7 commit: f050a7c6 (SPA setAst + echo-prevention + DiagnosticStrip)\n- Phase 4-6 commit: 9da9f14a","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-25T02:47:02.597860Z","created_by":"gordon","updated_at":"2026-05-25T20:12:51.817654Z","source_repo":".","compaction_level":0,"original_size":0}
 {"id":"bd-3lsb","title":"AST-level sync client API for quarto-sync-client","description":"Add onASTChanged/updateFileAst API pair to quarto-sync-client. Phase 1: dependency-injected parser/writer with new WASM exports (parse_qmd_content, ast_to_qmd). Phase 2: incremental write using quarto-ast-reconcile for localized string splicing. Plan: claude-notes/plans/2026-02-06-ast-sync-client-api.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-02-06T19:53:57.108941Z","created_by":"cscheid","updated_at":"2026-02-06T20:27:53.885293Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3mgb","title":"Reader rejects valid 4-space-indented list-item continuations as a parse error (issue #196)","description":"Regression from PR #194 (closes #184, Q-2-35). The new `INDENTED_CODE_BLOCK_DISALLOWED` external token in `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c` (line 2128) fires on list-item continuation lines whose preceding blank line carries >= 4 columns of trailing whitespace (4+ spaces or a tab). The result is a generic 'Parse error' (the (state, sym) pair at the recovery point isn't in the Q-2-35 friendly-error table) where the previous behaviour produced an OrderedList AST with two Para children.\n\nTrigger threshold is exactly 4 columns on the blank line. 2 trailing spaces still parses; 4 spaces or 1 tab does not. Independent of list marker kind (ordered, bullet) and continuation content kind (image, plain text).\n\nIn the wild: three real-world occurrences in quarto-dev/quarto-web (see triage doc for links).\n\nTriage: .worktrees/issue-196/claude-notes/issue-reports/196/triage.md\nWorktree branch: issue-196\nUpstream: https://github.com/quarto-dev/q2/issues/196\n\nFix should land in the scanner — either reset `s->indentation` on the BLANK_LINE_START path, or tighten the gate to skip list-item continuation contexts. See triage doc § 'Where the fix should land' for angles, and add a tree-sitter corpus regression alongside a positive Q-2-35 case to confirm the original PR's diagnostic still fires on real top-level indented blocks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-14T23:25:54.801581Z","created_by":"cscheid","updated_at":"2026-05-14T23:47:56.453256Z","closed_at":"2026-05-14T23:47:56.453081Z","close_reason":"Fixed in 85d12789 on issue-196: gate Q-2-35 detector with !(BLOCK_CONTINUATION && open_blocks > 0). Tree-sitter 483/483, workspace 8863/8863, all four Q-2-35 positives still fire, repro + three real-world quarto-web files parse cleanly.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3mgb","depends_on_id":"bd-7l1u","type":"discovered-from","created_at":"2026-05-14T23:25:54.801581Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-3n80","title":"Document hub-client features in docs/quarto-hub","description":"Create user-facing documentation for the hub-client prototype in the docs directory. Should cover core features: file management, live preview, themes, templates, project creation, and collaboration.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-12T21:14:38.273555Z","created_by":"cscheid","updated_at":"2026-02-12T21:20:39.282688Z","closed_at":"2026-02-12T21:20:39.282677Z","close_reason":"Documentation complete: created 7 pages covering overview, files, preview, themes, templates, projects, and collaboration","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3nzyd","title":"Hub-Client E2E: smoke-all preview-iframe tests fail (401 + peer-connection timeout) in CI","description":"Surfaced once the Playwright install hang was unblocked (PR #249 / bd-2njja pin). The Hub-Client E2E suite now RUNS to completion for the first time since ~2026-05-27, and reveals pre-existing failures in e2e/smoke-all.spec.ts (NOT caused by the Node pin, which only affects browser install).\n\nRun 26764975242 result: 84 passed, 2 failed, 6 flaky.\n\nHard failures (fail after 2 retries):\n- extensions/builtin-placeholder-shortcode/test.qmd [html]\n- q2-preview/multi-element-project/index.qmd [q2-preview]\n\nFlaky (passed on retry): builtin-lipsum-shortcode [html], highlighting/05-theme-none [html], includes/basic [html], metadata/appendix-style-inheritance/doc-override-default [html], q2-preview/body-container-full-layout, q2-preview/body-container-minimal.\n\nSignature: waitForPreviewRender (hub-client/e2e/helpers/previewExtraction.ts:87) throws 'Timed out after 75000ms waiting for preview iframe to render', with console error 'Failed to load resource: the server responded with a status of 401 (Unauthorized)'. Throughout the run, repeated 'Peer connection failed, creating project in offline mode: Error: Timeout waiting for peer connection'.\n\nHypothesis: in the CI e2e environment the preview iframe cannot auth/connect to the hub peer/sync (401 + peer-connection timeout), so it never renders within 75s. Likely a hub auth/signaling or globalSetup wiring issue in CI, or a genuine regression on main masked since the install started hanging. Needs investigation with the uploaded Playwright trace/video artifacts (playwright-report artifact on the run).\n\nNOTE: this is the real blocker to a green Hub-Client E2E once the install hang is resolved.","design":"CHOSEN FIX: Tier 2 (deterministic readiness gate) -- keeps the full Automerge sync path end-to-end, just stops the test racing it. Rejected Tier 1 (seed content locally) because it would bypass the very integration smoke-all exists to exercise.\n\nExact race confirmed by code read: seedProjectInBrowser -> projectStorage.addProject writes IDB ONLY. The seed reaches the SYNCED project set only via reconcileIntoConnectedProjectSet, which the app runs in a useProjectSet effect keyed on the status->connected TRANSITION (useProjectSet.ts:90) and which requires projectSetService.isConnected(). Because the test seeds AFTER bootstrapProjectSet already reached connected, that effect does not re-fire, so the seed lands in the set only if a fortuitous WS reconnect re-triggers reconcile -> flaky, and worker-count-independent (confirmed: workers:1 did not help).\n\nImplemented in PR #249:\n- hub-client/src/test-hooks.ts: expose the live projectSetService singleton (projectSet) + reconcileIntoConnectedProjectSet (reconcileProjectSet) on window.__quartoTest.\n- hub-client/e2e/helpers/testHooks.ts: matching QuartoTestHooks types.\n- hub-client/e2e/helpers/projectFactory.ts seedProjectInBrowser: after addProject, (1) wait up to 30s for projectSet.isConnected(), (2) call reconcileProjectSet() (idempotent) and wait until projectSet.getProject(indexDocId) is defined, before returning. Bounded waits fail loudly if the sync server is truly unreachable.\n- workers reverted to 2 (parallelism was never the cause).\n\nFOLLOW-UP (product, separate): the app arguably should reconcile IDB->set on IDB change, not only on the status transition -- so a project added while already-connected appears without a reconnect. Out of scope for the test fix.","notes":"VERIFIED: Tier-2 readiness gate landed in PR #249 -> CI run 26772812401 GREEN (78 passed / 14 flaky / 0 failed functional, 6 visual passed, ~13m, workers:2). The gate eliminated the hard failures (project-set seed/sync race) AND kept parallelism (workers reverted to 2; workers:1 had not helped).\n\nRESIDUAL (keep this bead open): 14 tests still pass-on-retry ('flaky'), up from ~6. Since 0 hard-failed, the gate never threw -- so the residual is in the TEST BODY (75s waitForPreviewRender occasionally needing a retry), most likely the project's FILE doc sync during render (a different doc than the project-SET seed race fixed here). Within the 2-retry budget so the run is green, but worth hardening: extend a similar 'await synced' gate to the project file docs before asserting render, or raise/justify the render wait. Plus the product follow-up: app should reconcile IDB->set on IDB change, not only on the status transition.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-06-01T15:56:36.919507Z","created_by":"gordon","updated_at":"2026-06-01T18:28:10.309750Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3odjm","title":"Plan 3: q2-preview orchestrator emits AST JSON that fails to round-trip through pampa::readers::json::read for lipsum content (MalformedSourceInfoPool)","description":"Surfaced by Plan 3's idempotence gate (`crates/quarto-core/tests/idempotence.rs::lua_shortcode_lipsum_fixed`). Reproduce:\n\n  cargo nextest run -p quarto-core --test idempotence lua_shortcode_lipsum_fixed\n\nThe `SingleFile` `DriveMode` passes — the fixture is genuinely idempotent at the pipeline level. The `ProjectOrchestrator` mode panics inside `run_orchestrator`:\n\n  re-parse AST JSON from orchestrator: MalformedSourceInfoPool\n\ni.e. the JSON the orchestrator emitted via `Pass2Payload::AstJson` (writer config `include_inline_locations: true`) is not parseable back by `pampa::readers::json::read`. This is a JSON-writer/reader round-trip bug, not a transform-determinism finding.\n\n**Root cause (confirmed 2026-05-21).** Type-code `3` mismatch between writer and reader in the `sourceInfoPool` wire format:\n\n- Writer (`crates/pampa/src/writers/json.rs:115,180-182`) emits `FilterProvenance` as type code `3` with `d = [filter_path: string, line: number]`.\n- Reader (`crates/pampa/src/readers/json.rs:252-283`) still treats code `3` as the long-removed `Transformed` variant and parses `d[0].as_u64()` for a parent_id. On the lipsum fixture `d[0]` is the `filter_path` string → `as_u64()` returns None → `MalformedSourceInfoPool`.\n\nLipsum trips this because the lipsum Lua shortcode synthesizes inlines whose `SourceInfo` is `SourceInfo::FilterProvenance { filter_path, line }` (via `crates/pampa/src/lua/diagnostics.rs`). Every other Phase 3/4a fixture's content is `Original` / `Substring` / `Concat` (codes 0/1/2), so they round-trip fine. The lipsum fixture is the first one in Plan 3's gate whose pipeline emits a `FilterProvenance` SourceInfo across the AST-JSON boundary.\n\n**Fix-owner: Plan 5 (`claude-notes/plans/2026-05-04-q2-preview-plan-5-wire-format.md`).** Plan 5 already covers exactly this bug as part of the wire-format extension for `Generated { by, from }` (Plan 4's typed-provenance variant; the anchor list field is named `from`, holding `SmallVec<[Anchor; 2]>`). Plan 5 retires `FilterProvenance`, adds wire code `4` for `Generated`, and makes the reader's code-`3` branch dispatch on `d[0]`'s JSON type:\n- numeric `[parent_id, ...]` → legacy Substring approximation (back-compat),\n- string-headed `[filter_path, line]` → `Generated { by: By::filter(...), from: smallvec![] }` (the latent FilterProvenance path).\n\nPer the long-lived-branch policy in Plan 3 §\\\"Phase 5 — Failure triage\\\", this issue stays open until Plan 5 lands. Do not fix locally on `feature/provenance`; close as duplicate when Plan 5's PR merges.\n\nThis blocks closing `lua_shortcode_lipsum_fixed` in the Plan 3 gate but does not block the other Phase 4 work.\n\nRefs:\n- claude-notes/plans/2026-05-04-q2-preview-plan-5-wire-format.md (fix-owner; §Goal calls this bug out by name)\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md (§\\\"Phase 5 — Failure triage\\\", §\\\"CI failure policy & sub-agent prompt template\\\")\n- branch: feature/provenance","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:00:50.016470Z","created_by":"gordon","updated_at":"2026-05-22T06:16:45.311056Z","closed_at":"2026-05-22T06:16:45.311028Z","close_reason":"Fixed in Plan 5 Phase 1 (commit d7b8450a on feature/provenance): the JSON reader's code-3 arm now dispatches on data[0]'s JSON type — numeric-headed legacy Transformed → Substring (back-compat); string-headed [filter_path, line] → Generated { by: filter, from: [] } (recovers the latent FilterProvenance shape). lua_shortcode_lipsum_fixed now passes; full Plan-3 idempotence suite is 27/27 green.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3odjm","depends_on_id":"bd-c3qe6","type":"discovered-from","created_at":"2026-05-21T21:00:50.016470Z","created_by":"gordon","metadata":"{}","thread_id":""}]}
 {"id":"bd-3oh3","title":"Create pure-automerge TypeScript reproduction for samod NotFound bug","description":"Create a minimal TypeScript reproduction of the samod-core NotFound bug that uses only automerge packages (automerge-repo, automerge-repo-network-websocket) with no quarto-specific dependencies. The reproduction should: (1) start a samod server, (2) create multiple automerge documents in quick succession via WebSocket, (3) disconnect, (4) reconnect with a fresh client, (5) verify all documents are available. This will be contributed upstream to help the samod author understand and verify the fix.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-03-04T13:57:08.965101Z","created_by":"cscheid","updated_at":"2026-03-04T14:34:31.202387Z","closed_at":"2026-03-04T14:34:31.202357Z","close_reason":"Created standalone reproduction at ts-packages/samod-repro/ with README, minimal Rust server, and pure-automerge TypeScript test. Verified fails without fix, passes with fix.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3oh3","depends_on_id":"bd-33qc","type":"discovered-from","created_at":"2026-03-04T13:57:41.028354Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-3okv","title":"Kanban: drag-and-drop status changes and hide redundant status dropdown","description":"In the kanban BoardView, status is shown redundantly: as a dropdown on each card AND as the section/row the card appears in. Replace the dropdown with drag-and-drop between status sections so the card's position IS the status indicator.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-12T15:04:14.134059Z","created_by":"cscheid","updated_at":"2026-02-13T22:42:33.520046Z","closed_at":"2026-02-13T22:42:33.520006Z","close_reason":"Implemented drag-and-drop status changes with @dnd-kit. Status dropdown hidden in BoardView, kept in CardDetailView. All tests pass.","source_repo":".","compaction_level":0,"original_size":0}
 {"id":"bd-3pe8","title":"Audit pampa production Lua code for Windows path escaping","description":"Tests needed to_forward_slashes for Lua string embedding but production code may have the same exposure. quarto-cli uses pathWithForwardSlashes in production when passing paths to Lua filters and metadata. Investigate whether pampa production code passes Windows paths into Lua string contexts. If so, to_forward_slashes should become a regular dependency (not dev-only) and the fix should be in the Lua runtime layer, not just tests.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-03-31T10:00:02.835216600Z","created_by":"cderv","updated_at":"2026-03-31T10:52:56.425993900Z","closed_at":"2026-03-31T10:52:56.425578300Z","close_reason":"Audited production Lua code in filter.rs: all path passing uses Lua C API (globals().set, load().set_name), never string interpolation into Lua source. lua.load(format!()) only exists in #[cfg(test)] modules. Production code is safe — the fix in test code was the correct approach.","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3sa5","title":"L9 follow-up: HTML-aware truncation in extract_first_para_html","description":"v1 of feed/reader_ext.rs::extract_first_para_html degrades to plain text when truncation under max_length is required, because scraper is read-only and DOM mutation isn't available. Q1 walks the DOM and clones with truncated text nodes, preserving tag structure. To match Q1, switch to an html5ever-based serializer or use scraper + custom node walker that produces a tag-balanced subset. Subscribers who hit a truncation see plain text instead of formatted text in v1 — workable but lower-fidelity than the underlying HTML.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:34:09.570667Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:09.570667Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-3sa5","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:09.570667Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-3so8f","title":"Upgrade @playwright/test to >=1.60.0 and drop the Node 24.15.0 pin","description":"See PR #249. Upgrade Playwright to >=1.60.0 (fixes the Node>=24.16 yauzl extraction hang), drop the Node pin, regenerate Chromium-148 visual baselines.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T15:37:57.921476Z","created_by":"gordon","updated_at":"2026-06-01T15:38:13.737933Z","closed_at":"2026-06-01T15:38:13.737912Z","close_reason":"Duplicate of bd-2njja (created in error by a shell fallback)","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-3y7ul","title":"CI on main broken: Instant::now() panics on WASM in pass_one","description":"After bd-m7x9s (Parallelize Pass-1 via rayon, 665bbb34), CI is failing on origin/main. hub-client wasm tests (assetManifestProject, themeFingerprint, customNodeWireFormatProject) panic with 'PanicError: time not implemented on this platform' from `std::time::Instant::now()` in `ProjectPipeline::pass_one` (orchestrator.rs:847). The Instant::now() and the subsequent .elapsed() feed the `perf.pass1` gauge, but they always run — not gated for WASM.\n\nFix: route monotonic-clock access through SystemRuntime with a WASM shim using `performance.now()`. Add `monotonic_now_nanos() -> u64` to the trait; native default uses a process-start Instant; WasmRuntime overrides with js_sys/performance.\n\nFailing run: https://github.com/quarto-dev/q2/actions/runs/26310309964/job/77457143629","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-05-22T21:03:37.847050Z","created_by":"cscheid","updated_at":"2026-05-22T21:16:17.323985Z","closed_at":"2026-05-22T21:16:17.323861Z","close_reason":"Fixed: SystemRuntime::monotonic_now_nanos shim (performance.now on WASM) + pass_one_dispatch_async to avoid pollster::block_on on WASM. Native + WASM tests green, full cargo xtask verify passes.","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-45yw","title":"Replay engine: deterministic in-Rust engine for tests","description":"From the bd-o8pr Phase 2 work session: writing E2E tests for engine-emitted resources (and other engine-channel features) requires either real R/Python/jupyter installs or a custom test injection point. Both are heavy.\n\nIdea: build a 'replay engine' that can reproduce the behavior of any existing engine but runs entirely in Rust. Records a real engine's transcript (markdown output, supporting_files, includes, …) into a fixture; replays deterministically without the engine runtime. Useful for:\n\n- CI tests that exercise engine paths without R/Python\n- Reproducing flaky engine bugs by capturing the real engine's output once\n- Fixture-driven testing of engine-channel features (resources, filters, ExecuteResult fields)\n- Especially valuable for Jupyter where custom kernels are common and impossible to test against\n\nDiscovered while writing tests for project resources (bd-o8pr). Filed for next session.\n\nReferences:\n- crates/quarto-core/src/engine/registry.rs (where it would register)\n- crates/quarto-core/src/engine/{markdown,knitr,jupyter}/* (existing engine impls to model)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-03T19:53:55.859078Z","created_by":"cscheid","updated_at":"2026-05-03T23:12:57.481440Z","closed_at":"2026-05-03T23:12:57.481252Z","close_reason":"Implemented; merged in 78c23573","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-45yw","depends_on_id":"bd-o8pr","type":"discovered-from","created_at":"2026-05-03T19:53:55.859078Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-469o","title":"Process: end-to-end verification before declaring features complete","description":"Track rollout of the end-to-end-verification convention introduced 2026-04-20 after the CodeHighlightStage-in-CLI-render-path incident. Plan doc: claude-notes/plans/2026-04-20-end-to-end-verification-process.md. Related: bd-n7x2 (syntax-highlighting design). Remaining work: audit other pipeline-builder branches for similar test-coverage gaps; explore a test helper that drives render_document_to_file against fixtures so CLI-visible features are verified against the file-on-disk contract, not just the in-memory RenderOutput.","status":"open","priority":1,"issue_type":"task","created_at":"2026-04-20T14:30:41.602217Z","created_by":"cscheid","updated_at":"2026-04-20T14:30:49.599840Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-469o","depends_on_id":"bd-n7x2","type":"discovered-from","created_at":"2026-04-20T14:30:49.599025Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
-{"id":"bd-66nd","title":"CI disk-space cleanup: profile.ci + drop redundant cargo build","description":"Test-suite workflow hits 'No space left on device' on ubuntu-latest during cargo nextest run despite the existing free-disk-space step (run 25062065055 on PR #139, freed 18.8 GB but not enough). Add [profile.ci] Cargo profile to strip debuginfo, remove redundant cargo build step before nextest, enable remove_tool_cache: true on free-disk-space, and prune Docker images. Full rationale in claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md. Implemented on branch ci-disk-space-profile-ci (4 commits, not yet pushed).","status":"open","priority":1,"issue_type":"chore","created_at":"2026-04-28T17:17:54.174452300Z","created_by":"cderv","updated_at":"2026-04-28T17:42:11.670015900Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-47w7o","title":"Support directory resources (recursive copy) in YAML resources:","description":"When a YAML 'resources:' entry resolves to a directory on disk (e.g. quarto-web's '/docs/blog/posts/2024-07-02-beautiful-tables-in-typst/demo'), the literal-path branch of expand_one returns it as a single PathBuf; copy_resources_to_output_dir then fails with 'the source path is neither a regular file nor a symlink to a regular file'.\n\nTS Quarto behavior (confirmed at external-sources/quarto-cli/src/core/path.ts:269-278): a literal path that resolves to an existing directory is rewritten to the recursive glob 'dir/**/*'. Q2 should match.\n\nPlan: claude-notes/plans/2026-05-21-resource-directory-recursive-copy.md\n\nDiscovered while landing bd-wlza2. Next blocker for rendering quarto-web end-to-end.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:39:29.468318Z","created_by":"cscheid","updated_at":"2026-05-21T21:52:47.700591Z","closed_at":"2026-05-21T21:52:47.700426Z","close_reason":"Literal directory resources now recursively expand to dir/**/* via expand_glob_files helper. 6 new tests added (4 failed pre-fix). e2e on quarto-web: demo/ directory copied 70/70 files; next blocker is theme dark-mode parsing (bd-0pic6, filed discovered-from).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-47w7o","depends_on_id":"bd-wlza2","type":"discovered-from","created_at":"2026-05-21T21:39:29.468318Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-49ar","title":"[websites] Sidebar collapse/expand JS","description":"Ship the interactive JS for sidebar section collapse/expand. Phase 2 emits structurally-correct Bootstrap markup (data-bs-toggle=\"collapse\", data-bs-target, aria-expanded) but the actual JS lives in Phase 5 (site_libs/). Blocked by Phase 5 scoped artifact store work.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-24T17:52:27.387148Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:27.387148Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-49ar","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:27.387148Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-4ciw","title":"Investigate tree-sitter ':' handling in line-break: definition list / fenced div edge cases","description":"Sibling of bd-af1e/bd-wv4e investigation. The line-break handler also excludes ':' as a paragraph interrupter. ':' has more entangled semantics in qmd:\n- Definition list term/definition (':' at start of line after a paragraph defines a definition list).\n- Fenced div marker (qmd-specific, ':::' or more).\n- Plain text otherwise.\n\nVerify whether ':something' (single colon then content) at line start is correctly soft-broken. Initial pampa output appeared to error on the test fixture; needs investigation.\n\nReference fix pattern: bd-af1e (claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-30T18:40:25.424566Z","created_by":"cscheid","updated_at":"2026-04-30T18:45:29.712291Z","closed_at":"2026-04-30T18:45:29.712148Z","close_reason":"Re-scoped: ':' has backslash-escape workaround (\\:foo). Not severe enough to fix in this pass.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-4ciw","depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:40:25.424566Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-4eyf","title":"Bootstrap JS runtime injection for HTML output","description":"Auto-include Bootstrap 5 JS (bundle, with Popper) for HTML renders that use a Bootstrap-backed theme, mirroring Quarto 1's behavior but via q2's artifact-store pipeline.\n\nPlan: claude-notes/plans/2026-05-04-bootstrap-js-injection.md\n\nScope:\n- Vendor bootstrap.bundle.min.js (5.3.1, ~80KB, includes Popper) under resources/js/bootstrap/.\n- Add BootstrapJsStage in crates/quarto-core/src/stage/stages/, run after CompileThemeCssStage.\n- Predicate: !is_minimal_html(meta) — same condition that triggers Bootstrap CSS compilation.\n- Register js:bootstrap as Project-scoped artifact; ApplyTemplateStage emits the ') at end of body (C1). Serialize back to QMD; return as ExecuteResult { markdown, ..Default }.\n- **Add a source-code comment** at the RawBlock-emission site pointing at bd-mqk49: 'when engines can declare per-format AST passes, route this through a format-conditional transform instead of emitting HTML inline. Today Quarto 2 only renders HTML so the format-locked emission is acceptable.'\n- Register in native + WASM EngineRegistry.\n\nTests: unit (engine on fixture) + pipeline (full HTML render) + end-to-end per CLAUDE.md verification policy (cargo run --bin q2 -- render fixture.qmd; grep output; record in plan).\n\nThe B2c/B2e (dedicated HTML-emit stage / engine-declared per-format pass) path was rejected for the first ship — Quarto 2 is HTML-only today, so format-agnostic decomposition would be hypothetical correctness against a future cost. The follow-up lives on bd-mqk49.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","notes":"Topic branch: beads/bd-gwfdo-implement-mermaidengine-b1-direct (commit 93418945). Working tree clean. cargo nextest run --workspace passes (9496 tests). End-to-end verified via cargo run --bin q2 -- render. cargo xtask verify --skip-hub-build in flight (background).","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-28T13:45:14.944001Z","created_by":"cscheid","updated_at":"2026-05-28T17:36:29.529560Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-gwfdo","depends_on_id":"bd-c6h96","type":"blocks","created_at":"2026-05-28T13:45:35.978499Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-gwfdo","depends_on_id":"bd-fztki","type":"blocks","created_at":"2026-05-28T13:45:36.396009Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-gwfdo","depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:14.944001Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-gz6k","title":"Cargo: upgrade sha1 v0.10.6 → v0.11.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.10.6 is range-pinned in workspace; latest is 0.11.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.170269Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.941246Z","closed_at":"2026-05-04T20:30:44.941104Z","close_reason":"merged: 0812812e","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-gz6k","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.443720Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-h4l6","title":"[websites phase 5] Scoped artifact store and site_libs/ dedup","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 5.\n\nDeliverables:\n- Add scope (Page | Project) to artifact entries in ArtifactStore.\n- Project-aware artifact writer: Project-scoped artifacts emitted once to _site/site_libs/{name}/...\n- Relocator: rewrite per-page HTML to point at shared site_libs/ paths correctly (handles subdirs, offset computation).\n- Migrate theme CSS, Bootstrap, quarto-nav JS, etc. to Project scope when inside a website project.\n- Preservation: single-doc renders unchanged (both scopes resolve under {stem}_files/).\n- Sequence the change in two steps: (a) pure refactor introducing scope with identical behavior, (b) switch websites to use Project scope.\n\nBlocked by Phase 1.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:43:08.936956Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.479325Z","closed_at":"2026-04-29T00:31:30.479019Z","close_reason":"Phase 5 (scoped artifact store + site_libs) implemented (commit dc4e81b0). Closed as part of Phase 9 cleanup.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-h4l6","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:08.936956Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-h4l6","depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:44.336998Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
 {"id":"bd-h5l7","title":"Diagnose and fix SourceInfo::eq hotspot in hub-client preview","description":"Chrome profile of hub-client on a moderately-sized document shows a large hotspot on ::eq, entered from parse_qmd_to_ast (crates/wasm-quarto-hub-client/src/lib.rs:757). Likely cause: SourceInfoSerializer::intern in crates/pampa/src/writers/json.rs:229 linearly scans content_map (Vec<(SourceInfo, usize)>) on every pointer-lookup miss, and SourceInfo is held by-value in AST nodes so pointer lookups almost always miss — giving O(n²) behavior per document. Also the first perf-profiling session on Quarto 2, so the plan deliberately establishes a repeatable native-side workflow (Criterion bench + samply flamegraph on the pampa binary) before any fix, since Chrome-side before/after is too noisy to iterate on. Plan: claude-notes/plans/2026-04-22-sourceinfo-eq-hotspot.md. Currently in draft — awaiting user review before any measurement work begins.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-22T20:00:48.019984Z","created_by":"cscheid","updated_at":"2026-04-22T23:23:38.315697Z","closed_at":"2026-04-22T23:23:38.315082Z","close_reason":"Landed on perf/2026-04-22-json-sourcemap in commit 8f6f21d9. Browser cross-validation confirmed SourceInfo::eq no longer a hotspot.","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-h736","title":"Default project render regression and project-level diagnostics","description":"Post-websites-merge: presence of `_quarto.yml` with `project: { type: default }` causes `q2 render` to silently produce zero output, and `q2 render index.qmd` to fail with a misleading 'excluded from render list' error. Root cause: `default_output_dir` returns the project root for default projects, so the discovery walker's output_dir-exclusion check rejects every file. Three goals: (1) fix the discovery regression so default projects walk the tree like websites do; (2) add a clear project-level diagnostic when the render set is empty so we no longer silently no-op; (3) add a project-level diagnostic surface that both the CLI and hub-client can render, since today only file-level diagnostics flow to hub-client. Plan: claude-notes/plans/2026-05-01-default-project-render-diagnostics.md (open design questions inside, awaiting user input before implementation starts).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T21:40:15.795872Z","created_by":"cscheid","updated_at":"2026-05-01T22:08:43.216214Z","closed_at":"2026-05-01T22:08:43.216070Z","close_reason":"Fixed default-project discovery regression (output_dir == project_dir) and added Q-PROJECT-EMPTY project-level diagnostic with non-zero exit. Plumbing reuses existing ProjectRenderSummary.project_diagnostics infrastructure, so hub-client surfaces the diagnostic via the existing warnings array. End-to-end verified against the user's fixture in claude-notes/plans/2026-05-01-default-project-render-diagnostics.md. Commits: dd959bdd (Phase 1: discovery fix + tests), fd06b8da (Phase 2: empty-set diagnostic + CLI exit policy).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-h736","depends_on_id":"bd-0tr6","type":"discovered-from","created_at":"2026-05-01T21:40:15.795872Z","created_by":"cscheid","metadata":"{}","thread_id":""}]}
+{"id":"bd-hb8h","title":"Design: cargo-dependency-upgrade skill for periodic dependency maintenance","description":"Design and implement an on-demand /upgrade-cargo-deps skill for periodic (bi-weekly) Rust dependency maintenance. Design settled 2026-05-04: skill-only (no scheduling); applies patch/minor upgrades automatically in a worktree, surfaces major upgrades for human judgment via plan doc + per-major beads issues; runs full 'cargo xtask verify' after applying; uses only built-in cargo tooling (cargo update, cargo tree --duplicates); npm equivalent deferred to v2. See claude-notes/plans/2026-05-04-cargo-dependency-upgrade-skill.md for full design and work items.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-04T15:49:18.455915Z","created_by":"cscheid","updated_at":"2026-05-04T16:19:43.493917Z","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-hfjj","title":"Hub-client decomposition: shared preview-pane package for hub-client + q2 preview SPA","description":"Design sprint + implementation of the React-component decomposition that lets hub-client's preview pane and the q2 preview SPA share components — same source files, same imports, same tests. Drawing the package boundary correctly is what makes new preview features land in both surfaces by construction (no second copy to maintain). Blocks Phase A of bd-kw93. See claude-notes/plans/2026-05-11-q2-preview-epic.md (§Build-time concerns, §Crate / SPA layout invariant, §Recommended next steps item 1). Open: exact package count + names (one shared package for render-time primitives? two for render + sync? more?), workspace layout, build-script wiring.","status":"closed","priority":1,"issue_type":"epic","created_at":"2026-05-11T15:40:51.137344Z","created_by":"cscheid","updated_at":"2026-05-13T16:58:37.200378Z","closed_at":"2026-05-13T16:58:37.200248Z","close_reason":"All 7 phases complete on branch feature/bd-hfjj-hub-client-decomposition-shared (commits 12347a54..06d03730). hub-client + preview-renderer + preview-runtime + q2-preview-spa green; cargo xtask verify 11/11 steps pass; end-to-end browser smoke verified by user.","source_repo":".","compaction_level":0,"original_size":0}
+{"id":"bd-hir7j","title":"Default table rendering parity with Quarto 1 (render + preview)","description":"## Problem\n\n`q2 render` and `q2 preview` produce visually-bare `
` markup that does not match Quarto 1's output. A doc as simple as a 3-row `::: list-table` renders with no Bootstrap styling, no ``/``. Same behavior in both render and preview pipelines (they share the HTML writer).\n\n## Evidence (2026-05-20)\n\nCompared three renders of `~/Desktop/daily-log/2026/05/20/tables.qmd` in Chrome DevTools:\n\n- Q1 (target): `
`, no row striping, a collapsed (content-width) table, and an empty `
` with proper ``, `
`, `tr.odd/.even`, Bootstrap CSS, `body.quarto-light`. Cells: 8.5px padding, header font-weight 700, border-bottom on header.\n- Q2 render: bare ``, no thead, no th, no row classes, empty ``, body just `fullcontent`. Browser-default cell padding (1px).\n- Q2 preview: identical DOM to render; different (also minimal) CSS bundle.\n\nScreenshots and computed-style dumps captured under `/var/folders/.../T/{q1-render,q2-render,q2-preview}.png`.\n\n## Plan\n\n`claude-notes/plans/2026-05-20-table-default-rendering-parity.md`\n\nPhased: markup parity (D1-D6) → render-side CSS (D7) → preview-side CSS (D8). Sub-issues to be filed under this epic as each phase is started.\n\n## Related\n\n- k-giyy (Investigate style differences between WASM and CLI rendering) — same gap from the WASM/preview side; D8 likely absorbed.\n- bd-ulgr (JS dependency handling) — JS analog; not blocking.\n- claude-notes/plans/2025-12-05-list-table-implementation.md — D1 amends a default chosen there.\n\n## Fixture\n\n```\n---\ntitle: Table test\n---\n\n::: list-table\n\n* * `qmd` syntax\n * Output\n\n* * ```qmd\n \n ```\n * \n\n* * ```qmd\n [Quarto](https://quarto.org)\n ```\n * [Quarto](https://quarto.org)\n\n:::\n```","status":"closed","priority":2,"issue_type":"epic","created_at":"2026-05-20T20:51:25.202168Z","created_by":"cscheid","updated_at":"2026-05-20T22:52:01.278439Z","closed_at":"2026-05-20T22:52:01.278267Z","close_reason":"Epic complete. All 9 sub-tasks closed: D1/D2/D3/D4-5/D6 (render path) + D4-5/D6 react mirrors + D7/D8 (no-op verifications). The daily-log fixture now renders byte-identically across q2 render, q2 preview, and Quarto 1 — confirmed via Chrome DevTools 2026-05-20. Implementation lives on feature/table-rendering-parity (13 commits).","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-hixmy","title":"D3: HTML writer suppresses empty ","description":"## What\n\n`crates/pampa/src/writers/html.rs:1383` emits `` whenever `table.colspec` is non-empty, even if every entry is `(Alignment::Default, ColWidth::Default)`. Quarto 1 / Pandoc HTML writer omits the colgroup in that case (no information to convey).\n\n## Fix\n\nAdd a check: skip the colgroup if every colspec entry is fully default. Still emit when any alignment or width is non-default.\n\n## Tests (TDD)\n\n1. Snapshot: list-table with no widths/aligns → no `` in output.\n2. Snapshot: list-table with explicit `widths: 1,2` → `` present with the appropriate `` widths.\n3. Snapshot: pipe table with `:---` alignment → `` present with alignment attrs.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D3 section)","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T20:54:58.879402Z","created_by":"cscheid","updated_at":"2026-05-20T21:25:38.642354Z","closed_at":"2026-05-20T21:25:38.642185Z","close_reason":"Implemented in this commit: writer skips colgroup when every colspec entry is default.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-hixmy","depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:54:58.879402Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-hjv5o","title":"Audit other navigation/metadata surfaces for source-location-driven path resolution","description":"bd-qor9a applied source-location-driven path resolution to navigation surfaces (sidebar / navbar / page-footer / page-nav) — paths declared in a doc's frontmatter now resolve relative to the doc's directory, not the project root.\n\nOther YAML positions that still treat hrefs as project-root-relative regardless of authoring location:\n\n1. **Body links** — `[text](foo.qmd)` in markdown body. Already source-aware via `resolve_doc_relative_href` (source_relative parameter) but does not yet plug `SourceInfo` into the Q-13-4 diagnostic. Lightweight follow-up.\n\n2. **`AutoSpec::Paths` / `AutoSpec::Path`** — sidebar `auto:` scope paths. Today treated as project-root-relative; could be source-aware.\n\n3. **`format.html.css` / `theme` / `template` / `include-in-header` / `bibliography`** — already largely covered by `adjust_paths_to_document_dir` when authored with `!path` tags. Audit which still use bare strings in doc frontmatter.\n\n4. **Listing `contents:` paths** — `listing.contents: foo/` could be source-aware.\n\n5. **Crossref absolute-file references** — `{#fig-x}` references that point at sibling docs.\n\nScope each surface separately if non-trivial. Sub-issues are fine.\n\nOut of scope: changing the project-root-relative interpretation of values declared in `_quarto.yml`. Those keep working because `_quarto.yml`'s hash-based FileId isn't in any document's SourceContext, so the helper degrades to today's behaviour for them — exactly what we want.\n\nPlan: to be written when work begins.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-20T17:25:03.120968Z","created_by":"cscheid","updated_at":"2026-05-20T17:25:03.120968Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-hjv5o","depends_on_id":"bd-qor9a","type":"discovered-from","created_at":"2026-05-20T17:25:03.120968Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-hp3tx","title":"Wire brand navbar logo / brand image into website navbar","description":"Brand data has logo (small/medium/large + images.*). Website navbar should be able to use brand.small or brand.images. as the navbar brand-image. Quarto 1 reference: external-sources/quarto-cli/src/project/types/website/website-navigation.ts (navbar.logo). Q2 has the data model in place (quarto-brand crate); just needs the navbar emission to consult it.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:30.944971Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:30.944971Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-ht0n","title":"[websites] Sidebar logo / subtitle / header / footer","description":"Render the sidebar's logo (with light/dark variants + logo-href + logo-alt), subtitle (parsed but not rendered in Phase 2), and the 'header:' / 'footer:' freeform content slots Q1 supports. All are parsed by Sidebar::from_config_value today but ignored in sidebar_to_html.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-24T17:52:25.088205Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:25.088205Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ht0n","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:25.088205Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-hva0","title":"Local-vendor opt-in for MathJax/KaTeX (offline rendering)","description":"bd-w5ov shipped CDN-default for math (parity with Pandoc / Quarto 1). Users who need offline / air-gapped rendering must today set 'html-math-method.url:' pointed at a self-hosted mirror.\n\nMake this easier: ship a 'quarto install mathjax' (and 'quarto install katex') CLI helper that downloads the bundle into a project resources dir and writes the URL override into _quarto.yml. This is 'we're better than Q1' territory — Q1 offers no equivalent automation.\n\nOut of scope for this issue: vendoring bytes by default in the binary (rejected in bd-w5ov §4.5 because of binary-size cost and parity with Q1).\n\nAcceptance: 'quarto install mathjax' downloads, lays out under project resources, configures override; 'quarto render' uses the local URL; offline rendering works.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-04T23:58:29.291389Z","created_by":"cscheid","updated_at":"2026-05-04T23:58:29.291389Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-hva0","depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:29.291389Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-hwdlq","title":"Non-deterministic diagnostic output: HashMap iteration in produce_diagnostic_messages (issue #222)","description":"GitHub issue #222 (reported by @rundel): pampa emits a different second diagnostic across runs of the same binary on the same input (`printf -- 'The \"_blank\" word.' | cargo run --bin pampa -- --no-prune-errors`).\n\nRoot cause: crates/quarto-parse-errors/src/tree_sitter_log.rs:48 declares `processes: HashMap`. crates/quarto-parse-errors/src/error_generation.rs:44 iterates `parse.processes.values()` and a (row, column) dedupe at lines 46-49 picks whichever GLR version's error state arrives first. Default RandomState means iteration order varies per process.\n\nTriage: claude-notes/issue-reports/222/triage.md\nPlan: claude-notes/plans/2026-05-20-issue-222-deterministic-diagnostics.md\n\nFix scope: swap HashMap for hashlink::LinkedHashMap in tree_sitter_log.rs (one import swap + Cargo.toml dep add); add a regression test that parses the issue-222 input N times and asserts byte-identical diagnostic output across runs. LinkedHashMap matches the convention already used in pampa/src/readers/json.rs and 7 other crates in the workspace.\n\nBranch: issue-222 (worktree at .worktrees/issue-222).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T03:03:07.138308Z","created_by":"cscheid","updated_at":"2026-05-21T13:53:34.714598Z","closed_at":"2026-05-21T13:53:34.714437Z","close_reason":"Fixed in PR #227 (squash-merged as bed7f5ed): swapped HashMap for hashlink::LinkedHashMap in tree_sitter_log.rs to make GLR diagnostic emission deterministic. Regression test in crates/pampa/tests/test_diagnostic_determinism.rs (50 iterations, asserts byte-identical output) lands on main. Follow-up audit: bd-x5tx2.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-hytl","title":"Phase B.4: Acceptance bundle — _quarto.yml + posts/_metadata.yml propagation to preview","description":"Single Playwright spec pinning the two observable plan acceptance criteria for q2 preview (Phase B):\n\n1. Editing _quarto.yml (title:) re-renders the active page; new title visible in DOM within 5 s.\n2. Editing posts/_metadata.yml (subtitle:) re-renders pages under posts/; new subtitle visible in DOM within 5 s.\n\nFixture (single, dual-purpose): _quarto.yml + posts/_metadata.yml + posts/post1.qmd (no frontmatter, inherits both). Empirically verified both knobs flow through to the rendered title-block (2026-05-13 probe with target/debug/q2 render).\n\nReuses the multi-file fixture helper generalised in bd-pf63 (B.3).\n\nPlan acceptance criterion 3 ('unrelated sibling re-renders the active page') is deferred and tracked separately — its relaxed-contract form (any edit fires a re-render) is invisible at the DOM without SPA instrumentation. See discovered-from follow-up.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid","updated_at":"2026-05-13T21:16:15.516971Z","closed_at":"2026-05-13T21:16:15.516850Z","close_reason":"Duplicate of bd-mrx1 — created by an accidental double-run during B.4 setup (jq parse error masked the first create's output). No work done against this ID; all B.4 work tracked under bd-mrx1.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-hytl","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-hytl","depends_on_id":"bd-pf63","type":"discovered-from","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-hzsi","title":"L10 — Q1 → Q2 listing template migration docs + LLM skill","description":"User-facing migration doc in docs/ covering EJS → doctemplate mapping (<%= … %> → $…$, control flow, helper-function → server-pre-rendered fields, item.extra). LLM skill in .claude/skills/ that suggests Q2 doctemplate equivalents from Q1 EJS templates. Worked examples for each built-in shape and a representative custom template. See claude-notes/plans/2026-05-05-listings-epic.md §L10.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid","updated_at":"2026-05-05T19:53:59.836077Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-hzsi","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-hzsi","depends_on_id":"bd-rqgx","type":"blocks","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-i1df","title":"Kanban: Card detail view on title click","description":"Clicking a card title opens a detail modal showing all card information: title, type, status, created/deadline dates, priority, full body text. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-11T18:32:37.650902Z","created_by":"cscheid","updated_at":"2026-02-11T18:36:06.274831Z","closed_at":"2026-02-11T18:36:06.274814Z","close_reason":"Implemented - card detail modal on title click","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-i4wv","title":"L9 follow-up: real version string in feed generator (replace quarto-2)","description":"L9 v1 emits quarto-2. Q1 emits quarto- from quartoConfig.version(). Replace with the actual Q2 version string when the version story stabilizes. Site: feed/binding.rs::FEED_GENERATOR.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:33:39.786912Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:39.786912Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-i4wv","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:39.786912Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-i6jy4","title":"Preview eager-capture driver iterates all files (binaries, configs), causing thread panic on first binary","description":"## Symptom\n\n```\n$ q2 preview # in a project containing any image/binary\nthread 'tokio-rt-worker' panicked at crates/quarto-parse-errors/src/error_generation.rs:121:35:\nstart byte index 7748 is not a char boundary; it is inside '�' (bytes 7746..7749 of string)\n```\n\nReproduces deterministically with the project at `docs/` (contains `quarto.png`).\n\n## Root cause\n\n`crates/quarto-preview/src/capture_driver.rs:55` (record_eager_captures) calls `ctx.index().get_all_files()` and iterates every entry. The index map covers *all* tracked project files: qmd, config (`_quarto.yml`), binaries (images), extension files, etc.\n\nThe doc comment on the function says: *\"Walk the project's .qmd files and record engine captures for any file that has code cells but no existing sidecar entry yet.\"* The code does not match the comment — it never filters by file kind. Each non-qmd file is shoved through `compute_input_qmd → parse-document`. Two distinct failure modes result:\n\n- `_quarto.yml` → parse-document errors out with \"Indented code blocks are not supported\". `record_one` returns `Err`, caught at line 109, logged as a WARN — visible noise but not crashing.\n- `quarto.png` → tree-sitter parses binary bytes, produces parse errors, then `produce_diagnostic_messages` panics on a non-UTF-8 byte (the lossy-string offset bug tracked in the sibling issue).\n\nThe PNG path also tells us the warning-only soft-fail at L109-115 doesn't catch panics — `compute_input_qmd` runs on a tokio worker, and the panic propagates as a worker-thread panic, not an `Err`.\n\n## Fix\n\nIterate `project_files().qmd_files` instead of `index.get_all_files()`. The currently-unused `_doc_id` from the index map can be looked up if needed, or dropped entirely if the downstream code doesn't need it (check `record_one` — `abs_path` and `rel_path` are the only inputs derived from the iteration item, both reconstructible from a qmd path).\n\nTests:\n- Regression test for the eager driver: project containing both a qmd and a binary, assert no panic and no spurious WARN for the binary.\n- Unit test that walks all `ProjectFiles` field combinations to confirm only `.qmd` files reach `record_one`.\n\nEnd-to-end verification: `q2 preview` on a fixture project with image asset must boot cleanly with no thread panic.\n\n## Out of scope\n\nDefensive hardening of `error_generation.rs` so that even a bug like this one cannot panic the worker. Tracked in sibling issue (link via discovered-from once filed). With the upstream filter in place, the panic still requires bad input to even reach that function.\n\n## Plan file\n\nTo be created at `claude-notes/plans/2026-05-19-bd-XXXX-capture-driver-qmd-filter.md` once issue ID is assigned.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-19T23:43:44.009707Z","created_by":"cscheid","updated_at":"2026-05-20T13:05:02.222953Z","closed_at":"2026-05-20T13:05:02.222785Z","close_reason":"Implemented in 408f4025 (merged via c8b4ab0b). record_eager_captures now iterates project_files().qmd_files. Verified by regression test capture_driver::tests::binary_files_are_not_fed_to_parse_pipeline and end-to-end: q2 preview on docs/ boots cleanly (no thread panic, no spurious _quarto.yml WARN). Defensive hardening of error_generation.rs tracked separately as bd-6qbto.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-i6jy4","depends_on_id":"bd-tnm3k","type":"discovered-from","created_at":"2026-05-19T23:43:44.009707Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-i992","title":"WASM hub-client recompiles default Bootstrap SCSS on every keystroke","description":"After bd-imiw landed the Q1-parity default theme behavior, hub-client renders re-compile the full Bootstrap + Quarto SCSS layer on every keystroke because the new no-theme code path in CompileThemeCssStage bypasses the runtime cache (unlike the themed path), and the WASM version of compile_default_css has no in-memory cache (unlike the native version, which uses a OnceLock). Users report the editor freezing for tenths of a second after every keystroke on documents with no theme/navbar/footer.\n\nRoot cause evidence:\n- crates/quarto-core/src/stage/stages/compile_theme_css.rs:175-195 — no-theme path calls compile_default() without any cache_get check.\n- crates/quarto-core/src/stage/stages/compile_theme_css.rs:206-279 — themed path DOES use ctx.runtime.cache_get(\"sass\", ...) then cache_set.\n- crates/quarto-sass/src/compile.rs:55,239-276 — native compile_default_css uses DEFAULT_CSS_CACHE OnceLock.\n- crates/quarto-sass/src/compile.rs:357-384 — WASM compile_default_css deliberately has no in-memory cache (comment defers to JS SassCacheManager / IndexedDB).\n\nPlan: claude-notes/plans/2026-04-18-wasm-scss-cache-regression.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-18T20:30:49.365984Z","created_by":"cscheid","updated_at":"2026-04-18T21:16:33.355871Z","closed_at":"2026-04-18T21:16:33.355017Z","close_reason":"Fixed in commit d89d1514 on feature/navigation. Four-item bundle: (1) OnceLock in WASM compile_default_css, (2) stage routes no-theme path through runtime cache, (3) generational purge on SCSS_RESOURCES_HASH mismatch (ensure_namespace_version helper), (4) per-namespace LRU size cap with 10 MB sass budget. 16 new tests, 7550 workspace tests pass, cargo xtask verify green, manually confirmed on hub-client.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-i992","depends_on_id":"bd-imiw","type":"discovered-from","created_at":"2026-04-18T20:30:49.365984Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-iey8o","title":"q2 render: add --json-errors for machine-readable diagnostics","description":"Add a --json-errors flag to `q2 render` so agents (Claude Code first) and other programs driving the binary can consume diagnostics (errors, warnings, info, project-level) in a structured form instead of scraping ariadne text out of stderr.\n\nScope (per planning conversation 2026-05-22):\n- Just `q2 render` in this issue. Pampa's existing --json-errors stays as-is; harmonizing the two CLIs is out of scope.\n- Emit the richer JsonDiagnostic shape from quarto-error-reporting (1-based line/col, pre-rendered ariadne snippet, source_file field) — the same wire format hub-client and the preview /api/preview/diagnostics endpoint already use.\n- NDJSON on stderr (one JSON object per line). Stdout left free for a possible future RenderOutcome object (deferred).\n- Exit codes unchanged. The strict pass-1 contract from bd-creo is unaffected.\n\nImplementation TDD-driven; tests modeled on crates/pampa/tests/test_json_errors.rs. End-to-end verification (real `cargo run --bin q2` invocation, observed JSON lines recorded in the plan file) is required before close per CLAUDE.md.\n\nPlan: claude-notes/plans/2026-05-22-q2-render-json-errors.md\n\nRelated: bd-creo (strict pass-1 exit), k-lckc (uniform error-reporting in render), bd-rqba (JsonPass1Failure shape).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-22T19:26:51.591582Z","created_by":"cscheid","updated_at":"2026-05-22T20:23:11.728062Z","closed_at":"2026-05-22T20:23:11.727852Z","close_reason":"Implemented on feature/q2-render-json-errors: --json-errors flag, JsonDiagnostic/JsonPass1Failure JSON Schemas, Q-7-2..8 catalog entries, drift test, and 7 integration tests. cargo xtask verify --skip-hub-build green; full workspace 9425/9425 pass.","source_repo":".","compaction_level":0,"original_size":0,"labels":["agent-ux","error-reporting"],"dependencies":[{"issue_id":"bd-iey8o","depends_on_id":"bd-creo","type":"related","created_at":"2026-05-22T19:26:55.899025Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-iey8o","depends_on_id":"k-lckc","type":"related","created_at":"2026-05-22T19:26:56.009277Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ij1l","title":"Phase 3: Wire forked runtimelib into Quarto, expose diagnostic error","description":"Add [patch.crates-io] entry pointing runtimelib at cscheid/runtimelib feat/venv-kernelspec-discovery branch (pin to a rev once stable). Switch crates/quarto-core/src/engine/jupyter/kernelspec.rs to list_kernelspecs_with_jupyter_paths(). Replace JupyterError::KernelspecNotFound { name } with { name, searched: Vec, available: Vec } and update Display to render searched paths, available kernels, and a remediation hint pointing at jupyter kernelspec list and JUPYTER_PATH.\n\nEnd-to-end verification per CLAUDE.md: render convert-test-3.qmd from a venv shell and confirm success; record invocation + output snippet.\n\nBlocked by: bd-34wy (fork must exist first).\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 3)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid","updated_at":"2026-05-04T16:15:19.841987Z","closed_at":"2026-05-04T16:15:19.841852Z","close_reason":"Wired runtimelib fork into Quarto via [patch.crates-io] (path patch — will become git rev before push). list_kernelspecs/find_kernelspec route through *_with_jupyter_paths variants. JupyterError::KernelspecNotFound now carries searched: Vec and available: Vec; Display renders a multi-line diagnostic with searched paths, available kernels, and a remediation hint. From pattern-matches KernelNotFound and forwards fields.\n\nEnd-to-end verified in commit 03e8cab2:\n- Original failing fixture (convert-test-3.qmd) now renders with kernel output, when run from the venv shell.\n- Ruby fixture (no kernel installed) produces the new multi-line diagnostic.\n- cargo build --workspace clean, cargo nextest run --workspace 8360 passed, cargo xtask verify --skip-hub-build all green.\n\nCloses the user-visible bug for bd-fu0l. Phase 4 (bd-875x, upstream PR) is now unblocked.","source_repo":".","compaction_level":0,"original_size":0,"labels":["dx","feature","jupyter"],"dependencies":[{"issue_id":"bd-ij1l","depends_on_id":"bd-34wy","type":"blocks","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ij1l","depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ilv8p","title":"tree-sitter qmd: allow line breaks inside inline code spans and inline math","description":"Pampa rejects multi-line inline code spans that pandoc accepts as a single Code element. Example: `A simple ``code\\nspan`` test.` errors at the opening backtick. See claude-notes/plans/2026-05-24-multiline-inline-code-spans.md for diagnosis and implementation plan.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-24T21:12:25.161104Z","created_by":"cscheid","updated_at":"2026-05-24T22:27:40.235371Z","closed_at":"2026-05-24T22:27:40.235225Z","close_reason":"Implemented in commit (pending). Scanner+grammar+post-processor changes for code spans and math spans; full E2E parity with pandoc verified on 11 fixtures; cargo xtask verify green (12/12 steps); 9425/9425 workspace tests pass. Plan: claude-notes/plans/2026-05-24-multiline-inline-code-spans.md","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-imiw","title":"Design and implement YAML-controlled top-level navbars and page footers for Quarto 2 HTML output","description":"Quarto 1 supports website navbars and page footers only as project-level (website/book) features. Quarto 2 already allows user-controlled TOCs via YAML metadata at the document level. This issue extends that pattern to top-level navbars and page footers: HTML documents should be able to declare and customize navbar/footer contents via YAML metadata, mirroring the TOC mechanism. Includes design proposal (YAML schema, familiar to Quarto 1 users), pipeline integration (Generate + Render transforms, mirroring TocGenerateTransform/TocRenderTransform), and template wiring.\n\nPlan: claude-notes/plans/2026-04-18-navbar-footer-design.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-04-18T17:13:52.866569Z","created_by":"cscheid","updated_at":"2026-04-18T18:17:33.919378Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-iq0hp","title":"Multi-engine preview: browser E2E + composing test engines","description":"A browser end-to-end test of MULTI-engine q2 preview was not possible during bd-5yff4: the preview server uses the default engine registry (real engines), the test-only FixtureEngine isn't registered there, and knitr/jupyter don't compose cleanly (knitr claims python cells). Single-engine preview is unchanged + unit-tested; the capture-sequence transport round-trips via quarto-preview integration tests. Options: (a) wire a flag-gated fixture engine into the preview server for tests, (b) build a real second engine, (c) hand-construct a two-capture sidecar and drive a browser session. Plan: claude-notes/plans/2026-05-27-multi-engine-execution.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-27T16:24:40.064471Z","created_by":"cscheid","updated_at":"2026-05-27T16:24:40.064471Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-iq0hp","depends_on_id":"bd-5yff4","type":"discovered-from","created_at":"2026-05-27T16:24:40.064471Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ir8n","title":"L9 follow-up: inline-code-style syntax-highlight class maps in full feeds","description":"Port Q1's inline-code-style transform: maps highlight classes (token comment, etc.) to inline style=\"color: ...\" so feeds render with colors when the subscriber's stylesheet doesn't include Quarto's CSS. v1 leaves highlight classes verbatim; readers without the CSS render code blocks in default mono. Reader extension lives in feed/reader_ext.rs; gated behind an RssReaderOptions flag.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:16.610890Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:16.610890Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ir8n","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:16.610890Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-itj9","title":"Add WASM test execution to CI","description":"Add real wasm32 smoke tests and CI job for pampa Lua WASM code paths. 6 tests in crates/pampa/tests/wasm_lua.rs verify restricted Lua VM, filter/shortcode execution, error handling, and synthetic io/os on wasm32-unknown-unknown. Includes wasm-c-shim shared crate, dev-dep gating, and wasm-tests CI job. Blocked by JS bridge raw_module paths in quarto-system-runtime needing feature-gate. Cfg proxy fix and cleanup shipped separately in PR #116.","notes":"PR #109 rebased on #116, base branch changed. PR #116 (cfg fix + cleanup) is CI green and ready to merge. PR #109 now focused solely on WASM CI test infrastructure. JS bridge blocker documented, recommended fix is feature-gating raw_module extern blocks in quarto-system-runtime.","status":"in_progress","priority":3,"issue_type":"task","created_at":"2026-04-02T10:43:59.896261300Z","created_by":"cderv","updated_at":"2026-04-24T17:13:49.430217800Z","source_repo":".","compaction_level":0,"original_size":0,"comments":[{"id":1,"issue_id":"bd-itj9","author":"cderv","text":"WASM test coverage analysis: npm run test:wasm (TS side) tests rendering, templates, format detection via compiled WASM module — does NOT cover Lua filter traversal. The test cfg proxy in Rust is the ONLY thing catching WASM-incompatible Lua code in filter tests. So the proxy has value on Linux/macOS — just not on Windows. wasm-pack test would be the proper replacement: compiles Rust to wasm32, runs #[wasm_bindgen_test] in browser/Node on the real WASM target. build-wasm.yml already installs wasm-pack but only runs build, not test. Infrastructure needed: wasm-pack test in CI, test harness crate with wasm_bindgen_test, possibly browser driver. Approach: (1) Remove test from cfg guard in filter.rs/shortcode.rs, (2) Add wasm-pack test to build-wasm.yml or new workflow with #[wasm_bindgen_test] versions of key filter tests, (3) Gate io_wasm/os_wasm unit tests to wasm32 target only.","created_at":"2026-04-02T15:10:34Z"},{"id":3,"issue_id":"bd-itj9","author":"cderv","text":"Important: this project does NOT use wasm-pack. It uses cargo build --target wasm32-unknown-unknown + wasm-bindgen CLI directly because -Zbuild-std=std,panic_unwind is needed for Lua error handling (setjmp/longjmp to panic/catch_unwind). See hub-client/scripts/build-wasm.js. This means wasm-pack test wont work — WASM testing would need cargo test --target wasm32-unknown-unknown -Zbuild-std plus wasm-bindgen-test-runner, mirroring the custom build approach.","created_at":"2026-04-03T09:09:11Z"},{"id":4,"issue_id":"bd-itj9","author":"cderv","text":"wasm-bindgen-test infrastructure already exists: wasm-qmd-parser/tests/web.rs has a placeholder #[wasm_bindgen_test] test with run_in_browser config. The crate already depends on wasm-bindgen-test 0.3.34. Pattern is ready to extend with real filter tests. Note: wasm-qmd-parser uses wasm-pack (simpler build), wasm-quarto-hub-client uses custom cargo build + wasm-bindgen (needs -Zbuild-std). Test runner choice depends on which crate hosts the WASM filter tests.","created_at":"2026-04-03T09:11:25Z"},{"id":6,"issue_id":"bd-itj9","author":"cderv","text":"Branch split decision (2026-04-13): PR #109 grew too large mixing cfg proxy fix with WASM CI test infrastructure. Split into two branches: (1) fix/wasm-cfg-proxy-and-cleanup ships the cfg proxy removal, dead crate cleanup, dtolnay replacement, and doc updates. (2) feature/wasm-testing-and-cleanup retains the WASM smoke tests, wasm-c-shim crate, CI job, and related infrastructure for a future PR. Known blocker for Branch B: quarto-system-runtime/src/wasm.rs has 4 raw_module extern blocks (/src/wasm-js-bridge/{template,sass,cache,fetch}.js) that get baked into any wasm32 binary. wasm-bindgen-test-runner generates require() calls for these absolute paths which fail in Node.js. Recommended fix: feature-gate the JS bridge (add js-bridge feature to quarto-system-runtime, gate the 4 extern blocks, provide stub impls when off, wasm-quarto-hub-client enables it, pampa test builds dont).","created_at":"2026-04-13T20:48:28Z"},{"id":7,"issue_id":"bd-itj9","author":"cderv","text":"PR restructured (2026-04-14): PR #116 (fix/wasm-cfg-proxy-and-cleanup) opened for Branch A, CI green. PR #109 rebased onto #116 and base changed to fix/wasm-cfg-proxy-and-cleanup. PR #109 diff now shows only WASM CI test additions. When #116 merges to main, GitHub auto-updates #109 base to main.","created_at":"2026-04-14T12:34:20Z"},{"id":8,"issue_id":"bd-itj9","author":"cderv","text":"PR #116 merged to main (squash commit 52968801) on 2026-04-23. Ships cfg proxy removal from filter.rs/shortcode.rs, dofile_wasm test skip on native, and updated docs (dev-docs/wasm.md, .claude/rules/wasm.md, testing.md). PR #109 remains open with WASM CI smoke test infrastructure; auto-rebased to main. Remaining blocker: JS bridge raw_module paths in quarto-system-runtime need feature-gating before wasm-bindgen-test-runner can work.","created_at":"2026-04-23T14:05:04Z"},{"id":10,"issue_id":"bd-itj9","author":"cderv","text":"2026-04-24 session: Rebased PR #109 onto latest origin/main (50+ commits since Gordon's prior rebase on Apr 17). 2 conflicts resolved (Cargo.toml + Cargo.lock). Docs audit found 3 drifts, fixed in b2e88ec1. cargo fmt on shim.rs in 1f080db5. Verified wasm-c-shim/src/shim.rs byte-identical to main's c_shim.rs modulo CRLF. Build succeeds after cmake install (bd-n7x2 introduced cmake as a hard requirement via tree-sitter wasm feature). Pending: cargo xtask verify + force-push to update PR. Dev-setup improvements split to bd-tjbr; tree-sitter CRLF Windows failures split to bd-ntnx (pre-existing, not caused by #109).","created_at":"2026-04-24T17:13:49Z"}]} -{"id":"bd-izh3","title":"Add PR trigger to hub-client E2E workflow for WASM build verification","description":"hub-client-e2e.yml only runs on push to main. PR changes to workflows or WASM build deps are not caught until merge. Add pull_request trigger with path filter so the WASM build runs on PRs. Playwright and visual regression steps should be gated to push-to-main only (expensive, auto-commits baselines). Open question: whether default ubuntu runner can handle the WASM build or if 8x is needed for the cargo build with -Zbuild-std. Discovered during PR #116 review when removing wasm-pack left wasm-bindgen-cli missing.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-14T15:47:10.281Z","created_by":"cderv","updated_at":"2026-04-14T15:47:10.281Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-iuzmk","title":"q2 preview: set browser-tab title to ' (Quarto Preview)' from the active AST's meta.title","description":"Today the q2-preview SPA's browser tab always reads 'Quarto Preview' regardless of which doc is active. With a real doc title in YAML frontmatter we should surface it as ' (Quarto Preview)' so users with the live site + preview open side-by-side can tell tabs apart. Implementation: useEffect in q2-preview-spa/src/PreviewApp.tsx watching state.astJson, parse meta.title (handle MetaString / MetaInlines / bare Inlines), set document.title. Fall back to 'Quarto Preview' when no title. Acceptance: integration test asserting title updates on AST change; browser verification against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website (should show 'Hello, world (Quarto Preview)').","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-18T16:20:13.444289Z","created_by":"cscheid","updated_at":"2026-05-18T16:30:32.982406Z","closed_at":"2026-05-18T16:30:32.982262Z","close_reason":"Implementation complete: AST meta.title surfaces in document.title as '<title> (Quarto Preview)'. Verified end-to-end against the fixture website; live-edit case (retitle on disk → tab updates) also confirmed. 3 new SPA integration tests; cargo xtask verify 12/12 green.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-iuzmk","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T16:20:13.444289Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-izfv","title":"Phase 9 follow-up: thread user_grammars through RenderToHtmlRenderer","description":"Today render_page_in_project's project-rendering branch drops user_grammars on the floor — the RenderToHtmlRenderer constructs its own per-page RenderContext and there's no path to attach user_grammars there. Single-file projects still wire user_grammars correctly via render_single_doc_to_response.\n\nThreading user grammars through the renderer is straightforward: add a field to RenderToHtmlRenderer holding an Arc<Mutex<Option<JsUserGrammars>>> (or similar) and have its render() method install the provider on the per-page RenderContext.\n\nFiled as discovered-from-bd-ayj6 and tagged P3 since most user-grammar use is for code-block highlighting which still works on the active page's first render — the gap is just for project renders where the hub-client passes a grammars handle but it gets ignored.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid","updated_at":"2026-05-12T13:41:25.597279Z","closed_at":"2026-05-12T13:41:25.597259Z","close_reason":"Threaded user_grammars through RenderToHtmlRenderer (Rc<RefCell<…>>); re-enabled e2e fixture by dropping SKIP_WASM_UNSUPPORTED entry on chore/e2e-ci, and fixed two test-harness gaps (binary fixture forwarding + getPreviewHtml userGrammars context) so the hub-client e2e suite can actually verify the fixture. Rust unit test crates/quarto-core/tests/render_to_html_user_grammars.rs passes; e2e fixture highlighting/03-user-grammar-toml.qmd passes when run in isolation. See claude-notes/plans/2026-05-10-thread-user-grammars-renderer.md for the verification artifact.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-izfv","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-izfv","depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-izh3","title":"Add PR trigger to hub-client E2E workflow for WASM build verification","description":"hub-client-e2e.yml only runs on push to main. PR changes to workflows or WASM build deps are not caught until merge. Add pull_request trigger with path filter so the WASM build runs on PRs. Playwright and visual regression steps should be gated to push-to-main only (expensive, auto-commits baselines). Open question: whether default ubuntu runner can handle the WASM build or if 8x is needed for the cargo build with -Zbuild-std. Discovered during PR #116 review when removing wasm-pack left wasm-bindgen-cli missing.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-14T15:47:10.281Z","created_by":"cderv","updated_at":"2026-05-25T02:11:19.651349Z","closed_at":"2026-05-25T02:11:19.651328Z","close_reason":"Closed by PR #231 (commit 016894a2 on feature/provenance): drops the path filter outright rather than expanding it, so e2e fires on every PR like the sibling heavy workflows. Catches the upstream-crate case the original path-filter proposal would still have missed (Carlos's 5/22 WASM regression on f96f56df; PR #231 itself).","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-izqh","title":"L1 — ListingItemInfoStage (auto-fill, pre-checkpoint)","description":"New pre-checkpoint stage between IncludeExpansionStage and DocumentProfileStage. Auto-fills unset listing_item fields: reading-time, word-count, date-modified, description (first paragraph plain-text from post-include AST, truncated), image (first body Image src). Author values always win. Always populates description+image as L7-fallback safeguards (mandatory contract). See claude-notes/plans/2026-05-05-listings-epic.md §L1.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid","updated_at":"2026-05-06T14:30:09.263877Z","closed_at":"2026-05-06T14:30:09.263724Z","close_reason":"L1 ListingItemInfoStage implemented per claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md. Merged in 38749998 / merge commit. 25 unit + 3 integration tests; cargo xtask verify clean. Follow-up bd-8h9o filed for shortcode-bearing image src.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-izqh","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-izqh","depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j1trh","title":"Phase 2: code copy button decoration","description":"Phase 2 of bd-1tl09 (blocked by Phase 0 skeleton).\n\n## Trigger\n\nDocument/format metadata `code-copy: true | false | hover` — default in Quarto 1 is hover-only (button shown on hover via SCSS $code-copy-selector).\n\n## Output (HTML)\n\n<div class=\"code-copy-outer-scaffold\"><div class=\"sourceCode\">…<pre class=\"code-with-copy\">…</pre></div><button class=\"code-copy-button\" aria-label=\"Copy code\"><i class=\"bi bi-clipboard\"></i></button></div>\n\nQ1 implements this in TypeScript post-DOM (format-html.ts:746-772), not Lua. We move it to the Render transform.\n\n## Work\n\n1. Add copy: CopyMode { Off, Hover, Always } to CodeBlockDecoration.\n2. Generate transform: resolve from per-block attr (override) or doc default. Default to Hover when nothing set (matches Q1).\n3. Render transform (HTML): emit the outer scaffold + button structure. Add code-with-copy class to the inner <pre>.\n4. Inject clipboard.js as an HTML dependency. Port the relevant SCSS:\n - _quarto-rules-copy-code.scss (button styling)\n - _quarto-variables-copy-code.scss (color variables)\n5. Mirror on React side.\n6. Port the JS handler that flashes the \"Copied!\" tooltip on success (Q1 inlines this in the HTML; for Q2 it should be a small standalone script in resources/js/).\n\n## Tests\n\n- Native: snapshot.\n- React: integration test asserting the wrapper + button.\n- Doc-default off: code blocks rendered without copy=true don't get the scaffold.\n\n## Acceptance\n\n- All tests pass.\n- cargo xtask verify passes.\n- Manual: click the copy button in a real browser; clipboard contains the code text.","notes":"Phase 0 (bd-ea5tl) and Phase 1 (bd-j73yw) have closed; Phase 2 is unblocked.\n\nHand-off context for the next session lives at the bottom of\nclaude-notes/plans/2026-05-19-code-block-features.md under\n'Hand-off to next session — Phase 2 (copy button), bd-j1trh'.\nRead that first; it covers:\n\n- Load-bearing architectural facts proven on Phase 1 (sideband\n shape, pipeline placement, AST rewrite pattern, native/React\n parity-for-free)\n- The Q1 reference for the copy button (TypeScript post-DOM, not\n Lua) — relevant when porting\n- Suggested 3-commit breakdown matching Phase 1's rhythm\n- Open questions to resolve up front (per-block override?\n hover/always default? clipboard.js dependency injection\n mechanism?)\n- Known blockers (bd-tnm3k single-file preview, pre-existing\n tree-sitter regression, expected_hashes.txt baseline drift)\n- Verification commands with skip flags for the pre-existing\n failures\n\nPinned design decision for this epic: decoration storage is the\nsideband HashMap on RenderContext, NOT a CustomNode wrapper\n(plan §Resolved decisions, cleared with the user 2026-05-19).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T20:13:13.013456Z","created_by":"cscheid","updated_at":"2026-05-19T21:59:32.279792Z","closed_at":"2026-05-19T21:59:32.279626Z","close_reason":"Phase 2 complete. Commits f3974cf2 + abc94e7d + 0e85f954 land the CopyMode payload, the Generate→Render data flow (code-with-copy class + scaffold + button), the ClipboardJsStage (vendors clipboard.min.js + ships the init handler), the SCSS port (copy-button visibility, icons, hover/checked states + the load-bearing div.code-copy-outer-scaffold{position:relative} rule from Q1's _quarto-rules.scss), and full browser e2e verification via Chrome DevTools MCP (hover shows icon, click swaps to checkmark + Bootstrap Tooltip 'Copied!', state reverts after 1s). 9177/9177 workspace tests pass. cargo xtask verify green. Phase 3 hand-off in claude-notes/plans/2026-05-19-code-block-features.md §'Hand-off to next session — Phase 3 (code folding), bd-g1prx'.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-j1trh","depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:13:13.013456Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-j1trh","depends_on_id":"bd-ea5tl","type":"blocks","created_at":"2026-05-19T20:13:59.635875Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j30t7","title":"Q-2-32 not emitted for `***` inside pipe-table cells (generic parse error instead)","description":"When a pipe-table cell contains `***hello` (e.g. `| ***hello |`), pampa returns the generic 'unexpected character or token here' parse error instead of the structured Q-2-32 'Triple star emphasis disallowed. Consider `*__` instead.' diagnostic that fires at the paragraph level. Verified to be pre-existing (reproduces on main pre-bd-qhb2o); discovered while sanity-checking the bd-qhb2o fix and intentionally left out of scope. Likely cause: Q-2-32.json's `prefixesAndSuffixes` corpus does not enumerate a pipe-table-cell context, so the LR state the parser reaches when it sees `***` inside a cell isn't in the merr-style state->Q-code table (resources/error-corpus/_autogen-table.json) and the diagnostic falls through to the generic path. Probable fix: add a pipe-table prefix/suffix pair like [\"| col |\\n|---|\\n| \", \" |\"] to Q-2-32.json and rerun crates/pampa/scripts/build_error_table.ts. Worth scoping as part of a broader Q-2-32 coverage audit — same gap may exist for other inline-receptive contexts not yet enumerated (e.g. footnote definitions, table captions, fenced-div contents, etc.).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-24T23:24:05.227777Z","created_by":"cscheid","updated_at":"2026-05-24T23:24:05.227777Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-j30t7","depends_on_id":"bd-qhb2o","type":"discovered-from","created_at":"2026-05-24T23:24:05.227777Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j3a0","title":"Body-link diagnostic dedup by (page, href)","description":"If a site has many broken .qmd links, the warning list grows fast (one per occurrence per page). A simple first-occurrence-wins dedupe per (page, href) tuple would tame the output. Originally deferred from Phase 6 (bd-v30t).","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:54.339618Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-j3a0","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-j3a0","depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j4fe","title":"Q-2-36: clean parse error for knitr-style chunk options (issue #152)","description":"Upgrade old-style knitr chunk headers ('{r echo=FALSE}', '{r test}', '{r, label=\"foo\"}', any engine) from the current Q-2-8 *warning* to a clean Q-2-36 *error* that points users at the '#| key: value' body syntax. The Pandoc class form '{.r echo=FALSE}' stays valid (negative control).\n\nApproach 1 (confirmed with user, 2026-05-14): upgrade the existing Q-2-8 warning site in crates/pampa/src/pandoc/treesitter.rs:1121-1144 to emit a Q-2-36 error (no scanner.c change, no grammar.js change), plus add Q-2-36.json corpus entries to Merr-map the parse-error forms (bare label, comma form).\n\nTriage doc: claude-notes/issue-reports/152/q236-triage.md (worktree branch issue-152, based on bugfix/issue-184 @ e2d224f6)\nFixtures: claude-notes/issue-reports/152/q236-repro.qmd, q236-repro-variants.qmd\nPlan: claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md (to be written)\n\nGitHub: https://github.com/quarto-dev/q2/issues/152\nTemplate (mechanics only, NOT structure): bd-7l1u / PR #194 (Q-2-35). Q-2-36 diverges because it has no silent-acceptance case to detect — see triage doc 'Approach' section.\n\nPhases (TDD):\n1. Test scaffolding: rewrite test_code_block_with_header_options_produces_warning to expect Q-2-36 error; add Q-2-36.json with bare-label / comma-args cases; run build_error_table.ts; confirm tests fail.\n2. Upgrade Q-2-8 site to Q-2-36 error (level + code + message + header-line clip).\n3. Wire up Merr for the parse-error forms; apply widen_diagnostic_to_line.\n4. End-to-end: pampa on q236-repro.qmd shows clean Q-2-36; cargo nextest workspace; cargo xtask verify (full).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-14T19:08:04.698114Z","created_by":"cscheid","updated_at":"2026-05-14T20:42:57.524647Z","closed_at":"2026-05-14T20:42:57.524487Z","close_reason":"Q-2-36 implemented across Phase 0-3 on branch issue-152 (commits 9bbb1de1, bd93ffa2, e848e47e, ee4195ce). Path A (treesitter.rs site) emits Q-2-36 error with inline-clipped header-line highlight. Path B (Merr-mapped knitr parse-error forms) emits Q-2-36 via Q-2-36.json corpus + widen_diagnostic_to_line gate. Full pampa suite + cargo xtask verify green. Reporter's case fires the new diagnostic; Pandoc-class form {.r ...} stays valid. Discovered-from: bd-jvxg (pre-existing reader limitation re: parse-error + warning-collector interaction in same doc).","source_repo":".","compaction_level":0,"original_size":0,"labels":["error-messages","readers-writers"]} +{"id":"bd-j60g","title":"L2 — Listing data model + YAML schema","description":"Port Q1's Listing, ListingItem, ListingDescriptor, ListingType, ListingSort, ListingFeedOptions, ListingSharedOptions to Rust (new crates/quarto-core/src/project/listing/ module). YAML schema in quarto-yaml-validation port from Q1's website-listing definitions. listing: as document-frontmatter key. template: path; .ejs.md accepted with deprecation diagnostic. No rendering yet. See claude-notes/plans/2026-05-05-listings-epic.md §L2.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-05T19:53:07.098182Z","created_by":"cscheid","updated_at":"2026-05-07T13:35:13.849288Z","closed_at":"2026-05-07T13:35:13.848933Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-j60g","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:07.098182Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j73yw","title":"Phase 1: filename header decoration","description":"Phase 1 of bd-1tl09 (blocked by Phase 0 skeleton). Smallest end-to-end slice that exercises the Generate → Render plumbing.\n\n## Trigger\n\n`{r filename=\"hello.R\"}` or `#| filename: hello.R` (chunk option).\n\n## Output (HTML)\n\nWrap the code block in <div class=\"code-with-filename\"><div class=\"code-with-filename-file\"><pre><strong>hello.R</strong></pre></div>…</div>. Matches Q1's customnodes/decoratedcodeblock.lua + quarto-pre/code-filename.lua.\n\n## Work\n\n1. Add `filename: Option<String>` to CodeBlockDecoration.\n2. Generate transform: read attr.filename or kvs[\"filename\"]. Resolve doc-level default if any (Q1 has none; check).\n3. Render transform (HTML branch): emit the wrapper Div block around the existing CodeBlock node.\n4. Port the matching SCSS from external-sources/quarto-cli/src/resources/formats/html/_quarto-rules-code-filename.scss to resources/scss/. Match the dark-mode handling.\n5. Mirror on the React side: ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx will need either a parent component or the transform output to already include the wrapper Divs (which the React Div renderer will handle).\n6. End-to-end: q2 render + q2 preview both show the filename header. Browser screenshot for both.\n\n## Tests\n\n- Native: snapshot test asserting the wrapper structure for a CodeBlock with filename kv.\n- React: integration test (q2-preview.integration.test.tsx) asserting the same shape.\n- Cross-pipeline: render the same fixture through both and assert the rendered HTML's div.code-with-filename subtree is identical (modulo whitespace).\n\n## Acceptance\n\n- All listed tests pass.\n- cargo xtask verify passes.\n- Visual diff between q2 render and q2 preview shows identical filename header.","notes":"Phase 1 complete via 3 commits:\n1. Sideband infrastructure (CodeBlockDecorationKey, code_block_decorations on RenderContext, filename field on CodeBlockDecoration)\n2. Generate→Render data flow (Generate populates sideband from kvs['filename'], Render replaces CodeBlock with code-with-filename wrapper Div around a RawBlock filename header + the original block)\n3. SCSS port + e2e verification (ported filename rules from Q1's _quarto-rules-code-filename.scss into _bootstrap-rules.scss; no React-side code change needed because q2-preview's Div + RawBlock renderers already handle both cases). Visual parity verified between q2 render and q2 preview.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T20:13:00.847471Z","created_by":"cscheid","updated_at":"2026-05-19T21:01:58.912079Z","closed_at":"2026-05-19T21:01:58.911924Z","close_reason":"done","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-j73yw","depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:13:00.847471Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-j73yw","depends_on_id":"bd-ea5tl","type":"blocks","created_at":"2026-05-19T20:13:59.480776Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-j9cf","title":"Recognize bare `<` as a Str token (currently a parse error)","description":"Today a literal `<` outside math/code/HTML produces a parse error. Minimal trigger: a single-line document containing `1 < 2`. Goal: bare `<` should parse as Str \"<\" when not the start of a recognized HTML element / autolink / raw-specifier / HTML comment. Plan: claude-notes/plans/2026-05-18-bare-lt-as-str.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-18T20:54:00.031438Z","created_by":"cscheid","updated_at":"2026-05-18T21:01:37.931022Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-jakt","title":"Investigate cargo xtask dev-setup --locked causing externref mismatch in TS Test Suite","description":"cargo xtask dev-setup installs wasm-bindgen-cli with --locked flag. When used in ts-test-suite.yml instead of the hardcoded cargo install wasm-bindgen-cli --version 0.2.108 (without --locked), the hub-client WASM tests fail with: CompileError: WebAssembly.instantiate(): call[0] expected type externref, found local.get of type i32. Reverted in PR 109. Root cause unknown — the --locked flag may produce a subtly different binary.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-09T17:59:23.500651300Z","created_by":"cderv","updated_at":"2026-04-09T17:59:23.500651300Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-jbml","title":"Navbar index-forgiveness (about/ == about/index.html)","description":"Phase 3 Navbar active-state uses strict source-path equality. Q1's itemHasNavTarget additionally treats 'about/' and 'about/index.html' as equivalent for active-marking. Revisit if a real site hits the edge case. See 2026-04-24-websites-phase-3.md follow-ups.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T19:42:58.920114Z","created_by":"cscheid","updated_at":"2026-04-24T19:42:58.920114Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jbml","depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:42:58.920114Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-jby1i","title":"Highlighted code blocks render a stray empty line at the bottom (trapped pre margin inside div.sourceCode)","description":"Highlighted code blocks (e.g. ```ts) in both `q2 render` HTML output and `q2 preview` show ~one line-height of extra background below the last code line.\n\nRoot cause (verified in-browser with Chrome DevTools): Bootstrap's `pre { margin-bottom: 1rem }` survives on `pre.sourceCode`, and `div.sourceCode { overflow-y: hidden }` (resources/scss/bootstrap/_bootstrap-rules.scss) creates a block formatting context that traps that 17px margin INSIDE the gray box. Measured: div bottom - pre bottom = 18px in Q2 vs 1px (border only) in Q1.\n\nQ1 avoids this via Pandoc's baseline highlighting CSS, which Q2 never emits:\n div.sourceCode { margin: 1em 0; }\n pre.sourceCode { margin: 0; }\n\nFix: add the two rules to resources/scss/html/templates/highlight.scss (Q2's pandoc-baseline equivalent, embedded via quarto-sass load_highlight_layer, so it covers native render AND the WASM preview client).\n\nPlan: claude-notes/plans/2026-06-03-codeblock-trailing-margin.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-06-03T19:58:06.834662Z","created_by":"cscheid","updated_at":"2026-06-03T20:16:01.734322Z","closed_at":"2026-06-03T20:16:01.734179Z","close_reason":"Fixed: added div.sourceCode{margin:1em 0} + pre.sourceCode{margin:0} to highlight.scss (Pandoc-baseline parity). Regression test in quarto-sass compile_all_themes_test.rs; verified e2e in q2 render and q2 preview (gap inside div: 18px -> 1px, matching Q1).","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-je48v","title":"Add mermaid diagram engine to Quarto 2","description":"Design + ship a minimal mermaid engine that handles `{mermaid}` code blocks. First cut: HTML-only, defers actual diagram rendering to the browser via jsdelivr mermaid.js script. Architectural goal: maintain Q2's format-agnostic AST processing vs. format-specific emission decomposition so the engine doesn't need to be reworked when non-HTML formats are added.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md\n\nThis epic is intentionally also a design session — the mermaid case forces us to confront several engine-API gaps (see follow-up issues filed as discovered-from the design task).","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-28T13:44:39.930118Z","created_by":"cscheid","updated_at":"2026-05-28T13:44:39.930118Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-jfyl","title":"Footer Text-region project-link rewriting","description":"Phase 3 decision 8 excluded footer Text regions (string-valued left/center/right) from .qmd → .html rewriting — that's Phase 6's body-content link rewrite territory. Once Phase 6 lands, audit whether footer Text regions should get the same treatment or stay as literal markdown. Decision to defer was recorded in 2026-04-24-websites-phase-3.md plan §Decision 8 and §Risks.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T19:42:43.935902Z","created_by":"cscheid","updated_at":"2026-04-24T19:42:43.935902Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jfyl","depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:42:43.935902Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-jgeu","title":"Home-link relativization for sidebar title + navbar brand","description":"Two related hardcoded fallbacks in crates/quarto-navigation/src/render_html.rs emit project-root-relative or current-dir-relative hrefs that don't account for the rendering page's depth:\n\n1. Sidebar title (line 211): hardcoded <a href=\"./\">. From posts/aardvark.html, points back to posts/ instead of the site root. Reproduces in examples/websites/02-auto-sidebar (compare _site/ vs q1-site/).\n\n2. render_brand (line 297): navbar.logo_href.as_deref().unwrap_or(\"/\") falls back to absolute /, which is deployment-fragile (only works for domain-rooted hosts; breaks on file://, GitHub Pages project sites, sub-path deployments).\n\nPlus an adjacent gap in NavbarRenderTransform (crates/quarto-core/src/transforms/navbar_render.rs:114): rewrite_navigation_item_hrefs walks navbar.left/right/dropdown menus through resolve_href_for_html but doesn't touch navbar.logo_href, so user-supplied logo-href: about.qmd doesn't get the .qmd->.html rewrite or page-relative URL treatment.\n\nSame root-cause family as bd-swpy (closed). Sweep of render_html.rs + main HTML template confirmed these are the only home-link-style hardcodes; other unwrap_or(\"#\")/unwrap_or(\"\") fallbacks are correct no-op anchors and out of scope.\n\nFix plan: claude-notes/plans/2026-04-30-sidebar-title-home-link-relativize.md. Add ResourceResolverContext::page_url_for_site_root_dir; thread home_url: &str through sidebar_to_html and navbar_to_html; compute home_url from ctx.resource_resolver in SidebarRenderTransform and NavbarRenderTransform; add navbar.logo_href to the navbar transform's resolver-rewrite walk.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T19:31:25.256931Z","created_by":"cscheid","updated_at":"2026-04-30T19:52:29.349611Z","closed_at":"2026-04-30T19:52:29.349437Z","close_reason":"Fixed in feature/websites. Added ResourceResolverContext::page_url_for_site_root_dir; threaded home_url through sidebar_to_html and navbar_to_html (default ./ for no-resolver/single-doc); SidebarRenderTransform and NavbarRenderTransform compute home_url from ctx.resource_resolver; navbar.logo_href now goes through resolve_href_for_html (same .qmd->.html + page-relative treatment as ordinary nav items). 17 new unit tests pass. End-to-end verified on 02-auto-sidebar (sidebar-title: ./ at root, ../ in posts/), 04-navbar-footer (navbar-brand: ./ at root, ../ at depth-1), and 03-nested-sidebar (depth-1 sidebars all emit ../). 8140/8140 workspace tests pass; cargo xtask verify (full) passes.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jgeu","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-30T19:31:28.472953Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-jgeu","depends_on_id":"bd-swpy","type":"discovered-from","created_at":"2026-04-30T19:31:25.256931Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-jjep","title":"q2: website.navbar / website.page-footer (nested form) not recognised by chrome transforms","description":"Discovered while smoke-testing Phase F.2 against docs/_quarto.yml. q2 NavbarGenerateTransform reads top-level meta.navbar (and FooterGenerateTransform reads top-level meta.page-footer), but TS Quarto and the docs site author these nested under website.navbar / website.page-footer (the historical schema). Result: docs/index.qmd renders without a navbar or footer under both q2 render AND q2 preview.\n\nTwo options:\n1. Add a metadata-normalize step that hoists website.navbar → navbar / website.page-footer → page-footer when the top-level form is absent.\n2. Update NavbarGenerateTransform / FooterGenerateTransform to also check the website.* nested paths.\n\nOption 1 is the smaller change. Path: crates/quarto-core/src/transforms/metadata_normalize.rs.\n\nEmpirical evidence (this worktree, 2026-05-14): running cargo run --bin q2 -- render docs/about.qmd produces an HTML file with 0 occurrences of 'navbar' or 'footer.footer'. The same fixture renders correctly under TS Quarto.\n\nNot a Phase F regression — q2 has never supported the nested form. Filed so the docs site authoring loop isn't blocked indefinitely.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-14T22:28:53.901801Z","created_by":"cscheid","updated_at":"2026-05-19T15:13:00.358360Z","closed_at":"2026-05-19T15:13:00.358215Z","close_reason":"Implemented in d66ff31c: quarto_config::resolve_website_value() merges meta.<key> and meta.website.<key> with top-level winning on conflicts. Rewired resolve_navbar, resolve_page_footer, resolve_sidebar_membership, SidebarGenerateTransform, and derive_doc_scss_layer. End-to-end verified against docs/_quarto.yml.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jjep","depends_on_id":"bd-kw93.15","type":"discovered-from","created_at":"2026-05-14T22:28:53.901801Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-jsbg","title":"Implement crossref functionality for Quarto 2","description":"Port crossref functionality to Quarto 2 with improved architecture. Single-file first, with foundations for multi-file (books/websites). Fixes Q1 structural limitations (engine responsibilities, FloatRefTarget underutilization, theorems.lua front-end/back-end mixing). See plan: claude-notes/plans/2026-04-15-crossref-design.md","status":"open","priority":1,"issue_type":"epic","created_at":"2026-04-15T16:38:42.165655Z","created_by":"cscheid","updated_at":"2026-04-15T16:38:42.165655Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-jvxg","title":"Reader skips warning-collector diagnostics when parse errors are present in the same document","description":"In crates/pampa/src/readers/qmd.rs:144, when tree-sitter parsing produces errors, `read` returns `Err(diagnostics)` *before* invoking `treesitter_to_pandoc` (line 167). The latter is where the warning-collector pass runs — including the Q-2-36 path-A diagnostic site in `treesitter.rs::process_fenced_code_block`.\n\nEffect: a document with **both** a parse-error form (e.g. `\\`\\`\\`{r test}`) and a warning-collector-emitted form (e.g. `\\`\\`\\`{r echo=FALSE}`) reports only the parse error. The user has to fix the parse error and re-run to discover the second issue.\n\nReproduction (from Q-2-36 Phase 3 verification, 2026-05-14):\n\n\\`\\`\\`\n$ printf '%s\\n' '\\`\\`\\`{r test}' '1+1' '\\`\\`\\`' '' '\\`\\`\\`{python echo=FALSE}' 'print()' '\\`\\`\\`' | cargo run --bin pampa --\n[31mError:[0m [Q-2-36] Old-style knitr chunk options are not supported\n ... (only the {r test} error; the {python echo=FALSE} block is silent)\n\\`\\`\\`\n\nCompare to single-block variants — each individually fires Q-2-36 correctly (verified with /tmp/q236-cases/case2-7 individually).\n\nWhy this is pre-existing (NOT a Phase 1 regression): the code at qmd.rs:144 has not changed in the bd-j4fe work. At HEAD (`e2d224f6`), the same behavior held — the Q-2-8 *warning* would have been silently dropped when a parse error was present elsewhere in the document. The shape of the limitation just becomes more noticeable now that the path-A site produces an *error* rather than a warning, because users now expect both halves of a 'do not use knitr syntax' diagnostic to fire together.\n\nPossible fixes (not designed yet — needs scoping):\n\n1. Run `treesitter_to_pandoc` regardless of parse-error presence. Risk: the function may panic or produce garbage on ERROR-node-containing trees. Needs an audit + likely some defensive plumbing.\n\n2. A two-pass approach: separate AST construction (which can fail) from warning-collector emission (which is independent). Refactor.\n\n3. Limited fix: walk the tree once for warning emission, then run `treesitter_to_pandoc` only if `had_errors()` is false. Conceptually clean but requires factoring out the warning pass from `process_fenced_code_block`.\n\nThis is scope-creep relative to bd-j4fe (Q-2-36); filing as `discovered-from` so it doesn't block the Q-2-36 ship.\n\nDiscovered during: bd-j4fe Phase 3 verification (claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-14T20:36:20.915148Z","created_by":"cscheid","updated_at":"2026-05-14T20:36:20.915148Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jvxg","depends_on_id":"bd-j4fe","type":"discovered-from","created_at":"2026-05-14T20:36:20.915148Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-jxs5","title":"Refactor filter traversal-order tests to not depend on io.open","description":"8 filter integration tests use io.open to write traversal order to a temp file. This was fine when tests used real Lua io, but the test cfg proxy forces them through synthetic WASM io which only handles POSIX paths. Two options: (A) Refactor tests to collect order in a Lua table instead of writing files — removes io.open dependency entirely. (B) Part of the larger fix in bd-itj9: remove test from the WASM cfg guard so native tests use real Lua io — these tests would just work without changes. Option B is preferred since it fixes the root cause. This issue becomes unnecessary if bd-itj9 is resolved.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-02T13:35:34.988582Z","created_by":"cderv","updated_at":"2026-04-03T09:30:44.806290500Z","closed_at":"2026-04-03T09:30:44.799534200Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-jxs5","depends_on_id":"bd-itj9","type":"related","created_at":"2026-04-02T13:48:51.679858600Z","created_by":"cderv","metadata":"{}","thread_id":""}],"comments":[{"id":2,"issue_id":"bd-jxs5","author":"cderv","text":"After investigation: this issue is only needed if bd-itj9 is NOT done. If the test cfg proxy is removed (bd-itj9), native tests use Lua::new() with real C io library and these 8 tests just work on all platforms without refactoring. The io.open usage is a test harness detail, not a feature dependency. Current stopgap: #[cfg_attr(windows, ignore)] on the 8 tests — they still run on Linux/macOS CI where the proxy works.","created_at":"2026-04-02T15:16:36Z"}]} +{"id":"bd-k4ahh","title":"q2 render <large-non-project-dir> also walks the tree before erroring","description":"Symmetric to bd-nmkmi but on the with-arguments path: `q2 render <dir>` where `<dir>` has no ancestor `_quarto.yml` walks the directory tree for `.qmd` files before deciding it's not a project. In `crates/quarto/src/commands/render.rs::classify_inputs` (lines ~206-235), each resolved input is passed to `ProjectContext::discover`, which falls through to the recursive walk on directory inputs without a project marker. The walk's output is discarded by the subsequent `is_real_project` check, then the `is_dir` branch returns `NoRenderableMatches`.\n\nSame fix pattern as bd-nmkmi: short-circuit the \"directory input, no ancestor `_quarto.yml`\" case using `find_project_root_upward` before calling `ProjectContext::discover`.\n\nLower priority (P3) than bd-nmkmi (P2) because the user has to explicitly point `q2 render` at a directory to hit it — much less common than the bare `q2 render`. Filed as discovered-from to keep the fix scope-disciplined.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-20T14:53:19.291221Z","created_by":"cscheid","updated_at":"2026-05-20T14:53:19.291221Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["cli","perf","render"],"dependencies":[{"issue_id":"bd-k4ahh","depends_on_id":"bd-nmkmi","type":"discovered-from","created_at":"2026-05-20T14:53:19.291221Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-k8ol","title":"Mode B: partial Pass-1 walk to skip non-target profile re-extraction","description":"Phase 8.2 originally planned partial Pass-1 in Mode B: only profile the user-named targets plus their dependency closure. Implementation discovered a chicken-and-egg with sidebar auto: expansion (the membership resolver consults the index, which doesn't yet exist for non-target pages until they've been profiled). v1 ships full Pass-1 in both modes; the cache makes it cheap on the warm path. Decoupling the auto: resolver from index existence lets us land the partial walk and amortize Pass-1 cost on truly cold runs of huge projects. See claude-notes/plans/2026-04-27-websites-phase-8.md §'Sub-phase 8.2 — Deviation from plan'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:47.359008Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-k8ol","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-k8ol","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-k8y0","title":"[websites] Sidebar vertical border missing (Q1 parity) — needs doc-derived SCSS variables seam","description":"Quarto 1 renders a faint vertical line between a docked sidebar and main content; Quarto 2 does not. Verified visually in examples/websites/03-nested-sidebar (q1-site has it, _site does not). \n\nRoot cause: two missing pieces in Q2.\n\n1. The SCSS rule '.sidebar.sidebar-navigation:not(.rollup) { border-right: 1px solid $table-border-color !important; }' (gated by '@if $sidebar-border') exists in Q1 (quarto-cli/src/resources/projects/website/navigation/quarto-nav.scss:552-556) but was never ported to resources/scss/bootstrap/_bootstrap-rules.scss in Q2.\n\n2. Q2 has no mechanism to inject per-document SCSS variables before the framework defaults. CompileThemeCssStage only reads theme config from doc.ast.meta; it never threads website.sidebar info into the SCSS bundle. Q1's format-html-scss.ts:631-642 synthesizes '$sidebar-border: <bool>;' per-document, defaulting to (style == 'docked').\n\nCustomization: end users override via 'sidebar.border: true|false' in YAML (Q1). Color follows the active Bootstrap/Bootswatch theme via $table-border-color (no special handling needed — themes already override it).\n\nPhased plan in claude-notes/plans/2026-04-30-sidebar-vertical-border.md:\n- Phase 1: port the @if $sidebar-border SCSS rule.\n- Phase 2: introduce derive_doc_scss_layer hook in CompileThemeCssStage; emit $sidebar-border per-document. Generic enough to reuse for sidebar/navbar/footer bg+fg later.\n- Phase 3: add 'border: Option<bool>' field to Sidebar struct for full Q1 parity.\n- Phase 4: end-to-end verification + docs.\n\nPhase 2 also tightens the theme CSS cache key to include the doc-vars layer so two docs with different sidebar configs don't collide on the generic 'default_minified' key.\n\nPlan file: claude-notes/plans/2026-04-30-sidebar-vertical-border.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-30T20:16:52.060454Z","created_by":"cscheid","updated_at":"2026-04-30T20:36:56.920069Z","closed_at":"2026-04-30T20:36:56.919907Z","close_reason":"Implemented across 4 phases: Phase 1 ported the @if $sidebar-border SCSS rule from quarto-cli quarto-nav.scss:552-556 into resources/scss/bootstrap/_bootstrap-rules.scss. Phase 2 introduced derive_doc_scss_layer() in CompileThemeCssStage and quarto_sass::compile_with_doc_vars() to thread per-document SCSS variables through the bundle ahead of framework defaults. Phase 3 added Sidebar.border (Option<bool>) for full Q1 parity on the sidebar.border knob. Phase 4 verified end-to-end via cargo run --bin q2 -- render on examples/websites/03-nested-sidebar — the rule now appears in the emitted CSS — and documented the knob in docs/navigation.qmd. Follow-up bd-8oqw filed for refactoring cache_key into a structured CompileInputs value type.","source_repo":".","compaction_level":0,"original_size":0,"labels":["scss","sidebar","websites"],"dependencies":[{"issue_id":"bd-k8y0","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-30T20:16:52.060454Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-k9i1","title":"project.resources support for non-renderable site resources","description":"Q1 supports project.resources: [patterns...] in _quarto.yml, which are globs for files to copy to the output dir alongside rendered HTML but not passed through the render pipeline (e.g. CNAME, robots.txt, images not referenced from qmds). Phase 1 of the website epic does not support this. Implement in ProjectPipeline (probably a third phase after Pass 2) or WebsiteProjectType::post_render.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T01:05:17.897545Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:17.897545Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-k9i1","depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:17.897545Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-khuj","title":"Hub-client UI smoke for template diagnostics","description":"After bd-xdnk plumbed doctemplate diagnostics through quarto render, the hub-client side rides the existing diagnostics_to_json -> JsonDiagnostic.warnings rails. No code changes were needed there, but a live browser smoke test would confirm a Q-10-2 warning shows up in the hub-client diagnostics panel and as a Monaco marker on the template file.\n\nSteps:\n1. Open hub-client against a project containing a custom template that references an undefined variable.\n2. Confirm the warning appears in the diagnostics panel with the correct file/line/column.\n3. Confirm Monaco shows a marker on the template's variable position when that file is open.\n4. Capture screenshots or notes in the bd-xdnk plan.\n\nDiscovered while doing bd-xdnk; not blocking that fix because the data flow uses well-tested rails.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-05T16:36:08.563749Z","created_by":"cscheid","updated_at":"2026-05-05T16:36:08.563749Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-khuj","depends_on_id":"bd-xdnk","type":"discovered-from","created_at":"2026-05-05T16:36:08.563749Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-kk0a","title":"qmd writer: position-dependent escapes (`:`, `'`/`\"` unbalanced, `1.`/`-`/`+` line-start list markers)","description":"Discovered during the bd-21gu Phase 2 audit (claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md). The qmd writer's escape_markdown helper is char-by-char and has no position context, so it can't fix escapes that depend on whether a char is at line-start or in unbalanced-quote position. The Phase 2 audit identified four bug classes that all need the same shape of fix:\n\n1. `:` at line start — triggers fenced div parser. Mid-line `:` is fine.\n Repro: a Str body containing \":word\" at the start of a line round-trips\n to a parse error.\n\n2. `'` and `\"` unbalanced — when a Str body coming from JSON contains a\n literal `'` or `\"` (not part of a Quoted node), the writer emits it\n unescaped and the re-parser produces an unclosed-quote error. Mid-word\n apostrophe (`a'b`) round-trips fine via smart-quote handling.\n\n3. `1.`/`-`/`+` followed by Space at line start — Str \"1.\" + Space + Str\n \"foo\" round-trips to OrderedList. Same for unordered list markers `-` /\n `+` followed by space at line start. The dot/dash itself is innocuous\n mid-word but becomes a list-marker trigger only at line-start with a\n following space.\n\n Repro:\n printf '1\\\\. foo\\n' | cargo run --bin pampa -- -t qmd | cargo run --bin pampa -- -t native\n → OrderedList (1, Decimal, Period) [[Plain [Str \"foo\"]]]\n Expected: Para [Str \"1.\", Space, Str \"foo\"]\n\nCommon requirement: writer needs (a) line-start tracking and (b) lookahead\nacross adjacent inline nodes to know whether escaping is needed for the\ncurrent character. This is a larger refactor than escape_markdown can\nabsorb — likely a new pass over the inline sequence in write_para or a\nposition-aware writer-context flag that get_str consults.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-01T00:31:59.051282Z","created_by":"cscheid","updated_at":"2026-05-01T00:32:14.786935Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kk0a","depends_on_id":"bd-21gu","type":"discovered-from","created_at":"2026-05-01T00:31:59.051282Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93","title":"q2 preview epic: ephemeral local hub-client as Q2 replacement for quarto preview","description":"Implement `q2 preview` as a native CLI wrapping an ephemeral local hub-client instance. Uses samod for sync, the q2-preview React format for incremental DOM-stable rendering, and engine: replay for server-records / browser-replays code execution. See claude-notes/plans/2026-05-11-q2-preview-epic.md for architecture, phasing (A: skeleton + standalone SPA serving, B: file-watcher and remap broadening, C: engine execution via replay-on-server, D: polish + parity, E: stretch), and open questions awaiting user sign-off before phase plans are drafted. Branch: feature/q2-preview.","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-11T14:14:19.736224Z","created_by":"cscheid","updated_at":"2026-05-11T15:41:14.986644Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93","depends_on_id":"bd-hfjj","type":"blocks","created_at":"2026-05-11T15:41:14.986468Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.1","title":"Phase C.3: IndexDocument capture sidecar schema + WASM signature widen","description":"Foundational schema change for Phase C engine execution. Lands the sidecar map on IndexDocument that C.1/C.2/C.4/C.5 all consume, and widens the WASM render_page_for_preview signature to accept an optional EngineCapture.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.3 for the full test plan and acceptance criteria.\n\nPer Q-C1 the schema is additive (sidecar map keyed by path, not migration of files):\n\n interface IndexDocument {\n files: Record<string, string>;\n captures?: Record<string, CaptureRef>;\n version?: number; // bumped to 2\n identities?: Record<string, ActorIdentity>;\n }\n interface CaptureRef {\n captureDocId: string;\n staleness?: boolean;\n state?: 'idle' | 'running' | 'error';\n lastError?: string;\n }\n\nPer Q-C4 the state field is reserved (not just an 'executing' boolean) so we can grow to a status enum without another migration.\n\nAffects: ts-packages/quarto-automerge-schema/src/index.ts, crates/quarto-hub/src/index.rs, ts-packages/quarto-sync-client/src/{types,client}.ts, and crates/wasm-quarto-hub-client/src/lib.rs:1171 + ts-packages/preview-runtime/src/wasmRenderer.ts:436.\n\nAcceptance: schema roundtrip + migration tests pass; full workspace remains green; SPA build unaffected for the (no-capture) case.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:02.968438Z","created_by":"cscheid","updated_at":"2026-05-14T14:52:55.421565Z","closed_at":"2026-05-14T14:52:55.421417Z","close_reason":"Phase C.3 schema lands across three commits on beads/bd-kw93.1-phase-c3-indexdocument-capture:\n\n 2bdd6a5e — TS schema: CaptureRef + captures? sidecar, CURRENT_SCHEMA_VERSION 1→2, migrateIndexDocument staged V0→V1→V2 (47 tests pass)\n 6a0af0e2 — sync-client wire-up: CaptureRef re-export, onCapturesChange callback, notifyCapturesIfChanged fires on connect/change/createProject (70/70 tests, typecheck clean)\n 804b8338 — Rust IndexDocument mirror: CaptureState enum, CaptureRef struct, set/get/has/remove/get_all_captures, files+captures independent maps test pins plan §Risks #3 cleanup obligation (186/186 quarto-hub tests)\n\ncargo xtask verify --skip-hub-build all 12 steps green.\n\nWASM signature widening (originally in the C.3 dep-graph summary) deferred to bd-kw93.3 (C.4) where the dispatch logic actually lives; doing it here without EngineRegistry::with_replay wiring would have been a half-finished parameter. bd-kw93.3 description updated to absorb it.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.3","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.1","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:02.968438Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.10","title":"Phase D.4: Diagnostics surface — render + engine errors in PreviewErrorOverlay","description":"PreviewErrorOverlay already handles connection errors (PreviewApp.tsx:291). D.4 extends it to (a) catch WASM-renderer exceptions in the active-page render useEffect and surface the message; (b) surface CaptureRef.lastError from C.5's re-execute path when state === 'error', so engine failures aren't invisible.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.4.\n\nAcceptance: 2 unit (SPA) + 1 e2e.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:37:54.466643Z","created_by":"cscheid","updated_at":"2026-05-14T19:03:56.199388Z","closed_at":"2026-05-14T19:03:56.199257Z","close_reason":"Phase D.4 complete: render-pipeline failures now overlay PreviewErrorOverlay on top of the last-good iframe render instead of flipping to terminal boot:error. New renderError state slot, distinct from boot error. Engine errors continue to surface via StaleCaptureOverlay (pinned with new integration test). Drive-by fix: pre-existing TS error in StaleCaptureOverlay test that was breaking npm run build. 3 new SPA integration tests; workspace nextest 8938/8938; production build clean. Merged to feature/q2-preview-command as commit 1d5c6c6e.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.10","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:54.466643Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.11","title":"Phase D.5: User-facing documentation for q2 preview","description":"New docs/q2-preview.qmd (or similar) covering: what q2 preview does, basic usage, flags, preview.engine config, staleness affordance, and known limitations. Add to docs/_quarto.yml navigation. Mirror TypeScript Quarto's preview docs in tone.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.5.\n\nAcceptance: docs build cleanly; manual review of rendered page.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-14T18:37:57.132290Z","created_by":"cscheid","updated_at":"2026-05-14T19:49:42.417213Z","closed_at":"2026-05-14T19:49:42.417063Z","close_reason":"Phase D.5 complete: docs/q2-preview.qmd covers usage, preview.engine config, error UX, flags, limitations. clap --help tightened to user voice. bd-9ofu filed to track the deferred 'find a proper home for Q2 CLI docs' IA question. quarto render of the page produces clean HTML; workspace nextest 8951/8951. Merged to feature/q2-preview-command as commit f5a5fac7.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.11","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:57.132290Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.12","title":"Phase D.6: Dep-graph filter for re-renders","description":"Every content change today bumps contentTick + re-renders the active page, even for unrelated sibling edits. This is the relaxed criterion from Phase B.4 (criterion 3). D.6 uses the existing ProjectDependencyGraph to filter: only signal the SPA's contentTick when the edited file is the active page OR a dependency of it.\n\nSettled: filter runs server-side. SPA tells the server its active path; the server's existing watcher → sync_file hook becomes filter-aware. Restores Phase B.4's strict criterion.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.6. Unblocks bd-0mji's regression tests.\n\nAcceptance: unit + 2 e2e (positive and negative cases).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:38:00.690236Z","created_by":"cscheid","updated_at":"2026-05-14T19:25:32.286028Z","closed_at":"2026-05-14T19:25:32.285894Z","close_reason":"Phase D.6 complete: GET /api/preview/deps?page=<rel> returns single-hop include-shortcode deps. SPA filters onFileContent — drops sibling .qmd edits not in the active page's dep set; non-qmd edits (CSS, _quarto.yml, .tsx, images) pass through. Restores Phase B.4's deferred strict criterion. 11 unit + 2 Playwright tests; B.3's include-shortcode spec still passes. Workspace nextest 8949/8949; SPA 21/21+8/8; Playwright 13/13. Out-of-scope follow-ups: transitive includes, image/bibliography deps. Merged to feature/q2-preview-command as commit 7310d44b.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.12","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:38:00.690236Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.13","title":"Phase D.2: Initial-path resolution (project index vs file)","description":"Today 'q2 preview foo.qmd' opens the SPA, which picks firstQmd from the file index (PreviewApp.tsx:199-203). The user's requested file isn't honored. D.2 threads the requested path from CLI -> URL query (?page=foo.qmd) -> SPA seeds activeFile from it. In project mode without a path, prefer index.qmd over firstQmd.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.2 for seams + tests.\n\nAcceptance: 1 unit (Rust) + 1 unit (TS) + 1 integration test.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:38:11.988045Z","created_by":"cscheid","updated_at":"2026-05-14T18:54:59.098690Z","closed_at":"2026-05-14T18:54:59.098418Z","close_reason":"Phase D.2 complete: CLI threads requested path via ?page=<rel> through to SPA. resolve_project_and_initial_page walks up for _quarto.yml so 'q2 preview <proj>/posts/intro.qmd' indexes the whole project and seeds activeFile. pickInitialPage on SPA side validates against index and rejects .. traversal. 9 Rust + 8 SPA unit + 2 SPA integration tests. Workspace nextest 8938/8938; SPA 26/26. Binary smoke against /tmp/q2-d2-smoke confirms three URL shapes. Merged to feature/q2-preview-command as commit f9e23762.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.13","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:38:11.988045Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.14","title":"Phase F.1: Cross-page navigation + link-rewriting + Bootstrap JS","description":"Foundational sub-task for Phase F (q2-preview website chrome). Three things land together because they're co-dependent:\n\n1. Include link-rewrite in q2-preview pipeline. Removes 'link-rewrite' from Q2_PREVIEW_TRANSFORM_EXCLUDED at crates/quarto-core/src/pipeline.rs:1057. After this, body and chrome hrefs alike are .html URLs.\n\n2. Cross-page click navigation in the SPA. Extend iframePostProcessor.ts to recognize .html URLs that map back to project .qmd files (check against project file index — NOT just the .html suffix, so external https://example.com/foo.html stays untouched). Wire onNavigateToDocument in PreviewApp.tsx — invocation calls setState to switch activeFile. history.pushState so browser back/forward walks the in-SPA navigation. popstate listener to handle back/forward. After activeFile changes and the render fires, scroll the iframe to window.location.hash if present (coordinate with iframe's post-render hook, not the state change, to avoid the race).\n\n3. Bootstrap JS in the iframe. The chrome HTML emitted by navbar-render etc. uses Bootstrap dropdowns/collapses. The WASM pipeline currently excludes BootstrapJsStage (crates/quarto-core/src/stage/stages/bootstrap_js.rs). Two options to evaluate during implementation:\n (a) Include BootstrapJsStage in the WASM pipeline by removing the cfg gate, if state-preservation concerns the original gate guarded against don't apply to q2-preview's iframe model.\n (b) Statically inject bootstrap.bundle.min.js into the iframe template alongside the existing Bootstrap CSS — cleaner for preview because it bypasses any state concerns and lets Bootstrap 5's data-bs-* auto-init handle freshly-rendered chrome DOM.\nPick whichever's cleaner; document the choice.\n\nReference: math_js.rs at crates/quarto-core/src/stage/stages/math_js.rs — MathJsStage ships on both native and WASM pipelines because the engine 'typesets once on DOMContentLoaded' and holds no cross-reinit state. Bootstrap can ride the same pattern.\n\nAcceptance (per plan §F.1):\n- Playwright spec navigates a multi-page fixture via body link clicks + window.history.back() — back-button works. Anchor links scroll to the right section. Missing-page link shows the D.4 error overlay.\n- Playwright spec verifies a Bootstrap-driven element actually toggles when clicked.\n- Existing tests + workspace nextest 8952/8952 don't regress.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-f.md §F.1 for full seams + test plan. Settled decisions baked into the plan: F-D1 (HTML injection), F-D2 (full SPA-style routing), F-D3 (all hrefs become .html), F-D4 (chrome scope = whatever q2 render emits today), F-D5 (structural assertions, not snapshot parity).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T20:51:59.453550Z","created_by":"cscheid","updated_at":"2026-05-14T21:54:47.981900Z","closed_at":"2026-05-14T21:54:47.981771Z","close_reason":"Phase F.1 implemented + verified. See feature/q2-preview-command merge commit 1c104916; plan §F.1 closeout for diff summary.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.14","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T20:51:59.453550Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.15","title":"Phase F.2: All chrome injection + favicon + docs closeout","description":"Bundles the five chrome injections (navbar, sidebar, page-nav, TOC, footer) + favicon polish + docs/q2-preview.qmd truthing-up + Phase F closeout. Each chrome item follows the same pattern, so they bundle cheaply.\n\nServer side: remove from Q2_PREVIEW_TRANSFORM_EXCLUDED at crates/quarto-core/src/pipeline.rs:1057:\n- 'navbar-render'\n- 'sidebar-render'\n- 'page-nav-render'\n- 'toc-render'\n- 'footer-render'\n- 'website-favicon'\n\nReact side: in ts-packages/preview-renderer/src/q2-preview/PreviewDocument.tsx, add five dangerouslySetInnerHTML slots reading meta.rendered.navigation.{navbar,sidebar,page-nav,toc,footer}. Use React.memo + prop-equality on the string so React only re-renders the slot when the chrome HTML actually changes (mostly: _quarto.yml edits and page switches). The wrapper structure (where each chrome slot lives in PreviewDocument) should mirror what q2 render emits for the same fixture — read examples/websites/04-navbar-footer/_site/index.html for a reference and copy the wrapper divs.\n\nImplementation pattern from the plan:\n\nconst navbarHtml = extractMetaString(meta.rendered?.navigation?.navbar);\nreturn <NavbarSlot html={navbarHtml ?? ''} />;\n\n// NavbarSlot.tsx\nconst NavbarSlot = memo(({ html }: { html: string }) => (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n));\n\nDocs: update docs/q2-preview.qmd to remove the limitations bullet about missing chrome; update the 'what live means' section to mention chrome re-render semantics (chrome re-renders on _quarto.yml change or page switch).\n\nPlan housekeeping: mark Phase F done in claude-notes/plans/2026-05-11-q2-preview-epic.md and claude-notes/plans/2026-05-14-q2-preview-phase-f.md.\n\nAcceptance (per plan §F.2):\n- Playwright specs against examples/websites/04-navbar-footer/, examples/websites/02-auto-sidebar/, examples/websites/03-nested-sidebar/:\n - Navbar renders + clickable + clicking switches active page (proves F.1 ↔ F.2 integration).\n - Sidebar renders; active page highlighted; clicking other pages re-highlights.\n - Page-nav renders on pages with sidebar ordering.\n - TOC renders on pages with sections; entry clicks scroll to section.\n - Footer renders on projects configuring page-footer:.\n - Bootstrap-driven chrome elements (navbar dropdown menus, sidebar collapse toggles) actually open/close.\n- Manual smoke against the q2 docs site fixture (the user's in-flight authoring target): full chrome visible, navigation works.\n- docs/q2-preview.qmd renders cleanly.\n- Workspace nextest 8952/8952 green; Playwright N+5 green.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-f.md §F.2 for full seams + test plan. The eventual React-components-replacing-HTML-injection follow-up is tracked separately as bd-d8fo (carlos@ asked it be filed at planning time).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid","updated_at":"2026-05-14T22:30:55.140008Z","closed_at":"2026-05-14T22:30:55.139881Z","close_reason":"Phase F.2 implemented + verified. Merged on feature/q2-preview-command. Discovered bd-jjep (website.navbar nested-form schema gap) — not a Phase F regression.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.15","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.15","depends_on_id":"bd-kw93.14","type":"blocks","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.2","title":"Phase C.1: Server-side first-time eager engine capture","description":"When q2 preview opens a doc with code cells and no existing capture, the server runs the engine once and writes the resulting EngineCapture into automerge as a binary doc, with a sidecar entry pointing at it.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.1 for the full test plan and acceptance criteria.\n\nPer Q-C2 the implementation reuses the existing pipeline, capped at EngineExecutionStage (a 'preview-record' sub-pipeline). New module crates/quarto-core/src/engine/preview_record.rs exports a record_capture(path, project, runtime) -> Result<Option<EngineCapture>> function. None means no code cells.\n\nPer Q-C3 the input_qmd recorded is the whole serialized post-include-expansion QMD (matches what EngineExecutionStage feeds to engines today and what ReplayEngine validates on).\n\nAffects: crates/quarto-preview/src/lib.rs (capture driver), crates/quarto-hub/src/server.rs (sync_file hook), new crates/quarto-core/src/engine/preview_record.rs.\n\nAcceptance: unit + integration tests pass; end-to-end smoke against a markdown-engine fixture (no R/Python needed in CI) shows 'Executing code…' overlay between mount and capture landing, then captured output in the rendered DOM.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid","updated_at":"2026-05-14T15:38:54.938362Z","closed_at":"2026-05-14T15:38:54.938187Z","close_reason":"Phase C.1 server-side eager engine-capture lands across four commits on beads/bd-kw93.2-phase-c1-server-side:\n\n be7898a1 — preview_record sub-pipeline + CaptureCollector observer in quarto-core (4 unit tests).\n 342a18c9 — capture_driver in quarto-preview: gzipped-JSON binary doc + sidecar write, sequential per-file, server hook via new on_ready callback in run_server_with (5 unit tests).\n 1b9c6443 — run_with_on_ready API + end-to-end integration test that drives the full server lifecycle against a passthrough-engine fixture, polls sidecar, round-trips binary doc (2 integration tests). Binary smoke confirms boot path.\n 31bfebb7 — plan checklist for C.1 marked complete.\n\nTotal: 11 tests pass (4 preview_record unit + 5 capture_driver unit + 2 integration); cargo xtask verify --skip-hub-build all 12 steps green.\n\nArchitectural notes:\n- is the only quarto-hub change. Engine awareness stays in quarto-preview (the engine-aware app).\n- Pipeline futures are ?Send by the project's async_trait convention; driver runs on spawn_blocking + pollster::block_on so the multi-threaded tokio runtime stays free.\n- Sequential per-file processing caps plan §C.1 Risk #2.\n- Real-engine end-to-end (jupyter/knitr) not run this session; integration test uses a passthrough engine via PreviewConfig::engine_registry.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.1","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.2","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.2","depends_on_id":"bd-kw93.1","type":"blocks","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.3","title":"Phase C.4: Browser-side replay wiring through render_page_for_preview","description":"Widen render_page_for_preview (and render_page_in_project) to accept an optional EngineCapture; inside WASM, construct EngineRegistry::with_replay(capture) when present, fall through to default otherwise.\n\nScope absorbed from C.3 (2026-05-14): the WASM signature widen was originally listed in the C.3 dependency-graph summary but its detailed Affects list + test plan in plan §C.4 own it; doing it in C.3 without the dispatch logic would be a half-finished implementation. C.3 (bd-kw93.1) closed without touching WASM; this issue now covers both the signature AND the dispatch.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.4 for the full test plan and acceptance criteria.\n\nThe capture flows from the binary doc (samod-stored gzipped JSON of EngineCapture) through the SPA, into the WASM renderer. Sidecar entry from C.3 (now landed) supplies the captureDocId; sync-client onCapturesChange callback (also landed in C.3) gives the SPA the path -> captureDocId map without further plumbing.\n\nAffects: crates/wasm-quarto-hub-client/src/lib.rs:1171 (render_page_for_preview), ts-packages/preview-runtime/src/wasmRenderer.ts:436, q2-preview-spa/src/PreviewApp.tsx:202.\n\nAcceptance: WASM unit tests with a hand-authored EngineCapture pass; SPA renders cleanly in both (capture supplied) and (no capture) paths.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid","updated_at":"2026-05-14T15:57:12.278221Z","closed_at":"2026-05-14T15:57:12.278057Z","close_reason":"Phase C.4 browser-side capture replay lands as 2f97c27b + 36816ca7 on beads/bd-kw93.3-phase-c4-browser-side.\n\nWiring:\n- WASM render_page_for_preview widened to take Option<Vec<u8>> (gzipped JSON EngineCapture bytes); internal build_replay_registry_from ungzips + parses + constructs EngineRegistry::with_replay.\n- render_qmd_to_preview_ast widened to accept engine_registry; threads through build_q2_preview_pipeline_stages -> EngineExecutionStage::with_registry.\n- TS surface: getBinaryDocById on the sync client + preview-runtime; CaptureRef re-exported from sync-client; renderPageForPreview takes the optional capture as Uint8Array.\n- SPA: PreviewApp listens for onCapturesChange, looks up the active page's captureDocId, fetches the binary doc, passes bytes to renderPageForPreview.\n\nTests: 2 new SPA integration tests (10/10 SPA tests pass), 70/70 sync-client tests, all 12 cargo xtask verify steps green (incl. real WASM build + hub-client tests).\n\nEnd-to-end loop is now closed: server records (C.1) -> automerge sidecar (C.3) -> browser replays (C.4).\n\nAcceptance gap: Playwright + real WASM smoke against a live preview with a hand-authored capture not run (substantial harness setup; not blocking).\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.4","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.3","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.3","depends_on_id":"bd-kw93.1","type":"blocks","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.4","title":"Phase C.2: Staleness detection on doc-content change","description":"On every doc-content change, if a capture exists for that doc, compare the freshly-serialized input_qmd byte-for-byte against the capture's input_qmd. If different, set staleness: true on the sidecar entry. Do NOT re-execute (unless preview.engine: auto — see C.6).\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2 for the full test plan and acceptance criteria.\n\nPer Q-C3 v1 uses whole-QMD byte-equality, matching ReplayEngine's validation. This means prose-only edits also flip staleness: true; documented as a known v1 limitation, refinement is a follow-up.\n\nAffects: crates/quarto-hub/src/server.rs:1040 (run_file_watcher → sync_file), reuses canonicalization function exported from C.1's preview_record module.\n\nAcceptance: unit + 2 integration tests pass (one for code-cell edit, one documenting the prose-edit known limitation).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid","updated_at":"2026-05-14T16:26:38.814900Z","closed_at":"2026-05-14T16:26:38.814761Z","close_reason":"Phase C.2 staleness detection lands across three commits on beads/bd-kw93.4-phase-c2-staleness-detection:\n\n 6c3b1ea9 — compute_input_qmd canonicalization function in quarto-core (4 unit tests).\n e0cc639b — capture_driver recompute_staleness + OnFileChangedCallback wiring through run_server_with (5 unit tests).\n 7caf027e — plan checklist for C.2 marked complete.\n\nTotal: 9 new unit tests; cargo xtask verify --skip-hub-build all 12 steps green.\n\nArchitecture:\n- compute_input_qmd truncates the q2-preview pipeline at PreEngineSugaringStage and serializes the AST to QMD. Same output EngineExecutionStage would hand to the engine; byte-equality vs the recorded capture's input_qmd is the staleness signal.\n- recompute_staleness reads existing sidecar entry, ungzips + parses the capture binary doc, runs compute_input_qmd on the current file, compares bytes, flips CaptureRef.staleness when needed. Idempotent.\n- New OnFileChangedCallback type on quarto_hub::server. quarto-preview registers it from run_with_on_ready alongside the existing on_ready. Pipeline futures are ?Send; dispatches via spawn_blocking + pollster::block_on.\n- Canonicalizes both project_root and the watcher's absolute path for macOS /tmp vs /private/tmp.\n\nPlan §Q-C3 v1 limitation pinned in tests: whole-QMD byte-equality means prose-only edits also flip staleness. A future cell-only diff lands as a deliberate behaviour change.\n\nAcceptance gap: an in-process Rust integration test for the full watcher→staleness loop was drafted but flaky under cargo nextest run on macOS (suspected notify-rs/FSEvents + nextest stdout capture interaction). Filed as bd-u3ze. Coverage by:\n- 9 unit tests + 4 prior compute_input_qmd tests.\n- Binary smoke (q2 preview against /tmp/c2-smoke with RUST_LOG=debug) confirms the watcher → sync_file → on_file_changed → recompute_staleness path fires.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.4","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.4","depends_on_id":"bd-kw93.2","type":"blocks","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.5","title":"Phase C.5: Stale-capture UX overlay + /api/preview/re-execute endpoint","description":"When staleness: true, the SPA still renders using the previous capture (preview remains responsive) and shows a fixed-position overlay 'Code has changed. Re-execute?' with a button. The button POSTs to a new /api/preview/re-execute endpoint, which validates the path, kicks off the engine driver from C.1, and returns 202 Accepted.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.5 for the full test plan and acceptance criteria.\n\nPer Q-C5: POST body { path }; server returns 202 with { captureDocId } — capture flows back via samod sync, not HTTP body. Concurrent re-execute requests for the same path get 409 Conflict; UI button is disabled while state == 'running'. Auth is loopback-only (carried from Phase A).\n\nAffects: q2-preview-spa/src/PreviewApp.tsx + new StaleCaptureOverlay component (mirror PreviewErrorOverlay), crates/quarto-preview/src/lib.rs (register route alongside extend_with_spa), server-side handler that re-uses C.1's capture driver.\n\nAcceptance: SPA unit tests, API unit tests for 400/409/403 error paths, and end-to-end Playwright spec for the full edit→overlay→click→new-capture flow.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid","updated_at":"2026-05-14T16:42:10.987517Z","closed_at":"2026-05-14T16:42:10.987362Z","close_reason":"Phase C.5 stale-capture UX + re-execute endpoint lands across cf33c604 + 8d31a320 on beads/bd-kw93.5-phase-c5-stale-capture.\n\nSurface: POST /api/preview/re-execute (400/409/202 semantics), new <StaleCaptureOverlay /> component, integrated into PreviewApp via the existing onCapturesChange channel. Hub router refactored to delay with_state(ctx) so extensions can register State<SharedContext>-extracting routes.\n\nTests: 3 new Rust unit tests (path validation, 202 happy path, 409 concurrent) + 6 SPA integration tests (button states, POST shape, error handling). 2118/2118 Rust tests, 16/16 SPA integration tests.\n\nEnd-to-end UX loop now closes: server records (C.1) → sidecar (C.3) → browser replays (C.4) → file edit flips staleness (C.2) → SPA overlay shows + Re-execute POSTs (C.5) → server records new capture → SPA picks it up via samod sync.\n\nAcceptance gap: Playwright e2e (edit cell on disk → overlay → click → new capture renders) deferred — depends on the broader e2e harness Phase D/E will introduce.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.5","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.5","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.5","depends_on_id":"bd-kw93.3","type":"blocks","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.5","depends_on_id":"bd-kw93.4","type":"blocks","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.6","title":"Phase C.6: preview.engine config (manual | auto | off)","description":"Read preview.engine from merged metadata. Three values:\n- manual (default): C.5 behaviour — server detects staleness, user must opt in via the overlay button.\n- auto: server re-executes on every code-cell change (no overlay needed).\n- off: server never executes. Code cells render as inert source; C.1's eager run is also skipped.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.6 for the full test plan and acceptance criteria.\n\nThe metadata flows through MetadataMergeStage like any other key. The consumer is the new preview-record driver (not the pipeline). Config is read at session start and on _quarto.yml changes (à la Phase B.4 propagation).\n\nAffects: crates/quarto-preview/src/config.rs (or similar) — read merged metadata; the existing C.1/C.5 driver branches on this.\n\nAcceptance: 1 unit + 3 integration tests (auto re-executes; off skips eager + suppresses code-cell exec; manual unchanged from C.5).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid","updated_at":"2026-05-14T17:16:42.583327Z","closed_at":"2026-05-14T17:16:42.583165Z","close_reason":"Phase C.6 complete: preview.engine config (manual|auto|off) parsed from _quarto.yml, EnginePolicy threaded through capture driver, Off skips eager + suppresses staleness, Auto kicks off re-execute via shared claim_and_spawn helper. 9 config unit tests + 3 driver tests + binary smoke against /tmp/q2-c6-smoke/{manual,auto,off}. Workspace nextest: 8913/8913. Merged into feature/q2-preview-command as commit 9fc4c984.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.6","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.6","depends_on_id":"bd-kw93.5","type":"blocks","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.7","title":"Phase C.7: Per-doc capture filesystem cache","description":"Filesystem cache at <tempdir>/captures/<content-hash>.bin (gzipped EngineCapture). When the server is about to run the engine, check the cache; if present, skip the engine and write the cached capture directly to automerge.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.7 for the full test plan and acceptance criteria.\n\nPer Q-C6 the cache key is the full input_qmd bytes (same canonicalization function as C.2's staleness check, kept in sync to prevent drift).\n\nAffects: new crates/quarto-preview/src/cache.rs; the C.1 capture driver wraps engine invocation with cache lookup/insert.\n\nOpen follow-up (noted in plan §C.7): cache lives in per-session tempdir for MVP; per-project location would be friendlier for cross-session reuse. Mark for review.\n\nAcceptance: round-trip unit test + 2 integration tests (revert-edit cache hit; cross-session reuse if applicable).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:30.638380Z","closed_at":"2026-05-14T17:35:30.638250Z","close_reason":"Phase C.7 complete: per-doc filesystem cache at <data_dir>/captures/<sha256(input_qmd)>.bin. record_capture_cached wrapper integrated into all three drivers (eager, Auto re-execute, HTTP /api/preview/re-execute). 8 cache primitives + 4 wrapper unit tests with counting engine + 1 integration test in tests/cache_hit.rs. cargo nextest run --workspace: 8926/8926 pass. Binary smoke against /tmp/q2-c7-smoke clean. Open follow-up: cache in per-session tempdir; per-project location for cross-session reuse is future work. Merged into feature/q2-preview-command as commit 3bac5e93.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.7","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-kw93.7","depends_on_id":"bd-kw93.5","type":"blocks","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.8","title":"Phase D.1: Browser-tab-on-startup + port-conflict retry","description":"Auto-open the boot URL in the user's default browser when --no-browser is unset (today the CLI prints a 'not implemented' note at crates/quarto/src/commands/preview.rs:107). Add a clear error when an explicit --port is bound (raw bind failure today). Use the 'open' (or 'webbrowser') crate; failure to open is logged + non-fatal.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.1 for the full test plan and acceptance criteria.\n\nAcceptance: unit + 1 integration test; manual smoke recorded.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:37:46.024702Z","created_by":"cscheid","updated_at":"2026-05-14T18:45:18.917558Z","closed_at":"2026-05-14T18:45:18.917426Z","close_reason":"Phase D.1 complete: open crate auto-opens browser tab on q2 preview boot; --no-browser short-circuits cleanly. validate_explicit_port pre-probes user-pinned ports and returns a friendly 'port N already in use; pass --port 0' error. Side fix: --port 0 now picks an OS-assigned port instead of printing http://127.0.0.1:0/. 3 unit tests + binary smoke recorded in commit body. Workspace nextest: 8929/8929. Merged to feature/q2-preview-command as commit c91abd27.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.8","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:46.024702Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-kw93.9","title":"Phase D.3: Verify static-file resources sync end-to-end","description":"Add Playwright e2e specs proving CSS in _extensions/, images, and theme files round-trip through samod binary-doc sync and re-render the preview within ~2s of a disk edit. Hub already syncs binary docs (Phase B.1 broadened the watcher), but the end-to-end 'edit foo.css -> preview reflects new colour' is unverified.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.3.\n\nAcceptance: at least one new spec in q2-preview-spa/e2e/. Any bugs surfaced fix-in-scope or file follow-up.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-14T18:37:50.917226Z","created_by":"cscheid","updated_at":"2026-05-14T19:15:32.981970Z","closed_at":"2026-05-14T19:15:32.981822Z","close_reason":"Phase D.3 complete: e2e Playwright spec for static-file sync (CSS in _extensions/, image SVG). Surfaced two real bugs and fixed in scope: (1) .css missing from WatchFilter::PreviewBroad allow-list, (2) SPA's setSyncHandlers wasn't wiring onBinaryContent so image edits never bumped contentTick. Added window.__renderTicks counter to PreviewApp (also closes item #1 of bd-0mji). 11/11 Playwright; 8938/8938 workspace; SPA 21/21+8/8. Merged to feature/q2-preview-command as commit 1ddcbeaf.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-kw93.9","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:50.917226Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ky14a","title":"Migrate pampa to hash-based FileIds for cross-parser interop","description":"Discovered while wiring bd-1pwy8 (SassError::UnknownTheme structured diagnostic): pampa's ASTContext uses sequential FileIds (always FileId(0) for the document's primary file), while quarto_yaml uses hash(filename) FileIds. The two schemes are incompatible — same FileId means different files depending on the producer.\n\nSymptoms / workarounds already in the tree:\n\n- crates/quarto-core/src/theme_diagnostic.rs takes (FileId, &Path) candidate pairs because the caller has to declare which scheme each candidate uses.\n- crates/quarto-core/src/stage/stages/include_expansion.rs:162-211 maintains TWO parallel SourceContexts and explicitly remaps FileId(0) → new_sequential_id for every included sub-document (with a debug_assert_eq! to catch desync).\n\nProposed fix: have pampa adopt quarto_yaml::file_id_for_filename so its FileIds are globally meaningful. Eliminates the workarounds and makes any future cross-context diagnostic consumer (hub-client, q2 preview, JSON endpoint) work without out-of-band FileId knowledge.\n\nCoordinate with the parallel source-location workstream before implementing — this touches ~50 hardcoded FileId(0) call sites in pampa. PR review needed, not direct-to-main.\n\nPlan: claude-notes/plans/2026-05-22-pampa-hash-fileids.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-22T16:13:27.241803Z","created_by":"cscheid","updated_at":"2026-05-22T16:13:27.241803Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","refactor","source-location"],"dependencies":[{"issue_id":"bd-ky14a","depends_on_id":"bd-1pwy8","type":"discovered-from","created_at":"2026-05-22T16:13:27.241803Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-l173","title":"Match Quarto 1 page-navigation default + styling + icons","description":"see plan","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-30T13:14:59.620901Z","created_by":"cscheid","updated_at":"2026-04-30T13:15:09.163538Z","closed_at":"2026-04-30T13:15:09.163374Z","close_reason":"duplicate of bd-bsut (created twice due to initial command parse issue)","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-l26u6","title":"Theme-config diagnostic overhaul (epic)","description":"Two issues bundled together: (1) make theme-config errors use the structured DiagnosticMessage + ariadne renderer like our other errors, and (2) coalesce per-page diagnostics so one bad _quarto.yml key produces one report listing affected pages rather than N copies.\n\nReproducer: cargo run --bin q2 -- render external-sources/quarto-web — today emits ~280 plain 'error: <path>: Invalid theme configuration' lines.\n\nPlan: claude-notes/plans/2026-05-22-theme-diagnostic-epic.md","status":"closed","priority":2,"issue_type":"epic","created_at":"2026-05-22T13:42:54.816887Z","created_by":"cscheid","updated_at":"2026-05-22T15:05:31.634700Z","closed_at":"2026-05-22T15:05:31.634520Z","close_reason":"Both children landed: bd-pgczr (theme errors use Q-14-1 ariadne diagnostics) and bd-9hlja (cross-page coalescing). User-visible: hundreds of plain-text 'error: <path>: Invalid theme configuration' lines on quarto-web now collapse into one ariadne block + 'Affected files: …' line listing the pages.","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","theme","website"]} +{"id":"bd-l6f0","title":"[websites] Honor explicit 'expanded: true' through active resolution","description":"Today resolve_active_state always sets expanded=true on ancestors of an active item, overriding any user-supplied 'expanded: false'. The YAML 'expanded: true' override is parsed but active-state unconditionally sets it to true — which is the right default but means a user cannot force a section collapsed when it contains the active page (rare but legitimate). Fix: honor the YAML value where it is 'true', but treat 'false' as a default that active-state can override up, never down.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-04-24T17:52:38.504797Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:38.504797Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-l6f0","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:38.504797Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-lekl","title":"Phase 9 follow-up: deprecate render_qmd in favor of render_page_in_project","description":"Phase 9 sub-phase 9.4 switched the hub-client's renderToHtml from renderQmd to renderPageInProject. render_qmd remains as the single-file fallback inside render_page_in_project plus as a backward-compat surface. After the new entry point has bedded in (one or two release cycles), deprecate render_qmd and remove it.\n\nSteps:\n1. Mark render_qmd with #[deprecated] + console.warn-style notice in the TS wrapper.\n2. Audit all hub-client + tests for direct render_qmd calls; migrate to render_page_in_project.\n3. Wait one release.\n4. Delete the public render_qmd export, fold its remaining body fully into render_single_doc_to_response (private).","status":"open","priority":4,"issue_type":"task","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:40.067893Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-lekl","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-lekl","depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-lgxdr","title":"Author error-docs pages for markdown subsystem (36 codes)","description":"Author docs/errors/markdown/Q-2-X.qmd pages for all 36 entries in error_catalog.json under subsystem=markdown.\n\nCatalog codes (36 total): Q-2-1 through Q-2-35 plus Q-2-39 (gap at 36-38).\n\nPer-page workflow:\n- 29 of 36 codes have rich data in crates/pampa/resources/error-corpus/Q-2-X.json (code, title, message, notes, cases with example triggering content) — use those as the basis for stub content.\n- 7 codes lack corpus files (Q-2-4, Q-2-6, Q-2-8, Q-2-9, Q-2-14, Q-2-30, Q-2-39); grep emit sites in crates/ for these.\n\nClosing criteria:\n- 36 pages present in docs/errors/markdown/\n- All at status=stub or better\n- Front-matter matches catalog (title, since_version)\n- Cross-references inside markdown subsystem are real links\n- End-to-end render exits 0\n\nPlan: claude-notes/plans/2026-05-22-error-docs-content.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-22T20:27:53.321997Z","created_by":"cscheid","updated_at":"2026-05-22T20:38:37.352927Z","closed_at":"2026-05-22T20:38:37.352554Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["content","documentation","error-reporting"],"dependencies":[{"issue_id":"bd-lgxdr","depends_on_id":"bd-an6z4","type":"parent-child","created_at":"2026-05-22T20:27:53.321997Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-lk66","title":"Hub-client website rendering UX issues (parse-error routing, missing sidebar, debug API)","description":"Track three hub-client UX problems uncovered while exercising examples/websites/08-hub-preview/ plus a debug-API enabler. See plan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md\n\nChildren:\n- Pass-1 parse error on the active page surfaces as a generic 'no output' message\n- Pass-1 parse error in another file is misattributed as 'Sidebar/Body link references unknown document'\n- Sidebar missing from hub-client website preview (cause TBD)\n- Console debug API enabler (window.quartoDebug for read/write/rerender)\n\nParent: bd-0tr6 (websites epic).","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-01T13:57:50.869653Z","created_by":"cscheid","updated_at":"2026-05-01T13:57:50.869653Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-lk66","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T13:57:50.869653Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-lnd3","title":"Hub-client: cross-doc link clicks don't switch editor in website projects","description":"Reproduced 2026-05-01 against the dev server.\n\nIn hub-client, clicking a cross-document link inside the preview iframe should switch the active editor file to the link's target. This works in non-website projects (link href ./another.qmd → editor switches) but is broken in website projects.\n\nIn a website project, the body-link / nav-href transforms rewrite [About](about.qmd) → <a href=\"/.quarto/project-artifacts/about.html\">. The rewrite is correct for deployed websites and is shared with the hub-client preview so artifact (CSS / image) resolution stays uniform. But the iframe click handler in hub-client/src/utils/iframePostProcessor.ts:140-158 only intercepts hrefs ending in .qmd; the rewritten .html URLs slip through and the click is a no-op inside the about:srcdoc iframe.\n\nSame defect applies to sidebar entries (when the sidebar is visible at vp >= 992 px) — they share the same artifact-rooted .html shape.\n\nRepro:\n- localhost:5173 'test website' (project ID prefix 25a55Noy, copy of examples/websites/08-hub-preview/).\n- Open index.qmd. Click [About] in body. Hash unchanged at …/file/index.qmd.\n- Compare to 'No website' (3ZcKVsWZ): clicking [page](./another.qmd) in index correctly switches the route to …/file/another.qmd.\n\nPlan: claude-notes/plans/2026-05-01-website-link-navigation.md (Option A recommended: reverse-map artifact-rooted .html → source .qmd at click time using the project file list as the source of truth).\n\nParent epic: bd-0tr6 (websites).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T17:05:53.926460Z","created_by":"cscheid","updated_at":"2026-05-01T18:00:39.879438Z","closed_at":"2026-05-01T18:00:39.879283Z","close_reason":"Fixed in 2441ad8d: reverseMapArtifactHref + new postProcessIframe pass intercepts artifact-rooted .html links and reverse-maps to source .qmd. Strict scope (only intercepts when source exists). 10 unit + 7 integration tests; verified end-to-end via Chrome DevTools MCP on test website (about.html / posts/first.html → switch editor) and No website (./another.qmd regression check).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-lnd3","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:05:53.926460Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-ltmn","title":"Fix toc: false semantics to be an affirmative disable (uniform with navbar/page-footer)","description":"Currently crates/quarto-core/src/transforms/toc_generate.rs only matches toc: true and toc: 'auto' for should_generate; toc: false falls through to 'don't generate', same as absent key. This means a document cannot override inherited toc: true from _quarto.yml with toc: false — users have to write toc: !prefer false.\n\nFix: treat toc: false after metadata merge as an affirmative disable. Apply identical logic across toc/navbar/page-footer so the rule is uniform.\n\nTracked alongside bd-imiw (navbar/footer design). See claude-notes/plans/2026-04-18-navbar-footer-design.md Phase 0.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-18T18:03:47.179494Z","created_by":"cscheid","updated_at":"2026-04-18T18:22:51.947379Z","closed_at":"2026-04-18T18:22:51.946590Z","close_reason":"Fixed: added is_feature_disabled helper and applied to toc_generate/toc_render. Tests in crates/quarto-core/src/transforms/{toc_generate.rs,toc_render.rs,config.rs}. Commit pending as part of bd-imiw work.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ltmn","depends_on_id":"bd-imiw","type":"discovered-from","created_at":"2026-04-18T18:03:47.179494Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-lucp","title":"ReplayEngine miss in q2 preview: server's recorded input_qmd != WASM-produced input_qmd (mtime-derived listing-item.date-modified)","description":"After bd-m0mu (project registry plumbing) and bd-4uvv (samod automerge: URL prefix) are fixed, the SPA delivers the recorded capture bytes to the WASM. EngineExecutionStage now constructs ReplayEngine successfully — but ReplayEngine's strict byte-equality miss policy fires: 'replay miss: input QMD does not match recorded input (recorded 579 bytes, got 551 bytes).' 28-byte delta. The recorded input_qmd includes 'listing-item.date-modified: 2026-05-18' (server reads file mtime via NativeRuntime). The WASM-side q2-preview pipeline, running over the same source under WasmRuntime, doesn't have the same mtime in VFS so the listing-item.date-modified line is absent (or different). Net: every q2 preview render of a project with a website-type _quarto.yml hits a replay miss and shows the error overlay instead of rendered output. Repro fixture: ~/Desktop/daily-log/2026/05/15/q2-preview-test-website. Diagnosed end-to-end on 2026-05-18. Design space (pick one, needs user judgment): (a) compute_input_qmd strips mtime-derived metadata before serialization on server; (b) WasmRuntime populates mtimes in VFS so listing-item.date-modified surfaces in WASM too; (c) ReplayEngine loosens miss policy under preview mode (probably wrong — replay is a regression-testing tool); (d) cell-only diff for input_qmd canonicalization (the Phase-C polish path the C.3 plan flagged as Q-C3 v2). Plan §Q-C3 originally accepted whole-QMD byte-equality as a known v1 limitation; this surfaces it as a hard user-facing blocker.","status":"open","priority":0,"issue_type":"bug","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid","updated_at":"2026-05-18T16:00:50.554693Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-lucp","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-lucp","depends_on_id":"bd-m0mu","type":"discovered-from","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid","metadata":"{}","thread_id":""}],"comments":[{"id":24,"issue_id":"bd-lucp","author":"cscheid","text":"Design pivoted 2026-05-18 after user clarification: preview should NOT consume captures through ReplayEngine (which is a deterministic regression-testing tool with intentionally strict miss policy). Instead, derive an AST-level transformation from (parse(input_qmd), parse(result.markdown)) and splice it onto the live-edited pre-engine AST. Full design at claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md. Supersedes bd-m0mu (closed). bd-4uvv stays valid. Key shape per user note: (structural_hash(cell_content), occurrence_index_in_doc_order) to disambiguate repeated identical cells.","created_at":"2026-05-18T15:41:13Z"},{"id":26,"issue_id":"bd-lucp","author":"cscheid","text":"Implementation complete 2026-05-18 on branch beads/m0mu-preview-project-replay-engine. The splice path landed exactly as designed: `quarto_core::engine::capture_splice` (9 unit tests green) + `stage::stages::capture_splice::CaptureSpliceStage` (inserted before EngineExecutionStage in `build_q2_preview_pipeline_stages`) + WASM `render_page_for_preview` deserializing capture_gz_json into a typed EngineCapture and threading it through. E2E verified against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website: iframe DOM now contains `<div class=\"cell\">` with `<div class=\"cell-output cell-output-stdout\"><pre><code>Hello, world</code></pre></div>` for the R cell. Live-edit case (appending a new prose paragraph) verified: the captured engine output survives the edit (which byte-equality replay never could). Awaiting user review for merge.","created_at":"2026-05-18T16:00:50Z"}]} +{"id":"bd-m0mu","title":"q2 preview: project-mode WASM render path drops engine_registry → cell output missing in iframe","description":"When q2 preview runs against a project (`_quarto.yml` present), the project-mode WASM render path in `render_project_active_page_to_response` (crates/wasm-quarto-hub-client/src/lib.rs:1431) takes `_engine_registry: Option<EngineRegistry>` and never threads it into the pass-2 renderer. `RenderToPreviewAstRenderer::render` (crates/quarto-core/src/project/pass2_renderer.rs:593) then calls `render_qmd_to_preview_ast(.., None)` with a hardcoded `None`. The ReplayEngine built from the capture binary doc is built and discarded — code cells render as raw `<pre><code class=\"{r}\">` source instead of the captured `<div class=\"cell\">` + `.cell-output-stdout` output. Single-file mode is fine; only project mode is broken. Reproduced 2026-05-18 against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website/. Plan: claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md. Documented as 'known gap tracked alongside C.4 polish' in the WASM source comment.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid","updated_at":"2026-05-18T15:41:13.792874Z","closed_at":"2026-05-18T15:40:52.418984Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-m0mu","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-m0mu","depends_on_id":"bd-z529","type":"discovered-from","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid","metadata":"{}","thread_id":""}],"comments":[{"id":25,"issue_id":"bd-m0mu","author":"cscheid","text":"Closed as superseded by bd-lucp. The engine_registry-on-renderer plumbing was correct for an architecture that doesn't apply: preview-side capture consumption should be AST-splice, not ReplayEngine-as-drop-in. See claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md §'Why this supersedes bd-m0mu'. Reverting the Rust changes; keeping bd-4uvv (samod URL prefix) since that's needed regardless.","created_at":"2026-05-18T15:41:13Z"}]} +{"id":"bd-m2w7a","title":"Migrate remaining unstructured DiagnosticMessage warnings in transforms to builder API","description":"Audit follow-up flagged in claude-notes/plans/2026-05-20-bd-8d6rk-navigation-diagnostics.md.\n\nbd-8d6rk migrates the navigation-surface warnings (`navigation_href.rs`, `sidebar_auto.rs`) to the structured `DiagnosticMessageBuilder` API with error codes, problem statements, and hints. The same anti-pattern (`DiagnosticMessage::warning(format!(...))` or `::error(format!(...))`) appears in other transforms and should get the same treatment:\n\n- `crates/quarto-core/src/transforms/theorem.rs:178` — 1 warning call site\n- `crates/quarto-core/src/transforms/crossref_resolve.rs:249,267` — 2 warning call sites\n- `crates/quarto-core/src/transforms/crossref_index.rs:374` — 1 error call site (duplicate crossref identifier)\n- `crates/quarto-core/src/transforms/attribution_render.rs:113` — 1 warning call site\n\nFor each:\n1. Allocate an error code in `error_catalog.json` under the appropriate subsystem (crossref likely gets a new subsystem; theorem and attribution may belong under `markdown` or get their own).\n2. Replace the inline `format!(...)` with builder construction (title / problem / hint / location).\n3. Update any tests asserting on the old title-string shape.\n\nLikely surfaces `SourceInfo` plumbing gaps in each subsystem (similar to bd-qor9a for navigation). Scope each transform separately if the plumbing turns out to be non-trivial — this issue is the umbrella; sub-issues are fine.\n\nOut of scope: behaviour changes. This is a shape-only migration. Any newly-discovered bugs in the underlying logic get separate issues.\n\nPlan: to be written when work begins (defer until bd-8d6rk lands, so the pattern is fully established).","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-20T16:08:53.537652Z","created_by":"cscheid","updated_at":"2026-05-20T16:08:53.537652Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-m2w7a","depends_on_id":"bd-8d6rk","type":"discovered-from","created_at":"2026-05-20T16:08:53.537652Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-m7x9s","title":"Parallelize Pass-1 across project files","description":"Pass-1 (profile extraction over every file in a project) is currently a sequential async loop in ProjectPipeline::pass_one. The 2026-05-22 quarto-web profile (post-engine-discovery fix, bd-c5u2g) shows the remaining wall time is dominated by per-doc CPU work (tree-sitter parsing + AST traversal). Pass-1 is embarrassingly parallel from a data-dependency standpoint, so a multi-thread fan-out should give a near-linear speedup up to the number of cores.\n\nPlan: claude-notes/plans/2026-05-22-parallelize-pass-one.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-22T17:05:18.473643Z","created_by":"cscheid","updated_at":"2026-05-22T18:01:16.824739Z","closed_at":"2026-05-22T18:01:16.824569Z","close_reason":"Pass-1 parallelized via rayon (Option D). Cold-cache quarto-web: Pass-1 2230→1280 ms (1.74×), total 3.73→2.81 s (1.33×). Warm-cache: 800→520 ms (1.54×). QUARTO_JOBS env override + sequential fallback for WASM/single-doc. All 9348 workspace tests pass, cargo xtask verify --skip-hub-build clean. Pass-2 parallelization (the next obvious win) deferred — no clean end-to-end test bed yet since quarto-web doesn't fully render under Q2.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-m7x9s","depends_on_id":"bd-9eltv","type":"discovered-from","created_at":"2026-05-22T17:05:18.473643Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-m9rm","title":"Default project render regression and project-level diagnostics","description":"Post-websites-merge: presence of `_quarto.yml` with `project: { type: default }` causes `q2 render` to silently produce zero output, and `q2 render index.qmd` to fail with a misleading 'excluded from render list' error. Root cause: `default_output_dir` returns the project root for default projects, so the discovery walker's output_dir-exclusion check rejects every file. Three goals: (1) fix the discovery regression so default projects walk the tree like websites do; (2) add a clear project-level diagnostic when the render set is empty so we no longer silently no-op; (3) add a project-level diagnostic surface that both the CLI and hub-client can render, since today only file-level diagnostics flow to hub-client. Plan: claude-notes/plans/2026-05-01-default-project-render-diagnostics.md (open design questions inside, awaiting user input before implementation starts).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T21:40:11.505417Z","created_by":"cscheid","updated_at":"2026-05-01T21:40:11.505417Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-m9rm","depends_on_id":"bd-0tr6","type":"discovered-from","created_at":"2026-05-01T21:40:11.505417Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mae2","title":"L9 follow-up: custom feed templates (feed.template:)","description":"L9's three feed templates (preamble/item/postamble) are embedded built-ins. L8's listing.template config affects the listing render, not the feed render. A new feed.template: config field would let authors swap in custom XML templates for the feed itself. New feature; not in the L9 scope.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:46.431634Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:46.431634Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mae2","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:46.431634Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-maz5","title":"Phase 1: Upgrade runtimelib 1.4 → 2.0 in quarto-core","description":"Bump runtimelib and jupyter-protocol from 1.4 to 2.0 in crates/quarto-core/Cargo.toml. Adds a wildcard arm in media_type_to_mime_entry (jupyter-protocol 2.0 makes MediaType #[non_exhaustive]).\n\nStatus: implementation complete in session 2026-05-04, verified with cargo build --workspace, cargo nextest run --workspace (8360 passed), cargo xtask verify --skip-hub-build. End-to-end render still produces 'kernelspec python3 not found' (expected: dirs.rs is unchanged 1.6 → 2.0). Awaiting commit.\n\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 1)","status":"closed","priority":1,"issue_type":"chore","created_at":"2026-05-04T15:49:39.408919Z","created_by":"cscheid","updated_at":"2026-05-04T15:50:40.465475Z","closed_at":"2026-05-04T15:50:40.465325Z","close_reason":"runtimelib 1.4 -> 2.0 upgrade landed in 378d2d54. Workspace builds, all tests pass, end-to-end confirms the bug persists (venv discovery is the next phase, bd-34wy).","source_repo":".","compaction_level":0,"original_size":0,"labels":["chore","jupyter"],"dependencies":[{"issue_id":"bd-maz5","depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:39.408919Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mflk","title":"Phase A.5: End-to-end boot integration test","description":"crates/quarto-preview/tests/boot.rs: spawn 'q2 preview --no-browser --port 0' against a fixture project; assert SPA served, WS handshake succeeds, tempdir created+deleted, launch URL is http://<host>:<port>/#/preview/<indexDocId>. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.5.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-13T16:53:28.279760Z","created_by":"cscheid","updated_at":"2026-05-13T19:09:52.165059Z","closed_at":"2026-05-13T19:09:52.164919Z","close_reason":"Phase A.5 complete: q2 preview boots, renders, and applies theme styling end-to-end. See merge commit on feature/q2-preview-command.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mflk","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.279760Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mgoh","title":"Sidebar renders below page content — body class & grid placement wrong","description":"Q2 website rendering places the sidebar at the bottom of the page (below `<main>` and below the prev/next strip) instead of in a left column.\n\nRoot cause (verified against examples/websites/01-minimal rendered with q2 vs q1):\n1. Body class is hardcoded `fullcontent` in crates/quarto-core/src/template.rs:162. The website pipeline never sets the `body-classes` template variable, so we never get `nav-sidebar` or `floating`/`docked`.\n2. resources/scss/bootstrap/_bootstrap-rules.scss keys the grid layout off body classes: `body.floating .page-columns { @include page-columns-float-wide(); }` produces a 150px sidebar column on the left, while `body.fullcontent:not(.floating):not(.docked)` produces no sidebar column.\n3. Without that column, the sidebar wrapper (`#quarto-sidebar-container` placed at `grid-column: body-content-start / body-content-end`, `grid-row: auto`) gets auto-placed in an implicit row after `<main>`, so it appears below the page content.\n4. Secondary structural difference: Q1 places `<nav id=quarto-sidebar>` directly as a grid child; Q2 wraps it in `#quarto-sidebar-container`. The SCSS in resources/scss expects the Q1 layout.\n\nPlan: claude-notes/plans/2026-04-29-website-sidebar-layout.md\n\nOut of scope: search bar (Q1 default that we are not adding yet).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-29T20:20:57.275263Z","created_by":"cscheid","updated_at":"2026-04-29T20:20:57.275263Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mgoh","depends_on_id":"bd-2jwk","type":"discovered-from","created_at":"2026-04-29T20:20:57.275263Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ml8z","title":"L3 — ListingResolveTransform (Pass-2, built-ins via doctemplate)","description":"New Pass-2 transform inside AstTransformsStage. Reads host's listing: config + ProjectIndex; resolves contents: globs; filters/sorts; truncates by max-items. Builds per-item TemplateValue::Map with curated profile fields, server-pre-rendered helpers (image_html, metadata_attrs), and listing_item.extra. Renders via doctemplate against built-in default/grid/table templates embedded with MemoryResolver. Emits placeholders for L7 alongside L1 fallback content. See claude-notes/plans/2026-05-05-listings-epic.md §L3.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","updated_at":"2026-05-07T13:35:17.550573Z","closed_at":"2026-05-07T13:35:17.550209Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ml8z","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ml8z","depends_on_id":"bd-b5jm","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ml8z","depends_on_id":"bd-izqh","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ml8z","depends_on_id":"bd-j60g","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ml8z","depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mlj6","title":"Conditional render lists / _quarto-*.yml profiles","description":"Q1 supports profile-specific renders via _quarto-<profile>.yml (e.g. _quarto-prod.yml vs _quarto-dev.yml). Phase 1 of the website epic ignores profile files entirely — discovery excludes them because of the leading underscore, and config parsing only reads _quarto.yml. Follow-up: decide how profiles compose with the base config, add CLI flag for selecting profile, thread through ProjectContext::discover. See claude-notes/plans/2026-04-23-websites-phase-1.md §Decisions log.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T01:05:24.479391Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:24.479391Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mlj6","depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:24.479391Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mot7","title":"qmd reader drops whitespace between code_span and html_element (issue #182)","description":"(see triage doc)","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T13:42:59.836284Z","created_by":"cscheid","updated_at":"2026-05-12T13:43:26.216838Z","closed_at":"2026-05-12T13:43:26.216709Z","close_reason":"Duplicate, accidental second create. Keeping bd-nkx4.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-mqa4j","title":"Phase 8 — quarto-sync-client header pass-through + connection-manager integration","description":"Add auth?.getBearer option to client.connect(); new Node-only NodeWebSocketClientAdapter inside quarto-sync-client that constructs new WebSocket(url, [], { headers }). Browser path unchanged.\n\nConnection-manager try-then-fallback policy: read bundle, attempt WS with Bearer if present, on 401-with-creds forceRefresh+retry-once then ReauthRequired, on 401-without-creds AuthRequired.\n\nlastObservedAuthMode state machine ({no-auth, requires-auth, unknown}, process-local) drives Phase 7's short-circuit.\n\nInsecure-Bearer gate: refuse to send Bearer over plain HTTP/WS to non-loopback without QUARTO_HUB_MCP_ALLOW_INSECURE_AUTH=1; loud warning on every connect when set.\n\nFollow-up: upstream PR to thread headers through BrowserWebSocketClientAdapter — file separately.\n\nPlan §Phase 8: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:25.451968Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:25.451968Z","source_repo":"kyoto","source_repo_path":"/Users/shikokuchuo/r/kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mqa4j","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:25.451968Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-mqk49","title":"Design: how should engines/extensions declare additional pipeline stages?","description":"build_html_pipeline_stages() in crates/quarto-core/src/pipeline.rs is a hardcoded ~19-stage list. Stages can be gated by config (e.g. native-only), but no engine, extension, or plugin can register a new stage.\n\n**More relevant after PR #238 (sequential multi-engine execution).** With engines as first-class pipeline citizens, the natural mechanism for 'format-agnostic engine output + format-specific emission' is to let an engine declare a per-format AST pass on its output. For mermaid: 'when emitting HTML, run this transform on my output blocks.' For graphviz/plantuml/dot later: same shape.\n\nA proper extension API would let engines/extensions declare:\n- a stage name + input/output kinds\n- a position (after-X / before-Y, or by precedence)\n- a per-format applicability predicate\n- a per-engine attribution back-reference (so trace events name the engine that contributed the stage)\n\n**Known beneficiary: the mermaid engine (bd-gwfdo).** Mermaid ships first under B1 (the engine emits RawBlock(HTML, '<pre class=\"mermaid\">...</pre>') directly — format-locked but acceptable while Q2 is HTML-only). A source-code comment in crates/quarto-core/src/engine/mermaid/ flags the TODO. **When bd-mqk49 lands, follow up on the mermaid engine** to refactor: the engine should emit a marker Div (e.g. Div.mermaid wrapping the source code block) and declare an HTML-conditional AST pass that turns the marker into the <pre class=\"mermaid\"> output. This removes the format coupling and makes the mermaid engine PDF-ready.\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G3.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-28T13:45:56.898020Z","created_by":"cscheid","updated_at":"2026-05-28T17:05:01.753171Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mqk49","depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:56.898020Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mre3","title":"[websites phase 2] Sidebar data model, generate, render, template","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 2.\n\nDeliverables:\n- Schema parsing for website.sidebar: Vec<Sidebar> with id, title, contents, style, collapse-level.\n- Contents supports: string (path), {href, text, icon}, {section, contents}, {auto: ...}.\n- quarto-navigation data types: Sidebar, SidebarEntry, SidebarContents.\n- SidebarGenerateTransform: reads YAML config + ProjectIndex to resolve auto and expand entries.\n- SidebarRenderTransform: emits Bootstrap-5 HTML matching Q1 class names where possible.\n- Template slot: $rendered.navigation.sidebar$.\n- Sidebar-for-page selection logic.\n- Integration tests with manual, auto, and nested contents.\n\nBlocked by Phase 1 (needs ProjectIndex).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-23T18:42:49.915763Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.148471Z","closed_at":"2026-04-29T00:31:30.148151Z","close_reason":"Phase 2 (sidebar) implemented — see git log Phase 2 sub-phase commits and claude-notes/plans/2026-04-24-websites-phase-2.md (closed as part of Phase 9 cleanup; this should have been closed earlier).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mre3","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:49.915763Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-mre3","depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:42.284820Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mrx1","title":"Phase B.4: Acceptance bundle — _quarto.yml + posts/_metadata.yml propagation to preview","description":"Single Playwright spec pinning the two observable plan acceptance criteria for q2 preview (Phase B):\n\n1. Editing _quarto.yml (title:) re-renders the active page; new title visible in DOM within 5 s.\n2. Editing posts/_metadata.yml (subtitle:) re-renders pages under posts/; new subtitle visible in DOM within 5 s.\n\nFixture (single, dual-purpose): _quarto.yml + posts/_metadata.yml + posts/post1.qmd (no frontmatter, inherits both). Empirically verified both knobs flow through to the rendered title-block (2026-05-13 probe with target/debug/q2 render).\n\nReuses the multi-file fixture helper generalised in bd-pf63 (B.3).\n\nPlan acceptance criterion 3 ('unrelated sibling re-renders the active page') is deferred and tracked separately — its relaxed-contract form (any edit fires a re-render) is invisible at the DOM without SPA instrumentation. See discovered-from follow-up.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid","updated_at":"2026-05-13T21:15:09.863020Z","closed_at":"2026-05-13T21:15:09.862892Z","close_reason":"Phase B.4 complete; zero production-code changes — new Playwright spec at q2-preview-spa/e2e/config-edits.spec.ts pins _quarto.yml + posts/_metadata.yml propagation. See commit df2f5f55 on beads/bd-mrx1-phase-b4-acceptance-bundle.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mrx1","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-mrx1","depends_on_id":"bd-pf63","type":"discovered-from","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-msp0","title":"Hub-client preview resource resolution via service worker (epic)","description":"Long-term direction: replace the iframe post-processor's resource-rewriting passes (CSS data-URIs, image data-URIs, the disabled <script> inlining block) with a service worker scoped to /.quarto/project-artifacts/ and project-relative paths. The SW intercepts fetch events and serves from the VFS, giving us:\n\n- Single resolution path shared between top-frame and iframe.\n- No data-URI churn on every render (iframes routinely carry hundreds of KB of inline base64 stylesheets today).\n- Clean answer for the in-project image redirection bug.\n- Plausible path for executing real JS bundles in preview iframes (Bootstrap collapse, search, copy-button, etc.) once SW + sandbox + COEP/COOP are set up correctly.\n\nNOT in scope: cross-doc link click → editor navigation (bd-lnd3). That's a DOM-event concern, not a fetch concern; about:srcdoc iframes drop link clicks silently regardless of network resolution. The click-interception path stays in iframePostProcessor.ts even after the SW arc lands.\n\nChildren candidates (file as separate issues when this epic gets traction):\n- SW bootstrap + scope registration in hub-client.\n- VFS → fetch handler.\n- Migration of CSS resolution (remove data-URI rewrite from iframePostProcessor).\n- Migration of image resolution (remove data-URI rewrite + fixes the in-project image redirect bug).\n- JS bundle execution in preview iframes (subsumes bd-e7b7 native+incremental constraints).\n- Sandbox / COEP / COOP setup as required.\n\nParent epic: bd-0tr6 (websites, since the immediate motivation is the website rendering pipeline, but the SW infrastructure is broadly useful).","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid","updated_at":"2026-05-01T17:18:45.016932Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-msp0","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-msp0","depends_on_id":"bd-e7b7","type":"related","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-msp0","depends_on_id":"bd-lnd3","type":"related","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mtzry","title":"D6: <body> emits quarto-light / quarto-dark class","description":"## What\n\nQ1 emits `<body class=\"fullcontent quarto-light\">` (or `quarto-dark` depending on theme). Q2 emits only `<body class=\"fullcontent\">`. Add the color-mode class based on the active theme config (default `quarto-light`).\n\n## Where\n\nTemplate body-class logic lives at `crates/quarto-core/src/template.rs:136` area (per existing comment: 'Mirrors TS Quarto's format-html-bootstrap.ts body-class logic').\n\n## Tests\n\nTemplate-render test asserting the body class for:\n- default config (no theme set) → `fullcontent quarto-light`\n- explicit dark theme → `fullcontent quarto-dark`\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D6 section)","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-05-20T20:55:25.035424Z","created_by":"cscheid","updated_at":"2026-05-20T21:39:26.262052Z","closed_at":"2026-05-20T21:39:26.261894Z","close_reason":"Implemented in this commit: quarto-light appended to body class for default renders.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mtzry","depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:25.035424Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mw7x","title":"[websites phase 3] Navbar/footer project integration","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 3.\n\nDeliverables:\n- Extend existing NavbarGenerateTransform and FooterGenerateTransform to read project-level config from _quarto.yml and resolve cross-doc hrefs via ProjectIndex.\n- Active-item highlighting for the current page.\n- Navbar search tool stays a stub (search is a follow-up epic).\n- Tests: navbar entries pointing at .qmd files correctly render as .html links; external URLs pass through unchanged.\n\nBlocked by Phase 1.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:42:59.202302Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.330069Z","closed_at":"2026-04-29T00:31:30.329739Z","close_reason":"Phase 3 (navbar/footer project integration) implemented — see git log Phase 3 commits. Closed as part of Phase 9 cleanup.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mw7x","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:59.202302Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-mw7x","depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:43.309371Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-mwtf","title":"Hub-client: active-page parse error renders as 'Project render produced no output for the active page'","description":"When a website document has a Pass-1 parse error AND it is the active page in hub-client, the preview overlay shows the literal string 'Project render produced no output for the active page' instead of the actual parse diagnostic.\n\nRepro: examples/websites/08-hub-preview/about.qmd has an unescaped apostrophe (line 11, 'pages\\\\'') that the strict Q2 markdown parser rejects with [Q-2-10] Closed Quote Without Matching Open Quote. The CLI shows the full ariadne-style snippet via 'warning: profile-pass skipped about.qmd: ...'. Hub-client shows only the generic message.\n\nRoot cause (located): crates/wasm-quarto-hub-client/src/lib.rs:1374-1428 — render_project_active_page_to_response() checks summary.pass2_failures but never checks summary.pass1_failures. When the active page failed Pass-1, both summary.outputs and summary.pass2_failures are empty, so the L1393 fallback fires.\n\nFix: in the L1381 'no output' branch, look up summary.pass1_failures for an entry whose input matches the active path; if found, build a RenderResponse with success: false, error from the failure summary, and diagnostics: failure.diagnostics mapped to JsonDiagnostic.\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Bug 2 section).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T13:58:04.540272Z","created_by":"cscheid","updated_at":"2026-05-01T13:58:04.540272Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-mwtf","depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:04.540272Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-my0o5","title":"q2 preview end-to-end verification for mermaid blocks","description":"Verify the MermaidEngine survives the q2-preview round trip (capture-splice path).\n\n**This task effectively closes PR #238's bd-iq0hp** — PR #238 documented that a browser E2E of multi-engine preview was not possible at PR time because the default registry uses real engines, FixtureEngine is test-only, and knitr/jupyter don't compose cleanly (knitr claims `{python}` via reticulate). Mermaid + knitr is the first real-engine pair with disjoint cell-class ownership (`{r}` vs `{mermaid}` never overlap).\n\nTest matrix:\n\n1. Document with mermaid block only — q2 preview renders the diagram.\n2. Document with engine: [knitr, mermaidjs], knitr block + mermaid block, with recorded captures — both render in preview.\n3. Edit the mermaid block — preview updates without re-running knitr's capture (capture invariance on engine 1's input).\n4. Confirm the jsdelivr script include arrives in the preview's HTML body. If C1 (inline RawBlock in engine markdown) is the chosen approach (per plan v2), this should Just Work because capture-splice preserves result.markdown. If C2/C3 is chosen instead, bd-cp3em becomes a blocker.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-28T13:45:19.961230Z","created_by":"cscheid","updated_at":"2026-05-29T13:25:16.167177Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-my0o5","depends_on_id":"bd-gwfdo","type":"blocks","created_at":"2026-05-28T13:45:37.473723Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-my0o5","depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:19.961230Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-n4e0p","title":"Canonical device-flow URL must be a module constant, not Google's response","description":"Anti-phishing requirement from plan §Phase 1 (threat #5). authenticate_start MUST return the hard-coded constant https://www.google.com/device as canonical_url alongside Google's verification_uri — and the canonical must come from a module-level constant in auth-tools.ts, NEVER copied from the AS response.\n\nTest name: start_canonical_url_is_a_constant_not_from_google_response in ts-packages/quarto-hub-mcp/test/auth/auth-tools.test.ts. Test uses a mock AS that returns a malicious verification_uri and asserts the tool's canonical_url is unchanged.\n\nPlan §Phase 7 + threat model #5: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:27:54.874842Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:54.874842Z","source_repo":"kyoto","source_repo_path":"/Users/shikokuchuo/r/kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-n4e0p","depends_on_id":"bd-cqkts","type":"parent-child","created_at":"2026-05-20T14:27:54.874842Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} {"id":"bd-n7x2","title":"Syntax highlighting design and implementation for Quarto 2","description":"Design and implement a syntax highlighting system for code blocks in Quarto 2. Generic span-annotation AST format + tree-sitter-driven pipeline stage + per-format writers. Plan: claude-notes/plans/2026-04-19-syntax-highlighting-design.md. Research notes under claude-notes/research/syntax-highlighting-*.md.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-19T14:50:53.168567Z","created_by":"cscheid","updated_at":"2026-04-19T14:50:53.168567Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-n8a4","title":"L0 — ListingItemInfo profile extension","description":"Add DocumentProfile.listing_item: ListingItemInfo with curated fields + extra: BTreeMap<String, ConfigValue>. Bump DOCUMENT_PROFILE_VERSION 2 → 3. Update document-profile-contract.md with the new row plus a new §'Scoped feature surfaces' explicitly forbidding non-listing reads of listing_item.extra. Schema update in quarto-yaml-validation. See claude-notes/plans/2026-05-05-listings-epic.md §L0.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-05T19:52:49.454592Z","created_by":"cscheid","updated_at":"2026-05-05T21:30:29.284197Z","closed_at":"2026-05-05T21:30:29.283825Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-n8a4","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:52:49.454592Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-n9dr","title":"[websites epic] Unify nav config placement across features","description":"Nav config placement across features. Phase 3 (2026-04-24) refined the framing: rather than 'unify everything into one namespace,' the principle is now \"placement follows feature semantics.\"\n\nCurrent placement (post-Phase 3):\n- 'navbar:' — top level (feature-scoped; works in single-doc + project)\n- 'page-footer:' — top level (same; revealjs/etc. legitimately use it)\n- 'website.sidebar:' — under website. (sidebar is inherently a multi-page website feature)\n- 'site-sidebar:' (per-doc override selecting which sidebar applies) — top level\n- 'website.title:' / 'website.site-url:' / 'website.favicon:' — under website. (site-scoped)\n\nThe only remaining tension is 'site-sidebar' being a doc-level override for a website-scoped feature. Options:\n(a) rename to 'website.sidebar-id' (canonical; website.sidebar-id already accepted in Phase 2 as an alias)\n(b) keep 'site-sidebar' since it's a per-doc override like 'draft:' / 'date:' and those also live at the top level\n\nNot a blocker for MVP; land before docs-facing release. See claude-notes/plans/2026-04-24-websites-phase-3.md §Decision 1 for the framing shift.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T17:53:00.610122Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:25.192319Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-n9dr","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:53:00.610122Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nb32","title":"Body-link 'data-noresolveinput' escape hatch (Q1 parity)","description":"Q1 lets users opt out of body-link rewriting via data-noresolveinput attribute on individual <a> elements. Phase 6 (bd-v30t) skipped this; file once a real workflow surfaces (e.g. literal .qmd hrefs that must NOT be rewritten).","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:47.962663Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nb32","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-nb32","depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nf50","title":"Page-navigation rules need user-facing docs","description":"User explicitly flagged (Phase 4 Decision 9) that the flatten + dedupe + separator-as-boundary + section-header-as-neighbor rules are non-obvious and need documentation in the Q2 docs site (bd-tr81). Tie to the docs epic.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid","updated_at":"2026-04-30T13:54:10.438123Z","closed_at":"2026-04-30T13:54:10.437973Z","close_reason":"Documented as part of bd-bsut. The new \"Page navigation (prev/next)\" → \"How prev/next are chosen\" subsection in docs/navigation.qmd covers all four non-obvious rules: depth-first flatten, duplicate-href dedupe, separator-as-hard-boundary, and section-header-with-href as neighbor.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nf50","depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-nf50","depends_on_id":"bd-tr81","type":"related","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nkx4","title":"qmd reader drops whitespace between code_span and html_element (issue #182)","description":"Reader silently drops leading/trailing whitespace on bare html_element nodes when they're converted to RawInline, so AST loses the Space between adjacent Code and RawInline siblings. Writer then collides backticks and round-trip fails to re-parse.\n\nReproduction, root cause, and recommended fix scope are documented in claude-notes/issue-reports/182/triage.md on branch issue-182 (worktree .worktrees/issue-182). Short version: the html_element visitor's anchor-shorthand branch already handles leading_ws/trailing_ws correctly by emitting adjacent Space inlines; the sibling RawInline branch in the same match arm does not. The fix mirrors that pattern.\n\nLocalized in crates/pampa/src/pandoc/treesitter.rs (html_element arm). TDD-first per crates/pampa/CLAUDE.md: add a roundtrip fixture and an AST assertion before changing code.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T13:42:55.415626Z","created_by":"cscheid","updated_at":"2026-05-12T14:07:10.065411Z","closed_at":"2026-05-12T14:07:10.065243Z","close_reason":"Fixed in f2867bb1 on branch issue-182. Reader now emits leading/trailing Space inlines around RawInline when the html_element node carries surrounding whitespace, mirroring the anchor-shorthand branch in the same match arm.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-nl5q","title":"Cargo: upgrade deno_core v0.376.0 → v0.400.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.376.0 is range-pinned in workspace; latest is 0.400.0. Type: pre-1.0 minor (semver-breaking); large jump. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.767839Z","created_by":"cscheid","updated_at":"2026-05-04T18:16:04.780626Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-nl5q","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.780303Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nmkmi","title":"q2 render with no args walks cwd before checking for _quarto.yml","description":"`q2 render` invoked with no arguments in a directory with no `_quarto.yml` (and no `_quarto.yml` in any ancestor) eventually emits the correct \"No input given and no `_quarto.yml` found at or above <cwd>\" error — but only AFTER recursively walking the entire cwd looking for `.qmd` files.\n\nIn an empty directory the error appears instantly. In a large tree (q2 repo root: ~64k entries in `target/`, more under `external-sources/quarto-cli/`), the command appears to hang for many seconds because the walker descends into `target/` and `external-sources/` (`is_excluded_component` excludes only `_*`, `.*`, and `node_modules`).\n\nThe walk's output is then thrown away — `classify_no_inputs` decides we have no project anyway.\n\nMeasured warm-cache cost in the q2 root: 0.3s. Cold-cache cost (or with `external-sources/quarto-cli/` fully populated): multi-second freeze.\n\n**Root cause:** `crates/quarto/src/commands/render.rs:331-346` (`classify_no_inputs`) calls `ProjectContext::discover(&cwd, ...)` before checking whether a real project exists. `ProjectContext::discover` does the upward `_quarto.yml` search (cheap), and on miss falls through to `discover_project_files` → `walk_qmd` (recursive cwd walk).\n\n**Fix:** Short-circuit `classify_no_inputs` — do the cheap upward `_quarto.yml`/`_quarto.yaml` ancestor search first, and only call `ProjectContext::discover` when a real project is known to exist. Inline the upward loop (six lines, only uses `runtime.path_exists`) rather than exporting a new helper for one caller.\n\n**Plan:** claude-notes/plans/2026-05-20-render-no-project-skip-walk.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T14:41:58.708780Z","created_by":"cscheid","updated_at":"2026-05-20T14:54:44.984036Z","closed_at":"2026-05-20T14:54:44.983847Z","close_reason":"Implemented in commit 58d2bd34.\n\nApproach: added `find_project_root_upward` (parsing-free\n`path_exists`-only ancestor walk) and made `classify_no_inputs` call\nit before delegating to `ProjectContext::discover`. The expensive\n`discover_project_files`/`walk_qmd` fall-through is now skipped\nentirely when no `_quarto.yml` ancestor exists.\n\nE2E timing (warm cache, debug build):\n q2 root: 0.318 s → 0.021 s (15×; cold-cache delta larger)\n /tmp/empty: unchanged (~6 ms)\n docs/: renders normally (unchanged)\n docs/<sub>/: renders normally (Test 3 e2e)\n\nError text byte-identical: \"No input given and no `_quarto.yml`\nfound at or above <cwd>\".\n\nRegression coverage: `classify_no_inputs_does_not_walk_cwd` asserts\n`dir_list_count == 0` via a `RecordingRuntime` wrapper around\n`NativeRuntime`. `classify_no_args_from_project_subdir_returns_full_project`\npins the cwd-inside-project case.\n\nVerification: `cargo nextest run -p quarto` 100/100 pass;\n`cargo xtask verify --skip-hub-build` all 12 steps green.\n\nOut-of-scope follow-up: bd-k4ahh tracks the symmetric `q2 render <dir>`\nwith-arguments path (lower priority, filed discovered-from).","source_repo":".","compaction_level":0,"original_size":0,"labels":["cli","perf","render"]} +{"id":"bd-nqcv","title":"Glob support in project.nav-dependencies declarations","description":"Today `project.nav-dependencies` accepts a flat list of paths. Some users may want `project.nav-dependencies: [posts/*.qmd]` or `[chapters/**/*.qmd]`. v1 doesn't support globs (open question 5 in the Phase 8 plan). Wire glob expansion through DocumentProfileStage when populating the field. Defer until a real user need surfaces.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:51.182984Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nqcv","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-nqcv","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-ntnx","title":"Investigate tree-sitter grammar CRLF handling on Windows","description":"Cargo xtask verify step 4 (tree-sitter test) fails 5/451 pipe-table tests on Windows but passes on ubuntu-latest CI. Surfaced during PR 109 Windows verification on 2026-04-24. Root cause is ambiguous between a test-corpus CRLF issue (Scenario A, .gitattributes fix) and a grammar CRLF-handling bug (Scenario B, grammar.js fix). Must investigate before remediating — fixing the test would mask a real Windows-user bug if Scenario B applies. See design for reproducer and both scenarios. Related to bd-tjbr (sibling Windows dev-ergonomics work). Target branch feature/dev-setup-improvements or its own branch.","design":"Failure mode. cd crates/tree-sitter-qmd/tree-sitter-markdown && tree-sitter test reports 451 parses, 446 successful, 5 failed on Windows. All 5 failures are pipe-table tests: Example 201 (GFM), Pipe table can precede content (two variants), Pipe table can follow content, Pipe table with blank-line caption. file test/corpus/pipe_table.txt shows CRLF line terminators (426 CR paired with 426 LF). git ls-files --eol confirms i/lf w/crlf — stored as LF in the index, materialized as CRLF on Windows checkout via core.autocrlf=true. Same mechanism caused the quarto-doctemplate failures catalogued in q2-windows-verify-tests memory note.\n\nScenario A — test-corpus CRLF. Grammar is CRLF-agnostic. Parse trees for LF and CRLF inputs are identical. Tests fail only because the corpus .txt file embeds both the input text AND the expected S-expression AST, and the expected AST was written assuming LF parse output. Remediation is a scoped .gitattributes entry: crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/*.txt eol=lf. One line, followed by git rm --cached then git checkout to normalize existing files. Real Windows user qmd content continues to parse correctly regardless of line endings.\n\nScenario B — grammar CRLF bug. Grammar does not treat carriage-return-linefeed as a block boundary where it should. Real Windows user qmd content with CRLF endings parses incorrectly — pipe tables do not detect captions as separate blocks, block boundaries drift. This is a user-facing bug; only a Windows contributor running pampa against CRLF content catches it. Remediation is in crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js — typically adding carriage-return to newline character classes or the external scanner logic. .gitattributes would mask this bug instead of fixing it.\n\nReproducer. Two layers, both diagnostic. Layer 1 tests grammar.js directly via tree-sitter parse. Layer 2 tests the full pampa pipeline that real users hit. Fixtures are written into the tree-sitter-markdown directory so tree-sitter parse picks up the configured grammar without an init-config step.\n\nLayer 1 (grammar.js):\n\nprintf 'before\\r\\n\\r\\n| a | b |\\r\\n|---|---|\\r\\n| 1 | 2 |\\r\\n\\r\\nafter\\r\\n' > crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd\nprintf 'before\\n\\n| a | b |\\n|---|---|\\n| 1 | 2 |\\n\\nafter\\n' > crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd\ncd crates/tree-sitter-qmd/tree-sitter-markdown\ntree-sitter parse test-crlf.qmd > test-crlf.parse\ntree-sitter parse test-lf.qmd > test-lf.parse\ndiff test-crlf.parse test-lf.parse\n\nLayer 2 (pampa end-to-end):\n\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd > pampa-crlf.out\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd > pampa-lf.out\ndiff pampa-crlf.out pampa-lf.out\n\nNotes on the prior reproducer in this design field. pampa has no parse subcommand — it is cargo run -p pampa --bin pampa -- input.qmd, with default -f markdown -t native. Git Bash /tmp resolves to %TEMP% but native Windows binaries resolve /tmp to C:\\tmp\\, so the previous version would have created files Git Bash could not find later. Use repo-local paths.\n\nIf both diffs are empty then Scenario A applies. If either diff is non-empty then Scenario B applies. Layer 2 also tells us whether the bug propagates past pampa's input handling into the Pandoc AST that real users render from.\n\nBroader git cross-platform context. The 2026 consensus is that most projects do not need .gitattributes. core.autocrlf=true plus LF-tolerant tooling handles 99 percent of cross-platform cases. quarto-cli is an example — no .gitattributes and no CRLF-related failures. .gitattributes is for files that must be a specific line ending (shell scripts, batch files), binary files misdetected as text, and whitespace-sensitive test corpora where the consuming tool is itself correct. Over-restrictive patterns like * text=auto eol=lf force LF everywhere and are worse for cross-platform dev than no config. The target for this project is minimal, scoped .gitattributes only where the test harness cannot be fixed — and only in Scenario A.\n\nOut of scope. Broader .gitattributes sweep for the whole repo. Fixing the 8 quarto-doctemplate CRLF failures already catalogued in q2-windows-verify-tests (separate work). Tree-sitter CLI changes (upstream, not ours).","acceptance_criteria":"Reproducer runs and classifies failure as Scenario A or Scenario B. If Scenario A then .gitattributes entry added for test/corpus/*.txt and cargo xtask verify step 4 passes on Windows. If Scenario B then follow-up beads issue filed for grammar.js fix at higher priority and this investigation issue closes with evidence. q2-windows-verify-tests memory note updated with resolution and link to fix PR or follow-up issue. No regression in CI — tree-sitter tests continue to pass on Linux.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T16:38:18.426543400Z","created_by":"cderv","updated_at":"2026-04-27T14:29:38.899054500Z","closed_at":"2026-04-27T14:29:38.898439400Z","close_reason":"Scenario B classified. Follow-up bd-0gsj filed at P1 for the grammar.js fix; full evidence in that issue's design and in the closing comment here.","source_repo":".","compaction_level":0,"original_size":0,"labels":["tree-sitter","windows"],"dependencies":[{"issue_id":"bd-ntnx","depends_on_id":"bd-tjbr","type":"related","created_at":"2026-04-24T16:39:17.513779500Z","created_by":"cderv","metadata":"{}","thread_id":""}],"comments":[{"id":12,"issue_id":"bd-ntnx","author":"cderv","text":"Investigation complete. Result: Scenario B (real grammar CRLF bug). Layer 1 (tree-sitter parse on grammar.js) showed pipe_table extents diverge between CRLF and LF inputs — CRLF case absorbs the trailing paragraph as a malformed table row. Layer 2 (cargo run -p pampa) confirmed pampa does not normalize line endings before parsing, so the bug propagates to the Pandoc AST that drives every output format. Real Windows users with default core.autocrlf=true and the common pattern of a pipe table followed by content render structurally wrong documents. .gitattributes alone would have masked this.\n\nFollow-up filed at higher priority: bd-0gsj — Fix CRLF handling in tree-sitter-qmd grammar.js for pipe tables (P1, bug). Full evidence and reproducer carried over to bd-0gsj design field.","created_at":"2026-04-27T14:28:37Z"}]} +{"id":"bd-nv5c","title":"Opt-in Pass-2 cache for filter-pure projects","description":"Phase 8 deliberately skips Pass-2 caching: filters/engines may have side effects, so caching past them is unsafe by default. A future user-opt-in surface (per-project YAML key like `pass2-cache: trusted`) could enable Pass-2 output caching for users who assert filter purity. Out of website-epic scope; lives in its own design discussion. See claude-notes/plans/2026-04-27-websites-phase-8.md §'Why no Pass-2 cache'.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:35.786086Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nv5c","depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-nv5c","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nvlxn","title":"Error-docs foundation: directory, front-matter, template, index","description":"Set up the docs/errors/ section so subsequent content + tooling work has a stable target.\n\nIncludes:\n- Directory layout (docs/errors/Q-X-Y.qmd, flat) and rationale doc\n- Front-matter schema: code, subsystem, title, description, status (draft|stub|complete|deprecated), since\n- Page template (sections: What this means / Why this happens / How to fix / Example / Related)\n- docs/errors/index.qmd as a Quarto listing page grouped by subsystem\n- _quarto.yml navbar + sidebar wiring\n- A README.md under docs/errors/ documenting the conventions\n- One worked example page (e.g. Q-1-1) at status=complete to anchor the template\n\nPlan: claude-notes/plans/2026-05-22-error-docs-foundation.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-22T17:09:28.478856Z","created_by":"cscheid","updated_at":"2026-05-22T19:25:25.908365Z","closed_at":"2026-05-22T19:25:25.908241Z","close_reason":"Foundation scaffold landed via merge into main: docs/errors/ directory with subsystem subdirs, README + front-matter schema + status enum + page template + cross-reference convention, listing index, Q-1-10 seed page at status: complete (chosen over the planned Q-1-1 because Q-1-1 has no production emit site), navbar/sidebar wiring, and the docs_url subsystem-segment rewrite across all 133 catalog entries. Verified end-to-end via 'cargo run --bin q2 -- render docs/' and full 'cargo xtask verify'. Tooling (bd-8otua) and content (bd-an6z4) now unblocked.","source_repo":".","compaction_level":0,"original_size":0,"labels":["documentation","error-reporting","website"],"dependencies":[{"issue_id":"bd-nvlxn","depends_on_id":"bd-94x8a","type":"parent-child","created_at":"2026-05-22T17:09:28.478856Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nwun","title":"Phase 4 — Page navigation (prev/next)","description":"Implement bottom-of-page prev/next navigation strip for website projects. Mirrors Q1 nextAndPrevious algorithm. See claude-notes/plans/2026-04-24-websites-phase-4.md. Decisions 1-9 confirmed 2026-04-24. Implementation committed as 4a59a9dd on feature/websites.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-24T22:47:44.938470Z","created_by":"cscheid","updated_at":"2026-04-24T22:48:18.483814Z","closed_at":"2026-04-24T22:48:18.483357Z","close_reason":"Implemented and shipped on feature/websites in commit 4a59a9dd. 48 new tests pass; cargo xtask verify --skip-hub-tests clean. Five follow-ups filed: bd-q1pe, bd-xwq8, bd-q6ky, bd-bobp, bd-nf50.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nwun","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-24T22:47:48.386065Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-nwyp","title":"Audit listing config parsing for PandocInlines / yaml-markdown-syntax-error fallthrough","description":"Discovered while writing L5 (bd-5vsr) snapshot test #33. Quarto YAML often parses bare frontmatter strings as PandocInlines (e.g. when a glob like 'posts/*.qmd' confuses the markdown sublexer and lands as a Span carrying the 'yaml-markdown-syntax-error' class). 'parse_contents' (config.rs:572) was matching only Scalar/Glob/Array variants, so 'contents: \"posts/*.qmd\"' silently parsed as an empty Vec, and apply_type_defaults then injected the default '*.qmd' glob — making cross-directory listing globs invisible at runtime even though the unit tests passed.\n\nFix in L5: route 'parse_contents' through 'as_plain_text' first, mirroring 'parse_listings' top-level shorthand handling. Two new unit tests lock the behavior (contents_pandoc_inlines_string_parses_as_glob, contents_array_with_pandoc_inlines_items_parses).\n\nAudit asks: what other listing-config parser branches in config.rs are still vulnerable to the same trap? Likely candidates from a quick read: parse_filter_list, parse_string_list, parse_sort, parse_field_types — any branch that matches on ConfigValueKind::Scalar(Yaml::String(_)) directly without a PandocInlines fallthrough should be reviewed and either rewritten to use as_plain_text first or have explicit PandocInlines handling added. Add unit-test coverage for each PandocInlines path discovered.\n\nOut of scope but related: this is also a signal that the YAML parser's 'PandocInlines wrapping for any string with markdown-special chars' choice imposes a hidden tax on every config consumer in the tree. A broader design pass on whether such strings should be unwrapped before reaching consumers (or whether consumers should always use as_plain_text by convention) would be worth doing.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-07T15:26:48.683892Z","created_by":"cscheid","updated_at":"2026-05-07T15:26:48.683892Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nwyp","depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T15:26:48.683892Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-nxe8","title":"Hub-client: refactor color scheme to auto/dark/light with browser detection","description":"Replace the binary light/dark toggle in ProjectSelector with a three-way color scheme preference (auto/dark/light). Auto mode follows prefers-color-scheme. Persisted via preferences service. Monaco editor follows the setting. Preview documents are out of scope. Plan: claude-notes/plans/2026-04-02-hub-client-color-scheme.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-02T21:21:58.194813Z","created_by":"cscheid","updated_at":"2026-04-02T21:21:58.194813Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-nxslt","title":"q2 preview: code cells render unhighlighted; include CodeHighlightStage + teach React CodeBlock to read data-hl-spans","description":"q2 render produces <span class=\"hl-function\">cat</span><span class=\"hl-string\">"Hello, world"</span>... for the example R cell; q2 preview shows the same cell as plain <pre><code class=\"r cell-code\">cat(\"Hello, world\")</code></pre>. Root cause: CodeHighlightStage was excluded from the q2-preview pipeline (Q2_PREVIEW_STAGE_EXCLUDED) even though it's AST-level (annotates data-hl-spans on the CodeBlock node — does not emit HTML). Two-part fix: (1) remove from the exclusion list so the AST nodes get annotated; (2) update React CodeBlock component (ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx) to read data-hl-spans, decode via the JSON triple-array format, and emit nested <span class=\"hl-CAP\">tokens</span> mirroring the HTML writer's behavior in crates/pampa/src/writers/html.rs:write_highlighted_body. Wire format: data-hl-spans=\"[[start_byte, end_byte, capture_name], ...]\". Capture-to-class: replace '.' with '-' (function.builtin → hl-function-builtin). WASM safety: quarto_highlight::annotate_pandoc and built-in grammars (including r) are WASM-safe; only user-grammars are native-only and they're not in scope here.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-18T16:43:57.892743Z","created_by":"cscheid","updated_at":"2026-05-18T16:51:36.354837Z","closed_at":"2026-05-18T16:51:36.354701Z","close_reason":"Implementation complete: code-highlight now runs in the q2-preview pipeline and the React CodeBlock component reads data-hl-spans + emits the same nested hl-* span markup as q2 render. Verified end-to-end on fixture website: R cell shows <span class='hl-function'>cat</span><span class='hl-punctuation-bracket'>(</span><span class='hl-string'>\"Hello, world\"</span>...</span>. 4 new SPA integration tests; 1 new Rust pipeline-inclusion test; cargo xtask verify 12/12 green.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-nxslt","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T16:43:57.892743Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-o505","title":"Wire nav-config-hash file write at end of project render","description":"Sub-phase 8.1 deferred writing the `<project>/.quarto/cache/nav-config-hash` file: 'nav_config_hash deferred — Phase 8 does not act on it per Decision 8; will land if a future refinement needs it.' The file is created when --clean-cache writes any state expectation, but no run actually produces it. Land alongside bd-par3 (smart nav-config-change detection) which is the consumer. See claude-notes/plans/2026-04-27-websites-phase-8.md §Decision 8 + Sub-phase 8.1.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid","updated_at":"2026-04-28T00:43:00.254499Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-o505","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-o505","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-o505","depends_on_id":"bd-par3","type":"related","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-o5wd","title":"Phase A.3: Fill in q2-preview-spa/src/main.tsx","description":"Replace the bd-hfjj Phase 6 placeholder with a real preview host: samod connect, initWasm, read indexDocId from window.location.hash, drive <Q2PreviewIframe> off automerge state. <PreviewApp> stays local to q2-preview-spa. Engine-less. Blocked by A.0 (bridge package). See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.3.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-13T16:53:28.085848Z","created_by":"cscheid","updated_at":"2026-05-13T18:02:48.368546Z","closed_at":"2026-05-13T18:02:48.368403Z","close_reason":"Phase A.3 (q2-preview-spa main.tsx fill-in) landed on branch beads/bd-o5wd-phase-a3-fill-q2 (commit c9923868). PreviewApp boots through @quarto/preview-runtime + renders via Q2PreviewIframe; 3/3 integration tests green; SPA prod build green; bundle audit clean (zero editor symbols). cargo xtask verify 11/11.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-o5wd","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.085848Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-o8pr","title":"Project resources: user- and engine-declared additional files","description":"Phase 0: complete (failing E2E tests written).\nPhase 1: complete -- ProjectConfig.resources, DocumentProfile v3 with resources, glob expansion, out-of-project guard, post-render copy in orchestrator. E2E verified with q2 render CLI.\n\nRemaining:\nPhase 2: engine channel + ResourceReportStage\nPhase 3: quarto.doc.add_resource Lua API\nPhase 4: render manifest + publish integration\nPhase 5: docs\n\nPlan: claude-notes/plans/2026-05-03-project-resources.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-03T18:52:39.439143Z","created_by":"cscheid","updated_at":"2026-05-03T20:04:42.900682Z","closed_at":"2026-05-03T20:04:42.900542Z","close_reason":"All 5 phases complete; feature verified end-to-end","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-o8pr","depends_on_id":"bd-k9i1","type":"related","created_at":"2026-05-03T18:52:50.754880Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-o8pr","depends_on_id":"bd-t3ny","type":"related","created_at":"2026-05-03T18:52:50.851218Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-o90m","title":"L9 — RSS feeds","description":"New write_rss_feeds step in WebsiteProjectType::post_render. One feed per listing host opting in via feed: true|{...}. Output: <output_dir>/<host-stem>.xml plus link rel=alternate in host's <head>. Three Q1 type modes: full, partial (reuse L7's readRenderedContents), metadata (profile only). Per-category sub-feeds. Templates as embedded doctemplate (feed/preamble, feed/item, feed/postamble) using L4's escape_xml pipe. Gated on website.site-url. See claude-notes/plans/2026-05-05-listings-epic.md §L9.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:26.344489Z","closed_at":"2026-05-08T17:34:26.344345Z","close_reason":"L9 implementation complete on branch beads/bd-o90m-listings-rss-feeds. Phase 1: diagnostics + imagesize dep (8b7a9286). Phase 2: feed binding (16ece34c). Phase 3: ListingFeedStageTransform (f4c241cf). Phase 4: ListingFeedLinkTransform (d2f79ccd). Phase 5: reader extension (33abdb8a). Phase 6: complete_staged_feeds post-render (4cdef213). Phase 7: end-to-end CLI verification (0bdd219e). 60 new tests across binding (32) + stage (10) + link_inject (6) + reader_ext (18) + complete (9) + catalog (1) = 76 tests added (workspace 1820 → 1896 in quarto-core). cargo xtask verify (full incl WASM hub-client) clean. Awaiting user merge approval. Follow-ups filed: bd-yd4q (math), bd-ir8n (highlight class maps), bd-4ho9 (W3C validator), bd-eips (format.metadata.description fallback), bd-udlt (title placeholder), bd-2vl0 (Q-12-15 dedup), bd-i4wv (generator version), bd-mae2 (custom feed templates), bd-sh4h (Atom 1.0), bd-d8go (date_format pipe), bd-varx (hoist append_to_rendered_header), bd-3sa5 (HTML-aware truncation), bd-xhvs (CDATA ]]> escape).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-o90m","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-o90m","depends_on_id":"bd-qf7r","type":"blocks","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-obcw","title":"Add publish.<provider>.* keys to YAML validation schema","description":"Once Quarto 2 has YAML validation infrastructure for _quarto.yml, add the publish.<provider>.* schema introduced by bd-t3ny.\n\nInitial keys (from bd-t3ny Phase 1):\n- publish.gh-pages.wait: boolean (default true) — whether to wait for the deployment to be live before declaring success.\n\nFuture keys (as providers land):\n- publish.<provider>.<provider-specific-config> — per-provider deployment configuration (custom domains, env, etc.).\n\nUntil this lands, quarto-publish does best-effort parsing with explicit error messages on malformed shapes — no schema validation, no IDE autocomplete.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md (see '_quarto.yml schema: publish.<provider>.*' section)","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-03T14:26:11.088052Z","created_by":"cscheid","updated_at":"2026-05-03T14:26:11.088052Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-obcw","depends_on_id":"bd-t3ny","type":"discovered-from","created_at":"2026-05-03T14:26:11.088052Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ochm","title":"Multi-format favicon variants (apple-touch-icon, sizes)","description":"Phase 7 emits a single <link rel=\"icon\"> tag. Some sites want apple-touch-icon, multiple sizes. Treat as enrichment of WebsiteFaviconTransform once a real consumer surfaces. Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.359523Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ochm","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ochm","depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ojtq","title":"xtask create-worktree: auto-detect integration branch (or warn) instead of defaulting to main","description":"Today `cargo xtask create-worktree <bd-id>` defaults `--base main`. For sub-task work inside an active epic (the dominant use case for create-worktree per .claude/rules/worktrees.md), main is almost always the wrong base — the convention is to branch off `feature/<epic-name>`. Silent default leads to a worktree at the wrong base that must be `git reset --hard`ed after creation, which is what happened during bd-kw93.1 setup on 2026-05-14.\n\nOptions:\n1. Auto-detect: if the beads issue has a parent-child to an epic whose branch can be inferred (e.g. the epic title or labels record it), use that branch as the base.\n2. Warn-on-default: when `--base` is not passed and the issue has a parent epic, print 'Using default base `main`; sub-tasks of <epic-id> typically branch off feature/<name>. Re-run with --base if needed.' and prompt or exit.\n3. Make `--base` required when the issue is a sub-task (has parent-child to a non-closed epic).\n\nOption 2 is the lowest-friction nudge. Option 1 needs a way to recover the integration branch name from the epic (could be a beads label, an external_ref, or just a convention scan).\n\nRelated friction: `switch-task` already does the right thing for sequential sub-task work but is under-discoverable when you've reached for create-worktree first. Cross-reference in the rules file or in xtask help text might help.\n\nAcceptance: pick one option, ship, no longer silently defaults to main when context says otherwise.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-14T14:40:07.105617Z","created_by":"cscheid","updated_at":"2026-05-14T20:03:15.368560Z","closed_at":"2026-05-14T20:03:15.368432Z","close_reason":"fetch_beads_metadata now reports parent_epic from the dependencies array; create-worktree warns when --base is at its default and the issue has an open parent epic. 5 new unit tests + 3-case binary smoke (warning fires; --base main silences; no parent = no warning). Workspace nextest 8864/8864. Merged to main as commit 28f1a18b.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ojtq","depends_on_id":"bd-kw93.1","type":"discovered-from","created_at":"2026-05-14T14:40:07.105617Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ooleh","title":"Print a one-line errors/warnings summary at the end of q2 render","description":"After a q2 render (especially a large project render with lots of scrolled-past output), print a single, formatted line summarizing the TOTAL number of errors and warnings the process generated. Counting logic lives in quarto-core (ProjectRenderSummary), formatting in crates/quarto/src/commands/render.rs near the existing render_summary_line. Plan: claude-notes/plans/2026-06-02-render-error-warning-summary.md. Design open for iteration before implementation.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-06-02T13:23:24.374653Z","created_by":"cscheid","updated_at":"2026-06-02T14:21:29.621260Z","closed_at":"2026-06-02T14:21:29.621109Z","close_reason":"Implemented + verified: one-line error/warning summary after q2 render. quarto-core DiagnosticCounts/diagnostic_counts (7 tests), quarto render formatting+wiring (8 tests), e2e through the binary, clean cargo xtask verify 9515/9515.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-oqbpi","title":"Author error-docs pages for listing subsystem (16 codes)","description":"Author stub-quality pages for all 16 Q-*-* listing subsystem error codes under docs/errors/listing/. Follow the template established in docs/errors/yaml/Q-1-10.qmd and docs/errors/README.md. Stub quality minimum: What this means / Why this happens / How to fix sections. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T20:35:51.314678Z","created_by":"cscheid","updated_at":"2026-05-24T20:41:36.047554Z","closed_at":"2026-05-24T20:41:36.047098Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-otmqu","title":"Listing sort: allow sorting by arbitrary front-matter fields, not just built-ins","description":"Q2's listing sort (crates/quarto-core/src/project/listing/sort.rs:117) only accepts a fixed set of built-in fields: title, subtitle, description, author, date, date-modified, image, image-alt, filename, path, output-href, reading-time, word-count.\n\nQ1 supports sorting by arbitrary front-matter field names. Without this, a listing of pages with custom front-matter (e.g. error-doc pages with 'code', 'subsystem', 'status' fields) can only sort by the built-ins — losing the natural sort axes the document author defined.\n\nRepro: any qmd with 'sort: code' (where 'code' is a front-matter field) emits 'Warning [Q-12-3]: Unknown sort field code; values will compare as equal.'\n\nWorkaround: sort by 'filename' if the filename encodes the sort key. Brittle but works for our error-doc pages where filenames are e.g. Q-1-10.qmd (sorts ~mostly correctly, though alphanumeric not numeric: Q-1-10 comes before Q-1-2).\n\nDiscovered while authoring docs/errors/index.qmd as part of bd-nvlxn (error-docs foundation).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-22T19:16:29.253170Z","created_by":"cscheid","updated_at":"2026-05-22T19:16:29.253170Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["listing"],"dependencies":[{"issue_id":"bd-otmqu","depends_on_id":"bd-nvlxn","type":"discovered-from","created_at":"2026-05-22T19:16:29.253170Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-p2tx","title":"Support <#foo> anchor shorthand notation in qmd","description":"Add support for <#foo> as shorthand for [foo](#foo){.anchor} in qmd reader and writer. Reader: intercept html_element nodes matching <#id> pattern and convert to Link with .anchor class. Writer: detect matching Link nodes and emit <#id> shorthand. Plan: claude-notes/plans/2026-02-10-anchor-shorthand.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-10T21:35:30.243155Z","created_by":"cscheid","updated_at":"2026-02-10T22:10:45.943407Z","closed_at":"2026-02-10T22:10:45.943379Z","close_reason":"Implemented anchor shorthand <#foo> in reader and writer. All 6394 workspace tests pass.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-p4sc","title":"Body-link rewriting: draft-mode visibility","description":"When DocumentProfile.draft && draft-mode != 'visible', replace the <a> with its inner content rather than just rewriting the href. Q1 parity. Requires draft-mode YAML config first (no Q2 surface today). Originally deferred from Phase 6 (bd-v30t).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:31.432468Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-p4sc","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-p4sc","depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-par3","title":"Mode B: smart nav-config-change detection","description":"Today Mode B (`quarto render foo.qmd`) renders exactly the user-named subset, regardless of whether _quarto.yml's navbar/sidebar/footer config changed since the last run. Decision 8 stores a nav-config-hash sentinel for this exact use case but Phase 8 doesn't act on it. Follow-up: when nav-config-hash differs from the cached value, also include any sidebar members of the targets in the augmented render set (their rendered HTML embeds nav HTML that may now be stale). See claude-notes/plans/2026-04-27-websites-phase-8.md §Decision 8.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:31.505676Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-par3","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-par3","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-pdwr","title":"Parallel per-file rendering in ProjectPipeline (rayon + pollster)","description":"Phase 1 ships ProjectPipeline as sequential. The plan §Parallelism readiness outlines the intended path: rayon + per-worker pollster::block_on, leaving the async stage trait as ?Send. Each thread drives one file's pipeline on a single-threaded executor local to it; the main thread builds ProjectIndex between passes. Requires confirming NativeRuntime: Send + Sync and adding a where-bound to the orchestrator. Benchmark before + after on a >=10-file fixture to validate speedup.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T01:05:40.090481Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:40.090481Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-pdwr","depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:40.090481Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-pf63","title":"Phase B.3: Verify cross-doc + include-shortcode edits propagate to preview","description":"After B.1 lands, verify the existing onFileContent → contentTick → render path covers cross-doc edges and include shortcodes correctly. Likely zero code changes; the work is empirical: build a fixture with an {{< include x.qmd >}} relationship, edit x.qmd, assert index re-renders.\n\nAdd a Playwright case to q2-preview-spa/e2e/. Re-render filtering against the dep graph (only re-render on edges) is an optimisation deferred to Phase D.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.3.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T19:34:52.827802Z","created_by":"cscheid","updated_at":"2026-05-13T20:59:06.765257Z","closed_at":"2026-05-13T20:59:06.765059Z","close_reason":"Phase B.3 complete; zero production-code changes — new Playwright spec at q2-preview-spa/e2e/include-shortcode.spec.ts pins the cross-doc include propagation. See commit ec72abc8 on beads/bd-pf63-phase-b3-verify-cross.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-pf63","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T19:34:52.827802Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-pf63","depends_on_id":"bd-z529","type":"blocks","created_at":"2026-05-13T19:34:58.241393Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-pgczr","title":"Migrate theme-config error to structured DiagnosticMessage","description":"Convert SassError::InvalidThemeConfig flow so it reaches the CLI as a DiagnosticMessage with code (Q-14-1 in proposed new 'theme' subsystem), SourceInfo pointing at the offending YAML in _quarto.yml, and ariadne-rendered output — instead of the current plain 'error: <path>: Invalid theme configuration: …' line.\n\nToday the source_info on the offending ConfigValue is discarded by .to_string() at CompileThemeCssStage's map_err (crates/quarto-core/src/stage/stages/compile_theme_css.rs:272-273), and file_failure_from_error only extracts diagnostics for QuartoError::Parse.\n\nThis is one of two children of the theme-diagnostic overhaul epic. Sibling issue handles cross-page coalescing.\n\nPlan: claude-notes/plans/2026-05-22-theme-diagnostic-structured.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T13:43:03.443230Z","created_by":"cscheid","updated_at":"2026-05-22T14:54:55.630083Z","closed_at":"2026-05-22T14:54:55.629887Z","close_reason":"Implemented in branch beads/bd-pgczr-migrate-theme-config-error. Theme errors now render as [Q-14-1] ariadne diagnostics with source spans pointing into _quarto.yml. Verified end-to-end against external-sources/quarto-web (345 structured emissions, 0 legacy plain-text). Repetition is bd-9hlja's domain.","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","sass","theme"],"dependencies":[{"issue_id":"bd-pgczr","depends_on_id":"bd-l26u6","type":"parent-child","created_at":"2026-05-22T13:43:03.443230Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-picv","title":"Fix Windows path-separator assumptions in pampa quarto_api path tests","description":"On Windows, ~10 tests in crates/pampa/src/lua/quarto_api.rs (test_normalize_path_simple, test_normalize_path_with_dots, test_normalize_path_with_dotdot, test_normalize_path_with_dotdot_at_root, test_normalize_path_relative, test_normalize_path_relative_with_dotdot, test_quarto_utils_resolve_path_relative, test_quarto_utils_resolve_path_relative_with_subdir, test_quarto_utils_resolve_path_with_dotdot, test_script_dir_stack_resolve_path_uses_top) fail because expected paths are hardcoded with forward slashes ('/some/extension/dir/data.json') while the Windows implementation joins with backslashes via Path::join. Different category from bd-3pe8 (PR #95) which fixed Lua source-string path interpolation; these are output-comparison failures. Need to decide: (a) normalize quarto.utils.resolve_path output to forward slashes in production (matches quarto-cli pathWithForwardSlashes convention), or (b) write tests with platform-correct expectations using PathBuf::join. Surfaced 2026-04-28 while running cargo nextest -p pampa on Windows. Same set of tests run twice (library + bin/pampa integration), so 18-20 visible failures from one root cause.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-28T13:07:09.316426300Z","created_by":"cderv","updated_at":"2026-04-28T13:07:56.882989800Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["lua","pampa","windows"],"dependencies":[{"issue_id":"bd-picv","depends_on_id":"bd-3pe8","type":"related","created_at":"2026-04-28T13:07:56.882332200Z","created_by":"cderv","metadata":"{}","thread_id":""}]} +{"id":"bd-povv","title":"Per-project capture cache for cross-session reuse","description":"Phase C.7 (bd-kw93.7) shipped the per-doc capture filesystem cache in <data_dir>/captures/ — the same tempdir that gets deleted when q2 preview exits. So closing and re-opening preview against the same project always misses the cache, even though the inputs are bit-for-bit identical.\n\nA per-project cache location (e.g. <project_root>/.q2/captures/, ignored by .gitignore convention) would unlock cross-session reuse. The cache key derivation (sha256 of canonical input_qmd) is already content-addressed and survives across sessions — only the directory choice changes.\n\nConsiderations:\n- Where: <project_root>/.q2/captures/? Some equivalent under XDG_CACHE_HOME keyed on project root? Discuss before implementing.\n- Cleanup: with content-hashed keys, old entries pile up across edits. A simple LRU sweep, or just letting the OS / git ignore handle it.\n- Gitignore: cache should not be committed. Either add a .q2/.gitignore on first write or document.\n- Concurrency: two q2 preview instances against the same project would race on the cache. Write atomicity is already last-writer-wins (atomic rename); concurrent readers handle a missing file gracefully.\n- Sandboxing: the existing loopback-only posture still applies.\n\nSee plan §C.7 'Open follow-up'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-14T17:35:41.522863Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:41.522863Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-povv","depends_on_id":"bd-kw93.7","type":"discovered-from","created_at":"2026-05-14T17:35:41.522863Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-pp89","title":"Native glob expansion for CLI render args","description":"Phase 8.4 ships with shell-only glob expansion: `quarto render *.qmd` works on Unix shells; on Windows or with quoted args it doesn't. Phase 1's discovery.rs already has expand_patterns helper for project.render globs. Extend commands::render::classify_inputs to recognize unexpanded glob patterns and route through that helper. Cross-platform parity, matches Q1 behavior.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:39.215996Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-pp89","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-pp89","depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-pphv","title":"Sitemap incremental merge (read-existing/update/write)","description":"Phase 7 ships fresh-write sitemap only. Phase 8's incremental rebuild needs to merge: read existing sitemap.xml, patch entries for re-rendered files, preserve others. Q1 reference: external-sources/quarto-cli/src/project/types/website/website-sitemap.ts lines 113-134 (readSitemap + merge logic). Originating phase: bd-b9mz.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid","updated_at":"2026-04-27T23:37:18.998907Z","closed_at":"2026-04-27T23:37:18.998535Z","close_reason":"Sitemap incremental merge implemented in Phase 8 sub-phase 8.3. write_sitemap reads existing _site/sitemap.xml, parses out loc→lastmod, refreshes entries for pages rendered this run, preserves entries for skipped pages. Falls through to fresh-write on parse failure. 6 unit tests + 1 integration test (mode_b_sitemap_preserves_untouched_entries_lastmod) verify the merge contract.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-pphv","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-pphv","depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-q1fyw","title":"Wire _brand.yml into the comprehensive YAML validator (once it exists)","description":"Phase 5 of the brand plan deferred schema validation in favor of serde deny_unknown_fields. When quarto-yaml-validation grows a comprehensive schema framework, port the brand-* schemas from external-sources/quarto-cli/src/resources/schema/definitions.yml and wire them in.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-21T02:31:31.142079Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.142079Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-q1pe","title":"Emit <link rel=\"prev/next\"> meta tags for page-navigation","description":"Q1 emits <link rel='prev'> / <link rel='next'> in <head> when page-navigation is active, for SEO and browser preload. Phase 4 deferred this (Decision 7) because it touches the HTML render config + template <head> slot, tangential to the page-nav feature itself. Add when convenient.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:54.468085Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:54.468085Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-q1pe","depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:54.468085Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-q30j","title":"Port automerge-inspector into hub-client as a debugging view","description":"Port external-sources/automerge-inspector into hub-client as a second Vite entry point (debug.html). Must work with the auth-enabled sync server by sharing hub-client's HttpOnly cookie over same-origin /ws proxy. Read-only document inspection + protocol traffic log. 'Out of general sight' — no link from main UI. See plan at claude-notes/plans/2026-04-16-hub-client-automerge-debugger.md for full design, open questions, and phased work items.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-16T15:54:33.232032Z","created_by":"cscheid","updated_at":"2026-04-16T15:54:33.232032Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["automerge","debugging","hub-client"]} +{"id":"bd-q6ed","title":"Display math inside a blockquote retains '> ' continuation prefix in content (issue #181)","description":"Tree-sitter grammar rule `pandoc_display_math` (crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js:367) matches its body as a single regex `/([^$]|[$][^$]|\\\\$)+/` between the two `$$` delimiters. When the math block is inside a blockquote, the interior `> ` block-continuation markers are never consumed by the grammar's `block_continuation` machinery; they end up verbatim inside the captured node text and then inside `Math.text` (see crates/pampa/src/pandoc/treesitter.rs:502-513). The qmd writer then correctly re-prefixes every line of the math body with `> ` when emitting it inside a blockquote, producing `> > p = q` and adding one more `> ` level on each round trip.\n\nFix is at the grammar level: make `pandoc_display_math` line-structured (loop over `$._newline | _math_line`) the way `pandoc_code_block` already is (grammar.js:828, with `_newline` consuming `block_continuation` at grammar.js:886). The writer is already correct; do not change it.\n\nTriage doc and minimal repros live at claude-notes/issue-reports/181/ on branch issue-181. See triage.md there for full evidence including CST output and a contrasting fenced-code-in-blockquote case that parses cleanly.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-12T17:34:18.793641Z","created_by":"cscheid","updated_at":"2026-05-12T17:34:18.793641Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-q6ky","title":"Plain-text aria-label projection for rich page-nav titles","description":"When DocumentProfile.title gains inline-markup support, project to plain text for aria-label and title attributes on the prev/next anchors. Phase 4 currently uses the title verbatim, which is fine while titles are plain String.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:59.865423Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:59.865423Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-q6ky","depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:59.865423Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qabnx","title":"Phase 1 — Design lock-in (hub-mcp device flow)","description":"Record-only phase. Captures the immutable v1 design decisions from empirical verification of Google's device-flow endpoints on 2026-05-19.\n\nNo code; closing condition is the plan's Phase 1 section being merged and the epic + sub-issues being filed.\n\nPlan §Phase 1: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-20T14:26:51.454050Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:18.060790Z","closed_at":"2026-05-20T21:22:18.060745Z","close_reason":"Design lock-in is recorded in plan §Phase 1 and replayed in the Phase 2 implementation. No further work.","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qabnx","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:26:51.454050Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-qawx","title":"cargo xtask create-worktree DWIMs remote-tracking branch as base, doesn't create requested branch","description":"Symptom: 'cargo xtask create-worktree --issue 152 --base bugfix/issue-184' printed 'Branch: issue-152' but the worktree was actually checked out on a freshly-created local 'bugfix/issue-184' branch (tracking origin/bugfix/issue-184). No 'issue-152' branch was ever created; 'git rev-parse refs/heads/issue-152' returns exit 1 immediately after the xtask reports success. Reflog confirms.\n\nReproduction (best-effort, from this session):\n- main worktree at .worktrees/issue-184/ already exists on a local 'issue-184' branch\n- remote bugfix/issue-184 exists; no local bugfix/issue-184 yet\n- cargo xtask create-worktree --issue 152 --base bugfix/issue-184\n- Result: .git/worktrees/issue-152/HEAD reads 'ref: refs/heads/bugfix/issue-184'\n- Expected: HEAD reads 'ref: refs/heads/issue-152'\n\nLikely cause: the underlying 'git worktree add -b issue-152 .worktrees/issue-152 bugfix/issue-184' invocation may interact poorly with git's DWIM when the start-point is a remote-tracking branch. Worth a small repro test in crates/xtask/.\n\nRecovered in-place via 'git checkout -b issue-152' inside the worktree (user-approved during triage). The xtask still claimed success in stdout, so the bug is silent — that's the most user-hostile part.\n\nDiscovered during: triage of issue #152 / bd-j4fe.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-14T19:08:20.229932Z","created_by":"cscheid","updated_at":"2026-05-14T19:08:20.229932Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qawx","depends_on_id":"bd-j4fe","type":"discovered-from","created_at":"2026-05-14T19:08:20.229932Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qb4o","title":"L11 — Listings epic close-out","description":"Compile per-phase follow-up bd log into single epic report. Confirm cargo xtask verify on a fresh checkout. Update document-profile-contract.md change log. Confirm hub-client renders listings end-to-end via WASM (real browser smoke test): multi-page project with listings, edit a content page, see listing host preview update with L1 fallbacks. See claude-notes/plans/2026-05-05-listings-epic.md §L11.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","updated_at":"2026-05-05T19:54:06.937522Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qb4o","depends_on_id":"bd-5vsr","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qb4o","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qb4o","depends_on_id":"bd-hzsi","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qb4o","depends_on_id":"bd-o90m","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qb4o","depends_on_id":"bd-qf7r","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qb4o","depends_on_id":"bd-xbnf","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qf7r","title":"L7 — Post-render placeholder upgrade (engine-rendered previews; BRACKETED)","description":"BRACKETED FEATURE — read epic §L7 'Bracketing rules' before extending. Upgrades L1-fallback description+image to engine-rendered firstPara+previewImage by reading sibling output files in WebsiteProjectType::post_render. Single module home, mandatory file-header discipline, CLI-only by construction (hub-client and quarto preview show L1 fallbacks), no cross-feature reuse, mandatory L1-fallback contract. See claude-notes/plans/2026-05-05-listings-epic.md §L7.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid","updated_at":"2026-05-07T21:11:33.486906Z","closed_at":"2026-05-07T21:11:33.486767Z","close_reason":"L7 (bd-qf7r) implemented + merged: post-render placeholder upgrade. impl d4877142, merge dc3a0f7b. CLI render now substitutes engine-rendered first paragraphs and preview images into listing entries via the bracketed post_render step. Hub-client preview retains L1 fallbacks per the bracketing rules. +50 tests over 8647 baseline → 8697 total. Follow-ups: bd-rvpd (span threading), bd-bpdz (L9 reader extension), bd-399t (docs callout), bd-fx23 (defensive id encoding).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qf7r","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-qf7r","depends_on_id":"bd-ml8z","type":"blocks","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qhb2o","title":"Parse error on `***` inline code content (regression from bd-ilv8p)","description":"Inline code content of exactly three asterisks (e.g. ```***```) fails to parse with 'unexpected character or token here'. Pandoc accepts it as Code \"***\" and pampa accepted it before commit 38e889ad (bd-ilv8p, 2026-05-24). Trigger is narrow: a run of exactly 3 consecutive asterisks at the start of inline-code content (```***```, ```***x```, ```***x***```). Four+ asterisks or asterisks after other content (```x***```, ```*x***```) parse fine. Likely cause: the new third alternative in the pandoc_code_span content rule (`alias($._soft_line_break, $.pandoc_soft_break)`) shifted parser-state precedence so the inline emphasis tokenizer's Q-2-32 'triple star' token beats the content regex inside code spans. See claude-notes/plans/2026-05-24-inline-code-triple-asterisk-regression.md for repro, characterization table, root cause hypothesis, and TDD work plan.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-24T22:49:19.359947Z","created_by":"cscheid","updated_at":"2026-05-24T23:22:59.128065Z","closed_at":"2026-05-24T23:22:59.127882Z","close_reason":"Fixed: gate TRIPLE_STAR emission on valid_symbols[EMPHASIS_OPEN_STAR] in scanner.c. Inline code spans containing literal *** now parse as Code, while paragraph-level Q-2-32 diagnostic still fires correctly. See claude-notes/plans/2026-05-24-inline-code-triple-asterisk-regression.md.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qhb2o","depends_on_id":"bd-ilv8p","type":"discovered-from","created_at":"2026-05-24T22:49:19.359947Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-qhkp","title":"New projects not added to Automerge project set (stale closure in App.tsx)","description":"handleProjectCreated and share link handler in App.tsx capture stale projectSetState/projectSetActions due to missing useCallback/useEffect dependencies. The status check always sees 'loading' instead of 'connected', so addProject is never called on the synced set. Plan: claude-notes/plans/2026-04-06-fix-project-set-stale-closure.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-06T20:27:45.091230Z","created_by":"cscheid","updated_at":"2026-04-06T20:27:45.091230Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-ql55q","title":"Preview navbar brand link points to artifacts VFS root and dead-ends iframe","description":"In hub-client / q2 preview, the navbar brand anchor (the title 'Quarto 2' in docs/) renders as <a class=\"navbar-brand\" href=\"/.quarto/project-artifacts/\">.\n\nLive repro 2026-05-20 (chrome-devtools MCP against q2 preview docs/):\nclicking it fires beforeunload on the iframe, iframe location moves to\n/.quarto/project-artifacts/, and NO NAVIGATE_TO_DOCUMENT postMessage fires —\nstranding the SPA on a URL the preview server doesn't serve.\n\nBoth TS link handlers reject the trailing-slash form:\n- iframeLinkHandlers.ts::parseArtifactHref (used by q2-preview SPA, this is the path that runs in q2 preview docs/)\n- iframePostProcessor.ts::reverseMapArtifactHref (used by hub-client HTML iframe)\nBoth require .html suffix on the stem.\n\nNative q2 render is correct (href=\"./\"). Bug is preview-only.\n\nFix in both TS link handlers — recognize the bare-directory artifact-root form as the project home (index.qmd). Resolver semantics unchanged.\n\nSee plan: claude-notes/plans/2026-05-20-preview-navbar-brand-artifacts-link.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:07:30.497517Z","created_by":"cscheid","updated_at":"2026-05-20T14:24:11.997050Z","closed_at":"2026-05-20T14:24:11.996869Z","close_reason":"Fixed in commit ebcc7f3e. Two-surface fix in TS:\n\n- iframeLinkHandlers.ts::parseArtifactHref (q2-preview SPA path,\n always-intercept) — empty-stem branch returns\n { qmdCandidate: 'index.qmd', anchor }.\n\n- iframePostProcessor.ts::reverseMapArtifactHref (hub-client HTML\n path, strict projectFilePaths lookup) — empty/null-stem branch\n tries each RENDERABLE_EXTS as 'index'+ext against projectFilePaths;\n returns first match or null per surface policy.\n\nResolver semantics in quarto-core unchanged — the trailing-slash\ndirectory URL is correct for static-served sites; the adaptation\nbelongs at the SPA-specific interception layer.\n\nE2E verified against docs/ via chrome-devtools MCP (post-fix\nsignature exactly inverts the 2026-05-20 repro): default prevented,\nno beforeunload, iframe stays at /q2-preview.html,\nNAVIGATE_TO_DOCUMENT fires with path=index.qmd, SPA route updates,\nheading after click is \"Quarto 2\".\n\nPlan: claude-notes/plans/2026-05-20-preview-navbar-brand-artifacts-link.md","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ql55q","depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-20T14:07:30.497517Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qod9s","title":"Phase 10 — operational hardening + documentation","description":"Operator runbook for Google OAuth client (Limited-Input-Devices type) registration. End-user .mcp.json example with QUARTO_HUB_MCP_CLIENT_ID/_SECRET. README: credential-sourcing rationale + threat-model #10 cross-ref. Per-platform credential-store clear commands. Revocation runbook (myaccount.google.com). Token-leak regression sweep.\n\nFuture-work list (not in v1) captured in plan: authenticate_status/clear tools, --login CLI flag, hub-side sub_denylist, per-scope auth, GitHub OIDC, refresh-expiry monitoring, PKCE on device-auth grant.\n\nPlan §Phase 10: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-20T14:27:35.458795Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:35.458795Z","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qod9s","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:35.458795Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-qor9a","title":"Resolve metadata paths relative to the file they were declared in (source-location-driven)","description":"Reproducer: `docs/guide/index.qmd` defines a sidebar in its frontmatter:\n\n```yaml\nsidebar:\n contents:\n - text: \"Introduction\"\n href: introduction.qmd\n - text: \"Markdown\"\n href: ../authoring/markdown/index.qmd\n```\n\nBoth targets exist relative to `docs/guide/index.qmd` (`docs/guide/introduction.qmd` and `docs/authoring/markdown/index.qmd`). Today `q2 render` warns:\n\n Sidebar references missing document information for 'introduction.qmd'\n Sidebar references missing document information for '../authoring/markdown/index.qmd'\n\nbecause `SidebarGenerateTransform` treats sidebar hrefs as project-root-relative regardless of where the YAML was written.\n\nRoot cause: `SidebarEntry::from_plain_string` (`crates/quarto-navigation/src/sidebar.rs`) and the bare-string code path in `SidebarEntry::from_config_value` strip `ConfigValue.source_info`, then `SidebarGenerateTransform` calls `index.lookup_by_source(Path::new(h))` on the bare string. There is no way at lookup time to know whether the href was written in `_quarto.yml` (project-root-relative) or in a doc's frontmatter (doc-relative).\n\nFix direction (chosen): hybrid 'known path-shaped keys' — the sidebar/navbar parser treats strings in href/file/contents/section-href positions as if they were `!path`, retaining the `ConfigValue.source_info` long enough to resolve them against `dirname(source_info.file)` at Generate time. Authors don't have to write `!path` tags. Mirrors the existing `adjust_paths_to_document_dir` machinery for directory metadata, extended to per-document frontmatter.\n\nScope: sidebar, navbar, page-footer entries (hrefs + contents items). Project-config / `_quarto.yml`-rooted values resolve to project-root-relative (unchanged behaviour). Per-doc / `_metadata.yml`-rooted values resolve to dirname-of-that-file, then normalized via `resolve_to_project_root`.\n\nThis issue also lands the SourceInfo plumbing through to the navigation diagnostics that bd-8d6rk migrates to the structured form — once the parser retains source_info, the diagnostic gets a real location and `--json` consumers can show the offending YAML line.\n\nPlan: claude-notes/plans/2026-05-20-bd-PLACEHOLDER-metadata-path-resolution.md (to be created)\n\nBlocks-on bd-8d6rk: the structured-diagnostic surface should exist before we wire SourceInfo into it.","notes":"Plan outline written: claude-notes/plans/2026-05-20-bd-qor9a-metadata-path-resolution.md (draft, awaiting iteration. Will be fleshed out in detail after bd-8d6rk lands)","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T14:56:32.967393Z","created_by":"cscheid","updated_at":"2026-05-20T17:26:26.218423Z","closed_at":"2026-05-20T17:26:26.218267Z","close_reason":"Implementation complete. RenderContext now carries source_context; NavigationItem / SidebarEntry::Section / Navbar carry href_source paired fields; resolve_metadata_path resolves hrefs against the YAML file they were authored in; sidebar/navbar/footer/page-nav generate+render pass href_source through to Q-13-* diagnostics. End-to-end verified on docs/guide/index.qmd (zero warnings; sidebar links resolve correctly). cargo xtask verify --skip-hub-build clean. Plan: claude-notes/plans/2026-05-20-bd-qor9a-metadata-path-resolution.md (all phases checked). Follow-up bd-hjv5o tracks broader generalization. Changes uncommitted pending user review.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qor9a","depends_on_id":"bd-8d6rk","type":"blocks","created_at":"2026-05-20T14:56:32.967393Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-qpa2","title":"Display math column-strip uses wrong column source, mishandles inline-wrapped and labeled math (issue #181 follow-up)","description":"Follow-up to bd-q6ed / issue #181, with revised diagnosis after a second-pass investigation (see `claude-notes/issue-reports/181/triage.md` § \"Second-pass investigation\").\n\n## Symptom\n\nTwo reporter-supplied edge cases (rundel, 2026-05-12):\n\n1. **Labeled display math inside a blockquote** — `> $$\\n> p(x)\\n> $$ {#eq-p}` round-trips with a literal `> ` left in `Math.text` after the second pass.\n2. **Labeled display math at top level** — `$$\\na\\n b\\n$$ {#eq-x}` loses one column of leading whitespace from interior lines on each round trip.\n\nSubsequent probing revealed both are instances of a broader brittleness in the column-strip introduced by bd-q6ed:\n\n3. `_$$\\na\\n b\\n$$_` (emph wrapping multi-line displaymath) loses one space on **first** parse — no round trip needed.\n4. `> _$$\\n> a\\n> b\\n> $$_` (same inside a blockquote) leaks `> ` AND loses interior whitespace on first parse.\n\n## Root cause\n\n`strip_continuation_prefix` in `crates/pampa/src/pandoc/treesitter.rs` uses `node.start_position().column` (the column of `$$`) as the strip width. That column equals the cumulative block-continuation prefix width **only when `$$` is the leftmost non-prefix character on its line**. Anything that precedes `$$` on the same line (`_`, `**`, `[`, the writer's own `[` for `quarto-math-with-attribute` Spans, etc.) shifts the column while the body bytes' source layout does not change. The strip then either eats real content (when the prefix is all whitespace/`>`) or refuses to strip real prefix (when the column overshoots into real content).\n\n## Constraint\n\n`DisplayMath` must remain an inline AST node — there are large existing corpora with display math nested inside paragraphs, and the grammar restructure proposed in the original triage would break those documents.\n\n## Fix shape (reader-side, no grammar change, no AST shape change)\n\nChange the strip-width source from `math_node.start_position().column` to the start column of the **enclosing block-leaf ancestor** (`pandoc_paragraph` / `pandoc_plain`). The cumulative block-continuation prefix width equals the paragraph's start column, which is constant across all interior lines of the paragraph regardless of what precedes `$$` on the opening line.\n\nPandoc's markdown reader uses this exact strategy (verified empirically). The fix matches Pandoc's behaviour on all probed cases — including lazy-continuation, nested blockquotes, list-item indent, and inline-wrapped multi-line math. The existing conservative `bytes ∈ {>, space, tab}` guard in the helper continues to handle lazy continuation correctly.\n\nThis single-input change subsumes:\n- bd-q6ed canonical case (paragraph col = math col, identical result)\n- bd-qpa2 edges A and B (paragraph col reflects true bq/top-level width)\n- Inline-wrapped multi-line math at any block context\n\n## Regression coverage to add\n\nFixtures under `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/`:\n\n- `labeled_display_math_in_blockquote.qmd` (bd-qpa2 edge A)\n- `labeled_display_math_top_level_indented.qmd` (bd-qpa2 edge B)\n- `emph_around_multiline_display_math.qmd`\n- `emph_around_multiline_display_math_in_blockquote.qmd`\n\nReference inputs preserved at `claude-notes/issue-reports/181/exp-labeled-math-in-bq.qmd` and `exp-labeled-math-toplevel.qmd`.\n\n## Worktree / branch\n\nImplementation on its own branch with plan file at `claude-notes/plans/2026-05-12-displaymath-column-strip-fix.md`. Upstream: https://github.com/quarto-dev/q2/issues/181.\n\n## Out of scope (separate issue if desired)\n\nThe writer's `[$$…$$]{attr}` emission for `quarto-math-with-attribute` Spans is suboptimal — Pandoc emits the natural form `$$\\n…\\n$$ {attr}` for the same AST. Switching to that form would improve readability and Pandoc compatibility, but with the reader fix above it is no longer required for round-trip correctness.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-12T19:32:00.197200Z","created_by":"cscheid","updated_at":"2026-05-12T19:55:56.757118Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-qpa2","depends_on_id":"bd-q6ed","type":"related","created_at":"2026-05-12T19:32:00.197200Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-r7v2","title":"Browser smoke: confirm MathJax/KaTeX typeset in real browser","description":"Phase 4.3 of bd-w5ov could not be completed in-session because chrome-devtools-mcp disconnected after a stale browser process was killed. Implementation is complete and Phase 4.2 (CLI exercise) verified the rendered HTML markup is correct. What remains: load the rendered fixtures in a real Chromium session and confirm the math is actually typeset, not just present as raw \\(x^2\\) text.\n\nAcceptance:\n- Render /tmp/q2-math-cli/inline_math.html, display_math.html, labelled_eq.html via http.server.\n- chrome-devtools-mcp: navigate, evaluate document.querySelectorAll('mjx-container').length > 0 (MathJax fixtures).\n- Render katex.html, evaluate document.querySelectorAll('.katex, .katex-display').length > 0.\n- Confirm zero console errors from the math runtime (404s on jsDelivr would fail this).\n- Record observations in claude-notes/plans/2026-05-04-math-mode.md.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-04T23:58:12.775314Z","created_by":"cscheid","updated_at":"2026-05-05T00:04:57.347714Z","closed_at":"2026-05-05T00:04:57.347571Z","close_reason":"Browser smoke completed in same session as bd-w5ov implementation: 5 fixtures verified live in Chromium via chrome-devtools-mcp. MathJax 3.2.2 typesets inline + display + labelled equations from jsDelivr; KaTeX typesets via auto-render; math-free pages stay clean; user URL override honored. Recorded in plan §Browser smoke log.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-r7v2","depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:12.775314Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-r82e","title":"DocumentProfile: add includes: Vec<PathBuf> for incremental-rebuild invalidation","description":"Surfaced during the main -> feature/websites merge (bd-xfwx) that threaded IncludeExpansionStage before the DocumentProfile checkpoint.\n\nProblem: after the merge, DocumentProfile.outline (and any other AST-derived fields) can be populated from headings / code / crossref targets spliced in via {{< include child.qmd >}}. The profile therefore depends on the contents of every included file, but the profile struct itself records no trail back to those files.\n\nFor incremental rebuilds (Phase 8 of the websites epic, bd-*) and for the future 'freeze' feature, the cache-key computation needs to invalidate a parent document's cached profile when ANY of its (transitive) includes change. Without tracking the include set on the profile, that is impossible.\n\nProposal: add a field roughly of the form\n\n includes: Vec<PathBuf> // or Vec<IncludeEntry { path, hash }>\n\nto DocumentProfile. Populated by IncludeExpansionStage (or by DocumentProfileStage reading a side-channel set that IncludeExpansionStage populated on the DocumentAst). Bump profile_version on the serialized shape.\n\nScope:\n- Decide on the shape (bare PathBuf list vs. (path, content-hash) pairs). For Phase 8 we'll likely want the hash too so nav-state invalidation can compare without re-reading the files.\n- Populate from IncludeExpansionStage.\n- Extend contract doc (claude-notes/designs/document-profile-contract.md).\n- Tests: profile records every included file (direct + transitive); round-trip serialization.\n\nNon-blocking for the website-epic MVP; becomes a hard prerequisite for Phase 8.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid","updated_at":"2026-04-28T00:43:08.078191Z","closed_at":"2026-04-28T00:43:08.077941Z","close_reason":"Closed as part of Phase 8.0 — DocumentProfile.includes added (v2). Verified by editing_include_invalidates_parent_profile (incremental_rebuild.rs).","source_repo":".","compaction_level":0,"original_size":0,"labels":["websites"],"dependencies":[{"issue_id":"bd-r82e","depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-r82e","depends_on_id":"bd-fegm","type":"blocks","created_at":"2026-04-27T22:21:01.025552Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-r82e","depends_on_id":"bd-xfwx","type":"related","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-r8n4r","title":"CaptureSplice fold: handle engine-handoff cells nested in cell wrappers","description":"apply_capture_splices folds capture splices for a multi-engine preview, but splice_cells walks TOP-LEVEL blocks only. If engine A emits engine B's cell inside a Div.cell wrapper, engine B's splice won't reach it and that cell renders as raw source. The common case (each engine's cells at top level) works. v1 limitation documented in capture_splice.rs and the plan.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-27T16:24:40.170895Z","created_by":"cscheid","updated_at":"2026-05-27T16:24:40.170895Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-r8n4r","depends_on_id":"bd-5yff4","type":"discovered-from","created_at":"2026-05-27T16:24:40.170895Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-r9hs","title":"Cargo: upgrade ureq v2.12.1 → v3.3.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 2.12.1 is range-pinned in workspace; latest is 3.3.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.424872Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.584646Z","closed_at":"2026-05-04T20:30:45.584505Z","close_reason":"merged: b0ee0f18","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-r9hs","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.861885Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ra5j","title":"L5 hub-client browser smoke for categories sidebar","description":"L5 (bd-5vsr) shipped per-item category chips and the right-margin categories sidebar. Native CLI e2e was verified directly (see plan §'End-to-end CLI verification record'). Hub-client browser smoke was deferred — same call as L3.\n\nTest plan: build hub-client (cd hub-client && npm run build:all && npm run dev), open dev server, load a multi-listing fixture project (or hand-author one in the editor), confirm:\n- Each post block shows clickable category chips.\n- The right margin shows the categories sidebar with the expected pills + counts.\n- Clicking a chip or a sidebar pill filters the listing via list.js.\n\nNote: until bd-57y4 (vendor + integrate quarto-listing.scss) lands, the visuals will look bare (vertical stack of plain divs, no hover states, no cloud sizing). The functionality should still be correct — clicks fire window.quartoListingCategory(...) and list.js filters items. Visual parity is bd-57y4's job; this issue is just the functional smoke that markup + JS still glue correctly in a real browser.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T14:20:13.761736Z","created_by":"cscheid","updated_at":"2026-05-07T14:20:13.761736Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ra5j","depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T14:20:13.761736Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-rcdo","title":"InlineSplice silently drops header attribute changes","description":"When changing a Header's attributes (classes, key-value pairs) without changing its inline content, the incremental writer's InlineSplice path preserves the original block text verbatim — including the old attribute suffix. The new attributes are silently lost. Discovered while testing the kanban demo's setCardStatus mutation.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-11T14:11:27.114610Z","created_by":"cscheid","updated_at":"2026-02-11T14:17:36.513428Z","closed_at":"2026-02-11T14:17:36.513409Z","close_reason":"Fixed: block_attrs_eq checks classes, kvs, and explicit IDs. 9 tests, all 6402 workspace tests pass.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-rhs6","title":"Cargo: upgrade serde_v8 v0.285.0 → v0.309.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.285.0 is range-pinned in workspace; latest is 0.309.0. Type: pre-1.0 minor (semver-breaking); large jump. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.119274Z","created_by":"cscheid","updated_at":"2026-05-04T18:16:05.361580Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-rhs6","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.361239Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-rmx3","title":"Tree-sitter scanner rejects Unicode whitespace (U+202F repro from Claude UI paste)","description":"pampa fails to parse `You (Apr 16, 2026, 10:18\\u202FAM)` with 'unexpected character or token here' at column 25. The byte sequence at that column is e2 80 af = U+202F NARROW NO-BREAK SPACE. Repro file: ~/Desktop/daily-log/2026/04/30/whitespace-bug.qmd. Origin: pasting a Claude web UI transcript into a qmd document (Claude.ai uses U+202F before AM/PM in timestamps). Plan: claude-notes/plans/2026-04-30-unicode-whitespace-handling.md. Likely broader exposure for other Unicode whitespace classes (U+00A0, U+2007, U+2009, U+2028, U+2029, etc.) — plan includes an audit phase.","status":"closed","priority":1,"issue_type":"bug","assignee":"cscheid","created_at":"2026-04-30T21:39:28.911409Z","created_by":"cscheid","updated_at":"2026-04-30T22:22:14.789643Z","closed_at":"2026-04-30T22:22:14.789493Z","close_reason":"Fixed: PANDOC_NON_ASCII_WHITESPACE added to grammar.js regex. Plan claude-notes/plans/2026-04-30-unicode-whitespace-handling.md. All tests pass; repro round-trips byte-for-byte through pampa.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-rqba","title":"Hub-client: parse error in another file is misattributed as 'Sidebar/Body link references unknown document'","description":"When a sibling page (e.g. about.qmd) fails Pass-1, opening a *different* page (e.g. index.qmd) shows two confusing warnings:\n- 'Sidebar references unknown document about.qmd'\n- 'Body link references unknown document about.qmd'\n\nThe file *exists*; it just failed to parse. The CLI also emits these warnings, but it additionally prints the underlying 'profile-pass skipped about.qmd: <diagnostic>' so a user can connect cause and effect. Hub-client never surfaces the Pass-1 failures at all — the diagnostics live on summary.pass1_failures[i].diagnostics and never cross the WASM boundary.\n\nRoot cause (located): crates/wasm-quarto-hub-client/src/lib.rs:1374-1428 ignores summary.pass1_failures entirely. The 'unknown document' warning itself is emitted at crates/quarto-core/src/transforms/navigation_href.rs:88-96 whenever ProjectIndex.get_profile(target) returns None.\n\nResolved fix shape (decisions D1, D2 in plan):\n1. Add a dedicated 'pass1_failures' field to RenderResponse (per-entry { source_file, error, diagnostics }). Do NOT fold them into 'warnings'. Engine stays policy-free; consumers choose strict-vs-lenient (CLI: bd-creo; preview: this issue).\n2. Add JsonDiagnostic.source_file: Option<String> so project-scoped warnings can be attributed.\n3. PreviewErrorOverlay grows a section listing Pass-1 failures with source attribution and ariadne-style formatting.\n4. navigation_href.rs wording change: 'references unknown document' → 'missing document information for' (proximal improvement; richer pass1-aware rewrite is a future task, not under this plan).\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Bug 1 + decisions D1/D2).\n\nNote: bd-mwtf (active-page case) is the narrower routing fix; bd-creo is the CLI-strictness sibling sharing the same wire-shape change.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid","updated_at":"2026-05-01T14:16:58.323704Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-rqba","depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-rqba","depends_on_id":"bd-mwtf","type":"related","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-rqgx","title":"L8 — Custom listing templates","description":"Wire template: config path through to ListingResolveTransform's resolver. Custom templates use FileSystemResolver rooted at host-page directory with MemoryResolver fallback for built-in partials. Custom templates receive the same data binding as built-ins, including listing_item.extra. template-params: exposed as listing.template_params. Missing-file diagnostic with YAML source span. Deprecation diagnostic for .ejs.md extension. See claude-notes/plans/2026-05-05-listings-epic.md §L8.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid","updated_at":"2026-05-08T14:59:38.124448Z","closed_at":"2026-05-08T14:59:38.124292Z","close_reason":"L8 implemented in 92ca4c52 on branch beads/bd-rqgx-listings-custom-templates. Custom listing templates load from host-dir-relative path with FileSystemResolver→MemoryResolver chain, allow shadowing built-in partials, and fall back gracefully via Q-12-14/Q-12-8/Q-12-10. End-to-end CLI verification recorded in the sub-plan; 8712 tests pass; cargo xtask verify green. WASM falls back to default with Q-12-8 (D1) — runtime/VFS plumbing tracked at bd-tmka. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-rqgx","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-rqgx","depends_on_id":"bd-b5jm","type":"blocks","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-rqgx","depends_on_id":"bd-ml8z","type":"blocks","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-rvpd","title":"Source-span threading for L7's Q-12-13 (and future L9 diagnostics)","description":"L7's Q-12-13 (\"Listing item from {href} produced no preview content\") fires from `post_render`, which operates on rendered HTML rather than source qmd. There's no source span available, so the diagnostic message cites the output href but not a position the user can navigate to.\n\nThreading a span through the L3-emitted placeholder comment is feasible: include the source-info offset of the listing item declaration in the begin marker, decode in L7, and attach to Q-12-13. L9 (RSS feeds) will hit the same problem; solving once is cleaner than twice.\n\nFiled at L7 close-out per the L7 plan §\"Filing reminder\" follow-up #1.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T19:51:07.917929Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:07.917929Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-rvpd","depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:07.917929Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-rwxa0","title":"Inline brand block in document frontmatter not wired through single-file render path","description":"from_config_value extracts brand: from a document's flattened metadata correctly, but single-file render mode (no _quarto.yml) appears to skip CompileThemeCssStage entirely and emit only the default styles.css. Project-level brand: works fine. Either route the inline brand through the single-file path or document the limitation. Discovered during Phase 7 e2e verification on 2026-05-20. Plan ref: claude-notes/plans/2026-05-20-brand-yml-support.md.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-21T02:31:10.966556Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:10.966556Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-rz2we","title":"Plan 3: q2-preview website-links fixture surfaces non-idempotent link rewriting (block 0 hash differs across runs with different project roots)","description":"Surfaced by Plan 3's idempotence gate (`crates/quarto-core/tests/idempotence.rs::website_links`). Reproduce:\n\n cargo nextest run -p quarto-core --test idempotence website_links\n\nPanic message:\n fixture website-links (ProjectOrchestrator): non-idempotent\n blocks: 58bea67d61ea7d0a vs 5b51945d38f146e1\n meta: 94dc6be205c977cb vs 94dc6be205c977cb\n first divergence: Block { index: 0, hash_a: 18150854589991019955, hash_b: 8368855784726903601 }\n\nMeta is stable across runs (hashes match). Blocks diverge at index 0, which is the paragraph containing `See [the other page](other.qmd) for more.`.\n\nHypothesis: the link-rewrite or link-resolution stage captures something path-dependent into the AST when it should produce a path-independent relative URL. Each `run_q2_preview` call creates a fresh `TempDir`, so the two runs see *different* project roots but identical fixture contents. For Plan 3's pipeline-determinism contract, structural AST should not depend on the absolute project root — only on its contents and relative layout. If the link's resolved target captures an absolute path or canonicalized tempdir form, two runs disagree.\n\nLikely surfaces in:\n- `LinkRewriteTransform` (crates/quarto-core/src/transforms/link_rewrite.rs)\n- `LinkResolutionStage`\n- whatever populates Link.target after these run.\n\nNote: SingleFile mode is not exercised here because website-links is orchestrator-only (chrome / link-resolution transforms need ProjectIndex). If the same bug bites SingleFile through a different fixture later, the fix should cover both.\n\nInvestigation starting points:\n1. `find_first_divergence` already names the block index — dump the actual `Inlines` of `doc_1.ast.blocks[0]` vs `doc_2.ast.blocks[0]` and diff. The plan's panic message tells you where to start.\n2. Inspect what the Link.target string looks like after `LinkRewriteTransform`. If it differs across runs, that's the immediate cause; trace back.\n3. The fix should canonicalize at the source: emit a path-independent relative URL (or a path-relative-to-project URL) into the AST, with the absolute-path machinery confined to source_info.\n\nThis blocks closing `website_links` in the Plan 3 gate. Failing fixtures are the triage backlog per the plan's long-lived-integration-branch policy.\n\nRefs:\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md\n- branch: feature/provenance","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:20:26.675413Z","created_by":"gordon","updated_at":"2026-05-21T22:36:57.023678Z","closed_at":"2026-05-21T22:36:57.023660Z","close_reason":"fixed: split vfs_root into write-root + url-root in ResourceResolverContext + per-renderer override (with_url_root). Native test helpers now pass /.quarto/project-artifacts as the URL prefix, decoupling rendered AST URLs from the host tempdir path. See claude-notes/plans/2026-05-21-vfs-url-write-root-split.md.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-rz6yb","title":"Hub: contain index-sourced paths to project root (path-traversal write)","description":"A connecting client can write the project index CRDT directly over the sync protocol. sync_all_documents (crates/quarto-hub/src/sync.rs:505) does project_root.join() on the untrusted index key with no containment, then std::fs::write — giving an arbitrary existing-file overwrite primitive (gated only by .exists()). Authoritative gate must be at the consumption site, not add_file (which the wire attack bypasses). Plan: claude-notes/plans/2026-05-30-hub-path-traversal-containment.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-30T15:43:44.767372Z","created_by":"shikokuchuo","updated_at":"2026-05-31T03:46:51.252768Z","closed_at":"2026-05-31T03:46:51.252713Z","close_reason":"Contained index-sourced paths in sync_all_documents: lexical contained_join + canonicalize symlink-escape check","source_repo":"kyoto","compaction_level":0,"original_size":0} {"id":"bd-s0ln","title":"hub-react-todo demo app (AST sync proof of concept)","description":"Standalone Vite React app in q2-demos/hub-react-todo that connects to a sync server, subscribes to a QMD file, and renders a live-updating todo list from the Pandoc AST. Demonstrates onASTChanged callback from Phase 1 of AST sync client API. Plan: claude-notes/plans/2026-02-06-hub-react-todo-demo.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T20:15:06.711433Z","created_by":"cscheid","updated_at":"2026-02-06T20:15:06.711433Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-s0ln","depends_on_id":"bd-3lsb","type":"discovered-from","created_at":"2026-02-06T20:15:06.711433Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-s3z1g","title":"React CodeBlock parity with native div.sourceCode wrapper","description":"Q2 has two HTML output paths: the Rust HTML writer in crates/pampa/src/writers/html.rs (used by 'q2 render') and the React renderer in ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx (used by 'q2 preview' / hub-client).\n\nCommit c81b6001 ('match Pandoc's codeblock styling output') updated the native writer to emit Pandoc's nested structure for highlighted code blocks:\n\n <div class=\"sourceCode [non-language classes]\" id=\"...\"><pre class=\"sourceCode lang\"><code class=\"sourceCode lang\">…</code></pre></div>\n\nThe React component still emits the pre-fix shape (`<pre class=\"sourceCode lang\"><code>…</code></pre>`), so the styling now drifts between 'q2 render' and 'q2 preview'. The component comments at CodeBlock.tsx:170-173 explicitly call out the parity invariant.\n\n## Scope\n\n- Mirror write_highlighted_codeblock in CodeBlock.tsx: when highlight spans are present, emit the div.sourceCode wrapper; move id + non-language classes to the div; emit class='sourceCode <lang>' on both <pre> and <code>.\n- Un-highlighted code blocks stay as bare <pre><code> — already in parity.\n- Update q2-preview.integration.test.tsx (two tests around lines 263 and 297) to assert the new shape.\n\n## Acceptance\n\n- Vitest passes for the integration test file.\n- 'npm run build:all' from hub-client succeeds.\n- Visual diff of rendered fixture (test.qmd from earlier session) between 'q2 render' and 'q2 preview' shows identical rounded-background styling.\n\n## Why this is the right first slice of bd-1tl09\n\nIt stress-tests the native/React parity invariant before any of the new decoration features (filename, copy, fold, etc.) introduce more parity surface. If maintaining parity by hand turns out to be sustainable here (one shape, two tests), the rest of the plan can proceed with confidence. If not, we add a shared contract before Phase 0.\n\nDiscovered-from: bd-1tl09 epic.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T19:36:31.804213Z","created_by":"cscheid","updated_at":"2026-05-19T19:49:42.966821Z","closed_at":"2026-05-19T19:49:42.966645Z","close_reason":"React CodeBlock now emits Pandoc's nested <div class=\"sourceCode\">…<pre class=\"sourceCode lang\">…<code class=\"sourceCode lang\">…</code></pre></div> structure for highlighted blocks; un-highlighted blocks unchanged. Verified end-to-end with q2 preview (project mode): DOM and visual rendering identical to q2 render. Found a separate bug along the way (bd-tnm3k, single-file preview mode broken).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-s3z1g","depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T19:36:31.804213Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-s58v1","title":"hub-mcp device-flow RFC 8628 §5.4 + RFC 7009 hardening","description":"Harden the existing device flow before/independent of the loopback+PKCE migration: (1) RFC 8628 §5.4 anti-phishing warning in the authenticate_start user-facing text + drop the redundant 'also valid' verification_uri line; (2) RFC 7009 best-effort refresh-token revocation in authenticate_clear (read->revoke->delete). Branch: device-flow-rfc8628-hardening. See plan 2026-05-28-hub-mcp-loopback-pkce.md for the migration these align with.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T19:56:07.930288Z","created_by":"shikokuchuo","updated_at":"2026-05-28T20:03:51.274682Z","closed_at":"2026-05-28T20:03:51.274638Z","close_reason":"Implemented on branch device-flow-rfc8628-hardening (commit ac7550af): §5.4 warning + dropped redundant URL line; RFC 7009 best-effort revoke-on-clear with 4 test cases. 147 package tests + typecheck green.","source_repo":"kyoto","source_repo_path":"/Users/shikokuchuo/r/kyoto","compaction_level":0,"original_size":0} +{"id":"bd-s8llm","title":"No internal API for pipeline producers to publish files into the VFS","description":"VirtualFileSystem (crates/quarto-system-runtime/src/wasm.rs:227-261) exposes write entry points only as wasm-bindgen exports — JS -> WASM. There is no internal Rust API a pipeline stage, engine, or extension can call to publish a file for downstream consumption.\n\nThis blocks any design that wants engines to ship Lua filter source as a virtual file (the natural extension of bd-execresult-filters-unused-once-fixed). It also limits what extensions can do at WASM runtime — they can't materialize generated resources for the renderer.\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G2.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-28T13:45:50.567084Z","created_by":"cscheid","updated_at":"2026-05-28T13:45:50.567084Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-s8llm","depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:50.567084Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-s9emf","title":"Author error-docs pages for navigation subsystem (7 codes)","description":"Author stub-quality pages for all 7 navigation subsystem error codes under docs/errors/navigation/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:56.756080Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.550067Z","closed_at":"2026-05-24T21:15:22.549714Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-sfr5l","title":"Phase 5 — hub-mcp credential storage (OS-native keyring)","description":"New module ts-packages/quarto-hub-mcp/src/auth/credential-store.ts using @napi-rs/keyring. Single opaque JSON blob per Entry(service, account). Per-platform service/account identifiers locked in Phase 1.\n\nTDD: cross-platform unit suite + headless-failure suite + platform-conditional suites (KEYRING_INTEGRATION=1 gate). Sibling bug bd-XXXX tracks the keyring-error blob-leak regression test specifically.\n\nAsymmetric error mapping: read returns null on backend-unavailable; write/clear throw typed KeyringUnavailableError. No silent plaintext fallback anywhere.\n\nPlan §Phase 5: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:10.359115Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:10.359115Z","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-sfr5l","depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:10.359115Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} {"id":"bd-sgm7","title":"Share link single-click: auto-connect without requiring manual project setup","description":"Make share links work in a single click regardless of whether the receiving user already has the project in their settings. Currently, new recipients must manually click 'Connect' in the ProjectSelector. The new flow should auto-create the project entry and connect immediately. Also add project name to the share URL for better UX. Plan: claude-notes/plans/2026-03-30-share-link-single-click.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-03-30T16:47:27.895709Z","created_by":"cscheid","updated_at":"2026-03-30T16:56:38.302807Z","closed_at":"2026-03-30T16:56:38.302195Z","close_reason":"Implemented: share links now auto-create project entries and connect immediately. Added project name to share URL. Removed pendingShareData plumbing. All tests pass.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-sh4h","title":"L9 follow-up: Atom 1.0 emission","description":"L9 emits RSS 2.0 only (with the atom:link rel=self extension element, matching Q1). A pure Atom 1.0 alternative would be a forward feature for users who prefer it. Likely shape: feed.format: rss|atom on the listing config; new templates under feed/templates/atom/.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-08T17:33:49.689660Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:49.689660Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-sh4h","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:49.689660Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-si8b","title":"Evaluate Temml as a third math engine for HTML output","description":"MathJax (default) and KaTeX shipped in bd-w5ov. Temml is a KaTeX fork that emits MathML directly (~80 KB bundle, native browser rendering, best a11y story). MathML support is now near-universal (Chromium since 2023, WebKit + Firefox always).\n\nInvestigate whether to add Temml as a third 'html-math-method' option:\n- Output contract differs from MathJax/KaTeX (MathML in markup vs TeX delimiters).\n- Could be added as a parallel arm in MathEngine / from_meta() / render_math_slot().\n- Decide: does q2 ship TeX-source delimiters and let Temml convert client-side, or do server-side TeX→MathML conversion at render time?\n\nOut of scope: making Temml the default. Default stays MathJax for parity with Quarto 1.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-04T23:58:18.920001Z","created_by":"cscheid","updated_at":"2026-05-04T23:58:18.920001Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-si8b","depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:18.920001Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-sizl","title":"q2-debug placeholder loses CustomNode type_name","description":"q2-debug's Block/Inline dispatchers (`hub-client/src/components/render/q2-debug/dispatchers.tsx`) currently render the miss path as `<span>Not registered: CustomBlock</span>` (or `<div>...</div>` for blocks) — using only `args.node.t`, which discards the CustomNode `type_name` discriminator.\n\nFor CustomBlock / CustomInline AST nodes, the rendered debug placeholder should include the type_name so developers can see *which* CustomNode hit the fallback path. Example: `Not registered: CustomBlock(Callout)` instead of `Not registered: CustomBlock`.\n\n~5 LOC change. Pattern: in the dispatcher, when `args.node.t === 'CustomBlock' || args.node.t === 'CustomInline'`, append the type_name to the displayed text.\n\n**Why**: q2-preview's parallel placeholder (`q2-preview/dispatchers.tsx` post-Plan-2C) already includes the tag name; q2-debug's debug-mode visualization should be at least as informative.\n\n**Discovered**: while reviewing Plan 2C (q2-preview customnode rendering, `claude-notes/plans/2026-05-09-q2-preview-plan-2c-customnode-rendering.md`). Not in 2C scope — q2-debug is a separate format. Filing as a follow-up.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-10T09:43:10.869153Z","created_by":"gordon","updated_at":"2026-05-10T09:43:10.869153Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-sjk4t","title":"braid 0.3.0 prerequisite features for q2 migration","description":"EXTERNAL/BLOCKING: four braid-side features must merge in the braid repo (~/rooms/room-1/braid) and ship as braid 0.3.0 before q2 cutover (Phase 2). Owned by a separate braid-repo agent; tracked here only as the q2 epic's blocker.\n\nFeatures: (1) recursive 'braid dep tree'; (2) 'braid create --deps <type>:<id>' one-shot create+link; (3) 'braid import' skip beads tombstones (q2 has 2: bd-1xf5, bd-298oe); (4) braid agents-info skill installer.\n\nFull spec: claude-notes/plans/2026-06-08-braid-0.3.0-features-for-migration.md\nParent: claude-notes/plans/2026-06-08-braid-migration.md (Phase 0)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-08T14:16:40.990334Z","created_by":"cscheid","updated_at":"2026-06-08T15:33:46.986727Z","closed_at":"2026-06-08T15:33:46.986490Z","close_reason":"braid 0.3.0 implemented + installed; all four features verified in-session 2026-06-08. Force-closed: beads treats the parent-child edge as a block (a beads quirk); the meaningful 'blocks' edge to the epic remains.","source_repo":".","compaction_level":0,"original_size":0,"labels":["braid","migration"],"dependencies":[{"issue_id":"bd-sjk4t","depends_on_id":"bd-a1qb3","type":"parent-child","created_at":"2026-06-08T14:16:41.075549Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-spsv","title":"Add cargo xtask create-worktree command with CLAUDE.local.md stub","description":"Add cargo xtask create-worktree subcommand that automates full worktree setup: git worktree add, beads redirect, and CLAUDE.local.md context stub prepended with markers. Three modes: beads ID (reads br show), --issue N (reads gh issue view), --upgrade (date-based). CLAUDE.local.md holds context only (worktree location, beads pointer, GitHub URL, plan placeholder) — beads tracks status. Plan at claude-notes/plans/2026-05-07-create-worktree-xtask.md. 8 files: .gitignore, xtask/src/main.rs, xtask/src/create_worktree.rs (new), .claude/rules/xtask.md, .claude/rules/worktrees.md, investigate-beads skill, triage skill, upgrade-cargo-deps skill.","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-07T14:23:51.141793100Z","created_by":"cderv","updated_at":"2026-05-11T16:49:51.239535200Z","source_repo":".","compaction_level":0,"original_size":0,"comments":[{"id":20,"issue_id":"bd-spsv","author":"cderv","text":"2026-05-07 design phase complete. Worktree: .worktrees/bd-spsv-create-worktree-xtask on branch beads/bd-spsv-create-worktree-xtask (commit 0a2def90).\n\nPlan committed at claude-notes/plans/2026-05-07-create-worktree-xtask.md (~480 lines). Two sub-agent design reviews passed: pass 1 (1 blocking + 12 required → all resolved), pass 2 (3 required → all resolved).\n\nKey design decisions locked:\n- clap struct-style variant `CreateWorktree { #[command(flatten)] args }` matching existing main.rs idiom\n- ArgGroup(required, single) for mode validation\n- Slug derive: split on whitespace+hyphen, ASCII-alphanumeric, drop stop-words, take 4, error on empty\n- CLAUDE.local.md idempotent prepend with BEGIN/END markers; full failure-case table + line-ending decision rules + atomic .tmp+rename\n- time = { version = \"0.3\", features = [\"macros\", \"formatting\"] }\n- xtask is filesystem-only (never touches beads state)\n- worktrees.md gets new sections: § CLAUDE.local.md, § Manual bootstrap (fallback)\n- --slug semantics: override in beads mode, suffix in issue/upgrade\n\nNEXT SESSION: from worktree .worktrees/bd-spsv-create-worktree-xtask, invoke /superpowers:writing-plans against the design plan to produce phased implementation plan with TDD task structure. Then implement.\n\nTouched files (8): .gitignore, crates/xtask/Cargo.toml, crates/xtask/src/main.rs, crates/xtask/src/create_worktree.rs (new), .claude/rules/xtask.md, .claude/rules/worktrees.md, .claude/skills/{investigate-beads,triage,upgrade-cargo-deps}/SKILL.md.\n\nSelf-bootstrap caveat: this worktree was set up with the manual git+echo commands the new xtask replaces (chicken-and-egg). E2E test of new command happens after merge, on next worktree any dev creates.","created_at":"2026-05-07T17:10:40Z"},{"id":21,"issue_id":"bd-spsv","author":"cderv","text":"Implementation complete on branch beads/bd-spsv-create-worktree-xtask (19 commits, 0a2def90..1672540a). 54 xtask tests passing. Final whole-branch review verdict: Ready to merge. Phase E smoke tests (Chris-driven) and Phase G push remain. Two optional follow-ups noted in review: clippy cleanup of new code (~5 lints), and reordering validate_slug ahead of fetch_beads_metadata in plan_beads to fail-fast on bad slug.","created_at":"2026-05-11T15:43:29Z"},{"id":22,"issue_id":"bd-spsv","author":"chris","text":"2026-05-11 session 3 — IMPLEMENTATION COMPLETE on branch beads/bd-spsv-create-worktree-xtask. HEAD 09eead55. 24 commits ahead of main. 55 xtask tests passing.\n\nNEXT SESSION (in priority order):\n\n1) Phase E end-to-end smoke (Chris-driven, from worktree .worktrees/bd-spsv-create-worktree-xtask). Full recipe in claude-notes/plans/2026-05-11-implement-create-worktree-xtask.md § Phase E. Quick form:\n cargo build -p xtask\n cargo xtask create-worktree --help\n cargo xtask create-worktree bd-spsv --slug e2e-beads\n ISSUE=$(gh issue list --repo quarto-dev/q2 --state open --limit 1 --json number --jq '.[0].number')\n cargo xtask create-worktree --issue \"$ISSUE\" --slug e2e-issue\n cargo xtask create-worktree --upgrade --slug e2e-upgrade\n mkdir -p .worktrees/bd-spsv-collision-test ; cargo xtask create-worktree bd-spsv --slug collision-test ; rmdir .worktrees/bd-spsv-collision-test\n cargo xtask create-worktree bd-spsv --slug \"foo/bar\" # rejected\n cargo xtask create-worktree bd-spsv --slug e2e-beads # rerun-fails by design\n Q2_CREATE_WORKTREE_INJECT_FAIL=after_worktree_add cargo xtask create-worktree bd-spsv --slug rollback-test\n test ! -d .worktrees/bd-spsv-rollback-test && git branch | grep -v 'beads/bd-spsv-rollback-test' && echo OK\n # cleanup: git worktree remove on each e2e dir + git branch -d on each e2e branch\n\n2) Capture smoke transcript for PR body (per CLAUDE.md \"end-to-end verification before declaring success\").\n\n3) Push: git push -u origin beads/bd-spsv-create-worktree-xtask:feature/bd-spsv-create-worktree-xtask\n\n4) gh pr create against main. PR body should reference: 24 commits, 55 tests, smoke transcript, optional follow-ups list (below).\n\nOPTIONAL FOLLOW-UPS (non-blocking, file separately if desired):\n- clippy cleanup in create_worktree.rs: ~5 findings (map_unwrap_or at :176/:448, collapsible_if at :570, print_literal at :160, naive_bytecount in tests at :759).\n- plan_beads ordering: move validate_slug ahead of fetch_beads_metadata to fail-fast on bad --slug overrides without burning a `br show` subprocess call.\n\nSELF-BOOTSTRAP CAVEAT: this worktree itself was set up with the manual git+echo commands the new xtask replaces. The first real end-to-end use of the new command happens after this PR lands on main, on whatever worktree the next developer creates.","created_at":"2026-05-11T16:49:51Z"}]} +{"id":"bd-sr73","title":"Re-measure trace size on a fixture that exercises a real engine (jupyter/knitr supporting_files)","description":"bd-5qnj's provisional size budgets (≤100 KB compressed for CI fixtures, ≤1 MB for user-attached bug reports) were measured on markdown-engine fixtures where `engine_capture` is `None`. After merging bd-45yw (replay engine recording), traces from real engine runs additionally carry `engine_capture.result.supporting_files` — for jupyter/knitr documents this can include base64-encoded PNG plots, data-frame snapshots, etc.\n\nInvestigate:\n- Capture a representative jupyter trace from a real notebook (a plot + a small dataset).\n- Measure: total `latest.json.gz` size, `engine_capture.result` share, supporting_files byte share.\n- Decide whether the 100 KB CI-fixture budget still holds, or whether engine_capture needs its own size accommodation (separate file? on-disk gzip-of-gzip is unhelpful for already-compressed PNGs).\n\nReferences:\n- claude-notes/plans/2026-05-03-trace-size-for-replay.md (Phase 3 outstanding follow-up)\n- claude-notes/plans/5qnj-trace-size-investigation/measurements.md (current measurements; markdown engine only)\n- crates/quarto-trace/src/lib.rs::EngineCapture (where supporting_files content lives)","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-03T23:28:59.411296Z","created_by":"cscheid","updated_at":"2026-05-03T23:28:59.411296Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-sr73","depends_on_id":"bd-5qnj","type":"discovered-from","created_at":"2026-05-03T23:28:59.411296Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-swpy","title":"Sidebar/navbar/footer hrefs not relativized to current page in nested directories","description":"Surfaced building examples/websites/03-nested-sidebar (bd-2jwk). resolve_href_for_html in crates/quarto-core/src/transforms/navigation_href.rs returns profile.output_href verbatim, which is project-root-relative. Body links go through resolve_doc_relative_href + ResourceResolverContext::page_url_for, so they get relativized correctly (e.g. inside _site/guide/installation.html the body link to index.qmd renders as 'index.html', not 'guide/index.html'). But sidebar / navbar / page-footer / page-nav hrefs use resolve_href_for_html and skip the resolver, producing absolute-looking project-relative paths like 'guide/index.html' from within a page at depth 1, which a browser resolves as 'guide/guide/index.html'. Reproduces in examples/websites/03-nested-sidebar/_site/guide/installation.html and reference/api.html. Fix plan: claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md (thread ResourceResolverContext through resolve_href_for_html + four Render transforms, route hits through page_url_for matching the body-link path).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid","updated_at":"2026-04-29T15:10:53.397840Z","closed_at":"2026-04-29T15:10:53.397537Z","close_reason":"Threaded ResourceResolverContext through resolve_href_for_html in commit aa50d29e. All four Render transforms (sidebar, navbar, footer, page-nav) now route hits through page_url_for, mirroring the body-link path. Native renders produce page-relative URLs (deployment-portable); hub-client vfs_root mode produces absolute /{vfs_root}/... URLs (intended). 8081 workspace tests + cargo xtask verify pass. Closes bd-swpy.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-swpy","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-swpy","depends_on_id":"bd-2jwk","type":"discovered-from","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-t3ny","title":"Publish command scaffolding + gh-pages provider","description":"Build the scaffolding for Quarto 2's `publish` command (mirroring Quarto 1's organization in src/publish/) and ship the `gh-pages` endpoint end-to-end. All other providers (quarto-pub, netlify, posit-connect, posit-connect-cloud, confluence, huggingface) and single-document publishing are explicitly deferred.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md\n\nStatus: design draft — pending user review before implementation.","status":"completed","priority":1,"issue_type":"epic","created_at":"2026-05-03T13:47:55.362968Z","created_by":"cscheid","updated_at":"2026-05-03T15:18:38.758969Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-t9zb","title":"Share crossref label formatting between CrossrefRenderTransform and the LSP outline","description":"CrossrefRenderTransform formats labels like 'Figure 1: <caption>' / 'Theorem 1: <title>' (hardcoded English, see crates/quarto-core/src/transforms/crossref_render.rs). The LSP outline walker (crates/quarto-lsp-core/src/analysis.rs::format_crossref_detail) now builds the same strings independently. When localization lands (crossref.fig-prefix, title-delim, etc.) the two call sites must stay consistent. Extract a shared label helper in quarto-core::crossref that both consumers call.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:35.378079Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:35.378079Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-t9zb","depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:35.378079Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tanz","title":"Cargo: upgrade runtimelib v1.6.0 → v2.0.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 1.6.0 is range-pinned in workspace; latest is 2.0.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.020523Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.678359Z","closed_at":"2026-05-04T20:30:45.678215Z","close_reason":"merged: b7b843fe","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-tanz","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.189033Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-td2a","title":"Footer text-region project-link rewriting (replaces bd-jfyl)","description":"Phase 5's bd-jfyl follow-up was deferred precisely because Phase 6's helper is its natural home: now that resolve_doc_relative_href exists, the footer renderer's text walker can call it for any .qmd hrefs in user-supplied footer text. This is the planned consumer for the helper, surfaced during Phase 6 close-out (bd-v30t). Probably also depends on the same walking infrastructure as the body-link transform.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid","updated_at":"2026-04-27T13:37:07.174383Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-td2a","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-td2a","depends_on_id":"bd-jfyl","type":"related","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-td2a","depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-telo","title":"Support nested website.navbar in addition to top-level navbar","description":"Today q2 only reads navbar config from a top-level `navbar:` key in `_quarto.yml` (alongside `project:`). Quarto 1 and the more natural project-level shape places it under `website:` (`website.navbar:`). Both forms should work:\n\n- Top-level `navbar:` is useful for non-website projects that want a navbar (e.g. a single-doc with custom navigation).\n- Nested `website.navbar:` is the natural project-level config home (matches Q1, matches `website.sidebar`).\n\nDiscovered while smoke-testing the bd-4eyf Bootstrap JS work — a fixture written with the natural `website.navbar:` shape silently produced no navbar markup (no error, no warning), which is a usability cliff. See claude-notes/plans/2026-05-04-bootstrap-js-injection.md (\"Browser smoke log\" section, navbar follow-up note).\n\nScope:\n- Reader/parser: accept `website.navbar:` as an alias for the existing top-level `navbar:`. If both are present, decide precedence (top-level wins? merge? error?) and document.\n- Same treatment for `website.page-footer` if not already supported.\n- Tests: extend navbar_footer_pipeline.rs with the nested shape; ensure existing top-level shape still works.\n- Possibly a deprecation/migration nudge for the top-level shape if we end up preferring nested.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-04T22:14:09.515305Z","created_by":"cscheid","updated_at":"2026-05-19T15:13:02.957324Z","closed_at":"2026-05-19T15:13:02.957195Z","close_reason":"Implemented in d66ff31c (alongside bd-jjep). website.navbar / website.page-footer / website.sidebar now all accepted as aliases for the top-level forms, via quarto_config::resolve_website_value(). Precedence: top-level wins, !prefer escapes the default field-wise merge. Same treatment also applied to website.sidebar's two other readers (SidebarGenerateTransform and derive_doc_scss_layer) for consistency.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-tep4x","title":"Author error-docs pages for writer subsystem (21 codes)","description":"Author stub-quality pages for all 21 Q-3-* writer subsystem error codes under docs/errors/writer/. Codes cover writer-side failures: IO errors, format-specific unsupported features (notes, attributes, ANSI), unresolved/unprocessed markup. Follow the template established in docs/errors/yaml/Q-1-10.qmd and docs/errors/README.md. Stub quality minimum: What this means / Why this happens / How to fix sections. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T20:24:35.322406Z","created_by":"cscheid","updated_at":"2026-05-24T20:32:20.610038Z","closed_at":"2026-05-24T20:32:20.609665Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-tfy0","title":"[websites] Deep-directory auto-sidebar grouping","description":"Phase 2's auto expansion groups at one level only: top-level files flat, subdir files grouped into a Section with that subdir's index-page title. Q1 produces recursively nested sections for 'docs/api/v1/reference.qmd' (Docs > Api > V1 > Reference). Design an intuitive N-level grouping; the current 1-level emits 'docs/api/v1.qmd' as one Link under the 'docs' section, which is not terrible but loses structure in deep hierarchies.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T17:52:45.561606Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:45.561606Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tfy0","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:45.561606Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-tjbr","title":"Improve cargo xtask dev-setup: cmake detection and xtask self-build lock","description":"Two cross-platform dev-ergonomics improvements surfaced while verifying PR 109 on Windows after rebasing on main. Both are orthogonal to the WASM work and belong in their own PR. Target branch feature/dev-setup-improvements, worktree at .worktrees/dev-setup-improvements. Base branch origin/main. See design and acceptance fields for details.","design":"Background. Main added quarto-highlight (commit 1fa33da0, bd-n7x2 epic) which enables the `wasm` feature on tree-sitter for native builds. That pulls in wasmtime-c-api-impl as a transitive dependency, whose build.rs shells out to cmake. Result: cmake is now a hard prerequisite for `cargo build --workspace` on every platform. GitHub Actions runners have it pre-installed. Local dev boxes frequently do not (confirmed on Chris's Windows setup).\n\nFix 1 — check_cmake() in crates/xtask/src/dev_setup.rs. Follow the existing check_pandoc() pattern at line 155. Detection via `cmake --version`. If missing, print a warning with platform-specific install commands (scoop/winget on Windows, brew on macOS, apt/dnf on Linux). Unlike pandoc the warning should be stronger because cmake missing means `cargo build --workspace` fails, not just specific tests. No version constraint — any modern cmake works for wasmtime-c-api. Single function, no NativeTool struct abstraction (YAGNI).\n\nFix 2 — `--exclude xtask` in crates/xtask/src/verify.rs step 3. The current code at line 112 runs `cargo build --workspace`, which re-links target/debug/xtask.exe while the currently-running xtask.exe holds a file lock on Windows. Error: `failed to remove file ... Accès refusé (os error 5)`. Linux/macOS tolerate overwriting a running exe, so this was latent. Change to `[\"build\", \"--workspace\", \"--exclude\", \"xtask\"]`. Step 5 (nextest) is unaffected — it compiles xtask as a test binary at a different path, no conflict. Cross-platform safe.\n\nFix 3 — CONTRIBUTING.md cmake subsection. Add after the existing \"macOS: Homebrew LLVM (for WASM builds)\" section. Same shape: one paragraph explaining why, then per-platform install commands. Covers Windows (scoop/winget), macOS (brew — note it bundles with Homebrew LLVM if already installed for WASM), Linux (apt/dnf).\n\nOut of scope. Generic NativeTool struct for future deps. Version floor for cmake. Windows MSVC Build Tools check (Microsoft's canonical Rust-on-Windows guide already covers this).\n\nRelated. bd-jakt investigates a different cargo xtask dev-setup issue (--locked causing externref mismatch) — same file, different concern.","acceptance_criteria":"check_cmake() runs in cargo xtask dev-setup and reports suitable version when cmake is on PATH. When cmake is absent, dev-setup prints a clear warning with platform-specific install commands but does not fail. cargo xtask verify succeeds on Windows without hitting the xtask.exe file lock. CONTRIBUTING.md lists cmake as a prereq with install commands for all three platforms. No regression in CI (xtask tests still run via step 5 nextest --workspace).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T16:03:48.543157300Z","created_by":"cderv","updated_at":"2026-04-27T14:30:22.022558600Z","closed_at":"2026-04-27T12:40:44.509969100Z","close_reason":"Merged via PR #136","source_repo":".","compaction_level":0,"original_size":0,"labels":["xtask"],"dependencies":[{"issue_id":"bd-tjbr","depends_on_id":"bd-jakt","type":"related","created_at":"2026-04-24T16:07:14.210865500Z","created_by":"cderv","metadata":"{}","thread_id":""}],"comments":[{"id":9,"issue_id":"bd-tjbr","author":"cderv","text":"All three fixes implemented and committed at 32667694 on feature/dev-setup-improvements. check_cmake() added to dev_setup.rs (platform-specific install hints via cfg; no version floor). --exclude xtask applied only on Windows (cfg-gated) in verify.rs step 3. CONTRIBUTING.md updated with cmake section. Local verification: dev-setup reports cmake 4.3.2 detected; verify steps 1-3 pass on Windows without the xtask.exe file lock; xtask unit tests 9/9 pass. Full workspace nextest run not yet performed — pending Chris to run and confirm before PR.","created_at":"2026-04-24T16:39:08Z"},{"id":11,"issue_id":"bd-tjbr","author":"cderv","text":"PR opened: https://github.com/quarto-dev/q2/pull/136 (commits 32667694, d34da980). Leaving issue open until merge.","created_at":"2026-04-24T19:10:48Z"},{"id":13,"issue_id":"bd-tjbr","author":"cderv","text":"Design rationale not captured above. The `wasm` feature on tree-sitter exists for runtime loading of user-defined tree-sitter grammars compiled to WASM, on the native side, via wasmtime-c-api. The 12 statically-linked grammars in quarto-highlight (python, R, JS, etc.) do not need it. Browser side uses a different mechanism (web-tree-sitter via wasm-bindgen, Phase 4). Source: crates/quarto-highlight/Cargo.toml:39-45. Already scoped to non-wasm32 targets, so the WASM build itself does not pay the cmake cost.\n\nCan we avoid cmake entirely while keeping native runtime user-grammar loading via WASM? Not today. Tree-sitter 0.25 exposes one WASM-runtime feature: `wasm` -> `wasmtime-c-api` -> `wasmtime-c-api-impl` (the cmake-shelling-out crate). No alternative for wasmer, wasmi, or pure-Rust wasmtime. The choice is hard-wired into tree-sitter's C layer (lib/src/wasm_store.c), not just the Rust bindings, so a Cargo-feature-only fix is impossible. Upstream issue tree-sitter/tree-sitter#4715 (\"Consider supporting wasm-c-api\") was closed without action; no upstream issue or PR for pure-Rust wasmtime. No third-party fork solves this for the WASM-loading path.\n\nOptions.\n\n(1) Contribute upstream pluggable WASM-runtime support or a pure-Rust wasmtime switch. Long path, depends on maintainers.\n\n(2) Feature-gate the `wasm` activation in quarto-highlight (e.g. default-on `user-grammars` feature) so devs without cmake can opt out via `--no-default-features` and lose only runtime custom-grammar loading. Does not avoid cmake for the default build.\n\n(3) Switch native runtime grammar loading from WASM to native shared libraries (.so / .dylib / .dll) using upstream's own `tree-sitter-loader` crate (crates/loader/ in tree-sitter/tree-sitter, published on crates.io). It uses `libloading` for dlopen / LoadLibrary and the `cc` crate to compile grammars to dylibs — only a C compiler, no cmake. This is the same path the `tree-sitter` CLI uses for `tree-sitter parse`. Trade-off: users distribute native dylibs per-platform instead of one portable .wasm.\n\nPR 136 documented and detected cmake without exploring (1)-(3). The trade-off belongs with the lead dev who introduced quarto-highlight in bd-n7x2.","created_at":"2026-04-27T14:30:22Z"}]} +{"id":"bd-tkamn","title":"D6 react: preview shell appends quarto-light to body class","description":"## What\n\nD6 in the Rust template (closed as bd-mtzry, commit 21c8ec04) appends `quarto-light` to the body class for parity with Quarto 1. The preview iframe doesn't go through that template — its body class is set imperatively in `ts-packages/preview-renderer/src/q2-preview/PreviewDocument.tsx`. Before this fix, the preview body was `fullcontent` only; render output was `fullcontent quarto-light`.\n\n## Fix\n\nMirror Rust `append_color_mode_class` in PreviewDocument.tsx as a small TS helper. Same shape (idempotent, handles empty string, suppresses append when `quarto-light` or `quarto-dark` already present).\n\n## Tests\n\nUpdated 4 existing PreviewDocument body-class tests + added 2 new tests (idempotent quarto-light, quarto-dark suppresses light).\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T22:46:44.717252Z","created_by":"cscheid","updated_at":"2026-05-20T22:47:30.899117Z","closed_at":"2026-05-20T22:47:30.898943Z","close_reason":"Implemented in this commit: appendColorModeClass mirrors Rust helper.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tkamn","depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T22:46:44.717252Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tky36","title":"StageContext eagerly creates+leaks a temp dir per document (lazy-init fix)","description":"StageContext::new (crates/quarto-core/src/stage/context.rs:215) eagerly calls runtime.temp_dir(\"quarto-pipeline\").into_path() for every document. The dir is created (per-page mkdir, ~2.9% of serial render CPU in the qmd-plans profile) AND leaked (into_path sets cleanup=false). The only production reader is engine_execution.rs:265, gated behind the to_run.is_empty() fast path (line 219) — so pure-markdown docs create+leak it but never read it.\n\nFix: make temp_dir lazily created on first access via std::sync::OnceLock<PathBuf> + a temp_dir(&self) -> Result<&Path> accessor. Preserves Send+Sync (no new dep). Discovered during bd-3gj56 post-fix profiling; see claude-notes/plans/2026-06-01-render-perf-profiling.md (filesystem bucket).","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-06-01T20:29:02.890587Z","created_by":"cscheid","updated_at":"2026-06-01T20:41:36.111739Z","closed_at":"2026-06-01T20:41:36.111601Z","close_reason":"StageContext temp dir now lazy (OnceLock + accessor). mkdir 3.01%->0%, serial 3650->3560ms, 0 leaked dirs (was +565). TDD + deliberate-break; full xtask verify green.","source_repo":".","compaction_level":0,"original_size":0,"labels":["perf"],"dependencies":[{"issue_id":"bd-tky36","depends_on_id":"bd-3gj56","type":"discovered-from","created_at":"2026-06-01T20:29:02.890587Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tmka","title":"L8 follow-up: WASM/VFS-aware custom listing template loading","description":"L8 D1 deferred this.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-08T14:56:54.353393Z","created_by":"cscheid","updated_at":"2026-05-08T14:56:54.353393Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tmka","depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:56:54.353393Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tnm3k","title":"q2 preview --single-file fails when no _quarto.yml ancestor exists","description":"When invoked on a single .qmd file with no _quarto.yml ancestor, q2 preview's single-file fallback sets project_root to the file path itself (a file, not a directory). The chain then fails:\n\n1. crates/quarto/src/commands/preview.rs:270-276 — 'No _quarto.yml ancestor → single-file mode (Phase A semantics). project_root is the file path itself.'\n2. crates/quarto-hub/src/discovery.rs::ProjectFiles::discover() walks via WalkDir, which on a single-file root yields exactly one entry: the file itself.\n3. path.strip_prefix(project_root) for the same file path returns an empty PathBuf, which is pushed into qmd_files.\n4. crates/quarto-hub/src/context.rs:431 reconcile_files_with_index does project_root.join(file_path). With file_path empty, the result is project_root + '/' (a trailing-slash variant of the file path).\n5. std::fs::read_to_string fails with ENOTDIR (os error 20) because the OS treats the trailing slash as 'I want a directory here'.\n\nSymptom: the warning 'quarto_hub::context: Failed to read text file, skipping path= error=Not a directory (os error 20)' with an empty path= field fires on every iteration. The preview SPA stays stuck at 'Initializing q2-preview…' indefinitely (no document content ever reaches it).\n\nReproduction:\n\n cp /any/file.qmd /tmp/\n q2 preview --no-browser --port 0 /tmp/file.qmd\n\n(must use a directory with no _quarto.yml anywhere above it).\n\nWorkaround: place a minimal _quarto.yml ('project: type: default') alongside the file, then q2 preview works correctly.\n\nLikely fix candidates:\n- preview.rs:270-276 should set project_root to canonical.parent() (the directory containing the file), and initial_page to the file name. This matches what happens when a _quarto.yml ancestor IS found, modulo where the project root sits.\n- Alternatively: detect single-file mode earlier and special-case ProjectFiles to contain exactly that one file with a non-empty relative path.\n\nThe cleaner fix is probably the former — there's no real benefit to having project_root be a file rather than its containing directory.\n\nDiscovered during bd-s3z1g (React CodeBlock parity verification): noticed the empty path= warning while trying to e2e-test the React change. Pre-existing, not caused by anything in bd-s3z1g.\n\nRelated: bd-1tl09 (code-block decorations epic) — many of those features will require working single-file preview.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-05-19T19:49:10.011815Z","created_by":"cscheid","updated_at":"2026-05-19T20:50:41.316998Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tnm3k","depends_on_id":"bd-s3z1g","type":"discovered-from","created_at":"2026-05-19T19:49:35.470732Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-tpve","title":"qmd parser/writer: round-trip `Str \"@{some-key}\"` (inline brace forms unsupported)","description":"Discovered while implementing bd-21gu. The qmd parser rejects bare `{...}` and `\\\\@{...}` in inline contexts:\n\n printf 'foo {some-key} bar\\n' | cargo run --bin pampa -- -t native\n → Parse error (column 6, '{')\n printf '\\\\@{some-key}\\n' | cargo run --bin pampa -- -t native\n → Parse error\n\nThis means a `Str` whose body contains `@{some-key}` (e.g. coming in via JSON) cannot be round-tripped, even though the writer-side `@` escape (bd-21gu) lookahead does include `{` so it would emit `\\\\@{some-key}` — the resulting qmd then fails to re-parse.\n\nTwo possible fixes (require investigation):\n 1. Parser: accept bare `{...}` as a literal (inline-brace context disambiguation).\n 2. Writer: escape `{` and `}` defensively for `Str` inlines (parallel to the @ fix).\n\nDefer until needed by a real-world case.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-01T00:19:41.166839Z","created_by":"cscheid","updated_at":"2026-05-01T00:19:41.166839Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tpve","depends_on_id":"bd-21gu","type":"discovered-from","created_at":"2026-05-01T00:19:41.166839Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tr81","title":"Documentation epic: bootstrap Quarto 2 docs using Quarto 2 itself","description":"Quarto 2 is now big enough to need standalone documentation. To avoid bootstrapping gaps, we want Quarto 2 to be documented using Quarto 2. This epic tracks the documentation work that the website-projects epic (bd-0tr6) enables.\n\nScope:\n- Build the Quarto 2 docs site with Quarto 2's own website project support.\n- Document the currently-existing Quarto 2 feature surface (pipeline, transforms, filters, navigation, config schemas, hub-client basics, etc.).\n- Document the new website-projects feature set introduced by bd-0tr6 (project.type, website.* schema, DocumentProfile contract, sidebars, shared resources, etc.).\n- Migration notes: differences from Quarto 1, what is deferred, what is gone.\n\nDepends on bd-0tr6 (website epic) reaching a minimum functional state (at least phases 0-2 + 5-7 user-visible output). Sub-plans to follow in a separate design session.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-23T18:43:32.089404Z","created_by":"cscheid","updated_at":"2026-04-23T18:55:41.200673Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-ts8j","title":"Phase 9 follow-up: browser smoke recipe + GIF capture","description":"Phase 9 sub-phase 9.5 deferred the browser smoke recipe + GIF capture to a follow-up session. The native integration test (crates/quarto-core/tests/render_page_in_project.rs) exercises the same Rust code path, but a real browser session against the hub-smoke fixture (crates/quarto-core/tests/fixtures/websites/hub-smoke/) is the canonical CLAUDE.md §End-to-end-verification check.\n\nThe manual recipe is documented in claude-notes/plans/2026-04-27-websites-phase-9.md §Sub-phase 9.5. Run it via claude-in-chrome to capture a GIF, save under claude-notes/research/, and link from the close-out commit.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:47.365912Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ts8j","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-ts8j","depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tv2s","title":"Cargo: upgrade automerge v0.8.0 → v0.9.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.8.0 is range-pinned in workspace; latest is 0.9.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.659246Z","created_by":"cscheid","updated_at":"2026-05-04T19:06:15.794106Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-tv2s","depends_on_id":"bd-0a3b","type":"blocks","created_at":"2026-05-04T19:06:15.793870Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-tv2s","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.613332Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-tyvt","title":"Open Graph / Twitter card / social meta tags","description":"Q1 has metadataHtmlPostProcessor for og:* and twitter:* meta tags. Out of Phase 7 MVP. Q1 reference: external-sources/quarto-cli/src/project/types/website/website-meta.ts. Filed as a separate transform alongside Phase 7's metadata transforms. Originating phase: bd-b9mz.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.023239Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-tyvt","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-tyvt","depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-u3ze","title":"Phase C.2 follow-up: in-process Rust integration test for watcher → staleness path","description":"Drafted in tests/staleness.rs during C.2 (bd-kw93.4) but dropped from the merge because the test is flaky under `cargo nextest run` on macOS. Symptoms:\n\n- Passes standalone (`cargo nextest run --test staleness`) in <1 second.\n- Passes under `cargo test -p quarto-preview --tests` (single-process multi-test).\n- Passes under `cargo nextest run --no-capture` (all 17 tests).\n- Fails (30 s timeout) under `cargo nextest run` (default capture, all tests) — staleness flag never flips even though the file watcher demonstrably works (binary smoke confirms).\n\nSuspected interaction between notify-rs's FSEvents backend and nextest's stdout capture across multiple test processes. The watcher arms, the file edit happens, but the change event never reaches `run_file_watcher` in this configuration.\n\nWhat's covered without this test:\n- 5 unit tests for `recompute_staleness` in capture_driver::tests.\n- 4 unit tests for `compute_input_qmd` in preview_record::tests.\n- Binary smoke confirming the watcher → sync_file → on_file_changed path on macOS.\n\nWhat this test would add: end-to-end coverage of the full file-watcher + on_file_changed + recompute_staleness + sidecar-update loop in a single Rust integration test.\n\nPath forward: file again once the Playwright e2e harness lands (Phase D / E) — Playwright drives the binary directly and doesn't have the nextest capture-pipe in the loop. Alternatively, dig into notify-rs's macOS quirks and find a workaround.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2 (acceptance gap).","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-14T16:25:55.539226Z","created_by":"cscheid","updated_at":"2026-05-14T20:18:16.791913Z","closed_at":"2026-05-14T20:18:16.791776Z","close_reason":"In-process staleness integration test landed in crates/quarto-preview/tests/staleness.rs. Original flake reproduced + traced: parallel nextest processes each arming an FSEvents watcher under default I/O capture causes silent event loss on macOS. Worked around with .config/nextest.toml — puts the three watcher-using integration test binaries (staleness, eager_capture, boot) in a max-threads=1 test group. 5/5 stable reruns; workspace nextest 8952/8952. Merged to feature/q2-preview-command as commit cc180477.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-u3ze","depends_on_id":"bd-kw93.4","type":"discovered-from","created_at":"2026-05-14T16:25:55.539226Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-u4ow","title":"L8 follow-up: docs/ page for custom listing templates","description":"L8 D11 deferred. When the user-facing Quarto-website tree under docs/ becomes a real public site, add a custom-listing-templates reference covering: the binding surface (listing.*, items[*].*, project.*, item.extra.*), the partial-resolver chain (FileSystemResolver primary, MemoryResolver fallback), the diagnostic meanings (Q-12-7/8/9/10/14), and the v1 limitations: no WASM custom-template loading; no extension-catalog lookup; no template cache. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §Decisions log D11.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-08T14:57:53.676341Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:53.676341Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-u4ow","depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:57:53.676341Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-u50w","title":"qmd writer drops empty bullet-list items / mutates empty list-table cells (issue #195)","description":"Two round-trip bugs in crates/pampa/src/writers/qmd.rs, both reported in https://github.com/quarto-dev/q2/issues/195 by @rundel.\n\n(1) write_bulletlist (L461) drops truly-empty items (Vec<Block> of length 0): the is_empty_item check at L480 requires item.len() == 1, so length-0 items fall through to the else branch and write nothing. No bare marker is ever emitted. Round-trip: `[..., []]` becomes `[...]`.\n\n(2) write_list_table (L986) writes literal '- []' for cells whose content is empty (L1129-1133). The reader parses that '[]' as inline text inside a Plain block, mutating the AST from cell content `[]` to `[Plain []]`.\n\nFix shape (per reporter): emit a bare marker line (e.g. '*\\n' or '-\\n') for truly-empty items / cells. The reader already accepts bare markers — input '- - X\\n -\\n' parses the trailing item as the empty Vec.\n\nIn scope:\n- write_bulletlist empty-item branch\n- write_list_table empty-cell branch\n- write_orderedlist (no is_empty_item check at all — same root cause; bundle the fix)\n- Round-trip fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ for both AST shapes\n\nTriage record: claude-notes/issue-reports/195/triage.md on branch issue-195. Existing fixture empty_list_item.qmd (covers [Plain []], not []) should keep round-tripping unchanged.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-14T21:52:44.921887Z","created_by":"cscheid","updated_at":"2026-05-14T22:11:08.972713Z","closed_at":"2026-05-14T22:11:08.972564Z","close_reason":"Fixed in commit bea39f57 on branch issue-195. write_bulletlist + write_orderedlist now emit bare marker for length-0 items; write_list_table drops literal '[]' for empty cells without attrs. Six new round-trip fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/. cargo xtask verify --skip-hub-build --skip-hub-tests passes; end-to-end against reporter's exact repros confirms AST round-trips and writer is idempotent. PR pending.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-u5pr","title":"Phase 5 — Scoped artifact store + site_libs/","description":"Add ArtifactScope { Page, Project } to artifacts. Theme CSS keyed by content fingerprint. Project-scoped artifacts drained per-doc, merged sequentially into ProjectContext.project_artifacts, flushed once in WebsiteProjectType::post_render to _site/site_libs/. Single-doc behavior byte-identical (regression-tested). See claude-notes/plans/2026-04-24-websites-phase-5.md.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-25T00:21:23.689378Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:43.689396Z","closed_at":"2026-04-25T01:31:43.689146Z","close_reason":"Implemented on feature/websites: ArtifactScope { Page, Project }, ResourceResolverContext (single_doc / website / vfs_root flavors), fingerprinted theme CSS (sha256 16-hex truncation), Project-scoped artifacts drained per-doc and merged sequentially into ProjectPipeline.project_artifacts, WebsiteProjectType::post_render flushes _site/site_libs/, single-doc behavior byte-identical (regression-tested against pre-Phase-5 baseline). 7827 workspace tests pass; cargo xtask verify (full, incl. WASM) green. Follow-ups: bd-b9za, bd-78ud, bd-apvo, bd-vdl8.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-u5pr","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-25T00:21:23.689378Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-u67gw","title":"Add quarto-scss-analysis-annotation markers to brand SCSS output","description":"Q1 emits // quarto-scss-analysis-annotation { ... } push/pop comments around each brand-derived SCSS block (color/typography/bootstrap-defaults). Q2's brand_layer.rs omits them — we have no analyzer that consumes them. Add when an analyzer materializes. Plan ref: claude-notes/plans/2026-05-20-brand-yml-support.md.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-21T02:31:31.204709Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.204709Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-u6ef","title":"hub-client e2e fails: @quarto/quarto-sync-client/dist/index.js not resolvable","description":"Running cargo xtask verify --e2e (or npm run test:all from hub-client) breaks Playwright with: 'Cannot find module .../node_modules/@quarto/quarto-sync-client/dist/index.js imported from hub-client/e2e/helpers/projectFactory.ts'.\n\nquarto-sync-client's package.json declares main: dist/index.js, but dist/ is not built as part of npm install — only the source/import/types entries (pointing at src/) get used by Vitest. Playwright runs the helper in a plain Node process that uses the default resolver, which falls back to main.\n\nReproduces on:\n- this branch (feature/q2-preview-command @ 63e27e8c)\n- main @ d0d5d39e (i.e. pre-existing, not introduced by the q2-preview work)\n\nLikely fix shapes:\n1. Add a workspace-wide pre-step that builds quarto-sync-client's dist/ (mirror of how WASM is built via 'npm run build:wasm').\n2. Switch hub-client's e2e helpers to import via a path that hits the source condition (loader / tsx / different resolver).\n3. Set 'imports' / 'exports' on quarto-sync-client so the default Node resolver finds .ts via source.\n\nDiscovered while wiring q2-preview-spa's own Playwright suite into 'cargo xtask verify --e2e' (bd-vpsy / Phase A.7); the q2-preview-spa suite is unaffected because it doesn't import quarto-sync-client at all.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-13T19:32:52.820888Z","created_by":"cscheid","updated_at":"2026-05-13T19:32:52.820888Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","e2e","hub-client"],"dependencies":[{"issue_id":"bd-u6ef","depends_on_id":"bd-vpsy","type":"discovered-from","created_at":"2026-05-13T19:32:52.820888Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-ubjo","title":"L8 follow-up: broader path resolution for YAML-declared paths","description":"L8 D2 deferred. The planned !path YAML tag + Q2 metadata-merging design should unify path resolution across _quarto.yml, per-page frontmatter, and listing templates. Listing template paths would resolve relative to the YAML they were defined in. L8 ships host-page-only resolution; this issue records the linkage so when the broader design lands, listing template paths fold in cleanly. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §Decisions log D2.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T14:57:39.790641Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:39.790641Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-ubjo","depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:57:39.790641Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-udlt","title":"L9 follow-up: title placeholder substitution from rendered HTML","description":"Q1 substitutes the rendered post title (post-engine) into RSS items, because engine output may contain math etc. that the metadata title doesn't. v1 uses item.title from the profile directly. Subscribers see the metadata title; if a feed item has math in its title, it'll show up as source markup, not the rendered form. File if a user reports this.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-08T17:33:32.947255Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:32.947255Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-udlt","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:32.947255Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-uhmzq","title":"Author error-docs pages for cli subsystem (8 codes)","description":"Author stub-quality pages for all 8 cli subsystem error codes under docs/errors/cli/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:56.482252Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.438176Z","closed_at":"2026-05-24T21:15:22.437806Z","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-ulgr","title":"Design JS dependency handling for Quarto 2 HTML output (Bootstrap JS and beyond)","description":"Quarto 2 HTML output currently emits correct DOM for Bootstrap-based features (navbars with dropdowns, collapsible navigation, future tabset panels, callout collapse, crossref popovers, dark-mode toggle, search) but ships no JavaScript dependencies, so interactive features do not function. Decide and implement a strategy for declaring, collecting, and emitting JS dependencies through the render pipeline.\n\nScope includes: vendor vs CDN choice; who declares dependencies (theme? feature transform? template?); how deps are collected into the final HTML; interaction with the resource-collector stage; how WASM / hub-client renders get these deps; version pinning aligned with the bundled Bootstrap SCSS in quarto-sass.\n\nOutline document: claude-notes/plans/2026-04-18-html-js-deps-design.md\n\nBlocks full UX of bd-imiw (navbar dropdowns, collapse) once implemented.","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-18T19:33:38.359516Z","created_by":"cscheid","updated_at":"2026-04-18T19:33:38.359516Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-uy3z","title":"pampa: wire Meta and Pandoc filter callbacks in typewise dispatch","description":"Discovered while testing bd-o8pr Phase 3 (Lua filter resource channel).\n\npampa::lua::filter::filter_names lists 'Pandoc', 'Doc', 'Meta', 'Block', 'Blocks', 'Inline', 'Inlines' as recognized filter handler names — they get copied from globals into the filter table. But the typewise traversal in apply_typewise_filter does not actually invoke them.\n\nThis means a Lua filter that does:\n function Meta(meta) ... end\nor:\n function Pandoc(doc) ... end\n\nis silently ignored. Para/Str/Header/etc. all work.\n\nThis blocks:\n- Lua-filter tests for the bd-o8pr 'additivity defense' (filter mutates meta.resources): the unit test in resource_report.rs covers the logic, but an E2E test through q2 render needs Meta callback support.\n- General pandoc filter compatibility: many real filters do all their work in Pandoc(doc) or Meta(meta).\n\nReferences:\n- crates/pampa/src/lua/filter.rs:308 (filter_names list)\n- crates/pampa/src/lua/filter.rs:1730 (apply_typewise_filter)\n- crates/quarto-core/tests/project_resources.rs (filter_removing_meta_resources_does_not_drop_author_declaration test note)","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-03T19:54:04.819189Z","created_by":"cscheid","updated_at":"2026-05-03T19:54:04.819189Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-uy3z","depends_on_id":"bd-o8pr","type":"discovered-from","created_at":"2026-05-03T19:54:04.819189Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-v0zm","title":"Cargo: upgrade reqwest v0.12.28 → v0.13.3","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.12.28 is range-pinned in workspace; latest is 0.13.3. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.971306Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.491686Z","closed_at":"2026-05-04T20:30:45.491526Z","close_reason":"merged: d5d9b5d1","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-v0zm","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.108448Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-v1qc","title":"qmd writer drops trailing newline inside code blocks (issue #173)","description":"The qmd writer in crates/pampa/src/writers/qmd.rs:628-634 emits the closing fence directly after the content text when the text already ends with '\\n', collapsing one content-line boundary. As a result, a CodeBlock whose AST text ends in '\\n' round-trips with the trailing newline removed.\n\nTriage doc: claude-notes/issue-reports/173/triage.md (on branch issue-173).\nRepro: claude-notes/issue-reports/173/repro.sh.\n\nThe pampa reader matches Pandoc exactly on this — verified across seven cases including CommonMark spec example 100. So the AST contract is correct; only the writer is wrong. Fix scope is in the triage doc.\n\nReporter: @rundel. GH issue: https://github.com/quarto-dev/q2/issues/173.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-11T20:52:28.394443Z","created_by":"cscheid","updated_at":"2026-05-11T20:52:28.394443Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-v30t","title":"Phase 6 — Cross-document link rewriting","description":"Rewrite body-content [link](other.qmd) references in the AST to relative output URLs. Sub-plan: claude-notes/plans/2026-04-24-websites-phase-6.md. Adds LinkRewriteTransform, resolve_doc_relative_href helper, page_url_for resolver method, and RenderContext.resource_resolver field.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-27T12:53:10.861557Z","created_by":"cscheid","updated_at":"2026-04-27T13:42:23.653492Z","closed_at":"2026-04-27T13:42:23.653203Z","close_reason":"Phase 6 complete on feature/websites: LinkRewriteTransform + resolve_doc_relative_href helper + page_url_for on ResourceResolverContext + resource_resolver field on RenderContext/StageContext. 49 new tests, full xtask verify green. Sub-plan: claude-notes/plans/2026-04-24-websites-phase-6.md. Follow-ups: bd-p4sc, bd-fo1r, bd-nb32, bd-j3a0, bd-gdrv, bd-td2a.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-v30t","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T12:53:10.861557Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-v5z8w","title":"Wire light/dark brand variants (brand: {light, dark}) once Q2 has light/dark SCSS seam","description":"Parsing accepts the {light, dark} shape today but uses only the light half; emits no warning. Once Q2 grows a light/dark seam in the SCSS pipeline (currently no such seam exists — bundle.rs::assemble_themes only produces a single light variant), wire the dark half through. Reference: claude-notes/plans/2026-05-20-brand-yml-support.md Phase 8. Q1 source: external-sources/quarto-cli/src/core/sass/brand.ts brandSassLayers light/dark branches.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:01.035107Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:01.035107Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-v8gx","title":"Rename flush_site_libs to flush_project_artifacts","description":"`flush_site_libs` in `crates/quarto-core/src/project/website_post_render.rs` is now called from both `WebsiteProjectType.post_render` (where the name is accurate) and `RenderToHtmlRenderer.render` (where 'site_libs' is misleading — default projects have no site_libs dir). The function body has always been general (it just iterates project_artifacts and calls `resolver.on_disk_path_for(Project, ...)`). Rename + update one error message for clarity. Pure naming hygiene.","status":"open","priority":4,"issue_type":"chore","created_at":"2026-05-01T22:49:10.919652Z","created_by":"cscheid","updated_at":"2026-05-01T22:49:10.919652Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-v8gx","depends_on_id":"bd-87fu","type":"discovered-from","created_at":"2026-05-01T22:49:10.919652Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-varx","title":"L9 follow-up: hoist append_to_rendered_header + escape_html_attr to a shared util","description":"L9's link_inject.rs duplicates two small helpers from website_favicon.rs (append_to_rendered_header to write into rendered.includes.header, and escape_html_attr for double-quoted attribute values). Both are now used by ≥2 transforms (favicon + listing-feed-link). Hoist to a shared module under crates/quarto-core/src/transforms/ or website_config.rs and have both call sites use the shared form.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:34:04.030827Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:04.030827Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-varx","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:04.030827Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-vdl8","title":"Retire DEFAULT_CSS_ARTIFACT_PATH constant once hub-client moves off synthetic VFS paths","description":"Phase 5 introduced ResourceResolverContext::vfs_root('/.quarto/project-artifacts') as the resolver flavor for the WASM hub-client, mapping artifact paths to absolute VFS URLs. The legacy DEFAULT_CSS_ARTIFACT_PATH constant is still re-exported from quarto-core::lib so it can serve as the canonical synthetic root. When Phase 9 (hub-client project rendering) migrates the hub-client off the synthetic VFS path convention (e.g. to per-page output paths), this constant can be removed. Tracked from Phase 5 task #13.","status":"open","priority":4,"issue_type":"chore","created_at":"2026-04-25T01:31:35.851331Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:35.851331Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-vdl8","depends_on_id":"bd-u5pr","type":"discovered-from","created_at":"2026-04-25T01:31:35.851331Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-ve2j","title":"Project selector: show connecting state inline instead of blank page","description":"When connecting to the project set sync server, show the ProjectSelector UI with an inline connecting message in the projects list area, instead of a blank white page with centered text. Plan: claude-notes/plans/2026-04-07-project-selector-loading-ux.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-04-07T15:29:53.350342Z","created_by":"cscheid","updated_at":"2026-04-07T15:33:38.542454Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-vet6","title":"tree-sitter qmd: multi-line block quote inside list item fails to parse","description":"Minimal repro:\n```\n- > a\n > b\n```\n\nPandoc parses this as BulletList[[BlockQuote[Para[Str \"a\", SoftBreak, Str \"b\"]]]]. Our parser fails with a parse error at line 2 col 6.\n\nRoot cause: in crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c, the LIST_ITEM match() function has a newline branch (line 537-540) that returns 2, causing match_line case 2 (line 1991-1996) to advance past the trailing \\n of a content line. When STATE_MATCHING is left set after a SOFT_LINE_ENDING and the next scan() runs at end-of-line-2, this consumes the \\n that the line-ending gate (line 2233) needs, breaking the parse.\n\nBLOCK_QUOTE match() has no newline branch and does not advance, which is why bq-in-bq (`> > a\\n> > b\\n`) works but bq-in-list-item does not.\n\nAffects all list markers: -, *, +, 1., 1), (1), (#).\n\nPlan: claude-notes/plans/2026-05-11-bq-multiline-in-list-item.md\n\nApproach (option 2 from the analysis): guard STATE_MATCHING re-entry so that when STATE_WAS_SOFT_LINE_BREAK is set and lookahead is \\n/\\r/EOF, we skip the match_line pass and let the line-ending gate handle it.\n\nTDD: failing corpus tests first.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-11T15:49:45.706143Z","created_by":"cscheid","updated_at":"2026-05-11T15:49:45.706143Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","parser","tree-sitter"]} +{"id":"bd-vpsy","title":"Phase A.7: Playwright smoke test for q2 preview","description":"q2-preview-spa/e2e/basic-preview.spec.ts spawns quarto preview against a fixture and drives a chromium session. Asserts initial render contains expected content, editing the .qmd on disk produces a visible change within 2s, force-refresh button works, and the DOM-stability invariant holds (a data-stable-id element keeps the same DOM node identity across an edit, by === reference equality). See claude-notes/plans/2026-05-13-q2-preview-phase-a.md section A.7.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T16:54:16.784229Z","created_by":"cscheid","updated_at":"2026-05-13T19:29:52.233453Z","closed_at":"2026-05-13T19:29:52.233317Z","close_reason":"Phase A.7 complete: Playwright suite at q2-preview-spa/e2e/basic-preview.spec.ts (4 cases) pinning initial render, on-disk-edit re-render, force-refresh button, and DOM-node-identity stability. Wired into cargo xtask verify --e2e.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-vpsy","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:54:16.784229Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-vtm7","title":"Investigate Windows WASM build support","description":"Check if scoop LLVM (22.1.1) supports wasm32 target on Windows. If so, build-wasm.js needs a Windows code path in findLlvmClang() and WASM tests could run locally on Windows too. Currently both WASM build and tests are Linux/macOS only.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-03T19:20:28.383217400Z","created_by":"cderv","updated_at":"2026-04-03T19:20:28.383217400Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-vtm7","depends_on_id":"bd-itj9","type":"related","created_at":"2026-04-03T19:20:28.383217400Z","created_by":"cderv","metadata":"{}","thread_id":""}]} {"id":"bd-vxl8","title":"Fix Windows Lua path escaping in pampa io_wasm tests","description":"On Windows, 9 tests in crates/pampa/src/lua/io_wasm.rs (test_io_open_append, test_io_open_read_all, test_io_open_read_bytes, test_io_open_read_line, test_io_open_read_number, test_io_open_write_and_close, test_io_open_write_flush_incremental, test_io_type, test_io_write_returns_handle_for_chaining) panic with SyntaxError: invalid escape sequence near '\"C:\\U'. Tests interpolate file_path.display() into a Lua source string via lua.load(format!(...)), and Windows backslashes are parsed as Lua escape sequences (\\U, \\t, etc.). Same root cause and same fix as PR #95 (bd-3pe8) which used quarto_util::to_forward_slashes for filter_tests.rs / mediabag.rs / system.rs. io_wasm.rs was either added after that PR or missed. Surfaced 2026-04-28 while running cargo nextest -p pampa on Windows. Documented pattern: memory note Windows Path Escaping in Lua String Contexts. The same pattern must also be applied to crates/pampa/src/lua/io_wasm.rs test code (replace file_path.display() with to_forward_slashes(&file_path) in every lua.load(format!(...)) call).","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-28T12:57:58.712055900Z","created_by":"cderv","updated_at":"2026-04-28T13:07:56.609333600Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["lua","pampa","windows"],"dependencies":[{"issue_id":"bd-vxl8","depends_on_id":"bd-3pe8","type":"related","created_at":"2026-04-28T13:07:56.607383400Z","created_by":"cderv","metadata":"{}","thread_id":""}]} +{"id":"bd-w0o9","title":"[websites] draft-mode include/visible/exclude option","description":"Phase 2 always excludes drafts from auto sidebars and any containment check. Q1 supports 'draft-mode: visible|unlinked|none' — visible keeps them in the sidebar (for local preview), unlinked lists but without links, none omits entirely. Wire this through DocumentProfile.draft filtering in sidebar_auto.rs::expand_spec and similar call sites.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T17:52:35.142347Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:35.142347Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-w0o9","depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:35.142347Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-w5os","title":"[websites phase 1] ProjectType trait and two-pass orchestration","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 1.\n\nDeliverables:\n- ProjectType trait (pre_render / per-file contributions / post_render).\n- DefaultProjectType (single-doc + loose directory, no-op hooks).\n- ProjectPipeline driver: discover files, pass 1 (sweep to checkpoint), build ProjectIndex, pass 2 (resume per file).\n- Wire into quarto binary: quarto render in a directory with _quarto.yml runs ProjectPipeline.\n- Regression coverage: single-doc renders still pass existing tests (now via DefaultProjectType).\n\nBlocked by Phase 0 (needs snapshot + checkpoint).","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:42:42.317267Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:47.976528Z","closed_at":"2026-04-24T01:05:47.975735Z","close_reason":"Phase 1 shipped: ProjectType trait + two-pass ProjectPipeline driver, DefaultProjectType/WebsiteProjectType placeholders, ProjectIndex, multi-file discovery, StageContext.project_index slot. All single-file and multi-file renders now flow through the driver. 7674/7674 workspace tests pass; WASM build clean. End-to-end verified on both single-file and multi-file website fixtures. Follow-ups filed as bd-ee4z, bd-d3ol, bd-2mo9, bd-p3vi, bd-5mpv, bd-9za7.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-w5os","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:42.317267Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-w5os","depends_on_id":"bd-f3jc","type":"blocks","created_at":"2026-04-23T18:43:41.255438Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-w5ov","title":"Math-mode rendering for HTML output (MathJax + KaTeX)","description":"Implement math equation rendering for HTML output via MathJax (default) and KaTeX, matching Quarto 1's user-facing surface (html-math-method:) but routed through q2's own pipeline (q2 does not invoke Pandoc).\n\nPlan: claude-notes/plans/2026-05-04-math-mode.md\nPredecessor handoff: claude-notes/plans/2026-05-04-math-mode-handoff.md (notes from bd-4eyf session)\nPredecessor work: bd-4eyf (Bootstrap JS injection — established the predicate→js:* artifact pattern this builds on)\n\nScope (v1):\n- New MathJsStage in crates/quarto-core/src/stage/stages/math_js.rs.\n- Trigger: AST walk over Inline::Math + CustomNode(\"Equation\") slots.\n- Engines: mathjax (default) + katex; html-math-method: bare-string and {method, url} object forms; user URL override skips vendoring.\n- New $math$ template slot in MINIMAL/FULL HTML templates, positioned before $for(scripts)$ so inline config block renders before the loader (matches Pandoc's slot order).\n- Loader emitted via Project-scoped js:mathjax / js:katex artifact when vendored; via direct $math$-slot injection when user supplies url:.\n- Vendor under resources/js/mathjax/ and resources/js/katex/. Bundle size strategy still TBD — see plan Q2 (recommendation: tex-chtml core ~150KB, not full ~10-15MB).\n- Hub-client (WASM): include the stage (math is stateless, no iframe-reinit problem like Bootstrap had).\n- Filter-extensibility: stage operates on publicly-described AST (Inline::Math, CustomNode(\"Equation\")) so a Lua filter could in principle implement custom math handling — same property as our navbar rendering.\n\nOut of scope (defer to follow-up issues):\n- webtex/gladtex/mathml/plain math methods.\n- Temml as a third engine (file separate evaluation issue).\n- User-supplied MathJax config object merge (v1.1).\n- 'quarto check' warning when custom templates lack $math$ slot.\n\nTDD per CLAUDE.md: tests first (unit predicate matrix in math_js.rs + integration in tests/math_mode_pipeline.rs + WASM-pipeline inclusion test); confirm red phase against noop stub; then implement; then full cargo xtask verify + CLI exercise + chrome-devtools-mcp browser smoke before closing.\n\nAwaiting decisions Q1-Q7 in plan §8 before starting.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T22:41:41.975994Z","created_by":"cscheid","updated_at":"2026-05-05T00:05:10.346568Z","closed_at":"2026-05-05T00:05:10.346419Z","close_reason":"Math-mode v1 shipped: MathJax (default) + KaTeX with html-math-method: bare-string and {method, url} object forms. New MathJsStage (post-AstTransforms, pre-RenderHtmlBody) walks AST for Inline::Math + CustomNode('Equation') slots and populates meta.math with engine config + CDN loader. New $math$ template slot lands the markup before $for(scripts)$ for correct MathJax config-before-loader ordering. CDN-default (parity with Pandoc/Quarto 1, zero binary growth). Hub-client/WASM gets the stage too. Tests: 11 unit + 7 integration + 3 pipeline-structure assertions, full workspace 8403/8403, full cargo xtask verify all 9 steps green. Live Chromium smoke confirmed MathJax 3.2.2 typesetting + crossref \\\\tag{N} numbering + KaTeX rendering + custom URL override + math-free clean. Plan: claude-notes/plans/2026-05-04-math-mode.md. Follow-ups filed: bd-si8b (Temml), bd-7sib (other methods), bd-hva0 (local-vendor opt-in).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-w5ov","depends_on_id":"bd-4eyf","type":"discovered-from","created_at":"2026-05-04T22:41:41.975994Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-w5ov","depends_on_id":"bd-r7v2","type":"blocks","created_at":"2026-05-04T23:58:34.028538Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-w66j","title":"Add SymbolKind icon for crossref targets in OutlinePanel","description":"hub-client/src/components/OutlinePanel.tsx::getSymbolIcon currently maps SymbolKind.Class to '◇' / 'code' styling. After bd-ascs, crossref targets (fig-x, thm-y, eq-z) use SymbolKind.Class and render with the generic code-glyph. Consider a dedicated icon or tooltip that hints at the ref type so users can tell figures / theorems / equations apart at a glance in the sidebar.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:52.493231Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:52.493231Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-w66j","depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:52.493231Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-w7x3","title":"[websites phase 4] Page navigation (prev/next)","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 4.\n\nDeliverables:\n- PageNavGenerateTransform and PageNavRenderTransform, pattern identical to other nav transforms.\n- Compute prev/next from flattened sidebar entries.\n- Opt in/out via page-navigation: true|false at project or page level.\n- Template slot: $rendered.navigation.page_navigation$.\n- Integration tests.\n\nBlocked by Phase 2 (needs Sidebar).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-23T18:43:02.852700Z","created_by":"cscheid","updated_at":"2026-04-23T18:43:47.440710Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-w7x3","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:02.852700Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-w7x3","depends_on_id":"bd-mre3","type":"blocks","created_at":"2026-04-23T18:43:47.439797Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-wgup","title":"Eliminate serde_json::Value intermediate in pampa JSON writer","description":"Native profile of parse_qmd_to_ast (the hub-client's entry) on scaled lorem-ipsum fixtures shows ~50-55% of runtime in memory movement (_platform_memmove) + allocator work, and ~5-7% in indexmap::Core::insert_full. Root cause: pampa::writers::json builds a full serde_json::Value tree (each node a Value::Object backed by IndexMap<String, Value> with fresh String keys for 'c'/'s'/'t'/etc.) and then serializes it to bytes via serde_json::to_writer. Two full passes, enormous intermediate allocation. At 8x the canonical doc, _platform_memmove alone is 41% of wall time. Plan: claude-notes/plans/2026-04-22-serde-json-value-intermediate.md. Hypothesis is 'replace the Value tree with direct Serialize impls that stream JSON to the output Writer,' to be validated with the perf-harness driver introduced in the same plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-22T22:47:51.778056Z","created_by":"cscheid","updated_at":"2026-04-23T00:11:51.390207Z","closed_at":"2026-04-23T00:11:51.389491Z","close_reason":"Streaming JSON writer landed on perf/2026-04-22-json-sourcemap in commits 4e7a43ec (Phase 1 scaffold) and b3e15a47 (Phase 2 cutover). 1.65x-2.3x speedup across 1x-8x fixtures; IndexMap/allocator hotspots eliminated. Browser-verified by Carlos. Remaining memmove cost is the output buffer's amortized doubling — a separate optimization, documented as follow-up in the plan.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-wjg4h","title":"Browser-verify _brand.yml support in hub-client q2 preview","description":"Phase 7 of the brand plan covered native render verification but not browser. Run the WASM rebuild chain (npm run build:wasm; cargo xtask build-q2-preview-spa; cargo build --bin q2) then open a project with _brand.yml under q2 preview and confirm the iframe applies brand colors/typography. The WASM code path is identical to native; just needs ground-truthing.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-21T02:31:31.264736Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.264736Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-wjpd","title":"Cargo: upgrade tree-sitter-highlight v0.25.10 → v0.26.8","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.25.10 is range-pinned in workspace; latest is 0.26.8. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.372492Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.850328Z","closed_at":"2026-05-04T20:30:44.850181Z","close_reason":"merged: 61b01cd4","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-wjpd","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.776730Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-wlza2","title":"Treat leading-/ resource paths as project-root-relative","description":"YAML 'resources:' patterns starting with '/' are interpreted as filesystem-absolute and rejected by the project-containment check. They should be project-root-relative (TS Quarto convention). Blocks rendering quarto-web under q2.\n\nPlan: claude-notes/plans/2026-05-21-resource-path-leading-slash.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T21:12:32.927216Z","created_by":"cscheid","updated_at":"2026-05-21T21:39:51.267265Z","closed_at":"2026-05-21T21:39:51.267102Z","close_reason":"Leading-/ YAML resource patterns now strip-prefix to project_root in expand_one. 5 new tests added (3 of which failed pre-fix). e2e on quarto-web: original error gone, four leading-/ file resources resolve correctly. Follow-up bd-47w7o tracks directory-resource handling.","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-wo59","title":"Per-project capture cache for cross-session reuse","description":"Phase C.7 (bd-kw93.7) shipped the per-doc capture filesystem cache in <data_dir>/captures/ — the same tempdir that gets deleted when q2 preview exits. So closing and re-opening preview against the same project always misses the cache, even though the inputs are bit-for-bit identical.\n\nA per-project cache location (e.g. <project_root>/.q2/captures/, ignored by .gitignore convention) would unlock cross-session reuse. The cache key derivation (sha256 of canonical input_qmd) is already content-addressed and survives across sessions — only the directory choice changes.\n\nSee plan §C.7 'Open follow-up'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-14T17:35:46.618486Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:46.618486Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-wo59","depends_on_id":"bd-kw93.7","type":"discovered-from","created_at":"2026-05-14T17:35:46.618486Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-wv4e","title":"Tree-sitter scanner over-eagerly excludes *, -, +, #, digits from soft-break","description":"The same class of bug as bd-af1e affects 5 more characters. The scanner's line-break handler at scanner.c:2286-2291 and 2371-2376 excludes these from soft-line-break candidates whenever they appear at the start of a continuation line:\n- '*' (could be emphasis, list, thematic break)\n- '-' (could be list, thematic break, setext header)\n- '+' (could be list)\n- '#' (could be ATX header)\n- digits 0-9 (could be ordered list)\n\nBut each of these only opens a block in specific contexts (most need a trailing space, '#' needs space, '*'/'-'/'+' need space for list, '***'/'---' need 3+ for thematic break, digits need '.' or ')' followed by space). A bare 'X' followed by content is just inline text and should soft-break.\n\nVerified pampa vs pandoc divergence on:\n foo bar\n *emph* baz → pampa splits, pandoc soft-breaks\n -text more → pampa splits, pandoc soft-breaks\n +text more → pampa splits, pandoc soft-breaks\n #hashtag more → pampa splits, pandoc soft-breaks\n 123abc more → pampa splits, pandoc soft-breaks\n\nCorrect exclusions (pampa already matches pandoc for):\n * list item → BulletList opens (correct)\n - list item → BulletList opens (correct)\n # heading → Header opens (correct)\n 1. item → OrderedList opens (correct)\n\nFix approach: same as bd-af1e (peek-count). For each char, peek the trailing context to decide if it actually opens a block:\n- '*', '-': count run; if >=3 with all whitespace/eol after, thematic break (interrupt). If '* ' or '*\\t', list (interrupt). Otherwise inline.\n- '+': only list if followed by whitespace.\n- '#': only ATX if followed by whitespace or eol.\n- digits: only ordered list if followed by '.' or ')' AND space.\n\n':' (fenced div / definition list) was excluded from this issue because its semantics are more entangled with qmd-specific features and pandoc-mode-specific rules — file separately if regression observed.\n\nSibling of bd-af1e. See claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md for the bd-af1e implementation pattern.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T18:40:17.998897Z","created_by":"cscheid","updated_at":"2026-04-30T18:45:29.625753Z","closed_at":"2026-04-30T18:45:29.625599Z","close_reason":"Re-scoped: see bd-wv4e replacement for asterisks-only fix. The other characters (-, +, #, digits, :) have a backslash-escape workaround (\\-text, \\#hashtag, etc.) so are not severe enough to fix in this pass.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-wv4e","depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:40:25.341409Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-wzhsf","title":"CVE-prevention: cookie+Bearer dual-credential MUST return 400","description":"Highest-impact item flagged in plan §Phase 2. A request carrying BOTH a session cookie AND an Authorization: Bearer header MUST be rejected with HTTP 400 and body {\"error\":\"conflicting_credentials\"} BEFORE any auth-decision logic runs.\n\nTest name: cookie_and_bearer_returns_400 in crates/quarto-hub/tests/auth_bearer.rs.\n\nThe dual-credential 400 rule must win over CSRF, WS-Origin, and per-credential auth checks (covered by sibling test dual_credential_400_wins_over_csrf_and_origin).\n\nPlan §Phase 2 — Cross-cutting security requirements: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-05-20T14:27:46.526825Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:18.258188Z","closed_at":"2026-05-20T21:22:18.258155Z","close_reason":"Dual-credential 400 enforced. cookie_and_bearer_returns_400 (REST), ws_upgrade_rejects_dual_credentials (WS), and dual_credential_400_wins_over_csrf_and_origin all pass. Body shape locked as {\"error\":\"conflicting_credentials\"} in extract_credential and the WS handler; auth_refresh re-runs the same check before CSRF. See plan §Phase 2 — completion notes (2026-05-20).","source_repo":"kyoto","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-wzhsf","depends_on_id":"bd-0ufq5","type":"parent-child","created_at":"2026-05-20T14:27:46.526825Z","created_by":"shikokuchuo","metadata":"{}","thread_id":""}]} +{"id":"bd-x5r4","title":"Optional-variable syntax: $variable?$ shorthand for $if(variable)$$variable$$endif$","description":"When users see Q-10-2 warnings on a variable they intend to be optional, today they have to wrap each reference in $if(variable)$$variable$$endif$. A short $variable?$ form would be cleaner and let authors silence the warning at the use site.\n\nFeasibility (recorded in bd-xdnk plan §Follow-up):\n- `?` is unused as a sigil in the current grammar.\n- Doesn't collide with any pipe name (`pairs|first|last|rest|allbutlast|uppercase|lowercase|length|reverse|chomp|nowrap|alpha|roman|left|center|right`).\n- Pipes already use `/` as separator (`tree-sitter-doctemplate/grammar/grammar.js:84-86`), so `?` doesn't conflict.\n- Implementation cost: one grammar token, one `bool optional` field on `VariableRef`, one branch in `render_variable` that returns `Doc::Empty` silently when `optional` is set and the lookup fails.\n\nOpen question: should `?` propagate to applied partials (`$var?:partial()$`)? Probably yes — same intent. Not applicable to `$if$` itself.\n\nDiscovered while wiring template diagnostics through quarto render (bd-xdnk). Now that template warnings are user-visible, having a clean opt-out becomes more valuable.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-05T16:36:00.814658Z","created_by":"cscheid","updated_at":"2026-05-05T16:36:00.814658Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-x5r4","depends_on_id":"bd-xdnk","type":"discovered-from","created_at":"2026-05-05T16:36:00.814658Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-x5tx2","title":"Audit HashMap/HashSet iteration in user-visible output paths","description":"Follow-up from bd-hwdlq (triage of issue #222). The bd-hwdlq fix addresses one specific instance of non-deterministic diagnostic output caused by HashMap iteration in crates/quarto-parse-errors. There may be others.\n\nScope: grep across the codebase for HashMap/HashSet whose iteration order is observable in user-facing output (diagnostics, writers, snapshots, JSON emission, source maps, anywhere a Vec/String/file is built from iteration). For each instance, decide whether the iteration order is actually deterministic-by-construction (e.g. all entries are equal under the user-visible projection), or whether it needs to migrate to hashlink::LinkedHashMap / BTreeMap / sorted Vec.\n\nOut of scope: HashMap/HashSet used only for membership tests (contains/insert) where iteration is not observed.\n\nSuggested approach:\n1. ripgrep 'HashMap<\\|HashSet<' across crates/, filter to non-test code paths\n2. For each hit, trace the variable to see if it's iterated (.iter(), .values(), .keys(), for loop, .collect::<Vec>())\n3. Of the iterated ones, check whether the iteration result reaches user-visible output\n4. File sub-issues or fix directly depending on volume\n\nConsider also adding a CLAUDE.md or .claude/rules/ note codifying 'containers iterated to produce user-visible output must have deterministic iteration order.'","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-21T13:14:58.809507Z","created_by":"cscheid","updated_at":"2026-05-21T13:14:58.809507Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-x5tx2","depends_on_id":"bd-hwdlq","type":"discovered-from","created_at":"2026-05-21T13:14:58.809507Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xbnf","title":"L6 — Dependency-graph integration (listing_content_targets)","description":"Add DocumentProfile.listing_content_targets: Vec<PathBuf> (additive, no version bump). Populate during dep-graph build by expanding host's listing.contents globs against project source paths. New automatic edge source in dependency_graph.rs. Mode B picks up listing hosts when their content files are touched. See claude-notes/plans/2026-05-05-listings-epic.md §L6.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid","updated_at":"2026-05-07T17:50:28.654543Z","closed_at":"2026-05-07T17:50:28.654365Z","close_reason":"L6 implemented and merged on feature/listings as 8b5efb91 (impl ffa4d227). +26 tests over 8621 baseline → 8647. cargo xtask verify all green incl. WASM. End-to-end CLI Mode-B verification in plan.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xbnf","depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-xbnf","depends_on_id":"bd-j60g","type":"blocks","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-xbnf","depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xdier","title":"q2 preview: per-doc sidebar lands at bottom of page (extra <div> wrapper breaks grid)","description":"Symptom: in docs/ website, q2 render places the per-document YAML sidebar (Quarto 2 / Introduction / Markdown) on the left as expected, but q2 preview renders the same sidebar elements at the bottom of the page (below <main>).\n\nReproduced with /Users/cscheid/rooms/room-1/q2/docs/. Render: nav#quarto-sidebar at x=310 width=250 left of main. Preview: same nav inside <div> wrapper at x=585 width=749 below main.\n\nRoot cause: ts-packages/preview-renderer/src/q2-preview/chromeSlots.tsx:53-56 (SidebarSlot, and sibling NavbarSlot/PageNavSlot/FooterSlot) wrap the injected chrome HTML in <div dangerouslySetInnerHTML=...>. The native template at crates/quarto-core/src/template.rs:185-188 emits $rendered.navigation.sidebar$ as a *direct* child of <div id=\"quarto-content\">, no wrapper. The Quarto theme CSS grid on #quarto-content assigns nav#quarto-sidebar to grid-area 'content-top / page-start / page-bottom / body-start' — but only when nav#quarto-sidebar is a grid child. With the extra wrapper <div>, the wrapper becomes the grid item with default placement 'body-content-start / body-content-end' + 'grid-row: auto', stacking below <main>.\n\nVerified by patching `display: contents` on the wrapper at runtime in the preview iframe — sidebar snapped to correct position (x=310, on left).\n\nExisting test PreviewDocument.integration.test.tsx:252 checks `quartoContent.querySelector('nav#quarto-sidebar')` (descendant), not direct-child relationship — missed the bug.\n\nFix: add `style={{display: 'contents'}}` to the wrapping <div> in SidebarSlot (and apply same fix to sibling slots NavbarSlot, PageNavSlot, FooterSlot for parity — they share the same root cause even if the symptoms are less severe today). Add tests that assert direct-child relationship via `Array.from(parent.children).includes(node)` rather than `parent.querySelector(...)`.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T18:31:14.064173Z","created_by":"cscheid","updated_at":"2026-05-20T18:36:14.362832Z","closed_at":"2026-05-20T18:36:14.362650Z","close_reason":"Wrapper <div> in chrome slots now display:contents — sidebar/navbar/footer/page-nav are transparent to parent CSS grid/flex layout, matching native template byte-for-byte. Fix verified via failing-first tests (4 new in PreviewDocument.integration.test.tsx) and end-to-end browser check on docs/: sidebar at x=310 width=250 (left), main at x=585.5 — identical to q2 render. cargo xtask verify: all 12 steps green.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xdier","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-20T18:31:14.064173Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xdnk","title":"Doctemplate diagnostics dropped on quarto render path","description":"The doctemplate engine produces ariadne-formatted warnings (e.g. Q-10-2 'Undefined variable') with accurate source locations. These surface correctly via the pampa CLI (crates/pampa/src/main.rs:449 calls template.render_with_diagnostics and prints them with ariadne), but the quarto render orchestrator path drops them: crates/quarto-core/src/template.rs:412 (render_with_compiled_template, used by crates/quarto-core/src/stage/stages/apply_template.rs) calls template.render(&ctx), the non-diagnostic API. As a result, undefined variables and similar template warnings are silently swallowed under 'quarto render'. Plan: claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-05T13:31:01.034589Z","created_by":"cscheid","updated_at":"2026-05-05T17:28:59.548543Z","closed_at":"2026-05-05T17:28:59.548414Z","close_reason":"Implemented and merged to main (commits acf589a2 sync, 6544ff1b feat, 3422b636 docs). Doctemplate diagnostics now flow through quarto render with ariadne-rendered source-located warnings; pre-existing template: YAML lookup bug also fixed. Plan: claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md. Follow-ups: bd-x5r4 ($variable?$ syntax → q2#158), bd-khuj (hub-client UI smoke).","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-xee1","title":"[websites phase 6] Cross-document link rewriting","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 6.\n\nDeliverables:\n- HTML post-render transform that rewrites href attributes pointing at project-relative .qmd paths to corresponding output hrefs using ProjectIndex.\n- Correctly handle query strings, hash fragments (#anchor), and subdirectory paths.\n- Diagnostic warning for broken .qmd links (target not in index).\n- Tests: fixtures with inter-page links, including anchor and query suffixes.\n\nBlocked by Phase 1 (needs ProjectIndex).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-23T18:43:12.763310Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.633024Z","closed_at":"2026-04-29T00:31:30.632656Z","close_reason":"Phase 6 (cross-document link rewriting) implemented (commit 070412c0). Closed as part of Phase 9 cleanup.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xee1","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:12.763310Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-xee1","depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:45.378785Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xfwx","title":"Merge main → feature/websites: IncludeExpansion before DocumentProfile checkpoint","description":"Merge main into feature/websites such that the include-shortcode expansion pipeline stage (main, 215482fb) is wired into the pipeline BEFORE the DocumentProfile checkpoint (feature/websites, e8674612).\n\nPost-merge pipeline order (HTML / WASM / analysis):\n Parse -> MetadataMerge -> IncludeExpansion -> DocumentProfile -> UnwrapProfile -> PreEngineSugaring -> ...\n\nRationale: statically-knowable information a document declares via {{< include ... >}} (headings, code blocks, crossref targets) must be visible to DocumentProfile so downstream project-level features (sidebars, nav, cross-doc links, incremental rebuilds, future freeze) see a consistent AST.\n\nGates start of Phase 4 of the website epic (bd-0tr6).\n\nPlan: claude-notes/plans/2026-04-24-include-expansion-merge.md\n\nMain conflicts expected in:\n- crates/quarto-core/src/pipeline.rs (imports, three builders, tests)\n- crates/quarto-core/src/stage/mod.rs (re-exports)\n- crates/quarto-core/src/stage/stages/mod.rs (module declarations)\n- .beads/issues.jsonl\n\nTDD: A regression test (profile sees heading from included file) is added BEFORE the merge and must fail on feature/websites HEAD for the right reason (no IncludeExpansionStage), then pass after the merge resolution.\n\nNo push without explicit user approval.","status":"in_progress","priority":1,"issue_type":"task","created_at":"2026-04-24T20:02:12.975940Z","created_by":"cscheid","updated_at":"2026-04-24T20:06:26.895630Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["websites"],"dependencies":[{"issue_id":"bd-xfwx","depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-24T20:02:12.975940Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-xgb4","title":"Share link project never joins synced project set","description":"Visiting #/share/<indexDocId> opens the project but never adds it to the user's synced project set (profile doc). Later trying to add the same docId via the Connect form fails with a misleading 'may already exist' error.\n\nRoot cause is three separate bugs:\n1. App.tsx share route gates projectSetActions.addProject on status === 'connected', which is racy against useProjectSet's async init. On initial share-link load the guard almost always fails, the add is skipped, and there is no retry.\n2. ProjectSelector renders the list from projectSetEntries when useProjectSet is true, so the share-flow's IDB-only entry is invisible.\n3. ProjectSelector.handleConnectProject skips the getProjectByIndexDocId dedupe check that the share route has, and projectStorage.addProject then collides with the IDB unique index on indexDocId. The form also never calls projectSetActions.addProject, so even a successful add wouldn't reach the synced set.\n\nFull analysis and TDD fix plan in claude-notes/plans/2026-04-16-share-link-project-not-added.md.\n\nRepro: https://quarto-hub.com/#/share/SNHcgVzUkWpGFmcxkCkpCDfFtmu?server=wss%3A%2F%2Fquarto-hub.com%2Fws&file=%2Felliot%2Findex.qmd&name=Demo+Playground — opens fine but SNHcgVzUkWpGFmcxkCkpCDfFtmu is absent from the reporting user's profile projects map, and manual add via Connect form fails with 'Failed to add project. The document ID may already exist.'","notes":"Reconciler implemented and verified. See phase 3 checklist in claude-notes/plans/2026-04-16-share-link-project-not-added.md. Awaiting user approval before committing/pushing.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-04-16T19:26:55.995937Z","created_by":"cscheid","updated_at":"2026-04-16T20:09:56.136603Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["hub-client","project-set","share"]} +{"id":"bd-xhvs","title":"L9 follow-up: escape ]]> in CDATA-wrapped feed bodies","description":"feed/complete.rs wraps the substituted body in <![CDATA[…]]>. If the rendered HTML contains the literal sequence ]]>, the CDATA terminates prematurely and the XML is malformed. The fix is to split such bodies at every ]]> and emit two CDATA sections: ]]><![CDATA[. v1 doesn't handle this because the typical Quarto-rendered output never contains ]]>; file a real-world report would force the issue.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-08T17:34:13.045704Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:13.045704Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xhvs","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:13.045704Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xly8b","title":"Catalog/corpus drift: markdown Q-2-X assignments diverge between error_catalog.json, pampa/resources/error-corpus/, and production-emit sites","description":"While authoring docs/errors/markdown/ pages (bd-lgxdr), found multiple drift cases between the three sources of truth:\n\n1. **Q-2-5**: catalog title 'Unclosed Emphasis' (generic), but corpus Q-2-5.json and production code (json.rs:328) use 'Unclosed Underscore Emphasis'. Catalog says Q-2-14 is the underscore-specific one. Production behavior collapses to Q-2-5; Q-2-14 is never actually emitted with the *with_code* API.\n\n2. **Q-2-35**: catalog says 'Invalid List-Table Structure' (matches production emits at treesitter_utils/postprocess.rs:785,976), but corpus Q-2-35.json claims 'Indented code blocks are not supported'. The corpus appears stale.\n\n3. **Q-2-36, Q-2-37, Q-2-38**: present in pampa/resources/error-corpus/ as Q-2-36.json (Old-style knitr chunk options), Q-2-37.json (Line break in link destination), Q-2-38.json (Unclosed Attribute Specifier) — and Q-2-36 is emitted in production (treesitter.rs:1244) — but NONE are in error_catalog.json. The catalog jumps Q-2-35 → Q-2-39.\n\n4. **Q-2-6, Q-2-8**: in catalog but never emitted in production. Reserved for future strict-mode (Q-2-6) and upgraded-to-error-and-renumbered (Q-2-8 → Q-2-36).\n\nPlan: the catalog is authoritative for docs_url; the corpus needs to be reconciled to match. Add missing Q-2-36/37/38 to the catalog (or remove from corpus if they should not exist). Fix Q-2-5 and Q-2-35 corpus titles to match catalog. Decide whether Q-2-14 should be deprecated or whether production should be updated to emit it for the underscore variant specifically.\n\nDiscovered from: bd-lgxdr (markdown subsystem error-docs pages).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-22T20:38:32.703765Z","created_by":"cscheid","updated_at":"2026-05-22T20:38:32.703765Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["documentation","error-reporting","markdown"],"dependencies":[{"issue_id":"bd-xly8b","depends_on_id":"bd-lgxdr","type":"discovered-from","created_at":"2026-05-22T20:38:32.703765Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xm7l","title":"Audit non-cargo / vendored dependencies and expand upgrade skill","description":"Expand the upgrade-cargo-deps skill (or add a sibling audit-vendored-deps skill) so the bi-weekly dependency audit also covers non-Cargo vendored assets — Bootstrap SCSS/Icons, chicago-author-date CSL, tree-sitter highlight queries, quarto-cli built-in extensions, knitr R scripts, Pandoc HTML template, quarto-system-runtime JS bundles, reveal.js-menu CSS, etc. Discovery strategies and a per-asset inventory live at claude-notes/research/vendored-dependencies-inventory.md. Plan + phased work items at claude-notes/plans/2026-05-04-vendored-deps-audit.md.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-04T21:14:02.442855Z","created_by":"cscheid","updated_at":"2026-05-04T21:14:02.442855Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["deps","vendored"]} +{"id":"bd-xoaic","title":"q2 get-config: emit merged document config as JSON","description":"GH #256. New CLI subcommand `q2 get-config <file> [yaml-path]` that returns the fully-merged document configuration (after _quarto.yml / _metadata.yml / frontmatter merge + format flattening) as JSON, so external tools don't have to reimplement Quarto 2 metadata-resolution semantics.\n\nEmpty path => entire merged metadata. Option to choose prose representation: plain/markdown string vs Pandoc AST JSON.\n\nReuses the parse+MetadataMerge (profile-checkpoint) pipeline; no engines/filters/render. Plan: claude-notes/plans/2026-06-02-get-config-command.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-06-02T22:40:37.283762Z","created_by":"cscheid","updated_at":"2026-06-03T02:14:39.874945Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-xs2u","title":"Em-dash / en-dash in document titles breaks something in hub-client","description":"User reported during L3 testing (2026-05-06): when uploading a project containing em-dash characters (U+2014, '—') in document titles, hub-client exhibits some bug. The user worked around it by replacing em-dashes with regular dashes in the Automerge documents.\n\nI (Claude) did not reproduce the bug myself; I only observed that the workaround (replace em-dash with single dash) made hub-client behave correctly afterwards. The bug could be in any of:\n- pampa parser handling of unicode dashes in YAML strings\n- hub-client / Monaco display of titles with non-ASCII characters\n- The Automerge text sync round-trip (less likely; bytes round-tripped identically in my test)\n\nReproduction (potentially):\n1. Create a Q2 .qmd with 'title: \"Some — text\"' (em-dash) in the frontmatter.\n2. Upload via scripts/upload-project.mjs to wss://sync.automerge.org.\n3. Open in hub-client and observe whatever the user observed.\n\nTo investigate: have the user describe the exact symptom (render error? blank title? wrong rendering?), then bisect against the affected component.\n\nDiscovered while testing L3 (bd-ml8z) listings via hub-client; see claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md §\"Hand-off summary\".","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-06T22:08:24.119375Z","created_by":"cscheid","updated_at":"2026-05-06T22:08:24.119375Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xs2u","depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T22:08:24.119375Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xvdop","title":"Experiment: consolidate integration tests to reduce target/ size","description":"Rust defaults give each tests/*.rs file its own test binary, fully linked against the crate + all transitive deps. We have 164 integration test files across 20 crates; target/debug is currently 251 GB while target/release is 2.7 GB, suggesting per-file debug binaries are the dominant bloat. The ark project applied matklad's tests/integration/ consolidation pattern (posit-dev/ark#1240) and saw a ~57% drop in fresh cargo clean size and a ~3x drop in CI runner footprint. This issue tracks an experiment to measure the same change on Q2 from a macOS dev machine, piloting pampa (57 files) first before deciding on a full rollout. Plan: claude-notes/plans/2026-05-28-integration-test-consolidation.md","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-28T16:16:18.200610Z","created_by":"cscheid","updated_at":"2026-05-28T16:16:18.200610Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-xwq8","title":"Suppress page-nav for custom-layout pages","description":"Q1 hides the prev/next strip when a page sets page-layout: custom. Phase 4 ships without this; defer until a real page hits the edge case. See Phase 4 plan non-goals.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:57.195184Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:57.195184Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xwq8","depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:57.195184Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-xxul","title":"Non-.qmd input extensions in project discovery (.md, .ipynb, .Rmd)","description":"Phase 1 of the website epic explicitly discovers only .qmd files. The plan §File-list expansion defers the decision about which non-.qmd extensions are renderable documents (to include in project.files) vs. source artifacts (to treat like resources). Needs a user conversation about semantics for .md (literal markdown — render? copy?), .ipynb (converted at render time in Q1), .Rmd. Once settled, extend discovery and the pipeline's SourceType handling.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T01:05:32.255233Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:32.255233Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-xxul","depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:32.255233Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-y1fs3","title":"q2 preview: CodeBlock DOM mismatches q2 render — classes go on <code> instead of <pre>, sourceCode class missing","description":"q2 render emits '<pre class=\"sourceCode r cell-code\"><code><span class=\"hl-…\">…</span></code></pre>'; q2 preview emits '<pre><code class=\"r cell-code\"><span class=\"hl-…\">…</span></code></pre>'. Two divergences: (1) language/role classes are on <code> in preview, but on <pre> in render (native writer's behavior, see crates/pampa/src/writers/html.rs:963-975); (2) the 'sourceCode' class — prepended to <pre>'s class list whenever data-hl-spans is present (write_code_container_attr at line 487-495) — is entirely missing from preview. Both differences break Quarto theme rules that key off .sourceCode and pre.sourceCode, causing the visible spacing/indentation drift the user reported. Fix in React CodeBlock: move classes + data-* kvs to <pre>; bare <code>; prepend 'sourceCode' to <pre>'s class list when data-hl-spans is non-empty.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid","updated_at":"2026-05-18T17:44:55.722896Z","closed_at":"2026-05-18T17:44:55.722758Z","close_reason":"Implementation complete: React CodeBlock now mirrors the native HTML writer's DOM shape — classes + data-* kvs on <pre>, bare <code>, sourceCode prepended when data-hl-spans is present. Verified end-to-end: pre.className matches between q2 render and q2 preview ('sourceCode r cell-code' on both), code.className empty on both. 2 tests rewritten, 0 new added; 150/150 SPA integration tests green; cargo xtask verify 12/12 green.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-y1fs3","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-y1fs3","depends_on_id":"bd-nxslt","type":"related","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-y9zl","title":"Add pandoc.List metatable to all list-like tables in Lua API","description":"Tables returned from element field access (classes, BulletList/OrderedList/LineBlock/DefinitionList content, etc.) are created as plain Lua tables without the pandoc.List metatable. This means List methods like :includes(), :map(), :filter() are not available on these tables, breaking compatibility with the Pandoc Lua API and Quarto 1 filters. The fix is to set the List metatable on every table that represents a sequence.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-10T20:31:24.710801Z","created_by":"cscheid","updated_at":"2026-04-10T20:52:46.525642Z","closed_at":"2026-04-10T20:52:46.524965Z","close_reason":"Implemented: all classes and container content fields now carry the pandoc.List metatable","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-yd4q","title":"L9 follow-up: math handling in full feeds","description":"Port Q1's KaTeX/MathJax preservation pathways from readRenderedContents. Currently L9 v1 emits math notation as it appears in the rendered HTML (typically <span class=\"math\">$…$</span> or rendered KaTeX HTML). RSS readers without Quarto's CSS may not render this; subscribers can click through to the linked HTML page in the meantime. Reader extension lives in feed/reader_ext.rs; gated behind an RssReaderOptions flag (math handling is currently noted as forward-compat in the L7 reader). See claude-notes/plans/2026-05-08-listings-L9-rss-feeds.md §\"Out of scope for L9 (deferred)\".","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:09.979615Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:09.979615Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-yd4q","depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:09.979615Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-ylig","title":"QMD writer drops shortcode arguments and delimiters","description":"User-reported round-trip failure: `printf '{{< video https://youtu.be/abc width=\"800\" height=\"450\" >}}\\n' | pampa -t qmd` produces `{{video}}` — losing the `{{<` / `>}}` delimiters, the URL positional arg, and named keyword args.\n\nRoot cause: `crates/pampa/src/writers/qmd.rs:1716` `write_shortcode` emits only `{{ + name + }}`, ignoring `is_escaped`, `positional_args`, and `keyword_args`. Even the no-arg form is wrong (qmd syntax requires `{{< name >}}`, not `{{name}}`).\n\nThe parser populates the `Shortcode` struct correctly; the JSON / native writers preserve all data via `shortcode_to_span`. Only the qmd writer is broken.\n\nThe existing roundtrip suite in `tests/roundtrip_tests/qmd-json-qmd/` does NOT catch this: it goes qmd → JSON → qmd, and the JSON writer converts `Inline::Shortcode` to `Inline::Span`, so `write_shortcode` is never exercised.\n\nPlan: claude-notes/plans/2026-04-30-shortcode-qmd-roundtrip.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T20:37:29.647311Z","created_by":"cscheid","updated_at":"2026-04-30T21:05:09.860926Z","closed_at":"2026-04-30T21:05:09.860702Z","close_reason":"Implemented qmd writer round-trip for shortcodes; switched keyword_args to LinkedHashMap for source-order preservation. End-to-end verified, full xtask verify green.","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-yttl","title":"Expose CrossrefIndex from LSP analyze_document for future features","description":"The LSP analysis pipeline now builds a full CrossrefIndex (via CrossrefIndexTransform running inside AstTransformsStage). We currently extract symbols out of the post-pipeline AST and discard the StageContext.crossref_index. Future analysis features — unresolved-ref diagnostics (a dangling @fig-xyz), hover previews that show the target's rendered label, go-to-definition for @references — all want that index. Surface it on the DocumentAnalysis return value so callers can use it without re-running the pipeline.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:46.157105Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:46.157105Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-yttl","depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:46.157105Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-yu16","title":"[websites phase 7] Post-render: sitemap, favicon, site-url, title prefix","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 7.\n\nDeliverables:\n- WebsiteProjectType::post_render orchestration.\n- Sitemap generation at _site/sitemap.xml, gated on website.site-url. Incremental-aware: read existing, update entries, write.\n- robots.txt referencing sitemap if not already present.\n- Favicon: copy to output dir, inject <link rel=icon> in page head.\n- Title prefix: rendered <title> becomes '<page-title> — <website-title>'.\n- Tests against fixtures.\n\nBlocked by Phase 1.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-23T18:43:17.733419Z","created_by":"cscheid","updated_at":"2026-04-23T18:43:46.410213Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-yu16","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:17.733419Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-yu16","depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:46.409250Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-yxlh","title":"Full Q1 sidebar rollup parity (Decision B from bd-f5yi breakpoint plan)","description":"Port Q1's mid-range sidebar UX from external-sources/quarto-cli/.../navigation/quarto-nav.scss:558-590. Below the lg (992 px) breakpoint, take the floating sidebar out of the grid (position: static), stack it horizontally below the navbar with a border-bottom, and make it Bootstrap-collapsible — visible only when a hamburger toggle adds the .show class.\n\nCurrently we ship the smaller fix (Decision A, c8dcbcf6): hide the sidebar entirely below lg. That makes the layout honest but leaves no in-pane way to navigate to siblings at half-pane previews. Q1 parity restores that affordance.\n\nRequires:\n1. Bootstrap's collapse JS bundle to be loaded — blocked on bd-e7b7 (JS library loading).\n2. Markup emission: nav.quarto-secondary-nav strip with the hamburger toggle (data-bs-toggle / data-bs-target wired to the sidebar's id).\n3. SCSS: port the rules under media-breakpoint-down(lg) from quarto-nav.scss:558-590 (sidebar position:static, .collapsing/.show z-index 1000, etc.).\n\nWhen this lands, the bd-f5yi-followup commit's display:none rule should be replaced with the rollup pattern — keep that in mind to avoid drift.\n\nPlan: claude-notes/plans/2026-05-01-website-sidebar-breakpoints.md (Decision B + future deferred work).\n\nParent epic: bd-0tr6 (websites).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid","updated_at":"2026-05-01T17:00:47.128592Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-yxlh","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-yxlh","depends_on_id":"bd-e7b7","type":"blocks","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-yxlh","depends_on_id":"bd-f5yi","type":"related","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-yxqt","title":"Phase A.1+A.2: quarto preview CLI shim + crates/quarto-preview shell crate","description":"Add 'quarto preview' clap subcommand (mirror commands/hub.rs) + new crates/quarto-preview/ that owns CLI logic, embedded SPA serving (include_dir!), and the build.rs placeholder pattern (mirrors quarto-trace-server). Engine-less for Phase A. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.1, §A.2.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-13T16:53:27.986192Z","created_by":"cscheid","updated_at":"2026-05-13T17:43:16.279448Z","closed_at":"2026-05-13T17:43:16.279315Z","close_reason":"Phase A.1 (CLI shape) + A.2 (quarto-preview crate + SPA-serving + smoke tests) landed on branch beads/bd-yxqt-phase-a1a2-quarto-preview (commit e085ad75). Rust-side verify green (cargo xtask verify --skip-hub-build et al). A.5 will replace the NotImplemented stub with real boot.","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-yxqt","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:27.986192Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-z2j7o","title":"Audit codebase for String→{String, SourceInfo} refactors; consider WithSourceInfo<T> wrapper","description":"As we add source-info to more data types (e.g. RawResourcePattern in bd-c1et2), we keep introducing ad-hoc wrappers of the shape:\n\n struct RawFoo { payload: String, source_info: SourceInfo }\n\nA parametric wrapper\n\n pub struct WithSourceInfo<T> {\n pub payload: T,\n pub source_info: SourceInfo,\n }\n impl<T> WithSourceInfo<T> { /* into_payload, as_ref, as_mut, map, ... */ }\n\nwould (a) eliminate boilerplate, (b) compose with iterators/traits, (c) make it easy to thread source info through generic code without writing a new struct each time.\n\nScope of the audit:\n1. Find existing ad-hoc wrappers of this shape across crates (likely candidates: quarto-core, quarto-yaml-validation, quarto-csl, quarto-pandoc-types, quarto-error-reporting). Grep for 'source_info:' adjacent to a payload field; check ConfigValue/ConfigMapEntry shape; check whether RawResourcePattern (bd-c1et2) qualifies.\n2. Decide whether unifying them on a common WithSourceInfo<T> is worth the churn — would all sites actually fit, or are some shaped enough differently (e.g. multiple spans per record) that a uniform wrapper would be procrustean?\n3. If yes: design the API (which methods, Deref or no, serde behavior, source-info-merging for derived values), prototype on one crate, fan out a small refactor in follow-up issues.\n4. If no: document the decision so the next person doesn't re-litigate it.\n\nNot urgent. Pick up when there's slack between user-facing features.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-21T21:58:55.016623Z","created_by":"cscheid","updated_at":"2026-05-21T21:58:55.016623Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-z2j7o","depends_on_id":"bd-c1et2","type":"discovered-from","created_at":"2026-05-21T21:58:55.016623Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-z529","title":"Phase B.1: Broaden FileWatcher allow-list for q2 preview","description":"Replace is_qmd_file with a richer predicate that admits .qmd, _quarto.yml, _metadata.yml, .png/.jpg/.jpeg/.gif/.svg/.webp, and .tsx (defer _extensions/** per plan Q-B1).\n\nPlumb through HubConfig as a WatchFilter enum so the hub binary keeps .qmd-only and quarto-preview opts into broad. Tests first: unit tests in crates/quarto-hub/src/watch.rs plus an integration test that edits _quarto.yml and asserts the event surfaces.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.1.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T19:34:52.716556Z","created_by":"cscheid","updated_at":"2026-05-13T19:56:05.279002Z","closed_at":"2026-05-13T19:56:05.278869Z","close_reason":"WatchFilter enum landed on feature/q2-preview-command (merge a528da4c). New PreviewBroad accepts _quarto.{yml,yaml}, _metadata.{yml,yaml}, image extensions, .tsx; hub keeps default QmdOnly. 5 unit + 2 integration tests in crates/quarto-hub/src/watch.rs. cargo xtask verify --skip-hub-build clean. End-to-end smoke verified through q2 preview binary (boot log shows filter=PreviewBroad; _quarto.yml edit produces File change detected + samod sync).","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-z529","depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T19:34:52.716556Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} {"id":"bd-z6we","title":"Kanban: Move status dropdown left of title","description":"Move the status dropdown in CardComponent.tsx from the bottom of the card to inline with the title, on the left side. Status and title should be on a single line. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-11T18:32:27.405581Z","created_by":"cscheid","updated_at":"2026-02-11T18:33:35.835738Z","closed_at":"2026-02-11T18:33:35.835721Z","close_reason":"Implemented - status dropdown moved to left of title","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-zb5k","title":"Suppress noisy 'lua error' panic stack traces in WASM (cosmetic — caught control flow)","description":"rust_lua_throw at crates/wasm-quarto-hub-client/src/c_shim.rs:452 panics with 'lua error' as a replacement for Lua's longjmp-based LUAI_THROW. The panics are caught by rust_lua_protected_call (catch_unwind) — this is expected control flow, not a bug. However, console_error_panic_hook prints the full stack trace for every panic, spamming both 'cargo xtask verify' output and hub-client production console (visible to users in browser).\n\nFix: install a custom panic hook that suppresses panics matching the Lua throw sentinel, while preserving full stack traces for genuine panics.\n\nThe hub-client e2e test helper already explicitly tolerates these as transient (hub-client/e2e/helpers/previewExtraction.ts:38-45).\n\nPlan: claude-notes/plans/2026-04-16-suppress-lua-panic-noise.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-16T18:20:50.553012Z","created_by":"cscheid","updated_at":"2026-04-16T19:08:52.428405Z","closed_at":"2026-04-16T19:08:52.427623Z","close_reason":"Implemented: LuaThrow sentinel + filter hook. cargo xtask verify clean (0 lua error mentions). Plan: claude-notes/plans/2026-04-16-suppress-lua-panic-noise.md","source_repo":".","compaction_level":0,"original_size":0} +{"id":"bd-zerg","title":"Phase 9 follow-up: parallel Pass-1 over project files","description":"On a _quarto.yml edit, the Phase-8 cache-key invalidation propagates to every profile entry simultaneously. The orchestrator's pass_one loop (crates/quarto-core/src/project/orchestrator.rs) is sequential: it runs N head pipelines back-to-back. Trivially parallelizable since per-file work is independent.\n\nNative: rayon + pollster-per-worker (matches the rest of the pipeline's Send-free trait shape). WASM: futures::future::join_all over the WasmRuntime calls.\n\nPhase 9 plan §Risks calls this out — order-of-seconds latency on a 100-file project after a _quarto.yml edit. Active page render still feels snappy on warm-cache edits; this is the genuine cold-path.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:22.622408Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-zerg","depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid","metadata":"{}","thread_id":""},{"issue_id":"bd-zerg","depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-zh24","title":"Cargo: upgrade similar v2.7.0 → v3.1.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 2.7.0 is range-pinned in workspace; latest is 3.1.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.269126Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.640911Z","closed_at":"2026-05-04T20:30:44.640764Z","close_reason":"merged: 4c337eb6","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-zh24","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.611150Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-znva","title":"Cargo: upgrade sha2 v0.10.9 → v0.11.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.10.9 is range-pinned in workspace; latest is 0.11.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.219569Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.031277Z","closed_at":"2026-05-04T20:30:45.031138Z","close_reason":"merged: 0812812e","source_repo":".","compaction_level":0,"original_size":0,"labels":["cargo","deps"],"dependencies":[{"issue_id":"bd-znva","depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.527354Z","created_by":"cscheid","metadata":"{}","thread_id":""}]} +{"id":"bd-zpl4u","title":"Heading inside list item is silently dropped by AST converter","description":"Minimal repro: `* # Section 1` produces an empty BulletList in pampa, while Pandoc produces a BulletList containing a Header.\n\n```bash\necho '* # Section 1' | cargo run --bin pampa -- --to json | jq '.blocks'\n# → [{\"c\":[[]],\"s\":0,\"t\":\"BulletList\"}] (one empty item)\n\necho '* # Section 1' | pandoc -f markdown -t json | jq '.blocks'\n# → BulletList containing one Header block\n```\n\nRoot cause: tree-sitter correctly produces `list_item → section → atx_heading`, but `process_list_item` in crates/pampa/src/pandoc/treesitter.rs (lines 262–317) has no `filter_map` arm for `PandocNativeIntermediate::IntermediateSection`. The catch-all `_ => None` (line 306) silently discards the section and all the blocks it contains.\n\n`process_section` in crates/pampa/src/pandoc/treesitter_utils/section.rs (lines 27–29) already handles this case correctly by extending the block vector. The fix to `process_list_item` should mirror that pattern (the current shape — `filter_map` returning `Option<Block>` — can't flat-map a multi-block section, so it'll need a small refactor to a `Vec<Block>` builder loop).\n\nThis is a data-loss bug. Any list item that contains a heading (or anything else wrapped in a `section` intermediate) loses that content entirely.\n\nPlan: claude-notes/plans/2026-05-20-heading-in-list-item-dropped.md\n\nTDD: write the failing parser test first, then implement.\n\nRelated but distinct: bd-vet6 (multi-line block quote inside list item is a tree-sitter scanner bug, not a converter bug).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T20:10:34.991088Z","created_by":"cscheid","updated_at":"2026-05-20T20:23:31.045315Z","closed_at":"2026-05-20T20:23:31.045143Z","close_reason":"Fixed: process_list_item now handles IntermediateSection by extending the block list (mirroring process_section). Refactored from filter_map to an explicit Vec<Block> builder so multi-block sections can be flattened. Also turned the previously-silent catch-all _ => None into a loud panic for unknown variants; added explicit no-op arms for IntermediateUnknown (ERROR nodes, marker delimiters) and bullet-marker node-name filters that preserve the existing tolerant behavior. Plan: claude-notes/plans/2026-05-20-heading-in-list-item-dropped.md","source_repo":".","compaction_level":0,"original_size":0,"labels":["bug","pampa","parser"]} +{"id":"bd-zvh2p","title":"q2-preview: thread attribution through render_page_for_preview","description":"The hub-client's q2-preview surface has attribution-ready consumer wiring (`useAttributionHover`, `<AttributionWrap>` on the q2-preview dispatchers, `{attr.stylesheet}` / `{...attr.hostProps}` / `{attr.overlay}` interpolated in `PreviewDocument.tsx`). All of this is inert today because `render_page_for_preview` (in `crates/wasm-quarto-hub-client/src/lib.rs`) doesn't accept an `attribution_json` argument, so the active-page ctx never gets a `PreBuiltAttributionProvider` and the resulting AST JSON's `astContext.attribution*` fields are empty. With an empty `AttributionLookupContext`, `useAttributionHover` returns its inert form and the consumer wiring renders nothing — DOM stays byte-identical to pre-attribution.\n\nExtending `render_page_for_preview` to accept `attribution_json: Option<String>` and forward it through the same machinery `parse_qmd_to_ast_with_attribution` and `render_page_in_project_with_attribution` already use is the missing piece. Once it lands, the React side lights up automatically — no further hub-client changes required.\n\nProducer-side reference points:\n- `crates/wasm-quarto-hub-client/src/lib.rs` — `render_page_for_preview` and the shared `render_project_active_page_to_response` it delegates to. After the May 2026 merge of origin/main, the latter already takes `attribution_json: Option<String>`; the preview entry just needs to accept and forward it.\n- `crates/quarto-core/src/transforms/attribution_generate.rs` + `attribution_render.rs` — the transforms that read `ctx.attribution_provider` and populate `astContext.attribution*`.\n\nDiscovered while merging origin/main into feature/q2-preview-command (PR #190 attribution pipeline). See:\n- claude-notes/research/2026-05-19-attribution-merge-briefing.md (overall merge context)\n- claude-notes/research/2026-05-19-PreviewDocument-merge-resolution.md (the consumer-side analysis that surfaced this gap)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-19T16:15:43.566932Z","created_by":"cscheid","updated_at":"2026-05-19T16:15:43.566932Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["attribution","q2-preview"]} +{"id":"bd-zzke","title":"Consolidate six divergent inlines_to_(plain_)text helpers","description":"Six functions in tree share names but disagree on semantics: code/math contribution, Quoted wrapping characters, Note recursion, LineBreak handling, trimming. Sites: quarto-pandoc-types/src/config_value.rs:22, quarto-core/src/transforms/title_block.rs:144, quarto-core/src/transforms/metadata_normalize.rs:110, quarto-core/src/template.rs:626, quarto-config/src/format.rs:129, quarto-lsp-core/src/analysis.rs:713. Each call site has subtly different requirements. A clean consolidation likely needs an options-driven helper (PlainTextOptions { wrap_quoted, line_break_as, include_code, include_notes, ... }) plus per-site audit and tests so existing snapshots don't churn. Surfaced during L1 (bd-izqh) sub-plan review on 2026-05-06; deliberately deferred — L1 picks metadata_normalize's helper to reuse without consolidating. P3 hygiene; not a listings-epic blocker. Comparison table and reasoning in claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md when updated.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-06T13:21:05.130039Z","created_by":"cscheid","updated_at":"2026-05-06T13:21:05.130039Z","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} diff --git a/.beads/metadata.json b/.beads/metadata.json index c787975e1..aba369b4c 100644 --- a/.beads/metadata.json +++ b/.beads/metadata.json @@ -1,4 +1,5 @@ { "database": "beads.db", - "jsonl_export": "issues.jsonl" + "jsonl_export": "issues.jsonl", + "last_bd_version": "0.24.3" } \ No newline at end of file diff --git a/.braid-project b/.braid-project new file mode 100644 index 000000000..d169a2f47 --- /dev/null +++ b/.braid-project @@ -0,0 +1 @@ +q2 diff --git a/.braid/README.md b/.braid/README.md new file mode 100644 index 000000000..386be2e7f --- /dev/null +++ b/.braid/README.md @@ -0,0 +1,38 @@ +# `.braid/` — braid backup snapshot + +This directory holds **backup-only** artifacts for the project's braid issue +tracker (the "skein"). The skein itself is an [automerge](https://automerge.org) +CRDT synced through a sync server — **that is the single source of truth**, not +anything in this directory. + +## `snapshot.jsonl` + +A `braid export` dump of every strand, regenerated with: + +```bash +cargo xtask braid-snapshot # writes .braid/snapshot.jsonl +``` + +It exists so issues stay greppable in PRs, diffable in git history, and +recoverable. It is committed to whatever work branch you are on. + +### ⚠️ One-directional — never import it back + +- The snapshot flows **automerge → file only**. It is **never** an import or + sync source. **Do not run `braid import .braid/snapshot.jsonl`.** The only + JSONL ever imported was the one-time beads→braid migration (done 2026-06-08). +- On a git **conflict** in `snapshot.jsonl`, do **not** hand-merge. Regenerate + from the live skein: `cargo xtask braid-snapshot`. The CRDT is authoritative; + this file is a photograph. (It may show strand state from another branch — + "cross-branch contamination" — which is expected and harmless, because the + file is not the truth.) + +See `CLAUDE.md` § Snapshot backup policy and +`claude-notes/plans/2026-06-08-braid-migration.md` for the full rationale. + +## Not in this directory + +The skein **secret** lives in `.braid.toml` at the repo root (gitignored, a +read/write bearer token — never committed). The committed, non-secret +`.braid-project` marker (also at the repo root) only names the project so +worktrees/clones resolve the skein. diff --git a/.braid/snapshot.jsonl b/.braid/snapshot.jsonl new file mode 100644 index 000000000..f5322bbac --- /dev/null +++ b/.braid/snapshot.jsonl @@ -0,0 +1,1145 @@ +{"id":"bd-068k","title":"Phase 0: quarto-publish crate scaffold + provider trait","description":"Phase 0 of bd-t3ny. Build the quarto-publish crate skeleton: types, PublishProvider trait (prepare/commit/verify), PublishHost, PublishRenderer, ProviderRegistry, NativeHost, CLI argument validation, and wire into crates/quarto/src/commands/publish.rs (replacing NotImplemented stub).\n\nProvider impls in this phase: gh-pages registered with prepare/commit unimplemented!() — tests exercise registry lookup and CLI dispatch only.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md (Phase 0 section)","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-03T14:37:32.946678Z","created_by":"cscheid","updated_at":"2026-05-03T14:57:58.079046Z","dependencies":{"bd-t3ny:parent-child":{"depends_on_id":"bd-t3ny","type":"parent-child","created_at":"2026-05-03T14:37:32.946678Z","created_by":"cscheid"}}} +{"id":"bd-0a3b","title":"Cargo: upgrade rand v0.9.4 → v0.10.1","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.9.4 is range-pinned in workspace; latest is 0.10.1. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.920222Z","created_by":"cscheid","updated_at":"2026-05-04T19:06:15.700658Z","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.024220Z","created_by":"cscheid"}}} +{"id":"bd-0fd0","title":"Lua filter injection slot between generate and render transforms","description":"Today, UserFiltersStage::pre() runs before AstTransformsStage and ::post() runs after. There is no Lua filter slot interleaved between generate-style transforms (NavbarGenerate, SidebarGenerate, ListingGenerate, etc.) and their render-side counterparts inside AstTransformsStage, so user filters cannot mutate resolved navigation/listings data before HTML emission.\n\nStrawman: split build_transform_pipeline (crates/quarto-core/src/pipeline.rs) into build_generate_transforms() and build_render_transforms() with a configurable user-filter bridge in between. The L3 listing transforms, navbar generate, sidebar generate, etc., become the first consumers.\n\nSource-code TODO markers should land at:\n- crates/quarto-core/src/pipeline.rs (NAVIGATION PHASE comment block)\n- crates/quarto-core/src/transforms/navbar_generate.rs (existing precedent with the same latent assumption)\n- crates/quarto-core/src/transforms/listing_generate.rs (added during L3)\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D2/D13 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T18:26:18.595826Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:18.595826Z","dependencies":{"bd-ml8z:discovered-from":{"depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:18.595826Z","created_by":"cscheid"}}} +{"id":"bd-0gkh3","title":"Phase 6 — hub-mcp refresh-on-401 (RefreshManager)","description":"New module ts-packages/quarto-hub-mcp/src/auth/refresh-manager.ts wrapping CredentialStore + oauth4webapi refresh-token grant.\n\nBehaviour fixed by empirical verification 2026-05-19: Google does NOT rotate refresh tokens for Limited-Input-Devices clients, so the persistence rule is keep-prior-on-missing. Defensive test still covers the rotated-refresh-token case.\n\nConcurrent-callers coalesce via in-flight-promise mutex; invalid_grant from Google triggers CredentialStore.clear() + typed ReauthRequired naming authenticate_start.\n\nPlan §Phase 6: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:14.252095Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:14.252095Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:14.252095Z","created_by":"shikokuchuo"}}} +{"id":"bd-0gsj","title":"Fix CRLF handling in tree-sitter-qmd grammar.js for pipe tables","description":"Tree-sitter grammar at crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js parses pipe tables incorrectly when input uses CRLF line endings. With LF input, the pipe table closes at the blank line and following content becomes a separate block. With CRLF input, the table absorbs the following paragraph as a malformed body row. Bug propagates through pampa end-to-end: rendered Pandoc AST is structurally wrong for any Windows user with core.autocrlf=true (default) authoring a pipe table followed by a paragraph. Affects all output formats (HTML, PDF, Word) since Pandoc AST is upstream of every writer. Surfaced 2026-04-24 during PR 109 Windows verification as 5 failing pipe-table corpus tests; investigation in bd-ntnx classified it as a real grammar bug, not a corpus formatting issue. Full reproducer and observed parse trees in the design field. Cross-reference q2-windows-verify-tests memory note for related Windows CRLF failures.","design":"Reproducer. Two layers, both diagnostic. Layer 1 tests grammar.js directly. Layer 2 tests the full pampa pipeline that real users hit. Fixtures live in the tree-sitter-markdown directory so tree-sitter parse picks up the configured grammar without an init-config step.\n\nLayer 1 (grammar.js):\n\nprintf \"before\\r\\n\\r\\n| a | b |\\r\\n|---|---|\\r\\n| 1 | 2 |\\r\\n\\r\\nafter\\r\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd\nprintf \"before\\n\\n| a | b |\\n|---|---|\\n| 1 | 2 |\\n\\nafter\\n\" > crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd\ncd crates/tree-sitter-qmd/tree-sitter-markdown\ntree-sitter parse test-crlf.qmd > test-crlf.parse\ntree-sitter parse test-lf.qmd > test-lf.parse\ndiff test-crlf.parse test-lf.parse\n\nLayer 2 (pampa end-to-end):\n\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd > pampa-crlf.out\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd > pampa-lf.out\ndiff pampa-crlf.out pampa-lf.out\n\nObserved parse trees from Layer 1 on this branch (fix/windows-tree-sitter-crlf at 80f07171). Both trees agree on the prefix, so the divergence is the trailing block:\n\nLF (correct, table closes at the blank line):\n pipe_table [2, 0] - [5, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pandoc_paragraph [6, 0] - [7, 0]\n pandoc_str [6, 0] - [6, 5]\n\nCRLF (buggy, table absorbs following paragraph):\n pipe_table [2, 0] - [7, 0]\n pipe_table_header [2, 0] - [2, 9] ...\n pipe_table_delimiter_row [3, 0] - [3, 9] ...\n pipe_table_row [4, 0] - [4, 9] ...\n pipe_table_row [6, 0] - [6, 5] <- SPURIOUS, should be a separate paragraph\n pipe_table_cell [6, 0] - [6, 5]\n pandoc_str [6, 0] - [6, 5]\n\nObserved Pandoc AST from Layer 2 (pampa default -t native), confirming the bug propagates past pampa input handling:\n\nLF: [Para [Str \"before\"], Table ... [body row [1,2]], Para [Str \"after\"]]\nCRLF: [Para [Str \"before\"], Table ... [body rows [1,2] AND [Plain \"after\"]]] <- no trailing Para\n\nConfirms pampa does NOT normalize line endings before feeding the grammar. End-user impact: any qmd document with CRLF endings, a pipe table, and following content produces structurally wrong output in every writer that consumes Pandoc AST.\n\nOpen design questions for the fix.\n\n1. Locate the bug in grammar.js. Likely candidates: newline character classes that match only \\n, or the external scanner (scanner.cc) handling of block boundary detection. Read both grammar.js and any external scanner before patching. Tree-sitter-markdown forks vary on this — confirm what our fork does versus what works.\n\n2. Upstream vs local fix. This grammar is forked from MDeiml/tree-sitter-markdown (or whichever upstream we track — confirm in tree-sitter.json or README). If upstream already fixes this, cherry-pick. If not, patch locally and consider an upstream PR.\n\n3. Test-corpus line-ending policy after the fix. Two viable strategies:\n a. Keep test/corpus/*.txt files materialized as CRLF on Windows checkout and rely on the fixed grammar to parse them identically. Tests then exercise CRLF on Windows and LF on Linux, which is useful coverage but creates a small risk that future grammar changes regress CRLF handling silently when only Linux CI runs.\n b. Pin test/corpus/*.txt to LF via .gitattributes (eol=lf for that subdirectory only) and add a separate Windows-only regression test that re-creates the fixtures with CRLF and asserts the parse trees match. More explicit, less coverage drift.\n\n The choice depends on whether we expect frequent grammar changes and whether ubuntu-only CI is sustainable. Recommend deciding before landing the grammar fix.\n\n4. Audit other CRLF patterns. The 5 failing pipe-table tests are the surface; there may be other constructs whose grammar paths assume \\n only. Grep grammar.js (and scanner.cc if present) for \\n usages and audit each one.\n\nReference. Investigation history and original framing in bd-ntnx (closed). Memory note q2-windows-verify-tests catalogues related Windows CRLF failures.","acceptance_criteria":"tree-sitter parse on matched CRLF and LF qmd inputs produces identical S-expression trees for pipe-table fixtures (Layer 1 reproducer diff is empty). pampa default native output is identical for the same matched inputs (Layer 2 reproducer diff is empty). All 5 originally-failing pipe-table tests under cd crates/tree-sitter-qmd/tree-sitter-markdown && tree-sitter test pass on Windows: Example 201 (GFM), Pipe table can precede content (two variants), Pipe table can follow content, Pipe table with blank-line caption. cargo xtask verify step 4 (tree-sitter test) passes on Windows. cargo nextest run --workspace and cargo xtask verify continue to pass on Linux CI (no regression). Decision recorded in commit message or PR description for upstream-vs-local fix and for test-corpus line-ending policy. Audit findings recorded for any other CRLF patterns discovered in grammar.js or scanner.cc. q2-windows-verify-tests memory note updated with PR link and resolution.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv","updated_at":"2026-05-04T13:45:00.482193500Z","closed_at":"2026-05-04T13:45:00.481818100Z","close_reason":"PR #139 merged 2026-04-30: fixed CRLF pipe-table line ending in scanner.c (typo fix at line 2259), added Rust regression test and xtask CRLF parity check","external_ref":"https://github.com/quarto-dev/q2/issues/138","labels":["tree-sitter","windows"],"dependencies":{"bd-ntnx:discovered-from":{"depends_on_id":"bd-ntnx","type":"discovered-from","created_at":"2026-04-27T14:26:53.718601600Z","created_by":"cderv"}},"comments":{"c-2vcbuybu":{"id":"c-2vcbuybu","author":"cderv","created_at":"2026-04-28T16:05:51Z","text":"Tomorrow's verification (next session pickup): (1) check PR #139 CI status — gh pr checks 139 --repo quarto-dev/q2; (2) if green, merge; (3) on merge, close bd-0gsj with PR link as the close reason; (4) flush and commit accumulated .beads/issues.jsonl from main repo (this session created bd-vxl8 and bd-picv, plus comments on bd-238o, bd-3pe8, bd-0gsj); (5) update q2-windows-verify-tests memory note status to fully resolved."},"c-swxf3f4l":{"id":"c-swxf3f4l","author":"cderv","created_at":"2026-04-29T16:25:17Z","text":"CRLF parity check landed in commit 8f61f587 on branch fix/windows-tree-sitter-crlf (PR #139). cargo xtask verify step 4 now re-runs tree-sitter test against a CRLF-converted corpus copy; 451/451 pass, regression-tested by reverting scanner.c (446/451, build fails). Awaiting PR merge to close."},"c-xjxgh7ir":{"id":"c-xjxgh7ir","author":"cderv","created_at":"2026-04-28T15:37:36Z","text":"PR #139 opened (https://github.com/quarto-dev/q2/pull/139). Layer 1 + Layer 2 reproducer diffs empty post-fix. tree-sitter test on Windows: 451/451 (was 446/451). Decision: local fix, not upstream — typo introduced on this fork in 79489c4e. Decision: no .gitattributes change for test corpus — fixed grammar parses LF and CRLF identically, so existing corpus tests both modes (LF on Linux, CRLF on Windows checkout). Audit: line 2259 was the only outlier; all other newline checks in scanner.c use paired '\\n' || '\\r'. Added Rust regression test pipe_table_crlf_matches_lf for cross-platform coverage."}}} +{"id":"bd-0jyl","title":"Source-info threading through listing markdown re-parse","description":"L3's ListingRenderTransform invokes pampa::readers::qmd::read on doctemplate output to obtain Pandoc blocks, then discards the fresh SourceContext. Diagnostics from that re-parse are collapsed into a single Q-12-10 host-page warning naming the listing id and first message — not threaded back to the host page's SourceContext.\n\nFor a proper design, a way is needed to merge the fresh SourceContext from the re-parse into the host page's SourceContext, *and* preserve the chain 'host YAML key → template substitution → markdown span' through to the diagnostic. Likely cuts across quarto-source-map, quarto-doctemplate, and the diagnostic-builder layer. Worth its own design session.\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D3 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T18:26:24.690377Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:24.690377Z","dependencies":{"bd-ml8z:discovered-from":{"depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:24.690377Z","created_by":"cscheid"}}} +{"id":"bd-0mji","title":"Phase D follow-up: SPA render-event hook + dep-graph filter regression tests","description":"Two related affordances needed once Phase D's dep-graph filter for re-render is implemented:\n\n1. **SPA render-event hook.** PreviewApp's render useEffect re-fires for every contentTick bump. Today this is invisible at the DOM when neither active-page content nor merged metadata change. A small test-only counter (window.__renderTicks or similar) would let Playwright assert 'this edit did/didn't trigger a re-render' for cases where the rendered output is identical.\n\n2. **Dep-graph filter regression tests.** Once Phase D filters re-renders against ProjectDependencyGraph, we need:\n - Active page re-renders when an edited sibling IS a dependency (positive case).\n - Active page does NOT re-render when an edited sibling is NOT a dependency (negative case — the savings).\n\nReframes the deferred Phase B.4 plan acceptance criterion 3 ('editing an unrelated sibling re-renders the active page only when there's a dep edge'). In Phase B the contract was relaxed to 'always re-renders' because no filter exists; Phase D restores the original strict contract.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4 (deferred criterion 3).","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid","updated_at":"2026-05-14T19:25:36.371752Z","closed_at":"2026-05-14T19:25:36.371611Z","close_reason":"Both items resolved: (1) window.__renderTicks render-event hook landed in D.3 (bd-kw93.9, commit 1ddcbeaf); (2) dep-graph filter regression tests landed in D.6 (bd-kw93.12, commit 7310d44b) — negative case in dep-graph-filter.spec.ts, positive case in the existing include-shortcode.spec.ts (Phase B.3).","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid"},"bd-mrx1:discovered-from":{"depends_on_id":"bd-mrx1","type":"discovered-from","created_at":"2026-05-13T21:11:41.646912Z","created_by":"cscheid"}}} +{"id":"bd-0pic6","title":"Support theme: {light, dark} dark-mode config (object form)","description":"TS Quarto supports a YAML-object form for 'theme:' in format.html, with 'light' and 'dark' keys whose values are theme-name + scss-file lists:\n\n format:\n html:\n theme:\n light: [cosmo, theme.scss]\n dark: [cosmo, theme-dark.scss]\n\nQ2 currently rejects this: 'Invalid theme configuration: theme must be a string or array of strings'. quarto-web uses this form, so it's the next blocker after bd-47w7o for a full quarto-web render.\n\nDiscovered after bd-47w7o (directory-resource recursive copy) landed and the render progressed past resource copying. To investigate: find where theme parsing happens in Q2 (search for 'Invalid theme configuration'), check TS Quarto behavior at external-sources/quarto-cli (light/dark theme spec), design the parsing + rendering path. The render-side work likely interacts with the existing SCSS resolution pipeline. Likely larger than a one-shot fix; may want a plan doc when picked up.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-21T21:51:40.488001Z","created_by":"cscheid","updated_at":"2026-05-21T21:51:40.488001Z","dependencies":{"bd-47w7o:discovered-from":{"depends_on_id":"bd-47w7o","type":"discovered-from","created_at":"2026-05-21T21:51:40.488001Z","created_by":"cscheid"}}} +{"id":"bd-0pm7a","title":"fix(preview): iframe src must be relative to support subpath deployment","description":"Q2DebugIframe and Q2PreviewIframe hard-code src='/q2-debug.html' and src='/q2-preview.html' (root-absolute). Vite is configured with base: './' so the rest of the build uses relative URLs. Locally and in Playwright the app is served at the host root, so the two are indistinguishable; when deployed under a subpath the iframe src resolves to the wrong origin path and the iframe loads a 404 / SPA shell, leaving the preview blank. Fix: drop the leading slash in both files.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T11:56:32.004803Z","created_by":"shikokuchuo","updated_at":"2026-05-21T12:11:14.743822Z","closed_at":"2026-05-21T12:11:14.743764Z","close_reason":"Dropped the leading slash on both iframe srcs (commit 843cd7c3). Subpath deployment verified locally."} +{"id":"bd-0tr6","title":"Website projects epic: multi-page sites with sidebars, shared resources, and hub-client integration","description":"Design and implement multi-page website projects for Quarto 2. Covers: typed static-document snapshots (PageSnapshot/DocumentProfile working name), pipeline resumability, ProjectType trait, website sidebars, scoped/relocatable artifact stores (site_libs), cross-doc link rewriting, sitemap/favicon/site-url, incremental rebuilds, and hub-client project rendering.\n\nMVP scope explicitly excludes: search, listings/RSS, aliases, announcements, analytics, 404, reader-mode, repo-actions, breadcrumbs, book project type, quarto preview, freeze.\n\nPlan: claude-notes/plans/2026-04-23-website-project-epic.md\n\nDesign decisions from initial conversation:\n- Snapshot is a typed serializable value produced at a pipeline checkpoint after MetadataMergeStage; downstream code consumes Vec<DocumentProfile>; user filters read but do not mutate.\n- Pipeline stages up to snapshot are resumable (cloneable) to avoid redundant execution across pass 1 (snapshot sweep) and pass 2 (per-file render).\n- ProjectType trait introduced now (website, default). Single-document renders go through DefaultProjectType.\n- Artifact stores scope-aware (Page vs Project) and relocatable; single-doc = project with implicit _quarto.yml.\n- Hub-client caches project nav state; renders active page with cached state. Design must leave room for Q2 'quarto preview' which will be a local hub-client instance.\n- Naming TBD in Phase 0 (DocumentProfile working name; user dislikes Page*/Metadata*).","status":"open","priority":1,"issue_type":"epic","created_at":"2026-04-23T18:42:28.206394Z","created_by":"cscheid","updated_at":"2026-04-23T18:42:28.206394Z"} +{"id":"bd-0ufq5","title":"Phase 2 — Hub middleware: Bearer extraction + audience allowlist + CSRF/Origin gating","description":"Land Bearer-auth support in crates/quarto-hub alongside the existing cookie path. TDD: write the 30-test set in crates/quarto-hub/tests/auth_bearer.rs first, then implement.\n\nTouch points: auth.rs (audience config, OidcClaims migration, azp/iat checks), server.rs (cookie extraction, Authenticated extractor, CSRF + WS-Origin gating).\n\nDual-credential 400 rule and full OIDC §3.1.3.7 azp logic are required. Sibling bug bd-XXXX tracks the dual-credential CVE test specifically.\n\nPlan §Phase 2: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-20T14:26:56.463684Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:38.345334Z","closed_at":"2026-05-20T21:22:38.345295Z","close_reason":"Phase 2 landed. AuthConfig.additional_audiences plumbed, OidcClaims gained aud/azp/iat, build_auth_state_from_parts added, extract_credential + CredentialKind + dual-credential 400 in server.rs, Authenticated carries credential_kind, CSRF/WS-Origin gated, audit emission via tracing::event!. 33 new integration tests + 7 lib tests pass; cargo xtask verify --skip-hub-build clean. See plan.","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:26:56.463684Z","created_by":"shikokuchuo"}}} +{"id":"bd-0wyo","title":"Server-precomputed other_metadata_html for default listing","description":"Q1's item-default.ejs.md iterates over fields *not* in the curated set ('title','image','image-alt','date','author','subtitle','description','reading-time','categories') and emits a <div class=\"metadata-value listing-{field}\">…</div> per such field. This is dynamic in EJS — there is no equivalent in doctemplate without server-side precomputation.\n\nL3 v1 ships the default listing with curated-fields-only output. This issue picks up the gap by adding an other_metadata_html string to the per-item TemplateValue::Map binding, computed server-side in the listing render transform. The built-in item-default.template gets one more interpolation site: $item.other-metadata-html$.\n\nSource-code TODO marker lands in crates/quarto-core/src/project/listing/templates/item-default.template at the otherFields gap location (added during L3).\n\nDiscovered while writing L3 (bd-ml8z) sub-plan; see D15 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-06T18:26:31.323613Z","created_by":"cscheid","updated_at":"2026-05-06T18:26:31.323613Z","dependencies":{"bd-ml8z:discovered-from":{"depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T18:26:31.323613Z","created_by":"cscheid"}}} +{"id":"bd-0xmt","title":"Phase A.0: Lift WASM JS bridge to @quarto/wasm-js-bridge workspace package","description":"Move hub-client/src/wasm-js-bridge/ to a new @quarto/wasm-js-bridge workspace package. Wire hub-client + q2-preview-spa + preview-renderer test configs to alias /src/wasm-js-bridge -> the package's src. Removes the cross-platform symlink/duplication risk for Phase A.3. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.0.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-13T16:53:11.353454Z","created_by":"cscheid","updated_at":"2026-05-13T17:07:44.781502Z","closed_at":"2026-05-13T17:07:44.781355Z","close_reason":"Bridge files moved to @quarto/wasm-js-bridge workspace package; consumers alias /src/wasm-js-bridge. Verified end-to-end (sass compile through bridge proven by hub-client test:wasm; cargo xtask verify 11/11). Commits ea1bb889 + changelog 043f65e1.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:11.353454Z","created_by":"cscheid"}}} +{"id":"bd-1066","title":"HTML comments lost during incremental writes","description":"HTML comments (<\\!-- ... -->) are dropped from the Pandoc AST during parsing. tree-sitter parses them as 'comment' nodes which become IntermediateUnknown and are silently removed. This causes comments to be lost when the incremental writer rewrites blocks containing comments. Block-level standalone comments survive as empty Para blocks (preserved via source spans on KeepBefore), but inline comments within paragraphs are completely gone.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-02-09T15:35:05.022976Z","created_by":"cscheid","updated_at":"2026-02-09T15:35:05.022976Z"} +{"id":"bd-11a1","title":"Automerge-backed project set storage","description":"Replace per-browser IndexedDB project list with a synced Automerge document. See claude-notes/plans/2026-03-31-automerge-project-set.md","status":"open","priority":1,"issue_type":"epic","created_at":"2026-03-31T20:37:29.036441Z","created_by":"cscheid","updated_at":"2026-03-31T20:37:29.036441Z"} +{"id":"bd-128x","title":"Slide renderer crashes on empty slides document","description":"When a document has format: q2-slides but no slide content (no headers, no title), parseSlides() returns an empty array. SlideAst then calls renderSlide(slides[0]) which is undefined, crashing on slide.type access. The fix should handle the empty slides case gracefully by showing an empty/placeholder slide. Plan: claude-notes/plans/2026-02-26-empty-slides-crash.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T15:13:14.778662Z","created_by":"cscheid","updated_at":"2026-02-26T16:34:51.200462Z","closed_at":"2026-02-26T16:34:51.200439Z","close_reason":"Fixed: guard renderSlide call and hide nav controls when slides array is empty"} +{"id":"bd-129m3","title":"Provenance follow-up: ValueSource anchor stamping for meta/var shortcodes","description":"Wires up the AnchorRole::ValueSource role (already defined in Plan 4's enum) so that meta/var shortcode resolutions carry a typed anchor pointing at where the value was defined (e.g., a key in _metadata.yml).\n\n**Today (Plan 4 + Plan 6 baseline):**\n- {{< meta footer >}} -> Generated { by: shortcode(\"meta\"), from: [Invocation -> token_si] }\n\n**After this issue:**\n- {{< meta footer >}} -> Generated { by: shortcode(\"meta\"), from: [Invocation -> token_si, ValueSource -> metadata_yml_si] }\n\nThe writer (Plan 7) keeps consulting invocation_anchor() only; ValueSource is diagnostic-only (\"hover the resolved value to see where it was defined\"). Doesn't affect round-tripping or attribution.\n\n**Blocker:** the metadata loader doesn't expose per-key source-info on merged metadata today. Each YAML key has source_info at parse time, but the merge step strips it. Threading it through requires extending the metadata value types to keep source_info alive past the merge.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-4-source-info-types.md §\"Deferred anchor role\"\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §\"ValueSource follow-up\"\n\n**Compatibility:** pure addition. AnchorRole::ValueSource already exists in Plan 4's enum from day 1. Plan 6's stamper gains conditional ValueSource emission for meta/var shortcodes whose values came from outside the active document.\n\n**Effort:** smaller than the Dispatch follow-up — self-contained (metadata loader + Plan 6 stamper). No new infrastructure crates.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T22:37:02.608131Z","created_by":"gordon","updated_at":"2026-05-21T22:37:02.608131Z","labels":["follow-up","provenance"]} +{"id":"bd-12fpz","title":"D4/D5: HTML writer emits odd/even and header row classes","description":"## What\n\n`write_table_row` in `crates/pampa/src/writers/html.rs:1490` emits bare `<tr>` for every row. Pandoc's reference HTML writer (which Q1 inherits) adds:\n\n- `<tr class=\"header\">` on header (thead) rows.\n- `<tr class=\"odd\">` / `<tr class=\"even\">` alternating on body rows.\n\n## Fix\n\nPass row index + is_header from the table-writing loop into `write_table_row` (it already gets `is_header`); add the class accordingly.\n\n## Tests (TDD)\n\nSnapshot test on a 3-row table (1 header + 2 body) showing:\n- header row: `<tr class=\"header\">`\n- first body row: `<tr class=\"odd\">`\n- second body row: `<tr class=\"even\">`\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D4, D5 sections — bundled because they share the same writer code path)","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T20:55:24.955808Z","created_by":"cscheid","updated_at":"2026-05-20T21:31:14.339774Z","closed_at":"2026-05-20T21:31:14.339617Z","close_reason":"Implemented in this commit: row classes (header/odd/even) emitted.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:24.955808Z","created_by":"cscheid"}}} +{"id":"bd-12vrr","title":"Callout default-title synthesizer + popup-menu callout-type switching (Plan 6 §B)","description":"Plan 6's audit identified crates/quarto-core/src/transforms/callout_resolve.rs:267 (default callout title 'Note'/'Tip'/'Warning'/...) as an AST synthesizer that today emits SourceInfo::default(). To bring it into the Generated shape Plan 6 establishes, it needs: (a) a new By::callout() constructor in quarto-source-map, (b) an atomicity decision (is_atomic_kind), (c) the fix at callout_resolve.rs:267, (d) a per-transform test. Deferred from Plan 6 because it was not enumerated in the plan body and requires the new By constructor + atomicity decision.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-22T16:19:01.484116Z","created_by":"gordon","updated_at":"2026-05-22T16:45:31.449690Z","dependencies":{"bd-129m3:related":{"depends_on_id":"bd-129m3","type":"related","created_at":"2026-05-22T16:19:13.342003Z","created_by":"gordon"}},"comments":{"c-gh26vk6d":{"id":"c-gh26vk6d","author":"Gordon Woodhull","created_at":"2026-05-22T16:45:31Z","text":"Why this matters beyond the audit fix: the React preview needs a UI affordance to **switch callout type** (Note → Tip → Warning → Important → Caution) via a popup menu on the callout block. For that to round-trip cleanly through Plan 7's writer, the default-title text (\"Note\", \"Tip\", …) must NOT be treated as user-editable Original content — otherwise typing-as-edit semantics would force the writer to materialize \"Note\" as literal text into source, even when the user only wanted to swap the type via the menu.\n\nThe `Generated { by: callout(), … }` stamping + the atomicity decision determine:\n\n1. **React-side**: whether the title region is gated read-only via Plan 2A's atomic check (so the user can't accidentally type into it; the menu is the only path to mutation).\n2. **Writer-side**: how a menu-driven type change serializes. The menu rewrites the Callout CustomNode's `plain_data` (e.g. `{\"type\": \"tip\"}`) and leaves the title-Generated either re-synthesized on next pipeline run or replaced with a fresh Generated whose `by.data` reflects the new type. Plan 7's let-user-win path handles the CustomNode rewrite naturally; the title region soft-drops on direct edits (Q-3-42-style).\n\nRecommend `is_atomic_kind = true` for `By::callout()`'s title-synthesizer use so the title is non-editable text and only menu-driven type changes mutate it. The popup-menu component lives in hub-client's React framework registry (post-Plan 2B); this beads owns the Rust-side provenance support that makes the round-trip behave.\n"}}} +{"id":"bd-140x","title":"Contribute samod fix upstream with pure-rust reproduction test","description":"Cherry-pick the NotFound race condition fix (431333f) from quarto branch to main on cscheid/samod fork, and write a pure-rust integration test in samod-core/tests/ that reproduces the bug independently of quarto-hub. The test should demonstrate that a document synced from a client to a DontAnnounce server is dropped during handle_load when pending_sync_messages are ignored. PR target: alexjg/samod.","status":"open","priority":1,"issue_type":"task","created_at":"2026-03-04T00:58:02.303737Z","created_by":"cscheid","updated_at":"2026-03-04T00:58:02.303737Z"} +{"id":"bd-14rer","title":"ExecuteResult.filters set by Knitr engine is never consumed downstream","description":"Workspace-wide grep for `result.filters` / `ExecuteResult.*filters` returns hits in tests, the Knitr write site, extension parsing, and a comment in capture-splice — but no production consumer.\n\nConcretely:\n- crates/quarto-core/src/engine/knitr/mod.rs:215 sets `filters: result.filters` from the R subprocess output (test fixture asserts `vec![\"rmarkdown/pagebreak.lua\"]`, knitr/types.rs:281).\n- crates/quarto-core/src/filter_resolve.rs only resolves filters from YAML `filters:` document metadata, not from ExecuteResult.filters.\n\nSo Knitr's pagebreak filter is silently dropped today. This also blocks any future engine (like a mermaid Lua-filter approach) that wants to declare filters dynamically.\n\nDecision needed: wire ExecuteResult.filters into the resolver, or remove the field if the architectural direction is different (e.g. all engine-side filters should be expressed as AST transforms instead).\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G1.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-28T13:45:45.986759Z","created_by":"cscheid","updated_at":"2026-05-28T13:45:45.986759Z","dependencies":{"bd-c6h96:discovered-from":{"depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:45.986759Z","created_by":"cscheid"}}} +{"id":"bd-159sr","title":"Verify @tip-foo crossref of callouts still works after class-vocabulary alignment","description":"The callout class-vocabulary fix (2026-05-22) reshaped\n\\`CalloutResolveTransform\\` output and added a defense-in-depth\nminimal-normalization. \\`CalloutTransform\\` still writes the\ncrossref triple (\\`ref_type\\`, \\`kind\\`, \\`identifier\\`) into\n\\`plain_data\\` for callouts whose id classifies (\\`callout.rs:236-241\\`),\nand the resolver now suppresses the screen-reader span when\n\\`ref_type\\` is present (correct behavior — the crossref-rendered\nprefix announces the type instead).\n\nVerify end-to-end:\n\n1. Render a doc with \\`::: {#tip-foo .callout-tip}\\` and \\`@tip-foo\\`\n elsewhere in the body.\n2. Check the rendered HTML:\n - The callout shows the type's display name (\\\"Tip\\\") in its\n title (default-injected, since no user title).\n - The body's \\`@tip-foo\\` resolves to the crossref-rendered text\n (e.g. \\\"Tip 1\\\" or whatever the locale specifies).\n - The hyperlink target is the callout's outer div id (#tip-foo).\n3. Confirm no screen-reader-only span is emitted on the callout\n (crossref prefix replaces it).\n4. Add a smoke-all fixture under \\`crates/quarto/tests/smoke-all/\\`\n if one doesn't already exist for this pattern.\n\nTracking item carried over from the 2026-05-22 plan's follow-up\nsection. P1 because a regression would silently break a feature\nsome users rely on.","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-26T13:44:11.453179Z","created_by":"gordon","updated_at":"2026-05-26T13:44:11.453179Z"} +{"id":"bd-15dw","title":"Navbar icon-only item enrichment tie-break","description":"Phase 3 enrichment fills navbar item.text from profile title only when text is None. An item that supplies icon but no text (common for social links) currently stays text-less. Confirmed intentional. Revisit if users ask for auto-text from titles even for icon-only items. See 2026-04-24-websites-phase-3.md §Follow-up beads.","status":"open","priority":4,"issue_type":"task","created_at":"2026-04-24T19:43:02.249186Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:02.249186Z","dependencies":{"bd-fqyg:discovered-from":{"depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:43:02.249186Z","created_by":"cscheid"}}} +{"id":"bd-18wn","title":"Fix file-locking test failures in quarto-hub on Windows","description":"2 storage tests fail because Windows uses mandatory file locking vs Unix advisory. File::create fails with sharing violation before try_lock_exclusive runs. Fix: use OpenOptions::new().write(true).create(true) instead of File::create, or map sharing violation error to HubAlreadyRunning. Affects test_storage_manager_prevents_double_lock and test_storage_manager_standalone_prevents_double_lock.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-03-20T13:36:06.424470600Z","created_by":"cderv","updated_at":"2026-03-20T13:36:06.424470600Z"} +{"id":"bd-195t","title":"Lua attribute-mutation: proxy tables so cb.attr.attributes[k]=v persists","description":"Quarto 2's Lua bridge returns fresh copies of `cb.attr` (and of `cb.attr.attributes`) on every read. In-place mutation like `cb.attr.attributes[\"k\"] = v` — the idiomatic Pandoc-Lua pattern — silently hits an ephemeral copy and is discarded. Surfaced while exercising Phase 3.5's filter-authored spans fixture (04-filter-authored-spans); the workaround there rebuilds the whole Attr with pandoc.Attr(...) and assigns as one value. Before we document the Lua-filter path to syntax highlighting as a user-facing feature, the idiomatic pattern must persist. See claude-notes/plans/2026-04-20-syntax-highlighting-phase-3.5.md 'Follow-up task: Lua attribute-mutation proxy'. Plan: claude-notes/plans/2026-04-21-lua-attr-mutation-proxy.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-21T17:19:19.121444Z","created_by":"cscheid","updated_at":"2026-04-21T17:19:19.121444Z"} +{"id":"bd-1c6x","title":"Incremental writer panics when original QMD lacks trailing newline","description":"The incremental writer (incremental_write_qmd WASM entry point) panics with 'byte index out of bounds' when the original QMD text doesn't end with a newline. The QMD reader internally pads input with \\n, producing source spans for the padded input, but incremental_write receives the unpadded string. Triggered by changing kanban card status when synced document text doesn't end with \\n. Plan: claude-notes/plans/2026-02-11-incremental-writer-trailing-newline-bug.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-02-11T20:48:21.313234Z","created_by":"cscheid","updated_at":"2026-02-11T21:07:59.477860Z","closed_at":"2026-02-11T21:07:59.477843Z","close_reason":"Fixed: added ensure_trailing_newline normalization in incremental_write and compute_incremental_edits. The QMD reader internally pads input with newline, so source spans reference the padded length. The incremental writer now pads its input to match, then strips the padding from results. 6 new tests added, all 6408 workspace tests pass."} +{"id":"bd-1d3e","title":"Fix CRLF test failures in quarto-doctemplate on Windows","description":"8 tests fail because template files are checked out as CRLF on Windows but tests compare against LF strings. Options: .gitattributes to force LF on template files, normalize CRLF in compile_from_file at parser.rs:225, or normalize in test assertions. Affects test_partial_resolution and 7 pandoc_equiv_tests.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-03-20T13:35:56.689880800Z","created_by":"cderv","updated_at":"2026-05-05T16:08:19.594867400Z","external_ref":"https://github.com/quarto-dev/q2/issues/157"} +{"id":"bd-1d6io","title":"annotated-qmd: source-tracking off-by-one in regenerated examples","description":"Two TS tests in ts-packages/annotated-qmd fail after regenerating example JSONs with the current pampa writer:\n\n1. substring-invariant.test.ts: 'substring invariant - links.qmd: inline code' — expects substring(125, 133) to be '`x = 5`' but gets ' `x = 5`' (extra leading space).\n2. block-types.test.ts: 'div-attrs.json - Div with attributes conversion' — key source text ' custom-key' has a leading space; the assertion 'should be a valid attribute key' fails because the substring extracted from source includes a preceding space.\n\nBoth fail in the same shape on the surface: the writer-recorded start offset for these tokens is 1 character too early, capturing the preceding whitespace. Whether they share a single root cause has not been confirmed.\n\n## Why this surfaces now (not on main)\n\nThe failures only surface when example fixtures (ts-packages/annotated-qmd/examples/*.json) are regenerated against the current pampa. The committed fixtures (regenerated 2025-10-24, commit 2b2337be by Carlos) predate the pampa changes that introduced the offset drift. cargo nextest run --workspace doesn't touch the fixtures — they're inert JSON loaded by the TS test suite (loadExample(...) in test/document-converter.test.ts and others) — so main's CI has been green throughout while the underlying writer behavior drifted.\n\nPlan 7f Phase 5 (wire-format rename attrS->a, sourceInfoPool->p) requires regenerating the fixtures because the TS code post-rename reads inline.a / astContext.p — old-format fixtures (attrS, sourceInfoPool) would be unreadable. Regeneration is a Phase-5 necessity. The regenerated fixtures capture current pampa writer behavior, including the off-by-one, and that's what trips these tests.\n\nPhase 5 itself only renamed JSON keys — no offset computation was touched. So Phase 5 is the messenger, not the cause.\n\n## Suspected commit for failure #1 (inline code) — NOT CONFIRMED\n\nPlausible candidate: commit 38e889ad (Carlos, 2026-05-24, 'tree-sitter qmd: allow line breaks inside inline code spans and inline math (bd-ilv8p)'). The commit substantially reworked code-span tokenization in the tree-sitter scanner + grammar — SOFT_LINE_ENDING absorb logic, pandoc_soft_break aliasing, an extract_code_span_text helper. It's the only recent commit between 2b2337be (2025-10-24) and HEAD that touches code-span tokenization.\n\nHypothesis: the rework widened the pandoc_code_span tree-sitter node by one byte to the left, to include the preceding-space character. Since Inline::Code's source_info is computed via node_source_info_with_context(node, context) at crates/pampa/src/pandoc/treesitter_utils/code_span_helpers.rs:171 — taking the whole node's byte range — that left-edge widening shows up directly as a 1-char-wider Code source range.\n\nNOT YET BISECTED. The hypothesis is consistent with the failure shape but a clean bisect would confirm or refute it.\n\n## Suspected commit for failure #2 (div key-source) — UNKNOWN\n\nThe div-attrs failure is in a different code path (attribute key-source recording during div parsing). The \"leading space byte gets included\" pattern matches surface-level, but I have NOT verified that this is the same code path or the same root cause. It could be:\n* the same scanner-side absorb pattern leaking into adjacent attr/key-source tokens, OR\n* a separate regression introduced by a different commit, OR\n* older than 2025-10-24 and only now visible because the regenerated fixture happens to record a real source range where the old fixture had something stale.\n\nA clean bisect against the example regen is the cheapest way to find out.\n\n## Repro\n\n cd ts-packages/annotated-qmd\n npm test\n\nFailures: 2 of 156 tests fail. The other 154 pass — including substring-invariant tests on Str / Space / Header / BulletList / ordered-list / link target / link text — which means the off-by-one is not pervasive; it's localized to specific token boundaries.\n\n## Fix direction\n\n1. Bisect each failure independently against the example fixture regen. Use a known-good baseline of pampa from 2025-10-24 (around commit 2b2337be) and walk forward.\n2. If failure #1 lands on 38e889ad, audit pandoc_code_span node-range computation in the scanner — likely the absorb-leading-space behavior needs to start the node at the opening backtick.\n3. If failure #2 lands on a different commit (likely), the fix is independent.\n4. Add a CI lane that regenerates the annotated-qmd example fixtures (or at minimum diffs the writer output against them) so the next time a tree-sitter scanner change drifts the output, this catches at the PR level instead of accumulating until the next forced regen.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-06-01T15:58:10.144959Z","created_by":"gordon","updated_at":"2026-06-01T18:26:49.621585Z","comments":{"c-9upid7i4":{"id":"c-9upid7i4","author":"Gordon Woodhull","created_at":"2026-06-01T18:26:49Z","text":"Investigation complete (worktree bd-1d6io, plan: claude-notes/plans/2026-06-01-bd-1d6io-investigation.md). VERDICT: ready — two distinct scanner-side bugs, both accidental leading-whitespace absorption; Rust writers correct. #1 (inline code): REGRESSION in 2025-10-30/31 inline-parser rewrite (good@2b2337be r:[126,133]; bad@5cc1a849 'code spans'); CODE_SPAN_START token absorbs preceding inline whitespace; 38e889ad REFUTED (parent 5d35218d already bad). #2 (div custom-key): ORIGINAL DEFECT since >=2025-08-06; 2nd+ key_value_key/KEY_SPECIFIER token absorbs inter-pair space; committed [252,262] never matched live pampa even at fixture birth d6230301 (live [251,262]). CI stayed green: insta json snapshots lack inline-Code/multi-kv cases; pandoc-match-corpus is source-range-blind; annotated-qmd JSON is static/hand-regenerated and inert to nextest. FIX: scanner fixes both tokens; add CI-resident byte-offset regression tests (TDD); add xtask verify guard diffing live writer over examples/*.qmd vs committed JSON."}}} +{"id":"bd-1e6a5","title":"AttrSourceInfo: caption-attr merge into table breaks positional alignment","description":"When the qmd parser merges caption attributes into a table's Attr at:\n\n- crates/pampa/src/pandoc/treesitter_utils/section.rs:85-113\n- crates/pampa/src/pandoc/treesitter_utils/postprocess.rs:1483-1496\n\nit calls table.attr.2.insert(k, v) and table.attr_source.attributes.push(...). If a caption attribute key already exists on the table (e.g. both have id or class), LinkedHashMap::insert updates the existing entry in place while push always appends — leaving attr.2.len() and attr_source.attributes.len() out of sync. The positional alignment AttrSourceInfo.attributes[i] = (key_src, val_src) for the i-th entry in Attr.2 is broken whenever caption + table attribute keys overlap.\n\n**Discovered while reviewing Plan 6's theorem.rs::extract_name_attr fix** (claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet). Plan 6 mitigates with a runtime guard but the underlying bug pre-dates Plan 6.\n\n**Fix sketch:**\nFor each (k, v, key_src, val_src) being merged:\n- If table.attr.2.contains_key(&k), find its position, overwrite both attr.2's value AND attr_source.attributes[pos] in lockstep.\n- Else, append to both.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet (positional-alignment safeguards)\n- crates/quarto-pandoc-types/src/attr.rs:27-32 (AttrSourceInfo definition)","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-22T06:44:51.585690Z","created_by":"gordon","updated_at":"2026-05-22T06:44:51.585690Z","labels":["bug","provenance"]} +{"id":"bd-1elkd","title":"Brand-aware favicon: read logo.small from _brand.yml when website.favicon unset","description":"Q1 falls back to brand.light.favicon when website.favicon is unset. Now that Q2 has Brand data via quarto-brand, wire it into the favicon emission path. Brand::favicon() already returns the small logo's path. Likely closes bd-97yc. Q1 reference: external-sources/quarto-cli/src/project/types/website/website.ts:185-205.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:07.428762Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:07.428762Z","dependencies":{"bd-97yc:related":{"depends_on_id":"bd-97yc","type":"related","created_at":"2026-05-21T02:31:07.428762Z","created_by":"cscheid"}}} +{"id":"bd-1g5f","title":"Make default sync server configurable via environment variable","description":"Allow build-time configuration of the default Automerge sync server URL via VITE_DEFAULT_SYNC_SERVER environment variable. Currently hardcoded to wss://sync.automerge.org in routing.ts and ProjectSelector.tsx. Needed for internal deployments with private sync servers so beta users don't have to manually enter a custom URL.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-04T21:26:45.230188Z","created_by":"cscheid","updated_at":"2026-02-04T21:48:29.989386Z","closed_at":"2026-02-04T21:48:29.989369Z","close_reason":"Implemented: DEFAULT_SYNC_SERVER now reads from import.meta.env.VITE_DEFAULT_SYNC_SERVER with fallback. Commit 3ed1c1bf."} +{"id":"bd-1hdz","title":"Title-prefix home-page carve-out (Q1 stem==index parity)","description":"Q1 only injects website.title as pagetitle for the home page (stem == \"index\" && offset === \".\") when both title and pagetitle are absent. Phase 7 takes the broader \"any untitled page falls back to website title\" rule (Decision 4). Revisit if a real fixture surfaces a problem. Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.707126Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.707126Z","created_by":"cscheid"}}} +{"id":"bd-1hwd","title":"Phase 5: Inline splicing for incremental writer","description":"Implement inline-level splicing in the incremental writer. When a reconciliation plan involves changes that neither add nor remove nodes that create newline characters (SoftBreak, LineBreak), indentation boundaries are preserved and inline changes can be spliced without rewriting the entire indentation boundary. This is a critical optimization for the common case of text edits within paragraphs inside lists and block quotes. Plan: claude-notes/plans/2026-02-10-inline-splicing.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-10T15:09:50.520536Z","created_by":"cscheid","updated_at":"2026-02-10T16:37:28.833053Z","closed_at":"2026-02-10T16:37:28.833034Z","close_reason":"Implemented inline splicing for incremental writer. All phases complete (5a-5g): safety checks, source span utilities, inline coarsening/assembly, comprehensive property tests, integration. 124 tests across 4 test files. 6394 workspace tests pass.","dependencies":{"bd-2t4o:discovered-from":{"depends_on_id":"bd-2t4o","type":"discovered-from","created_at":"2026-02-10T15:09:50.520536Z","created_by":"cscheid"}}} +{"id":"bd-1inj0","title":"Provenance follow-up: code-block decoration synthesizers (Plan 6 §C)","description":"Plan 6's audit identified crates/quarto-core/src/transforms/code_block_generate.rs and code_block_render.rs as a smaller audit pass for code-block decoration synthesizers (filename labels, captions). Deferred from Plan 6 because scope was bounded to the explicitly-enumerated transforms. Likely needs a By::code_block_chrome() (or similar) constructor and a small set of per-transform tests.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-22T16:19:08.284554Z","created_by":"gordon","updated_at":"2026-05-22T16:19:13.446418Z","dependencies":{"bd-129m3:related":{"depends_on_id":"bd-129m3","type":"related","created_at":"2026-05-22T16:19:13.446359Z","created_by":"gordon"}}} +{"id":"bd-1jnb","title":"q2-demos vite build fails: imports /src/wasm-js-bridge/cache.js","description":"The vite build of q2-demos/hub-react-todo and q2-demos/kanban fails with:\n\n [vite]: Rollup failed to resolve import \"/src/wasm-js-bridge/cache.js\"\n from \"crates/wasm-quarto-hub-client/pkg/wasm_quarto_hub_client.js\"\n\nThe wasm-bindgen-generated JS glue references an absolute path that\nresolves correctly when vite roots at hub-client/ (which has\nsrc/wasm-js-bridge/cache.js), but the demos do not have that file.\n\nThe demos likely need either:\n - their own copy of the cache.js bridge module, or\n - vite alias config that resolves the path to hub-client's copy, or\n - the wasm crate's #[wasm_bindgen(module = \"...\")] path changed to\n something portable.\n\nSurfaced while getting the Hub-Client E2E Tests workflow to run on CI\n(branch chore/e2e-ci). The workflow now builds only ts-packages +\nhub-client to avoid this failure; the demos remain broken at build\ntime. See claude-notes/ for session notes if needed.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-10T23:16:12.128803Z","created_by":"gordon","updated_at":"2026-05-10T23:16:12.128803Z"} +{"id":"bd-1kly","title":"Complete FootnotesTransform for reference-location: block/section","description":"FootnotesTransform at crates/quarto-core/src/transforms/footnotes.rs:99-105 currently no-ops for reference-location: block and section, leaving raw Inline::Note nodes in the AST with a stale comment claiming \"Pandoc handles this\". pampa's HTML writer (crates/pampa/src/writers/html.rs:806-817) also doesn't handle them correctly — it emits <sup>[N]</sup> where N is the length of the note content array, not a sequential number, with a TODO acknowledging the gap.\n\nNeither layer numbers Notes correctly for these configs. The work is missing in both places.\n\nThe proper fix is to extend FootnotesTransform to handle block/section: number all Notes in document order (already done for document-mode) and emit per-block or per-section footnote sections at the right boundary instead of a single document-end section.\n\nDiscovered while reviewing q2-preview Plan 2B (claude-notes/plans/2026-05-04-q2-preview-plan-2b-builtin-components.md) — q2-preview's Note.tsx falls back to JS-side numbering with body-in-tooltip rendering for these configs as a temporary v1 measure. When this beads is closed and the upstream transform handles all four reference-location values uniformly, q2-preview's Note.tsx fallback can be deleted.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-09T20:40:28.166910Z","created_by":"gordon","updated_at":"2026-05-09T20:40:28.166910Z"} +{"id":"bd-1kor9","title":"Implement callout output for non-HTML formats: revealjs, typst, latex","description":"TS Quarto's \\`customnodes/callout.lua\\` registers per-format\nrenderers for Bootstrap HTML, EPUB/RevealJS, GitHub Markdown,\nLaTeX, Typst, and a default fallback (\\`callout.lua:135-220\\`).\n\nq2 currently only wires up the Bootstrap HTML renderer via\n\\`CalloutResolveTransform\\`. Other formats either render callouts\nas plain Div blocks (no styling) or aren't supported at all.\n\nOut of scope for the 2026-05-22 class-vocabulary alignment; tracked\nas a follow-up. Each format will likely want its own dedicated\nresolve-like transform.\n\nReference: \\`/Users/gordon/src/quarto-cli/src/resources/filters/\ncustomnodes/callout.lua:130-220\\`.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-26T13:44:16.175550Z","created_by":"gordon","updated_at":"2026-05-26T13:44:16.175550Z"} +{"id":"bd-1kvf","title":"Incremental writer loses blank line between front matter and first block","description":"When toggling a checkbox via the React todo demo, the blank line between the YAML front matter closing --- and the first div (::: {#todo}) disappears. Root cause: metadata_structurally_equal() uses ConfigValue PartialEq which includes source_info, causing false inequality between re-parsed original and JSON-deserialized new AST. Secondary latent bug: the metadata rewrite path doesn't emit the gap separator. Plan: claude-notes/plans/2026-02-08-incremental-writer-metadata-gap.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-08T16:08:02.508695Z","created_by":"cscheid","updated_at":"2026-02-08T16:30:27.327884Z","closed_at":"2026-02-08T16:30:27.327868Z","close_reason":"Fixed: content-only metadata comparison + gap preservation on rewrite","labels":["bug","incremental-writer"]} +{"id":"bd-1mbj","title":"build_q2_preview_transform_pipeline_is_subset_of_html drift: HTML pipeline gained listing-* stages not in q2-preview subset","description":"Test at crates/quarto-core/src/pipeline.rs:1942 fails on feature/q2-preview-work HEAD. The HTML pipeline added listing-generate, listing-render, categories-sidebar, listing-feed-stage, listing-feed-link stages without updating the q2-preview subset (or the test). Surfaced during Plan 2A item 11 implementation; pre-existing on the branch (verified by stashing 2A changes — failure persists). Decide: include these in q2-preview's subset, exclude them by name in the assertion, or update the test's expected subset.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-09T16:21:16.410360Z","created_by":"gordon","updated_at":"2026-05-09T18:11:42.819490Z","closed_at":"2026-05-09T18:11:42.819459Z","close_reason":"Fixed by 0887a3fa (refactor q2-preview pipeline to deny-list construction) — listing-* stages now flow into q2-preview by default since the subset is HTML-pipeline minus an explicit exclusion list, not a hand-maintained allow-list. The test was deleted with the assertion infrastructure.","labels":["bug","plan2a-discovered"]} +{"id":"bd-1oxt","title":"Project ZIP export from hub-client","description":"Add exportProjectAsZip() to quarto-sync-client that walks all project files and returns a Uint8Array of ZIP bytes. Add an Export ZIP button to the PROJECT tab in hub-client. See plan: claude-notes/plans/2026-02-11-project-zip-export.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-11T19:56:41.539365Z","created_by":"cscheid","updated_at":"2026-02-11T19:56:41.539365Z","labels":["hub-client","quarto-sync-client"]} +{"id":"bd-1pwy8","title":"Wire SassError::UnknownTheme through the structured diagnostic system","description":"Follow-up discovered after the bd-l26u6 epic merged. SassError::UnknownTheme (raised by BuiltInTheme::from_str when a theme name is not recognized) still surfaces as the span-less, code-less 'Error: SASS error / Unknown theme: default' line — the theme_diagnostic fallback path.\n\nReproducer: q2 render external-sources/quarto-web — emits both Q-14-1 (coalesced, from _quarto.yml:686) AND the bare 'Unknown theme: default' line (from docs/output-formats/html-themes.qmd:11, which has 'theme: default' in its document frontmatter).\n\nFix follows the bd-pgczr pattern:\n- Add location: Option<SourceInfo> to SassError::UnknownTheme.\n- Add SassError::with_location(self, SourceInfo) -> Self helper so the next variant migration is trivial.\n- Propagate value.source_info.clone() at the ThemeSpec::parse call sites in extract_theme_specs (crates/quarto-sass/src/config.rs:455, :465).\n- Allocate Q-14-2 'Unknown theme name' in error_catalog.json under the existing 'theme' subsystem.\n- Extend theme_diagnostic::sass_error_to_parse_error to render UnknownTheme as a structured DiagnosticMessage with Q-14-2 + source span.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T15:40:16.192572Z","created_by":"cscheid","updated_at":"2026-05-22T16:00:33.283018Z","closed_at":"2026-05-22T16:00:33.282854Z","close_reason":"UnknownTheme now flows through quarto-error-reporting as Q-14-2. Verified end-to-end: pandas-acting-on-data.qmd:7:12 'default' produces a proper ariadne block. No more plain-text SASS error fallback in quarto-web.","labels":["diagnostics","theme"],"dependencies":{"bd-l26u6:related":{"depends_on_id":"bd-l26u6","type":"related","created_at":"2026-05-22T15:40:16.192572Z","created_by":"cscheid"}}} +{"id":"bd-1qk5","title":"Inline grammar: post-codespan apostrophe trips Q-2-7 (Unclosed Single Quote)","description":"The inline grammar's smart-quote rule treats `'` immediately after a\nclosing-backtick (code span boundary) as an *opening* single quote,\neven when followed by letters as in a possessive. Real Pandoc treats\nthe same construct as a possessive and emits no error. As a result,\ncommon technical writing patterns trip Q-2-7:\n\n `setAst`'s callback → FAIL (Q-2-7)\n `Para`'s rendering → FAIL\n `framework/Ast.tsx`'s → FAIL\n `<AssetManifestContext>`'s → FAIL (the angle brackets are not the\n trigger — backticks alone suffice)\n\nThis has tripped the changelogRender.wasm.test.ts at least twice:\n- 0c78b1a4 (2026-05-08): \"fix(hub-client): rewrite changelog 2026-05-08\n entry to clear Q-2-7 parse error\" — diagnosis blamed `<Tag>` HTML-\n like content; the angle brackets are coincidental.\n- d7d7e063 (2026-05-10): same trigger pattern in Plan 2B Phase 1/2\n changelog entries; rewrote in plain prose.\n\n## Empirical scope\n\n| Pattern | Result | Why |\n|------------------------------------|--------|----------------------------------|\n| `` `code`'s gate `` | FAIL | post-codespan `'` promoted |\n| `` `code`'foo bar `` | FAIL | same |\n| `` `code` 's gate `` | FAIL | whitespace between doesn't help |\n| `` `code`\\'s gate `` | PASS | escaped apostrophe |\n| `` word's gate `` | PASS | letter-letter → possessive |\n| `` `code`'s and `other`'s pair `` | PASS | two opens form a balanced pair |\n| `` `code`'s and word's pair `` | FAIL | only one promoted-to-opening |\n\nReproducer: see /tmp/q27[a-e].qmd patterns in the discovery session\nor just `printf \"x \\\\\\`code\\\\\\`'s\\\\n\" | cargo run --bin pampa -- -t json -i -`.\n\n## Proper fix\n\nIn `tree-sitter-markdown-inline`'s grammar, extend the rule for\nopening single quote so a `'` immediately after a closing-backtick\n(or, more generally, after any inline-end token) is treated as a\npossessive when the next character is a letter — same heuristic\nthat already saves `word's`. Pandoc proper does this; the smart-\nquote algorithm there is \"an apostrophe between letters or after a\nmarkup boundary that resolves to letters is a possessive.\"\n\nAfter regenerate + build, add a test case to the inline grammar's\ntest corpus and a passing case to resources/error-corpus\ndemonstrating that `` `code`'s `` no longer fires Q-2-7.\n\n## Workarounds available today\n\n1. Pair them deliberately within the same block (two close-backtick\n apostrophes form a smart-quote pair).\n2. Backslash-escape: `` `code`\\'s ``.\n3. Rephrase to put the apostrophe inside a word (`the setAst\n callback's behavior`).\n4. bd-kk0a's writer-side escape (separate issue, AST→qmd direction).\n\n## Related\n\n- bd-kk0a: writer-side escape for unbalanced apostrophes in JSON\n → qmd round-trip. Option-4-of-this-issue (parser fix) would\n obviate part of bd-kk0a's escape work.\n- crates/pampa/snapshots/error-corpus/text/006.snap, 009.snap:\n current Q-2-7 examples for the parser-state mapping table at\n resources/error-corpus/_autogen-table.json:18686.\n- Discovery transcript: changelog Q-2-7 thread in\n feature/q2-preview implementation session 2026-05-10.","notes":"Pandoc-comparison findings posted to GH #221 (https://github.com/quarto-dev/q2/issues/221): symmetric notAfterString/notBeforeAlphanum predicates + speculative-balance fallback. Pandoc shares the same fundamental ambiguity but doesn't error — silently mis-quotes. Proposed fix scope: 'be at least as good as Pandoc' on the scope-table cases; a stricter fix (bias open-after-inline-end toward apostrophe) is harder design work.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-10T06:44:33.152101Z","created_by":"gordon","updated_at":"2026-05-20T21:13:53.979030Z","dependencies":{"bd-kk0a:related":{"depends_on_id":"bd-kk0a","type":"related","created_at":"2026-05-10T06:44:33.152101Z","created_by":"gordon"}}} +{"id":"bd-1s21","title":"Span writer: drop {} for empty attributes, use [ ] for empty span","description":"Change the QMD writer so that a Span with empty content and empty attributes is written as '[ ]' (space between brackets) instead of '[]{}'. This improves readability for the checkbox use case in hub-react-todo.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-08T15:37:32.152755Z","created_by":"cscheid","updated_at":"2026-02-08T15:45:48.708881Z","closed_at":"2026-02-08T15:45:48.708865Z","close_reason":"Implemented: spans with empty attrs drop {}, empty span writes as [ ]. All 6247 tests pass."} +{"id":"bd-1tl09","title":"Code-block decorations (filename, copy, fold, line-numbers, annotations, preview)","description":"Port Quarto 1's code-block decorations to Quarto 2 using the existing Generate/Render transform pattern. One format-agnostic CodeBlockGenerateTransform extracts a typed CodeBlockDecoration from the AST; one CodeBlockRenderTransform per format emits the format-specific markup.\n\nFeatures in scope (sized as phases in the plan):\n1. Filename header ({r filename=\"x.R\"})\n2. Code copy button (clipboard.js + scaffold)\n3. Code folding ({code-fold: true|show}, <details>)\n4. Line numbers ({code-line-numbers: true|\"3,5-7\"})\n5. Code preview iframe ({code-preview=\"foo.qmd\"})\n6. Code annotations (# <N> markers + following ordered list)\n\nArchitecture, phase breakdown, open questions, and Q1 audit summary in:\n claude-notes/plans/2026-05-19-code-block-features.md\n\nOut of scope (separate plans): LaTeX/PDF rendering, Reveal.js-specific line-number ranges, annotation tooltip interaction modes.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-19T19:28:00.077936Z","created_by":"cscheid","updated_at":"2026-05-19T19:28:00.077936Z"} +{"id":"bd-1ui2","title":"Suppress auto-generated header IDs in QMD writer roundtrips","description":"Headers like '## project {.a-class}' roundtrip as '## project {#project .a-class}', adding an auto-generated ID that wasn't in the source. Similarly, '## project' becomes '## project {#project}'. The writer should detect auto-generated IDs (AttrSourceInfo.id is None) and omit them when they match what auto_generated_id() would produce. Plan: claude-notes/plans/2026-02-10-suppress-auto-header-ids.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-02-11T15:07:48.060023Z","created_by":"cscheid","updated_at":"2026-02-11T16:05:08.293864Z","closed_at":"2026-02-11T16:05:08.293837Z","close_reason":"Implemented. Auto-generated header IDs are now suppressed in QMD writer output. All 6394 workspace tests pass."} +{"id":"bd-1uky","title":"New file templates from project _quarto-hub-templates directory","description":"Allow users to create new files from project-specific templates stored in _quarto-hub-templates directory. Templates are .qmd files with template-name metadata. The New File dialog shows a dropdown selector populated from available templates.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-12T20:19:14.894114Z","created_by":"cscheid","updated_at":"2026-02-12T20:19:14.894114Z"} +{"id":"bd-1ul3","title":"Apply assert_filtered_subset drift helper to build_analysis_transform_pipeline","description":"Plan 1 (`claude-notes/plans/2026-05-04-q2-preview-plan-1-pipeline.md` §\"Resolved decisions / Drift-protection test\") originally promised a follow-up applying `assert_filtered_subset` to `build_analysis_transform_pipeline`. Scope has narrowed since that promise.\n\n## Background\n\nThe original drift helper (`assert_filtered_subset` in commit 60658a4e) was removed when q2-preview's pipeline was flipped to deny-list construction (`build_q2_preview_transform_pipeline` is now `build_transform_pipeline` filtered by `Q2_PREVIEW_TRANSFORM_EXCLUDED`; `build_q2_preview_pipeline_stages` is similarly built from the HTML stage list with `Q2_PREVIEW_STAGE_EXCLUDED`). The drift mode the helper guarded against is now impossible by construction for q2-preview.\n\n`build_analysis_transform_pipeline` (`crates/quarto-core/src/pipeline.rs:470`) is a different beast: a hand-written 6-transform sequence (sugar transforms + `crossref-index`) — *not* a deny-list of the full HTML transforms. Today it is protected only by:\n- the doc-comment at `pipeline.rs:454-469` (\"**Deliberately omitted**\" rationale),\n- a hand-rolled ordering test (`test_build_analysis_transform_pipeline_ordering`, `pipeline.rs:1392`) that asserts sparse position relations.\n\nBecause it's a hand-written allow-list (not a deny-list), the full HTML pipeline can grow new transforms relevant to outline analysis without anyone noticing — there's no test that fires when that happens.\n\n## Work\n\nThis issue is now exclusively about the analysis pipeline. Two paths:\n\n**Path A (cheaper)** — add a `seq_diff_eq` / `assert_seq_diff_eq` helper to the test module, expressing the analysis pipeline as `build_transform_pipeline` *minus* the exclusions documented at `pipeline.rs:454-469`. This treats the analysis pipeline as a deny-list at test time even though the runtime construction stays as an explicit allow-list.\n\n**Path B (more work, more upside)** — flip `build_analysis_transform_pipeline` itself to deny-list construction (mirroring what was just done to q2-preview), with `ANALYSIS_TRANSFORM_EXCLUDED` as a `const &[&str]`. The unknown-name validator pattern (see q2-preview tests in `pipeline.rs`) replaces the assertion. This makes drift impossible by construction.\n\nPath B is preferred if the analysis pipeline really does want to be defined relative to the HTML pipeline (today it skips render-shape transforms, which is an HTML-pipeline-relative concept). Path A is the right choice if there's reason to keep analysis as a hand-written allow-list (e.g. its 6-transform shape is small enough that listing them is clearer than subtracting from HTML's 30+).\n\nThe doc-comment at `pipeline.rs:454-469` enumerates the deliberate omissions; the exclusion-list candidates are derivable from it. Verify each name against actual `Transform::name()` strings — the unknown-name validator catches typos / renames.\n\n## Acceptance\n\nEither:\n- (Path A) New test in the `tests` module calls a deny-list-style assertion on `build_analysis_transform_pipeline`. Adding a new transform to `build_transform_pipeline` that isn't documented as either included or excluded in analysis trips the test.\n- (Path B) `build_analysis_transform_pipeline` rewritten as `build_transform_pipeline(...).retain_excluding(ANALYSIS_TRANSFORM_EXCLUDED)`. Existing `test_build_analysis_transform_pipeline_ordering` either becomes redundant (deny-list construction preserves order trivially) or stays for the cross-relation check. Unknown-name validator added.\n\n## Notes\n\nThe naming question — if Path A is chosen and a helper is added: `assert_seq_diff_eq` was discussed (sequence difference `A - B = C` is the formal operation). See conversation around the deny-list flip for the naming rationale.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-08T01:29:14.526011Z","created_by":"gordon","updated_at":"2026-05-09T17:46:11.628226Z"} +{"id":"bd-1vlw8","title":"Implement quarto use brand scaffolding command","description":"Q1 has 'quarto use brand' at src/command/use/commands/brand.ts that scaffolds a _brand.yml. Q2's quarto-project-create crate is the analogous home. Low priority — manual editing works fine.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-21T02:31:31.081057Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.081057Z"} +{"id":"bd-1wxq","title":"Diagnostic popups clipped by navbar when near top/bottom of editor","description":"Monaco diagnostic hover popups get clipped by the top navbar (and potentially the bottom edge) because the editor container uses overflow:hidden. When a diagnostic appears on a line near the top of the editor, the hover popup extends above the editor-main container and gets cut off. The fix should ensure the popup is shifted vertically to stay within visible bounds, rather than changing z-order.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-02-11T17:59:16.576579Z","created_by":"cscheid","updated_at":"2026-02-11T17:59:16.576579Z"} +{"id":"bd-1xph","title":"Tree-sitter splits paragraph at line starting with * (emphasis or strong)","description":"Same class as bd-af1e. The scanner's line-break handler at scanner.c:2286-2291 and 2371-2376 excludes '*' from soft-line-break candidates whenever it appears at the start of a continuation line. But '*' only opens a block in specific contexts:\n- '* ' followed by space → list marker\n- '*** ' or longer with whitespace/eol → thematic break\n- otherwise → inline emphasis ('*emph*') or strong ('**strong**'), which should soft-break\n\nVerified pampa-vs-pandoc divergence:\n foo bar\n *emph* baz → pampa: 2 paragraphs, pandoc: 1 with SoftBreak + Emph\n **strong** baz → pampa: 2 paragraphs, pandoc: 1 with SoftBreak + Strong\n\nWhy this matters (severity sibling of bd-af1e): the asterisk IS the syntax for inline emphasis/strong. A user CANNOT work around the bug with backslash escaping (\\\\*emph\\\\* renders literally as '*emph*'). Underscore alternatives (_emph_, __strong__) work correctly already because '_' is not in the exclusion list, but many users prefer asterisks.\n\nBy contrast, '-', '+', '#', and digits at line start CAN be worked around via backslash escape (\\\\-text, \\\\#hashtag, \\\\123abc render as plain text starting with the punctuation), so we are deferring those.\n\nFix approach (same as bd-af1e — peek-count): when first_lookahead == '*', advance through consecutive asterisks. Then check what follows:\n- whitespace/eol after a single '*' → list marker (interrupt)\n- whitespace/eol after 3+ '*' → thematic break (interrupt) \n- anything else → inline (allow soft break)\n\nReference implementation: bd-af1e fix in scanner.c:2263-2308 (commit 274547af). The peek-without-mark_end + STATE_MATCHING-fallback pattern from that fix should generalize directly. See claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md.\n\nTest the fix doesn't break: '* item' (list opens), '*** ' (thematic break), '**foo**' at line start (inline strong), and '*foo*' / '**foo**' as continuation lines (soft break).","status":"closed","priority":1,"issue_type":"bug","assignee":"cscheid","created_at":"2026-04-30T18:45:50.725551Z","created_by":"cscheid","updated_at":"2026-04-30T18:56:04.698163Z","closed_at":"2026-04-30T18:56:04.698013Z","close_reason":"Fixed: extended bd-af1e peek-count pattern to '*' at line start. Single '*' followed by ws/eol → list marker (interrupt); >=3 '*' followed by ws/eol → thematic break (interrupt); otherwise inline emph/strong → soft break. Tree-sitter test 462/462 pass; workspace 8125/8125 pass; pampa output matches pandoc.","dependencies":{"bd-af1e:related":{"depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:45:50.725551Z","created_by":"cscheid"}}} +{"id":"bd-205v6","title":"Flaky proptest: reconciliation_preserves_structure_full_ast","description":"On 2026-05-26, while running cargo xtask verify on the CoarsenedEntry self-contained refactor (commit pending on feature/provenance), the proptest property_tests::reconciliation_preserves_structure_full_ast in quarto-ast-reconcile failed with shrunken input cc 8f798bbfabf9a12269dc90aa13188f685afe8cbf6f4acb2da01f9bff1af93158. The failure was reproducible with the saved regression seed but did not reproduce with fresh seeds (re-running cargo nextest without the proptest-regressions/lib.txt file passed 9656/9656). Test passed against unmodified feature/provenance HEAD as well. Not caused by the pending refactor — the only code changes in that session are in pampa and quarto-error-reporting, neither of which is exercised by apply_reconciliation. The failing message: 'Result should be structurally equal to after' at crates/quarto-ast-reconcile/src/lib.rs:1242. Need to investigate: (1) regenerate the saved seed and inspect the AST shape; (2) determine whether the shape exposes a real apply_reconciliation bug or whether the structural_eq_blocks comparison has a false-negative; (3) commit the regression seed once the bug is fixed (or after determining it's expected behavior with an updated assertion).","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-26T12:01:51.810903Z","created_by":"gordon","updated_at":"2026-05-26T12:01:51.810903Z"} +{"id":"bd-217g","title":"Build headless sync testing infrastructure in quarto-sync-client","description":"Extend quarto-sync-client with a headless test harness for programmatic sync server testing. Should support: (1) creating projects against a sync server URL without a browser, (2) disconnect/reconnect cycles, (3) verifying document presence and content after reconnection, (4) starting/stopping hub and TS sync servers programmatically, (5) protocol-level tracing for debugging. This pays dividends for every future sync-related bug or feature. Plan: claude-notes/plans/2026-03-03-hub-sync-missing-docs.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-03T23:05:32.421813Z","created_by":"cscheid","updated_at":"2026-03-03T23:05:32.421813Z","dependencies":{"bd-33qc:related":{"depends_on_id":"bd-33qc","type":"related","created_at":"2026-03-03T23:05:32.421813Z","created_by":"cscheid"}}} +{"id":"bd-21gu","title":"qmd writer: missing @ escape in link text causes citation re-parse","description":"From issue #150 (item 1): When a link text contains an escaped @ like `[\\@jjallaire](url)`, the qmd writer outputs the link text without re-escaping the @. Round-tripping turns the Str into a Cite. Repro:\n\n printf 'See [\\\\@jjallaire](https://github.com/jjallaire/) for details.\\n' | cargo run --bin pampa -- -t qmd\n See [@jjallaire](https://github.com/jjallaire/) for details.\n\nReporter notes there are likely other cases where escaping is needed; this is the one they saw. Plan in claude-notes/plans/ to follow.","notes":"Plan: claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md\nRoot cause: crates/pampa/src/writers/qmd.rs:1226 escape_markdown omits @\nFix: lookahead-based escape of @ when followed by alnum/_/{\nBug also reproduces outside link context (any Str starting with @<ident>).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T00:01:48.216570Z","created_by":"cscheid","updated_at":"2026-05-01T00:32:59.278601Z","closed_at":"2026-05-01T00:32:59.278440Z","close_reason":"Fixed in escape_markdown: always escape @ in Str bodies. Phase 2 audit of writer-escape gaps also identified { and } as same class; both fixed in this change. Position-dependent escapes (:, unbalanced ' \", line-start list markers 1./-/+) deferred to bd-kk0a. See claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md."} +{"id":"bd-21q16","title":"Spike: explore contenteditable patterns for q2-preview Pandoc/Quarto React components","description":"Investigation/spike. Survey idiomatic React approaches for making text-bearing Pandoc/Quarto element components in ts-packages/preview-renderer (Str, Para, Header, Strong, etc.) editable via contenteditable. Initial scope: every element with text. Deliverable: a research note in claude-notes/research/ with 2-4 concrete approaches (with pros/cons), a small proof-of-concept on one approach, and a recommendation. Branch: feature/contenteditable-spike.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-22T05:53:04.231514Z","created_by":"gordon","updated_at":"2026-05-22T05:53:18.549583Z"} +{"id":"bd-233j","title":"Hub-Client E2E logs are flooded with YAMLWarning [TAG_RESOLVE_FAILED] !str","description":"Playwright e2e runs produce hundreds of warnings of the form:\n\n (node:NNNNN) [TAG_RESOLVE_FAILED] YAMLWarning: Unresolved tag: !str at line 14, column 12:\n - [!str \"<pre class=\\\"sourceCode toml\\\"\",\n ^^^^\n\nThe yaml npm library is encountering explicit !str tags it doesn't have\na resolver for. It falls back to treating the value as a string, so tests\nkeep running — but the noise drowns out useful output.\n\nSource of the warning: some fixture or generated YAML emits !str-tagged\nscalars (looks like syntax-highlighted HTML being serialized into YAML).\nFix is either to register a custom tag resolver for !str, or change the\nemitter to use plain quoted strings.\n\nDiscovered while getting hub-client-e2e.yml workflow to run on CI\n(branch chore/e2e-ci). Not a test failure cause, just log noise.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-10T23:50:06.274679Z","created_by":"gordon","updated_at":"2026-05-10T23:50:06.274679Z"} +{"id":"bd-238o","title":"Port 3 known pampa Windows fixes from quarto-markdown","description":"3 fixes from quarto-markdown are proven but not yet applied in q2: (1) write_safe_string missing backslash-r escape in native.rs:14 (f8968d7), (2) CRLF normalization in test file reads (eb6d1e0), (3) path separator normalization in JSON writer json.rs:1843 (50256f3). Cannot verify until pampa is compilable on Windows (v8 exclusion resolved).","status":"open","priority":3,"issue_type":"task","created_at":"2026-03-20T13:36:17.010374400Z","created_by":"cderv","updated_at":"2026-04-28T13:07:13.060345200Z","comments":{"c-17dgpsvx":{"id":"c-17dgpsvx","author":"cderv","created_at":"2026-04-28T13:07:13Z","text":"Now verifiable on Windows since v8 rlib unavailability was resolved (2026-03-23). Confirmed 2026-04-28 via cargo nextest -p pampa: failures observed in pampa::test unit_test_snapshots_native, unit_test_snapshots_json, test_html_writer, test_json_writer, unit_test_corpus_matches_pandoc_markdown, and test_metadata_source_tracking::test_metadata_source_tracking_002_qmd. Symptoms match the 3 unported quarto-markdown fixes (write_safe_string \\r escape, CRLF normalization in test reads, JSON writer path separator). Ready to port and verify."}}} +{"id":"bd-2ag1c","title":"Consider excluding bootstrap-js and clipboard-js stages from q2-preview","description":"BootstrapJsStage (added in bd-4eyf) and ClipboardJsStage (added in bd-j1trh) are in the q2-preview pipeline by default because Q2_PREVIEW_STAGE_EXCLUDED only names math-js, render-html-body, apply-template. Worth checking whether that's the intent.\n\nBoth stages are gated #[cfg(not(target_arch = \"wasm32\"))], so the hub-client (WASM) preview never sees them. Native q2-preview does run them.\n\nTheir WASM-exclusion rationale (bootstrap_js.rs:48-55, clipboard_js.rs:45) is that the hub-client iframe reinitializes on every render tick, wiping any state held by Bootstrap components. That argument applies just as well to native q2-preview, which also targets the iframe.\n\nBoth stages mutate only ctx.artifacts; neither touches doc.ast.meta or doc.ast.blocks. The downstream consumer that turns js:* artifacts into <script> tags is ApplyTemplateStage, which q2-preview already excludes. Net effect: on native q2-preview these stages register JS artifacts that nothing reads.\n\nQuestion: should Q2_PREVIEW_STAGE_EXCLUDED also list 'bootstrap-js' and 'clipboard-js'?\n\nFor exclusion:\n- Matches the WASM HTML pipeline.\n- Removes orphan artifact registration on native q2-preview.\n\nAgainst:\n- The deny-list framing at pipeline.rs:1170 says q2-preview opts a stage out only when there's a concrete reason. These stages are deterministic and harmless; the case for excluding them is tidiness, not correctness.\n- If a future non-iframe q2-preview renderer wants to consume those artifacts, the exclusion would have to be undone.\n\nContext: surfaced during Plan 3 (idempotence verification) review on 2026-05-20. Plan 3's hash test is unaffected either way — these stages don't write to the hashed surface — so this is filed separately rather than bundled into Plan 3.\n\nReferences:\n- crates/quarto-core/src/pipeline.rs:355 — Q2_PREVIEW_STAGE_EXCLUDED\n- crates/quarto-core/src/stage/stages/bootstrap_js.rs:48-55\n- crates/quarto-core/src/stage/stages/clipboard_js.rs:45\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-21T16:49:30.611239Z","created_by":"gordon","updated_at":"2026-05-21T16:49:30.611239Z"} +{"id":"bd-2c8rg","title":"D2: HTML table emits Bootstrap 'caption-top table' classes","description":"## What\n\nEvery `Block::Table` should have CSS classes `caption-top` and `table` in its rendered HTML output (matches Quarto 1 / Bootstrap convention).\n\n## Approach (chosen in plan)\n\nNew pipeline stage `HtmlTableClassTransform` in `crates/quarto-core/src/stage/stages/` that augments `Block::Table.attr.1` (class vec) with `caption-top` and `table` if missing. Stage runs only for HTML output formats; preserves round-trip qmd writer (writer does not see Quarto-added classes since classes are added post-AST sanitization for HTML output only).\n\nRationale for stage (vs writer hack): preserves separation of concerns — HTML writer renders what's in the AST; format-specific class augmentation happens in a stage. Mirrors TS Quarto's `quarto-bootstrap-table.lua` filter pattern.\n\n## Tests (TDD)\n\n1. Unit test on the transform: input table with no classes → output has `caption-top table`. Running transform twice doesn't duplicate (idempotent).\n2. Unit test: input table with existing `my-class` → output has `my-class caption-top table` (preserves user classes, dedupes).\n3. End-to-end render test against `tables.qmd` fixture → produced HTML contains `<table class=\"caption-top table\">`.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D2 section)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-20T20:54:58.806604Z","created_by":"cscheid","updated_at":"2026-05-20T21:18:46.028499Z","closed_at":"2026-05-20T21:18:46.028305Z","close_reason":"Implemented in 987bdc9f via TableBootstrapClassTransform in FINALIZATION phase. Q1 markup parity for <table> classes achieved (still needs Bootstrap CSS — D7).","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:54:58.806604Z","created_by":"cscheid"}}} +{"id":"bd-2ercw","title":"whitespace_re regex recompiles per inline-processing call in native_visitor","description":"crates/pampa/src/pandoc/treesitter.rs:606 declares `let whitespace_re: Lazy<Regex> = Lazy::new(|| Regex::new(r\"\\s+\").unwrap());` as a FUNCTION-LOCAL. The Lazy wrapper is pointless when local — a fresh Lazy is built (and \\s+ recompiled on first touch) on every call to this per-node inline-processing function.\n\nEvidence: samply profile of full q2 render of claude-notes/qmd-plans (565 files) attributes ~5% of ALL samples to the Thompson NFA compiler / Utf8State construction (regex::Regex::new), 100% under native_visitor's closure. See claude-notes/plans/2026-06-01-render-perf-profiling.md.\n\nFix: hoist to a module-level static (LazyLock<Regex> or once_cell Lazy). Must land before any Pass-2 parallelization, otherwise every worker thread recompiles it per node.\n\nTDD: add a regression guard (e.g. a test/bench asserting the regex is shared / compiled once, or a micro-benchmark over the corpus). Verify end-to-end via q2 render wall-time before/after.","notes":"FIXED. Hoisted whitespace_re to module-level static WHITESPACE_RE in crates/pampa/src/pandoc/treesitter.rs. Added regression test test_whitespace_re_compile_once (asserts \\s+ compiles <=1x via WHITESPACE_RE_COMPILE_COUNT). Buggy compiled \\s+ 20806x over the 565-file corpus; fixed compiles 1x.\n\nPerf (median-of-5, release): isolated parse path -11.5% serial (2822->2496ms), -9.9% at 16 threads (391.6->352.7ms). End-to-end q2 render ~-24% (4720->3540ms) — render parses each file twice (Pass1 profile + Pass2 render) so the per-parse cost is paid 2x. Profile: regex-compile self-time 14.27%->0.02%, total CPU samples -17%.\n\nBonus finding: parse path parallelizes 7.1x on 16 threads with zero lock contention — confirms bd-3gj56 (parallelize Pass 2) is unblocked post-#247. Results in claude-notes/plans/2026-06-01-render-perf-profiling.md.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-06-01T14:45:03.449547Z","created_by":"cscheid","updated_at":"2026-06-01T15:13:56.742855Z","closed_at":"2026-06-01T15:13:56.742722Z","close_reason":"Hoisted whitespace_re to module static; regression test + perf-harness driver added; ~24% end-to-end render speedup, regex-compile self-time 14.3%->0.02%. Full cargo xtask verify green.","labels":["perf"]} +{"id":"bd-2gc9","title":"Nested tight lists incorrectly marked as loose (Para instead of Plain)","description":"In process_list() at crates/pampa/src/pandoc/treesitter.rs:183-192, multi-block list items with at least one paragraph are unconditionally marked as loose. This is wrong: a list item containing [Paragraph, BulletList] (e.g., '* foo\\n * bar') has no blank line between blocks and should remain tight. The CommonMark spec says a list is loose only when items are separated by blank lines or contain two block elements WITH A BLANK LINE between them.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-13T22:49:14.652871Z","created_by":"cscheid","updated_at":"2026-02-13T23:05:58.650439Z","closed_at":"2026-02-13T23:05:58.650417Z","close_reason":"Fixed: detect blank lines via tree-sitter block_continuation spans in process_list_item, propagate through IntermediateListItem"} +{"id":"bd-2gkx","title":"Kanban: New card creation button with form","description":"Add a 'New Card' button that opens a form with: title (required), type dropdown (feature/milestone/bug/task), optional deadline with date picker, optional status. Default creation date to today. Extend addCard() in astHelpers.ts to support deadline and status. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-11T18:32:46.896753Z","created_by":"cscheid","updated_at":"2026-02-11T18:39:33.119846Z","closed_at":"2026-02-11T18:39:33.119829Z","close_reason":"Implemented - new card form with type, status, and deadline"} +{"id":"bd-2h6x","title":"Slide thumbnails show in outline pane for non-slide documents","description":"The useSlideThumbnails hook runs unconditionally for all documents, generating thumbnails even for regular HTML documents. PreviewRouter detects format: q2-slides but doesn't communicate the format back to Editor.tsx. Fix: add onFormatChange callback from PreviewRouter so Editor can conditionally generate thumbnails. Plan: claude-notes/plans/2026-02-26-slide-thumbnails-conditional.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-26T15:04:39.650792Z","created_by":"cscheid","updated_at":"2026-02-26T15:10:26.512270Z","closed_at":"2026-02-26T15:10:26.512246Z","close_reason":"Fixed: slide thumbnails now conditional on format: q2-slides"} +{"id":"bd-2jwk","title":"Example Quarto 2 website projects for end-to-end feature testing","description":"Created 8 example Quarto 2 website projects under examples/websites/ that exercise each feature from the website epic (bd-0tr6). Each project demonstrates one aspect (sidebar manual/auto/nested, navbar+footer, shared site_libs/, site-metadata, incremental rebuilds, hub preview) with a README plus prose embedded in the qmd files. User-driven, not wired into CI. Plan: claude-notes/plans/2026-04-29-website-examples.md. Closed in commit 3629169b. Surfaced bd-swpy (closed by aa50d29e).","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid","updated_at":"2026-04-29T15:12:10.360266Z","closed_at":"2026-04-29T14:17:12.186716Z","close_reason":"All eight example projects built and verified end-to-end via 'q2 render' (08-hub-preview is a manual browser recipe). Surfaced bd-swpy (sidebar/navbar/footer href non-relativization in subdirectories). Plan: claude-notes/plans/2026-04-29-website-examples.md.","dependencies":{"bd-0tr6:related":{"depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid"},"bd-tr81:related":{"depends_on_id":"bd-tr81","type":"related","created_at":"2026-04-29T13:58:09.151620Z","created_by":"cscheid"}}} +{"id":"bd-2kt7f","title":"annotated-qmd: source-tracking off-by-one in regenerated examples","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-06-01T15:58:16.516338Z","created_by":"gordon","updated_at":"2026-06-01T15:58:39.818426Z","closed_at":"2026-06-01T15:58:39.818407Z","close_reason":"Duplicate of bd-1d6io"} +{"id":"bd-2mxo","title":"Metadata materialization drops source_info provenance","description":"MergedConfig::materialize() in quarto-config/src/materialize.rs loses source provenance that pampa's YAML parser correctly provides:\n- Map container source_info replaced with heuristic/default (lines ~121-161)\n- Map entry key_source always set to SourceInfo::default() (line ~132)\n- Array container source_info uses only last item (lines ~109-113)\n\nScalar values are preserved correctly. Affects error reporting for any metadata-related diagnostics after the merge stage. The code has an explicit comment acknowledging the key_source loss: 'We lose key source info during materialization.'\n\nPre-existing since commit 955bc326 (2025-12-07, 'config merging in'). Not blocking Plan 0 but degrades the YAML frontmatter Concat piece in the QMD writer's SourceInfo output.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-20T15:52:16.644685Z","created_by":"gordon","updated_at":"2026-04-20T15:52:16.644685Z"} +{"id":"bd-2njja","title":"Upgrade @playwright/test to >=1.60.0 and drop the Node 24.15.0 pin","description":"The Hub-Client E2E workflow currently pins Node to 24.15.0 (PR #249) to dodge a yauzl extraction-hang regression in Node >=24.16 that hangs 'playwright install chromium' at 100% with Playwright <1.60. The CORRECT, durable fix is to upgrade @playwright/test from ^1.50.0 (locked 1.58.0) to >=1.60.0, which contains the upstream fix (microsoft/playwright#40747, issue #40724) and is compatible with Node 24.16+/26.\n\nScope:\n- Bump @playwright/test to ^1.60.0 in hub-client/package.json; refresh package-lock.json.\n- Remove the 'node-version: 24.15.0' pin in .github/workflows/hub-client-e2e.yml (restore to '24' and delete the explanatory comment).\n- Chromium goes 145 -> 148 (1.59=147), so the pixel-comparison VISUAL-REGRESSION baselines will shift. Regenerate them via the workflow_dispatch 'recreate-all-snapshots' path (baselines must be generated on the Linux runner, not locally) and review the snapshot diffs per the CLAUDE.md snapshot-review rules.\n- Verify a full green e2e run (functional + visual) before merge.\n\nRefs: PR #249 (interim pin), microsoft/playwright#40724 / #40747.","status":"open","priority":2,"issue_type":"task","created_at":"2026-06-01T15:37:57.663402Z","created_by":"gordon","updated_at":"2026-06-01T15:37:57.663402Z"} +{"id":"bd-2olu","title":"Hub MCP Server: automerge project access for AI agents","description":"Design and implement an MCP server that allows AI coding agents (Claude Code, Codex, etc.) to read and write files in Quarto Hub projects via automerge sync, without requiring filesystem access. Plan: claude-notes/plans/2026-03-13-hub-mcp-server-design.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-03-13T23:38:33.161278Z","created_by":"cscheid","updated_at":"2026-03-13T23:38:33.161278Z"} +{"id":"bd-2qjnd","title":"Listing config: parse_sort scalar arm should accept PandocInlines via as_plain_text","description":"Q2's listing parse_sort (crates/quarto-core/src/project/listing/config.rs:692) has inconsistent handling between its scalar and array arms:\n\n- Scalar arm matches only ConfigValueKind::Scalar(Yaml::String(s)) — fails on PandocInlines.\n- Array arm uses .as_plain_text() — handles PandocInlines fine.\n\nRepro: in a listing block, write 'sort: code' (unquoted). Q2 metadata parsing turns it into PandocInlines('code'), parse_sort falls through to the _ arm, and emits Q-12-3 'sort: must be a string, array of strings, or false'. Workaround: 'sort: [code]' uses the array path and works.\n\nFix: change line 695 from 'ConfigValueKind::Scalar(Yaml::String(s)) => vec![parse_one_sort_key(s)]' to use 'value.as_plain_text()' like the array branch.\n\nDiscovered while authoring docs/errors/index.qmd as part of bd-nvlxn (error-docs foundation, parent bd-94x8a). The workaround in that file should be removed once this is fixed.\n\nRelated: sort-ui only accepts boolean in Q2 (line 452); Q1's 'list of allowed sort fields' form is not implemented. That's a separate feature gap, not this bug.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-22T19:15:20.730868Z","created_by":"cscheid","updated_at":"2026-05-22T19:15:20.730868Z","labels":["diagnostics","listing"],"dependencies":{"bd-nvlxn:discovered-from":{"depends_on_id":"bd-nvlxn","type":"discovered-from","created_at":"2026-05-22T19:15:20.730868Z","created_by":"cscheid"}}} +{"id":"bd-2quy","title":"[websites] Audit Stage<->RenderContext bridge completeness","description":"During Phase 2, AstTransformsStage was missing 'project_index' in its StageContext->RenderContext bridge, silently disabling the sidebar Render-step .qmd->.html rewrite. Integration tests caught it; unit tests (which built their own RenderContext) did not. Audit the bridge code to verify every field that exists on both sides is transferred correctly — and consider structural guards (e.g. a test that compares field sets, or a derive-style helper to replace manual field-by-field copying).","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T17:52:49.777311Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:49.777311Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:49.777311Z","created_by":"cscheid"}}} +{"id":"bd-2rbk","title":"Improve pampa test skip behavior when Pandoc is absent","description":"4 pampa tests hard-assert instead of gracefully skipping when Pandoc is not available. Should use test skip or conditional compilation so cargo xtask test runs cleanly without Pandoc. Low priority since pampa is currently excluded from Windows test compilation due to v8.","status":"open","priority":3,"issue_type":"task","created_at":"2026-03-20T13:36:13.451656600Z","created_by":"cderv","updated_at":"2026-03-20T13:36:13.451656600Z"} +{"id":"bd-2rv8","title":"Hub-client console debug API (window.quartoDebug for read/write/rerender)","description":"Enabler ticket. Add a window-global debug API to hub-client so an agent (or developer) can read/write project files and trigger renders from the DevTools console without going through the menu UI.\n\nSketched surface:\n window.quartoDebug = {\n project: () => ProjectInfo,\n listFiles: () => string[],\n readFile: (path: string) => string,\n writeFile: (path: string, contents: string) => Promise<void>,\n rerender: () => Promise<void>,\n getActiveFile: () => string,\n setActiveFile: (path: string) => void,\n lastRenderResponse: () => unknown,\n vfsList: (prefix?: string) => string[],\n vfsRead: (path: string) => Uint8Array | null,\n };\n\nConstraints:\n- writeFile goes through the same Automerge mutation path the editor uses, so sync is exercised.\n- Dev-only by default (import.meta.env.DEV) with an opt-in escape hatch for prod debugging — see Q5 in plan.\n- Don't bypass auth / project ownership.\n- Confirmed greenfield: no existing window.* assignments in hub-client/src/.\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Enabler section). Suggested to land first since it speeds up debugging the other three children.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-01T13:58:38.836884Z","created_by":"cscheid","updated_at":"2026-05-01T13:58:38.836884Z","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:38.836884Z","created_by":"cscheid"}}} +{"id":"bd-2s6j","title":"Kanban: Horizontal rows instead of columns","description":"Change the board layout from vertical status columns to horizontal rows. Each status group becomes a full-width row with cards flowing left-to-right. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-11T18:32:33.985420Z","created_by":"cscheid","updated_at":"2026-02-11T18:34:29.136267Z","closed_at":"2026-02-11T18:34:29.136249Z","close_reason":"Implemented - board now uses horizontal rows"} +{"id":"bd-2t4o","title":"Incremental QMD writer for localized AST-to-string updates","description":"Design and implement an incremental writer for pampa that converts localized AST changes into localized string edits. When an AST node changes, only the corresponding portion of the QMD string should be rewritten, preserving the rest of the original source text. Key challenge: markdown's indentation-sensitive constructs (block quotes, lists) mean inner node source spans are non-contiguous, requiring a 'loosened incrementality' approach.","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-07T18:27:04.058233Z","created_by":"cscheid","updated_at":"2026-02-07T18:27:04.058233Z","dependencies":{"bd-3lsb:discovered-from":{"depends_on_id":"bd-3lsb","type":"discovered-from","created_at":"2026-02-07T18:27:04.058233Z","created_by":"cscheid"}}} +{"id":"bd-2vl0","title":"L9 follow-up: Q-12-15 dedup (per-project, not per-host)","description":"v1 emits Q-12-15 once per ListingFeedStageTransform invocation (= once per host page that has feeds configured + missing site-url). For a project with N feed-configured hosts, the user sees N Q-12-15 warnings. Consolidate to once per project — track an already_warned: bool on a project-scoped state, or dedupe via ctx.diagnostics post-hoc.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:33:37.197930Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:37.197930Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:37.197930Z","created_by":"cscheid"}}} +{"id":"bd-2w80","title":"Investigate CSL manifest test failure after rebase","description":"quarto-citeproc::csl_conformance::csl_validate_manifest fails. Was previously resolved as stale artifact but reappeared after rebasing windows-and-improvement on main. May be a lockfile mismatch that needs regeneration or a genuine regression from main.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-03-20T13:36:09.944920300Z","created_by":"cderv","updated_at":"2026-03-20T13:36:09.944920300Z"} +{"id":"bd-2x4l","title":"Kanban demo app (hub + incremental writer)","description":"Minimal Kanban-style project tool backed by QMD files, demonstrating bidirectional editing via React components + incremental writer. Each card = level-2 header + body. React provides views (board, milestones) while the document stays human-readable. Plan: claude-notes/plans/2026-02-10-kanban-demo.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-02-10T20:54:43.438414Z","created_by":"cscheid","updated_at":"2026-02-10T20:54:43.438414Z","labels":["demo","hub"]} +{"id":"bd-31lk","title":"Div transforms (definition-list, list-table) not applied to JSON input","description":"The transform_definition_list_div and transform_list_table_div transforms are applied in postprocess() which is only called from the qmd reader path. When the input format is json, the code bypasses postprocess() and these transforms are never applied. This means divs with 'definition-list' or 'list-table' classes are not converted to their proper AST representations when processing JSON input.\n\nPlan: claude-notes/plans/2026-02-05-div-transforms-json-input.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-05T14:54:35.844209Z","created_by":"cscheid","updated_at":"2026-02-05T21:16:48.523250Z","closed_at":"2026-02-05T21:16:48.523226Z","close_reason":"Fixed: Added transform_divs() function and applied it in the JSON reader. Tests added and passing."} +{"id":"bd-33qc","title":"Hub sync server loses documents on project creation","description":"When using the hub binary as a standalone automerge sync server, newly created projects lose some automerge documents on reconnection. Creating a project in hub-client and then reconnecting shows missing file documents. This does not happen with the TypeScript automerge-repo-sync-server. Likely root cause: samod Repo::create() returns before storage I/O completes, and there is no flush/drain API to wait for pending writes. Plan: claude-notes/plans/2026-03-03-hub-sync-missing-docs.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-03-03T23:05:26.668905Z","created_by":"cscheid","updated_at":"2026-03-03T23:05:26.668905Z"} +{"id":"bd-34wy","title":"Phase 2: Fork runtimelib and add venv-aware kernelspec discovery","description":"Fork runtimed/runtimelib to cscheid/runtimelib at the v2.0.0 tag. Add data_dirs_with_jupyter_paths() that augments data_dirs() with paths from ask_jupyter() (jupyter --paths --json). Add list_kernelspecs_with_jupyter_paths() and update find_kernelspec to use it. Extend RuntimeError::KernelNotFound with searched_paths: Vec<PathBuf>. Match upstream conventions (cfg-gating, thiserror style, tests parallel to test_list_kernelspec_jsons).\n\nTDD per CLAUDE.md: failing test first for each behaviour.\n\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 2)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T15:49:47.470140Z","created_by":"cscheid","updated_at":"2026-05-04T16:08:33.192757Z","closed_at":"2026-05-04T16:08:33.192617Z","close_reason":"Fork branch feat/venv-kernelspec-discovery in cscheid/runtimed at commit 6647651. Added data_dirs_with_jupyter_paths(), list_kernelspecs_with_jupyter_paths(), find_kernelspec_with_jupyter_paths(), extended RuntimeError::KernelNotFound with searched_paths: Vec<PathBuf>. 18 tests pass (10 baseline + 8 new). cargo fmt --check and cargo clippy -- -D warnings clean. Branch not pushed yet (per CLAUDE.md no-push policy).","labels":["feature","jupyter"],"dependencies":{"bd-fu0l:discovered-from":{"depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:47.470140Z","created_by":"cscheid"}}} +{"id":"bd-352bh","title":"q2 preview diagnostics overlay: include ariadne source-context snippet (bd-b9kzg follow-up)","description":"Today's PreviewDiagnosticsOverlay shows the compact one-line summary for each warning (Line N: [code] title - problem). User asks for the rich ariadne-rendered source-context snippet (matching hub-client's overlay screenshot) so the preview surface looks like the q2 render stdout output.\n\nPath: DiagnosticMessage::to_text(Some(&source_context)) produces the snippet today (see ParseError::render in crates/quarto-core/src/error.rs:32-38). Pass-1 failures already flow through to the overlay via failure.error → result.error → overlay <pre>. Warnings don't carry a rendered text yet — the JsonDiagnostic transport shape (lifted into quarto-error-reporting/src/json.rs under bd-b9kzg) doesn't have a field for it.\n\nScope:\n(1) Add rendered: Option<String> to JsonDiagnostic and populate in diagnostic_to_json by calling diag.to_text(Some(ctx)).\n(2) Mirror the field on the TS Diagnostic interface.\n(3) Update PreviewDiagnosticsOverlay to render rendered as a <pre> (with stripAnsi) when present, keeping the compact list as fallback for diagnostics without locations / source context.\n(4) End-to-end verify against docs/ — the [Q-13-4] body-link warning should look like the user's q2 render stdout output, with the ╭─[ ... ]─╯ box around the offending line.\n\nPlan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-ariadne.md (to be drafted).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid","updated_at":"2026-05-21T19:04:06.677144Z","closed_at":"2026-05-21T19:04:06.676974Z","close_reason":"Implemented: ariadne source-context snippets now render in the q2-preview overlay, matching the user's reference image and q2 render stdout output. Added rendered: Option<String> to JsonDiagnostic (populated server-side via diag.to_text(Some(ctx))), mirrored on TS Diagnostic interface, branched PreviewDiagnosticsOverlay to render <pre>{stripAnsi(d.rendered)} for located diagnostics with the compact line as fallback. End-to-end verified against docs/ for both [Q-13-4] body-link and [Q-1-20] metadata-as-markdown warnings. cargo xtask verify 12/12 green. Merged to main as commit 2911db60. Plan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-ariadne.md","dependencies":{"bd-b9kzg:discovered-from":{"depends_on_id":"bd-b9kzg","type":"discovered-from","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-21T18:40:04.198154Z","created_by":"cscheid"}}} +{"id":"bd-36fr9","title":"Provenance follow-up: Dispatch anchor for Lua-handler filter & shortcode","description":"Extends the provenance-epic AnchorRole enum with `Dispatch`, used to point at Lua source for filter-kind and Lua-handler-shortcode-kind Generated nodes.\n\n**Today (Plan 4 baseline):**\n- filter: Generated { by: filter{filter_path, line}, from: [] } -- path/line in by.data\n- shortcode (Lua handler): Generated { by: shortcode{name, lua_path, lua_line}, from: [Invocation -> token_si] }\n\n**After this issue:**\n- filter: Generated { by: filter{}, from: [Dispatch -> lua_si] }\n- shortcode (Lua handler): Generated { by: shortcode{name}, from: [Invocation -> token_si, Dispatch -> lua_si] }\n\nThe writer (Plan 7) keeps consulting invocation_anchor() only; Dispatch is diagnostic-only (\"which Lua handler resolved this\").\n\n**Blocker:** requires registering Lua filter files in SourceContext so they get FileIds. Touches:\n- Lua engine (mlua bridge)\n- SourceContext (file registry / interning)\n- Diagnostic machinery (reconcile with existing per-Lua-file diagnostics)\n- Cache-key surface (Lua files become cache input)\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-4-source-info-types.md §\"Deferred anchor role\"\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §\"Dispatch follow-up\"\n\n**Compatibility:** pure addition. AnchorRole gains Dispatch; by.data shrinks for filter/Lua-shortcode kinds. Anchor list shape unchanged.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T22:36:48.538531Z","created_by":"gordon","updated_at":"2026-05-21T22:36:48.538531Z","labels":["follow-up","provenance"]} +{"id":"bd-399t","title":"Docs callout: L7 listings preview is CLI-only (engine-rendered)","description":"When the user-facing docs site under `docs/` becomes a real published site, add a callout to the listings reference page documenting L7's bracketing-rule-3 behavior:\n\n> Engine-rendered previews are available in `quarto render` only. In interactive environments, listings show static-AST previews — set `description:` and `image:` explicitly if you need a specific preview to appear during preview.\n\nWording is locked in the L7 plan (`claude-notes/plans/2026-05-07-listings-L7-postrender-upgrade.md` §D13) and the listings epic plan (`claude-notes/plans/2026-05-05-listings-epic.md` §L7 §\"Bracketing rules\" rule 3). The future docs work copies it verbatim.\n\nFiled at L7 close-out per the L7 plan §\"Filing reminder\" follow-up #6.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-07T19:51:23.473994Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:23.473994Z","dependencies":{"bd-qf7r:discovered-from":{"depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:23.473994Z","created_by":"cscheid"}}} +{"id":"bd-3a0o","title":"Surface a diagnostic for unresolved nav-dependency declarations","description":"Decision 12 says: 'A nav-dependency that does not resolve to a project document emits a diagnostic warning at graph-build time and is dropped.' The graph builder today silently drops the edge (see crates/quarto-core/src/project/dependency_graph.rs:155-167 comment). compute_augmented_render_set passes a graph_diags Vec but does not propagate it. Wire it through summary.project_diagnostics and add an integration test that asserts the warning appears. Test 57 currently verifies render-proceeds half only.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:56.192415Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:56.192415Z","created_by":"cscheid"}}} +{"id":"bd-3aga","title":"Hub: optional local project watching (standalone sync server mode)","description":"Make local project watching optional so hub can run as a standalone sync server without a local Quarto project. The hub binary should default to no local project (sync-only), while quarto hub should default to watching the current project. Plan: claude-notes/plans/2026-03-03-hub-no-local-watch.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-03-03T17:17:34.628633Z","created_by":"cscheid","updated_at":"2026-03-03T17:36:24.629683Z","closed_at":"2026-03-03T17:36:24.629667Z","close_reason":"Implemented: StorageManager::new_standalone(), optional project_root, CLI flags (--project/--no-project/--data-dir), all tests passing (6502/6502)"} +{"id":"bd-3aolj","title":"AttrSourceInfo: duplicate-key handling breaks positional alignment with Attr.2","description":"When the qmd parser sees an attribute list with a duplicate key like {foo=1 foo=2}, the construction loop in crates/pampa/src/pandoc/treesitter_utils/commonmark_attribute.rs:41-49 calls:\n\n- attr.2.insert(key, value) -- LinkedHashMap::insert on a duplicate key UPDATES the existing entry in place without growing the map.\n- attr_source.attributes.push(...) -- always appends.\n\nAfter processing {foo=1 foo=2}, attr.2.len() == 1 but attr_source.attributes.len() == 2. The positional alignment AttrSourceInfo.attributes[i] = (key_src, val_src) for the i-th entry in Attr.2 is broken.\n\n**Discovered while reviewing Plan 6's theorem.rs::extract_name_attr fix** (claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet), which indexes attr_source.attributes by the position of name in attr.2. Plan 6 mitigates with a runtime length-check guard and falls back to SourceInfo::default() when alignment is broken — but the underlying bug pre-dates Plan 6 and affects any future caller that relies on the invariant.\n\n**Fix options:**\n1. On duplicate keys, also overwrite attr_source.attributes[existing_idx] instead of pushing a new entry. Preserves alignment; loses the first key's source location (consistent with LinkedHashMap's value-overwrite behavior).\n2. Reject duplicate keys at parse time with a diagnostic. More invasive; changes user-facing behavior.\n3. Change attr.2 to allow duplicate keys (Vec<(String, String)>). Largest change; affects every consumer of Attr.\n\nOption 1 is the minimum-blast-radius fix; Plan 6's guard handles the symptom either way.\n\n**Plan refs:**\n- claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md §Scope theorem bullet (positional-alignment safeguards)\n- crates/quarto-pandoc-types/src/attr.rs:27-32 (AttrSourceInfo definition)","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-22T06:44:43.151226Z","created_by":"gordon","updated_at":"2026-05-22T06:44:43.151226Z","labels":["bug","provenance"]} +{"id":"bd-3az78","title":"refactor canonicalize_within_project to take Option<&SourceInfo>","description":"Plan 7f Phase 6.5 follow-up. Today's signature requires a SourceInfo, forcing Engine/Lua-filter resource-entry resolution (crates/quarto-core/src/project_resources.rs:541) to pass a sentinel `By::unknown()` value because those entries genuinely have no YAML source location. The receiver only uses the source location for diagnostic-span rendering, which already degrades gracefully. Refactoring the signature to `Option<&SourceInfo>` removes the sentinel from the call site and lets the receiver decide explicitly how to handle `None` for span-less diagnostics.","status":"open","priority":3,"issue_type":"task","created_at":"2026-06-01T18:26:14.218956Z","created_by":"gordon","updated_at":"2026-06-01T18:26:14.218956Z","dependencies":{"bd-1ngyy:discovered-from":{"depends_on_id":"bd-1ngyy","type":"discovered-from","created_at":"2026-06-01T18:26:14.218956Z","created_by":"gordon"}}} +{"id":"bd-3c6e","title":"Pipeline execution tracing","description":"Add ability to trace and inspect the state of the rendering pipeline at each step. Extend PipelineObserver with data-bearing callbacks, implement concrete trace observers (summary, JSON), add CLI/YAML/env activation. Plan: claude-notes/plans/2026-04-13-pipeline-tracing.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-13T20:37:52.537535Z","created_by":"cscheid","updated_at":"2026-04-13T21:18:02.143957Z","dependencies":{"bd-ft03:blocks":{"depends_on_id":"bd-ft03","type":"blocks","created_at":"2026-04-13T21:18:02.143227Z","created_by":"cscheid"}}} +{"id":"bd-3cus","title":"Pre-fill new file dialog with current file's directory path","description":"When opening the new file dialog via the '+ New' button, pre-fill the filename field with the directory path of the currently active file. For example, if the user is editing 'docs/chapter1.qmd', the filename field should show 'docs/' so they only need to type the new filename. Files at the root level should not pre-fill anything.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-02-04T17:04:35.946556Z","created_by":"cscheid","updated_at":"2026-02-04T17:06:06.266467Z","closed_at":"2026-02-04T17:06:06.266419Z","close_reason":"Implemented: handleNewFile in Editor.tsx now extracts directory prefix from currentFile.path and passes it as initialFilename to NewFileDialog"} +{"id":"bd-3day","title":"customRegistry accumulator bug in ast-renderer-entry.tsx loses earlier-loaded user TSX exports","description":"In hub-client/src/ast-renderer-entry.tsx:72, the loadCustomComponents loop does: customRegistry = { ...componentRegistry, ...module } — overwriting customRegistry with the static componentRegistry plus only the current module's exports. Each iteration loses earlier modules' contributions. Should be: customRegistry = { ...customRegistry, ...module }. Affects multi-file render-components configurations where users split overrides across simple.tsx + html.tsx + comment.tsx etc. — only the last-loaded file's exports survive. The render_components.qmd docs describe the intended behavior correctly. q2-preview's entry (Plan 2A) will mirror the pattern but fix this bug; this issue tracks back-porting the fix to q2-debug.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T21:39:36.019777Z","created_by":"gordon","updated_at":"2026-05-08T19:39:59.708377Z","closed_at":"2026-05-08T19:39:59.708358Z","close_reason":"Fixed in 1e5a930f on branch bugfix/react-components-not-loading (q2-debug back-port of the customRegistry accumulator fix)"} +{"id":"bd-3f1z9","title":"Preview navbar brand link points to artifacts VFS root and dead-ends iframe","description":"Bug placeholder","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:07:30.585480Z","created_by":"cscheid","updated_at":"2026-05-20T14:07:49.477814Z","closed_at":"2026-05-20T14:07:49.477621Z","close_reason":"Duplicate of bd-ql55q (first create attempt was a fallback placeholder)","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-20T14:07:30.585480Z","created_by":"cscheid"}}} +{"id":"bd-3flm","title":"Make cargo xtask verify match CI checks","description":"cargo xtask verify passes locally but CI fails because verify doesn't set RUSTFLAGS=\"-D warnings\", doesn't run custom lints, and doesn't run tree-sitter grammar tests. See plan: claude-notes/plans/2026-03-09-xtask-verify-ci-parity.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-03-09T17:05:42.756553Z","created_by":"cscheid","updated_at":"2026-03-09T17:19:16.101527Z","closed_at":"2026-03-09T17:19:16.101508Z","close_reason":"All work items complete: removed unused trim_prefix_suffix feature, added -D warnings/lint/tree-sitter steps to xtask verify"} +{"id":"bd-3fwnh","title":"q2-preview SPA boot fails: samod findDoc(indexDocId) times out at 5s","description":"**Reproducer:**\n1. `cargo build --bin q2`\n2. `./target/debug/q2 preview <any-fixture>.qmd`\n3. Open the printed URL in a browser.\n4. SPA displays \"Initializing q2-preview\" for ~5 seconds, then PreviewDiagnosticsOverlay shows:\n `Document automerge:<doc-id> is unavailable`\n5. Boot state goes to `'error'` so the rendered content never appears.\n\nReproduces with any fixture (verified with callouts-matrix.qmd and basic-render.qmd, different doc ids each time). Hard refresh + restart of the server do not help.\n\n**Investigation so far:**\n\n- `/health` correctly returns the fresh `index_document_id` matching the one the SPA later tries to subscribe to (verified with curl).\n- HTTP-level WS upgrade succeeds (`curl -H \"Upgrade: websocket\" /ws` returns 101 Switching Protocols with a valid Sec-WebSocket-Accept).\n- The 5-second timeout in PreviewApp.tsx:505 (`connect(wsUrl, indexDocId, undefined, undefined, undefined, 5000)`) is firing on every cold load. The comment at lines 500-504 acknowledges this race was already mitigated once.\n- onError handler at PreviewApp.tsx:494-497 sets `boot: 'error'`, so the SPA shows the error screen instead of the rendered content.\n\n**Likely layer:** the samod protocol exchange ON TOP of the WS — peer announcement / sync messages aren't flowing within the 5s budget. Stack on this branch:\n- Server: Rust `samod = 0.9.0` (quarto-dev/samod q2 branch) in quarto-hub.\n- Client: JS `@automerge/automerge-repo@2.5.1` + `@quarto/quarto-sync-client` (workspace package).\n\n**History:** commit 2541f228 (\"Fix race condition in automerge sync causing document unavailable errors\") fixed an earlier instance by adding `waitForPeer()`. The 5s extra timeout in PreviewApp was the second mitigation. The race is still winning at boot on at least one developer's machine consistently.\n\n**Discovered during:** Phase 6 verification of the callout class-vocabulary fix\n(claude-notes/plans/2026-05-22-callout-class-vocabulary-fix.md). Unrelated to\nthat work — callout HTML render path verifies fine through\n`cargo run --bin q2 -- render <fixture>`.\n\n**Possible next steps:**\n- Add samod-protocol-level logging on both sides during the first 5s of a fresh q2 preview session to see what messages (if any) traverse the WS after the upgrade.\n- Check whether samod 0.9.0 vs automerge-repo 2.5.1 have a protocol-version mismatch.\n- Try clearing IndexedDB on the SPA origin — might rule out any client-side storage layer interaction.\n- Bisect commits to wasm-quarto-hub-client / quarto-hub / quarto-preview / samod-related files in the past 3 weeks.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-26T12:38:32.512565Z","created_by":"gordon","updated_at":"2026-05-26T12:38:32.512565Z"} +{"id":"bd-3gej","title":"Fix TOCTOU race in JupyterDaemon::get_or_start_session","description":"**Location:** `crates/quarto-core/src/engine/jupyter/daemon.rs:74-85`\n\n**Race:** `get_or_start_session` reads `self.sessions` under a read lock, drops the lock, then calls `start_kernel(&key).await?` (which takes the write lock at lines 197-199 and inserts). Between the two lock acquisitions, a second concurrent caller for the same `(kernel_name, working_dir)` key can pass the same `contains_key` check and also enter `start_kernel`. The second `start_kernel` overwrites the first's entry in the sessions map, leaking a kernel subprocess (the first kernel's handle is dropped without shutdown).\n\n**Mitigation today:** the render pipeline runs single-threaded (`pollster::block_on`, `?Send` async), so no two callers race in practice.\n\n**When it surfaces:** as soon as parallelism is added — `rayon`-per-worker is foreshadowed in `crates/quarto-core/src/project/orchestrator.rs` docstrings (\"a future rayon + pollster-per-worker parallelism path\"). Also surfaces under any future async runtime that schedules tasks across threads.\n\n**Fix sketch:** acquire the write lock first, re-check `contains_key` under the write lock, and either return the cached session or insert a placeholder before calling `start_kernel`. The standard \\\"upgrade and re-check\\\" pattern, equivalent to `entry().or_insert_with(...)`.\n\n**Discovered:** during the TS engine extensions plan-review session on 2026-04-28. The TS engine work explicitly chose a different concurrency strategy (harness-side idempotency on repeat \\`LoadEngine\\`/\\`LaunchEngine\\`) precisely so it wouldn't inherit this pattern. See claude-notes/plans/2026-04-16-plan1a-protocol-and-core.md \\\"Race-free init via harness idempotency\\\" and the corresponding section in claude-notes/plans/2026-04-16-plan1b-engine-host-deno.md.\n\n**Related:** lines 244-260 and 263-270 in the same file have the same shape but each takes the write lock atomically, so they are not racy. Only `get_or_start_session` at lines 74-85 needs fixing.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-05T13:48:20.303702Z","created_by":"gordon","updated_at":"2026-05-05T13:48:20.303702Z"} +{"id":"bd-3gj56","title":"Parallelize Pass-2 render loop (orchestrator.rs) with rayon","description":"Pass 2 (qmd->HTML render-to-file) is a serial for-loop at crates/quarto-core/src/project/orchestrator.rs:1013, awaiting each page sequentially on the main thread. It is ~98% of full-project render wall time (Pass 1 is already parallel: perf.pass1 docs=565 threads_used=16 wall_ms=19).\n\nEvidence: samply profile of q2 render of claude-notes/qmd-plans — main q2 thread holds 93% of samples, 16 quarto-pass1 workers idle (6.9% combined). See claude-notes/plans/2026-06-01-render-perf-profiling.md.\n\nThe locale-lock that previously blocked MT scaling (bd-b7eb7) is FIXED by PR #247 (verified: lock waits dropped 77% -> 0.65% in the profile). Parallelism is now unblocked.\n\nInfrastructure already laid for this: pass2_renderer.rs:73 names 'a future rayon-per-worker parallelism path', the Pass2Renderer trait is ?Send, per-render args are Arc-wrapped. Main obstacle: the &mut self.project_artifacts accumulator (each page drains project-scoped artifacts into it) — needs per-worker accumulators merged at end. Must preserve deterministic output ordering and fail-fast semantics. Land bd-2ercw (regex recompile fix) first.","notes":"IMPLEMENTED (pending full verify + commit). Approach: Pass2Renderer::render_batch trait method, default serial (WASM/tests untouched, no Send bounds); RenderToFileRenderer overrides with rayon fan-out. Refined per-worker -> PER-DOCUMENT artifact stores merged in doc order = exact serial parity for conflict attribution. ProjectPipeline::with_jobs(n) for test-pinned parallelism; worker_count() shared with Pass 1 (QUARTO_JOBS, cap 16). perf.pass2 gauge added.\n\nResults (qmd-plans 565 files, release, median-of-5): end-to-end 3650ms(j=1) -> 500ms(j=16) = 7.3x; Pass-2 itself 3551 -> 446ms (~8x). Byte-equivalence: diff -r of serial vs 16-thread _site IDENTICAL (571 files). Tests: pass_two_preserves_input_order, pass_two_parallel_matches_serial (byte-exact), pass_two_parallel_renders_all_pages; deliberate-break sanity confirmed order guard bites. All 2163 quarto-core tests pass. Plan: claude-notes/plans/2026-06-01-parallelize-pass-two.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-06-01T14:45:12.317267Z","created_by":"cscheid","updated_at":"2026-06-01T16:40:40.581728Z","closed_at":"2026-06-01T16:40:40.581595Z","close_reason":"Pass-2 parallelized via rayon (render_batch trait method, native override, per-doc artifact stores merged in doc order). 7.3x end-to-end / ~8x Pass-2 on 16 threads; serial vs parallel _site byte-identical (571 files). 3 correctness tests + deliberate-break sanity; full cargo xtask verify green. Deferred (optional follow-up): a deterministic Pass-2-failure fixture for fail-fast/panic-isolation tests — hard to construct (parse errors fail in Pass 1); the AtomicBool/catch_unwind logic mirrors Pass 1's tested pattern.","labels":["perf"],"dependencies":{"bd-2ercw:blocks":{"depends_on_id":"bd-2ercw","type":"blocks","created_at":"2026-06-01T14:45:12.317267Z","created_by":"cscheid"}}} +{"id":"bd-3gtn","title":"WASM artifact flush overwrites user uploads with empty bytes for resource images","description":"**Discovered during**: q2-preview Plan 2A review (2026-05-07).\n\n## The bug\n\n`crates/wasm-quarto-hub-client/src/lib.rs:1208-1214` (single-doc render path) and `:1364-1369` (project render path) loop over `ctx.artifacts` and write each artifact's content to VFS:\n\n```rust\nfor (_key, artifact) in ctx.artifacts.iter() {\n if let Some(artifact_path) = &artifact.path {\n let vfs_path = resolver.on_disk_path_for(artifact.scope, artifact_path);\n runtime.add_file(&vfs_path, artifact.content.clone());\n }\n}\n```\n\nThere is no guard against empty content. `ResourceCollectorTransform` (in `crates/quarto-core/src/transforms/resource_collector.rs:65-71`) produces artifact entries via `Artifact::from_path(...)`, which sets `content: Vec::new()` (`crates/quarto-core/src/artifact.rs:108-116`). The artifact's `path` field is `base_dir.join(url)` — typically absolute in WASM context.\n\n`Path::join` semantics: an absolute second argument replaces the first. So `vfs_root.join(\"/project/hero.png\")` collapses to `/project/hero.png`, which is also where `automergeSync` (in `hub-client/src/services/automergeSync.ts:84,87`) wrote the user's image bytes via `vfsAddFile` / `vfsAddBinaryFile`.\n\n**Result**: the flush overwrites the user's upload with empty bytes on every render that references the image.\n\n## How it surfaces\n\nToday, in HTML preview, embedded images may appear broken on second-and-subsequent renders. Hasn't been widely reported — possibly because users don't often embed local images, or because path semantics in some cases avoid the collision (the bug is conditional on whether `ctx.document.input` is absolute or relative; both occur depending on how JS calls the WASM entry).\n\nFor q2-preview (Plan 2A), the iframe rewriter explicitly relies on the user's upload bytes being present. Without the fix, q2-preview renders with embedded images would produce empty data: URIs after the first render.\n\n## Fix\n\nAdd an `is_empty()` guard to both flush loops:\n\n```rust\nfor (_key, artifact) in ctx.artifacts.iter() {\n if let Some(artifact_path) = &artifact.path {\n if !artifact.content.is_empty() {\n let vfs_path = resolver.on_disk_path_for(artifact.scope, artifact_path);\n runtime.add_file(&vfs_path, artifact.content.clone());\n }\n }\n}\n```\n\nThis preserves manifest semantics for `ResourceCollectorTransform` (the entries still exist in `ctx.artifacts` for downstream consumers like `ResourceReportStage`) while preventing the overwrite. Theme CSS / icon CSS / fonts (which use `Artifact::from_bytes` with real content) keep flushing correctly.\n\n## Tests\n\n- Strengthen the website-fixture test in `crates/quarto-core/tests/render_page_in_project.rs::website_q2_preview_renders_through_orchestrator`: pre-populate VFS at the user's expected upload path with non-empty bytes, run the render, assert bytes are unchanged. (Today's test asserts only that the manifest entry exists.)\n- Add a similar regression test for `RenderToHtmlRenderer` if not already present.\n\n## Plan references\n\n- Plan 2A §\"Risk areas → Empty-content artifact overwrite (latent bug discovered during plan review)\" — `claude-notes/plans/2026-05-04-q2-preview-plan-2a-iframe-foundation.md`\n- Plan 1 §\"Multi-plan contract: page-scoped image artifacts\" — `claude-notes/plans/2026-05-04-q2-preview-plan-1-pipeline.md`\n- Plan 1 §Test plan, \"Website fixture with embedded image\" — references this issue for the deferred 6th assertion (bytes survive render).","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T13:14:56.576599Z","created_by":"gordon","updated_at":"2026-05-10T07:15:15.347294Z","closed_at":"2026-05-10T07:15:15.347266Z","close_reason":"Fixed in c8a684bd on feature/q2-preview: empty-content guard added to both WASM flush loops. Test in assetManifestProject.wasm.test.ts walks through bug-then-fix with binary upload BEFORE render in its natural lifecycle.","labels":["q2-preview"]} +{"id":"bd-3izo3","title":"Plan 7 Phase 8 e2e: Playwright matrix for incremental-write round-trips","description":"Deferred from the Plan 7 session that landed Phases 4-7 + the WASM-level wrapper test. The Rust-side soft-drop matrix is already covered in crates/pampa/src/writers/incremental.rs; this ticket tracks the *delivery* coverage at the browser surface.\n\nScenarios (one Playwright spec each):\n\nHub-client (e2e/):\n- Sectionized doc + edit one paragraph round-trip (section structure preserved in saved qmd)\n- Single-inline shortcode + edit different paragraph (shortcode preserved verbatim)\n- Multi-inline shortcode + edit different paragraph in same Para (shortcode appears once via dedupe)\n- Edit resolved shortcode title → Q-3-42 surfaced + doc byte-equal to no-op\n- Edit inside synthesized footnotes container → Q-3-43 surfaced + container regenerates\n\nSPA (q2-preview-spa/e2e/):\n- Project + edit paragraph round-trip\n- Single-file mode (bd-tnm3k path) + edit paragraph round-trip\n- Edit shortcode → Q-3-42 surfaces in DiagnosticStrip\n- Mixed atomic + non-atomic edit → non-atomic applies, atomic preserved\n- Content-match echo-prevention: induce echo loop (write → samod echo → fnv1aHex match in lastEmittedRef), assert exactly one render bumps __renderTicks after the edit; assert an interleaved unrelated file still re-renders\n\nEach spec needs a tempdir fixture + spawned hub/preview server; the existing hub-client e2e/ and q2-preview-spa/e2e/ infra (helpers/previewServer.ts pattern) is the model.\n\nRun gate: cargo xtask verify --e2e (currently optional in CI, not blocking). Should stay --e2e-gated to avoid taxing every PR.\n\nReferences:\n- Plan 7: claude-notes/plans/2026-05-04-q2-preview-plan-7-incremental-writer.md §Phase 8\n- Phase 7 commit: f050a7c6 (SPA setAst + echo-prevention + DiagnosticStrip)\n- Phase 4-6 commit: 9da9f14a","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-25T02:47:02.597860Z","created_by":"gordon","updated_at":"2026-05-25T20:12:51.817654Z"} +{"id":"bd-3lsb","title":"AST-level sync client API for quarto-sync-client","description":"Add onASTChanged/updateFileAst API pair to quarto-sync-client. Phase 1: dependency-injected parser/writer with new WASM exports (parse_qmd_content, ast_to_qmd). Phase 2: incremental write using quarto-ast-reconcile for localized string splicing. Plan: claude-notes/plans/2026-02-06-ast-sync-client-api.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-02-06T19:53:57.108941Z","created_by":"cscheid","updated_at":"2026-02-06T20:27:53.885293Z"} +{"id":"bd-3mgb","title":"Reader rejects valid 4-space-indented list-item continuations as a parse error (issue #196)","description":"Regression from PR #194 (closes #184, Q-2-35). The new `INDENTED_CODE_BLOCK_DISALLOWED` external token in `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c` (line 2128) fires on list-item continuation lines whose preceding blank line carries >= 4 columns of trailing whitespace (4+ spaces or a tab). The result is a generic 'Parse error' (the (state, sym) pair at the recovery point isn't in the Q-2-35 friendly-error table) where the previous behaviour produced an OrderedList AST with two Para children.\n\nTrigger threshold is exactly 4 columns on the blank line. 2 trailing spaces still parses; 4 spaces or 1 tab does not. Independent of list marker kind (ordered, bullet) and continuation content kind (image, plain text).\n\nIn the wild: three real-world occurrences in quarto-dev/quarto-web (see triage doc for links).\n\nTriage: .worktrees/issue-196/claude-notes/issue-reports/196/triage.md\nWorktree branch: issue-196\nUpstream: https://github.com/quarto-dev/q2/issues/196\n\nFix should land in the scanner — either reset `s->indentation` on the BLANK_LINE_START path, or tighten the gate to skip list-item continuation contexts. See triage doc § 'Where the fix should land' for angles, and add a tree-sitter corpus regression alongside a positive Q-2-35 case to confirm the original PR's diagnostic still fires on real top-level indented blocks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-14T23:25:54.801581Z","created_by":"cscheid","updated_at":"2026-05-14T23:47:56.453256Z","closed_at":"2026-05-14T23:47:56.453081Z","close_reason":"Fixed in 85d12789 on issue-196: gate Q-2-35 detector with !(BLOCK_CONTINUATION && open_blocks > 0). Tree-sitter 483/483, workspace 8863/8863, all four Q-2-35 positives still fire, repro + three real-world quarto-web files parse cleanly.","dependencies":{"bd-7l1u:discovered-from":{"depends_on_id":"bd-7l1u","type":"discovered-from","created_at":"2026-05-14T23:25:54.801581Z","created_by":"cscheid"}}} +{"id":"bd-3n80","title":"Document hub-client features in docs/quarto-hub","description":"Create user-facing documentation for the hub-client prototype in the docs directory. Should cover core features: file management, live preview, themes, templates, project creation, and collaboration.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-12T21:14:38.273555Z","created_by":"cscheid","updated_at":"2026-02-12T21:20:39.282688Z","closed_at":"2026-02-12T21:20:39.282677Z","close_reason":"Documentation complete: created 7 pages covering overview, files, preview, themes, templates, projects, and collaboration"} +{"id":"bd-3nzyd","title":"Hub-Client E2E: smoke-all preview-iframe tests fail (401 + peer-connection timeout) in CI","description":"Surfaced once the Playwright install hang was unblocked (PR #249 / bd-2njja pin). The Hub-Client E2E suite now RUNS to completion for the first time since ~2026-05-27, and reveals pre-existing failures in e2e/smoke-all.spec.ts (NOT caused by the Node pin, which only affects browser install).\n\nRun 26764975242 result: 84 passed, 2 failed, 6 flaky.\n\nHard failures (fail after 2 retries):\n- extensions/builtin-placeholder-shortcode/test.qmd [html]\n- q2-preview/multi-element-project/index.qmd [q2-preview]\n\nFlaky (passed on retry): builtin-lipsum-shortcode [html], highlighting/05-theme-none [html], includes/basic [html], metadata/appendix-style-inheritance/doc-override-default [html], q2-preview/body-container-full-layout, q2-preview/body-container-minimal.\n\nSignature: waitForPreviewRender (hub-client/e2e/helpers/previewExtraction.ts:87) throws 'Timed out after 75000ms waiting for preview iframe to render', with console error 'Failed to load resource: the server responded with a status of 401 (Unauthorized)'. Throughout the run, repeated 'Peer connection failed, creating project in offline mode: Error: Timeout waiting for peer connection'.\n\nHypothesis: in the CI e2e environment the preview iframe cannot auth/connect to the hub peer/sync (401 + peer-connection timeout), so it never renders within 75s. Likely a hub auth/signaling or globalSetup wiring issue in CI, or a genuine regression on main masked since the install started hanging. Needs investigation with the uploaded Playwright trace/video artifacts (playwright-report artifact on the run).\n\nNOTE: this is the real blocker to a green Hub-Client E2E once the install hang is resolved.","design":"CHOSEN FIX: Tier 2 (deterministic readiness gate) -- keeps the full Automerge sync path end-to-end, just stops the test racing it. Rejected Tier 1 (seed content locally) because it would bypass the very integration smoke-all exists to exercise.\n\nExact race confirmed by code read: seedProjectInBrowser -> projectStorage.addProject writes IDB ONLY. The seed reaches the SYNCED project set only via reconcileIntoConnectedProjectSet, which the app runs in a useProjectSet effect keyed on the status->connected TRANSITION (useProjectSet.ts:90) and which requires projectSetService.isConnected(). Because the test seeds AFTER bootstrapProjectSet already reached connected, that effect does not re-fire, so the seed lands in the set only if a fortuitous WS reconnect re-triggers reconcile -> flaky, and worker-count-independent (confirmed: workers:1 did not help).\n\nImplemented in PR #249:\n- hub-client/src/test-hooks.ts: expose the live projectSetService singleton (projectSet) + reconcileIntoConnectedProjectSet (reconcileProjectSet) on window.__quartoTest.\n- hub-client/e2e/helpers/testHooks.ts: matching QuartoTestHooks types.\n- hub-client/e2e/helpers/projectFactory.ts seedProjectInBrowser: after addProject, (1) wait up to 30s for projectSet.isConnected(), (2) call reconcileProjectSet() (idempotent) and wait until projectSet.getProject(indexDocId) is defined, before returning. Bounded waits fail loudly if the sync server is truly unreachable.\n- workers reverted to 2 (parallelism was never the cause).\n\nFOLLOW-UP (product, separate): the app arguably should reconcile IDB->set on IDB change, not only on the status transition -- so a project added while already-connected appears without a reconnect. Out of scope for the test fix.","notes":"VERIFIED: Tier-2 readiness gate landed in PR #249 -> CI run 26772812401 GREEN (78 passed / 14 flaky / 0 failed functional, 6 visual passed, ~13m, workers:2). The gate eliminated the hard failures (project-set seed/sync race) AND kept parallelism (workers reverted to 2; workers:1 had not helped).\n\nRESIDUAL (keep this bead open): 14 tests still pass-on-retry ('flaky'), up from ~6. Since 0 hard-failed, the gate never threw -- so the residual is in the TEST BODY (75s waitForPreviewRender occasionally needing a retry), most likely the project's FILE doc sync during render (a different doc than the project-SET seed race fixed here). Within the 2-retry budget so the run is green, but worth hardening: extend a similar 'await synced' gate to the project file docs before asserting render, or raise/justify the render wait. Plus the product follow-up: app should reconcile IDB->set on IDB change, not only on the status transition.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-06-01T15:56:36.919507Z","created_by":"gordon","updated_at":"2026-06-01T18:28:10.309750Z"} +{"id":"bd-3odjm","title":"Plan 3: q2-preview orchestrator emits AST JSON that fails to round-trip through pampa::readers::json::read for lipsum content (MalformedSourceInfoPool)","description":"Surfaced by Plan 3's idempotence gate (`crates/quarto-core/tests/idempotence.rs::lua_shortcode_lipsum_fixed`). Reproduce:\n\n cargo nextest run -p quarto-core --test idempotence lua_shortcode_lipsum_fixed\n\nThe `SingleFile` `DriveMode` passes — the fixture is genuinely idempotent at the pipeline level. The `ProjectOrchestrator` mode panics inside `run_orchestrator`:\n\n re-parse AST JSON from orchestrator: MalformedSourceInfoPool\n\ni.e. the JSON the orchestrator emitted via `Pass2Payload::AstJson` (writer config `include_inline_locations: true`) is not parseable back by `pampa::readers::json::read`. This is a JSON-writer/reader round-trip bug, not a transform-determinism finding.\n\n**Root cause (confirmed 2026-05-21).** Type-code `3` mismatch between writer and reader in the `sourceInfoPool` wire format:\n\n- Writer (`crates/pampa/src/writers/json.rs:115,180-182`) emits `FilterProvenance` as type code `3` with `d = [filter_path: string, line: number]`.\n- Reader (`crates/pampa/src/readers/json.rs:252-283`) still treats code `3` as the long-removed `Transformed` variant and parses `d[0].as_u64()` for a parent_id. On the lipsum fixture `d[0]` is the `filter_path` string → `as_u64()` returns None → `MalformedSourceInfoPool`.\n\nLipsum trips this because the lipsum Lua shortcode synthesizes inlines whose `SourceInfo` is `SourceInfo::FilterProvenance { filter_path, line }` (via `crates/pampa/src/lua/diagnostics.rs`). Every other Phase 3/4a fixture's content is `Original` / `Substring` / `Concat` (codes 0/1/2), so they round-trip fine. The lipsum fixture is the first one in Plan 3's gate whose pipeline emits a `FilterProvenance` SourceInfo across the AST-JSON boundary.\n\n**Fix-owner: Plan 5 (`claude-notes/plans/2026-05-04-q2-preview-plan-5-wire-format.md`).** Plan 5 already covers exactly this bug as part of the wire-format extension for `Generated { by, from }` (Plan 4's typed-provenance variant; the anchor list field is named `from`, holding `SmallVec<[Anchor; 2]>`). Plan 5 retires `FilterProvenance`, adds wire code `4` for `Generated`, and makes the reader's code-`3` branch dispatch on `d[0]`'s JSON type:\n- numeric `[parent_id, ...]` → legacy Substring approximation (back-compat),\n- string-headed `[filter_path, line]` → `Generated { by: By::filter(...), from: smallvec![] }` (the latent FilterProvenance path).\n\nPer the long-lived-branch policy in Plan 3 §\\\"Phase 5 — Failure triage\\\", this issue stays open until Plan 5 lands. Do not fix locally on `feature/provenance`; close as duplicate when Plan 5's PR merges.\n\nThis blocks closing `lua_shortcode_lipsum_fixed` in the Plan 3 gate but does not block the other Phase 4 work.\n\nRefs:\n- claude-notes/plans/2026-05-04-q2-preview-plan-5-wire-format.md (fix-owner; §Goal calls this bug out by name)\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md (§\\\"Phase 5 — Failure triage\\\", §\\\"CI failure policy & sub-agent prompt template\\\")\n- branch: feature/provenance","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:00:50.016470Z","created_by":"gordon","updated_at":"2026-05-22T06:16:45.311056Z","closed_at":"2026-05-22T06:16:45.311028Z","close_reason":"Fixed in Plan 5 Phase 1 (commit d7b8450a on feature/provenance): the JSON reader's code-3 arm now dispatches on data[0]'s JSON type — numeric-headed legacy Transformed → Substring (back-compat); string-headed [filter_path, line] → Generated { by: filter, from: [] } (recovers the latent FilterProvenance shape). lua_shortcode_lipsum_fixed now passes; full Plan-3 idempotence suite is 27/27 green.","dependencies":{"bd-c3qe6:discovered-from":{"depends_on_id":"bd-c3qe6","type":"discovered-from","created_at":"2026-05-21T21:00:50.016470Z","created_by":"gordon"}}} +{"id":"bd-3oh3","title":"Create pure-automerge TypeScript reproduction for samod NotFound bug","description":"Create a minimal TypeScript reproduction of the samod-core NotFound bug that uses only automerge packages (automerge-repo, automerge-repo-network-websocket) with no quarto-specific dependencies. The reproduction should: (1) start a samod server, (2) create multiple automerge documents in quick succession via WebSocket, (3) disconnect, (4) reconnect with a fresh client, (5) verify all documents are available. This will be contributed upstream to help the samod author understand and verify the fix.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-03-04T13:57:08.965101Z","created_by":"cscheid","updated_at":"2026-03-04T14:34:31.202387Z","closed_at":"2026-03-04T14:34:31.202357Z","close_reason":"Created standalone reproduction at ts-packages/samod-repro/ with README, minimal Rust server, and pure-automerge TypeScript test. Verified fails without fix, passes with fix.","dependencies":{"bd-33qc:discovered-from":{"depends_on_id":"bd-33qc","type":"discovered-from","created_at":"2026-03-04T13:57:41.028354Z","created_by":"cscheid"}}} +{"id":"bd-3okv","title":"Kanban: drag-and-drop status changes and hide redundant status dropdown","description":"In the kanban BoardView, status is shown redundantly: as a dropdown on each card AND as the section/row the card appears in. Replace the dropdown with drag-and-drop between status sections so the card's position IS the status indicator.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-12T15:04:14.134059Z","created_by":"cscheid","updated_at":"2026-02-13T22:42:33.520046Z","closed_at":"2026-02-13T22:42:33.520006Z","close_reason":"Implemented drag-and-drop status changes with @dnd-kit. Status dropdown hidden in BoardView, kept in CardDetailView. All tests pass."} +{"id":"bd-3pe8","title":"Audit pampa production Lua code for Windows path escaping","description":"Tests needed to_forward_slashes for Lua string embedding but production code may have the same exposure. quarto-cli uses pathWithForwardSlashes in production when passing paths to Lua filters and metadata. Investigate whether pampa production code passes Windows paths into Lua string contexts. If so, to_forward_slashes should become a regular dependency (not dev-only) and the fix should be in the Lua runtime layer, not just tests.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-03-31T10:00:02.835216600Z","created_by":"cderv","updated_at":"2026-03-31T10:52:56.425993900Z","closed_at":"2026-03-31T10:52:56.425578300Z","close_reason":"Audited production Lua code in filter.rs: all path passing uses Lua C API (globals().set, load().set_name), never string interpolation into Lua source. lua.load(format!()) only exists in #[cfg(test)] modules. Production code is safe — the fix in test code was the correct approach."} +{"id":"bd-3sa5","title":"L9 follow-up: HTML-aware truncation in extract_first_para_html","description":"v1 of feed/reader_ext.rs::extract_first_para_html degrades to plain text when truncation under max_length is required, because scraper is read-only and DOM mutation isn't available. Q1 walks the DOM and clones with truncated text nodes, preserving tag structure. To match Q1, switch to an html5ever-based serializer or use scraper + custom node walker that produces a tag-balanced subset. Subscribers who hit a truncation see plain text instead of formatted text in v1 — workable but lower-fidelity than the underlying HTML.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:34:09.570667Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:09.570667Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:09.570667Z","created_by":"cscheid"}}} +{"id":"bd-3so8f","title":"Upgrade @playwright/test to >=1.60.0 and drop the Node 24.15.0 pin","description":"See PR #249. Upgrade Playwright to >=1.60.0 (fixes the Node>=24.16 yauzl extraction hang), drop the Node pin, regenerate Chromium-148 visual baselines.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-01T15:37:57.921476Z","created_by":"gordon","updated_at":"2026-06-01T15:38:13.737933Z","closed_at":"2026-06-01T15:38:13.737912Z","close_reason":"Duplicate of bd-2njja (created in error by a shell fallback)"} +{"id":"bd-3y7ul","title":"CI on main broken: Instant::now() panics on WASM in pass_one","description":"After bd-m7x9s (Parallelize Pass-1 via rayon, 665bbb34), CI is failing on origin/main. hub-client wasm tests (assetManifestProject, themeFingerprint, customNodeWireFormatProject) panic with 'PanicError: time not implemented on this platform' from `std::time::Instant::now()` in `ProjectPipeline::pass_one` (orchestrator.rs:847). The Instant::now() and the subsequent .elapsed() feed the `perf.pass1` gauge, but they always run — not gated for WASM.\n\nFix: route monotonic-clock access through SystemRuntime with a WASM shim using `performance.now()`. Add `monotonic_now_nanos() -> u64` to the trait; native default uses a process-start Instant; WasmRuntime overrides with js_sys/performance.\n\nFailing run: https://github.com/quarto-dev/q2/actions/runs/26310309964/job/77457143629","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-05-22T21:03:37.847050Z","created_by":"cscheid","updated_at":"2026-05-22T21:16:17.323985Z","closed_at":"2026-05-22T21:16:17.323861Z","close_reason":"Fixed: SystemRuntime::monotonic_now_nanos shim (performance.now on WASM) + pass_one_dispatch_async to avoid pollster::block_on on WASM. Native + WASM tests green, full cargo xtask verify passes."} +{"id":"bd-45yw","title":"Replay engine: deterministic in-Rust engine for tests","description":"From the bd-o8pr Phase 2 work session: writing E2E tests for engine-emitted resources (and other engine-channel features) requires either real R/Python/jupyter installs or a custom test injection point. Both are heavy.\n\nIdea: build a 'replay engine' that can reproduce the behavior of any existing engine but runs entirely in Rust. Records a real engine's transcript (markdown output, supporting_files, includes, …) into a fixture; replays deterministically without the engine runtime. Useful for:\n\n- CI tests that exercise engine paths without R/Python\n- Reproducing flaky engine bugs by capturing the real engine's output once\n- Fixture-driven testing of engine-channel features (resources, filters, ExecuteResult fields)\n- Especially valuable for Jupyter where custom kernels are common and impossible to test against\n\nDiscovered while writing tests for project resources (bd-o8pr). Filed for next session.\n\nReferences:\n- crates/quarto-core/src/engine/registry.rs (where it would register)\n- crates/quarto-core/src/engine/{markdown,knitr,jupyter}/* (existing engine impls to model)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-03T19:53:55.859078Z","created_by":"cscheid","updated_at":"2026-05-03T23:12:57.481440Z","closed_at":"2026-05-03T23:12:57.481252Z","close_reason":"Implemented; merged in 78c23573","dependencies":{"bd-o8pr:discovered-from":{"depends_on_id":"bd-o8pr","type":"discovered-from","created_at":"2026-05-03T19:53:55.859078Z","created_by":"cscheid"}}} +{"id":"bd-469o","title":"Process: end-to-end verification before declaring features complete","description":"Track rollout of the end-to-end-verification convention introduced 2026-04-20 after the CodeHighlightStage-in-CLI-render-path incident. Plan doc: claude-notes/plans/2026-04-20-end-to-end-verification-process.md. Related: bd-n7x2 (syntax-highlighting design). Remaining work: audit other pipeline-builder branches for similar test-coverage gaps; explore a test helper that drives render_document_to_file against fixtures so CLI-visible features are verified against the file-on-disk contract, not just the in-memory RenderOutput.","status":"open","priority":1,"issue_type":"task","created_at":"2026-04-20T14:30:41.602217Z","created_by":"cscheid","updated_at":"2026-04-20T14:30:49.599840Z","dependencies":{"bd-n7x2:discovered-from":{"depends_on_id":"bd-n7x2","type":"discovered-from","created_at":"2026-04-20T14:30:49.599025Z","created_by":"cscheid"}}} +{"id":"bd-47w7o","title":"Support directory resources (recursive copy) in YAML resources:","description":"When a YAML 'resources:' entry resolves to a directory on disk (e.g. quarto-web's '/docs/blog/posts/2024-07-02-beautiful-tables-in-typst/demo'), the literal-path branch of expand_one returns it as a single PathBuf; copy_resources_to_output_dir then fails with 'the source path is neither a regular file nor a symlink to a regular file'.\n\nTS Quarto behavior (confirmed at external-sources/quarto-cli/src/core/path.ts:269-278): a literal path that resolves to an existing directory is rewritten to the recursive glob 'dir/**/*'. Q2 should match.\n\nPlan: claude-notes/plans/2026-05-21-resource-directory-recursive-copy.md\n\nDiscovered while landing bd-wlza2. Next blocker for rendering quarto-web end-to-end.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:39:29.468318Z","created_by":"cscheid","updated_at":"2026-05-21T21:52:47.700591Z","closed_at":"2026-05-21T21:52:47.700426Z","close_reason":"Literal directory resources now recursively expand to dir/**/* via expand_glob_files helper. 6 new tests added (4 failed pre-fix). e2e on quarto-web: demo/ directory copied 70/70 files; next blocker is theme dark-mode parsing (bd-0pic6, filed discovered-from).","dependencies":{"bd-wlza2:discovered-from":{"depends_on_id":"bd-wlza2","type":"discovered-from","created_at":"2026-05-21T21:39:29.468318Z","created_by":"cscheid"}}} +{"id":"bd-49ar","title":"[websites] Sidebar collapse/expand JS","description":"Ship the interactive JS for sidebar section collapse/expand. Phase 2 emits structurally-correct Bootstrap markup (data-bs-toggle=\"collapse\", data-bs-target, aria-expanded) but the actual JS lives in Phase 5 (site_libs/). Blocked by Phase 5 scoped artifact store work.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-24T17:52:27.387148Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:27.387148Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:27.387148Z","created_by":"cscheid"}}} +{"id":"bd-4ciw","title":"Investigate tree-sitter ':' handling in line-break: definition list / fenced div edge cases","description":"Sibling of bd-af1e/bd-wv4e investigation. The line-break handler also excludes ':' as a paragraph interrupter. ':' has more entangled semantics in qmd:\n- Definition list term/definition (':' at start of line after a paragraph defines a definition list).\n- Fenced div marker (qmd-specific, ':::' or more).\n- Plain text otherwise.\n\nVerify whether ':something' (single colon then content) at line start is correctly soft-broken. Initial pampa output appeared to error on the test fixture; needs investigation.\n\nReference fix pattern: bd-af1e (claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-30T18:40:25.424566Z","created_by":"cscheid","updated_at":"2026-04-30T18:45:29.712291Z","closed_at":"2026-04-30T18:45:29.712148Z","close_reason":"Re-scoped: ':' has backslash-escape workaround (\\:foo). Not severe enough to fix in this pass.","dependencies":{"bd-af1e:related":{"depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:40:25.424566Z","created_by":"cscheid"}}} +{"id":"bd-4eyf","title":"Bootstrap JS runtime injection for HTML output","description":"Auto-include Bootstrap 5 JS (bundle, with Popper) for HTML renders that use a Bootstrap-backed theme, mirroring Quarto 1's behavior but via q2's artifact-store pipeline.\n\nPlan: claude-notes/plans/2026-05-04-bootstrap-js-injection.md\n\nScope:\n- Vendor bootstrap.bundle.min.js (5.3.1, ~80KB, includes Popper) under resources/js/bootstrap/.\n- Add BootstrapJsStage in crates/quarto-core/src/stage/stages/, run after CompileThemeCssStage.\n- Predicate: !is_minimal_html(meta) — same condition that triggers Bootstrap CSS compilation.\n- Register js:bootstrap as Project-scoped artifact; ApplyTemplateStage emits the <script> tag automatically, no separate raw-HTML injection step.\n- DO NOT add the stage to build_wasm_html_pipeline() — hub-client's iframe-reinit-per-render breaks stateful Bootstrap components. Same skip pattern as EngineExecutionStage.\n\nOut of scope:\n- MathJax/math-mode injection (next session; q2 cannot delegate to Pandoc the way Q1 does because the q2 HTML pipeline doesn't invoke Pandoc — see plan doc for notes).\n- Any richer JsFeature/registry abstraction. Defer until a third concrete consumer arrives.\n- Bootstrap-icons CSS (verify it's already in the SCSS bundle; if missing, file a separate follow-up).\n\nTDD per CLAUDE.md: write the predicate-matrix unit tests + end-to-end render-through-CLI tests + WASM-pipeline omission test before implementing.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T21:41:13.795242Z","created_by":"cscheid","updated_at":"2026-05-04T22:09:35.376988Z","closed_at":"2026-05-04T22:09:35.376837Z","close_reason":"Bootstrap JS runtime injected as Project-scoped js:bootstrap artifact when theme is Bootstrap-backed; native pipeline only (WASM omitted); 21/21 bootstrap-related tests pass, 8384/8384 workspace, full cargo xtask verify green; live Chromium smoke confirmed bootstrap 5.3.1 + Popper. Plan: claude-notes/plans/2026-05-04-bootstrap-js-injection.md"} +{"id":"bd-4g6g","title":"[websites epic] Move sidebar to Q1 template position (sidebar-left)","description":"Phase 2 puts the sidebar beside the TOC on the right — minimum churn in the existing FULL_HTML_TEMPLATE. Q1 renders sidebar-left, TOC-right. Moving to the Q1 layout is a template restructuring task: change the two-column grid, adjust layout CSS, and re-verify any layout-sensitive tests. Separate from sidebar feature work.\n\nPlan reference: claude-notes/plans/2026-04-24-websites-phase-2.md Decision 4 + follow-up.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T17:53:05.037896Z","created_by":"cscheid","updated_at":"2026-04-24T17:53:05.037896Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:53:05.037896Z","created_by":"cscheid"}}} +{"id":"bd-4ho9","title":"L9 follow-up: validate against W3C feed validator","description":"L9 v1 ships snapshot tests + manual end-to-end inspection. File any parse warnings raised by canonical RSS validators on representative outputs and fix. Validators to try: W3C feed validator (online), feedvalidator.org's offline tool, Pandoc's own RSS schema if available.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-08T17:33:22.925543Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:22.925543Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:22.925543Z","created_by":"cscheid"}}} +{"id":"bd-4ltdl","title":"Author error-docs pages for template subsystem (7 codes)","description":"Author stub-quality pages for all 7 template subsystem error codes under docs/errors/template/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:57.022926Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.653391Z","closed_at":"2026-05-24T21:15:22.653051Z"} +{"id":"bd-4uvv","title":"SPA getBinaryDocById missing automerge: URL prefix → binary capture docs never reach WASM","description":"ts-packages/quarto-sync-client/src/client.ts:getBinaryDocById passes the bare docId from the IndexDocument capture sidecar straight to repo.find(). The samod TS library rejects this with 'Error: Invalid AutomergeUrl: <id>' because it requires the 'automerge:' scheme prefix. The text-doc loader (loadFileDocuments) prepends the prefix explicitly (lines 305-307); getBinaryDocById doesn't. Net effect: every project-mode q2 preview render falls back to the default registry because captureGzJson is undefined, and code cells render as inert source — the exact user-reported bug. Diagnosed end-to-end on 2026-05-18 against the fixture website. Trivial fix: same 'automerge:' prefix-normalize pattern as loadFileDocuments. Critical because it makes the entire Phase C.4 replay path silently inert for real users.","status":"open","priority":0,"issue_type":"bug","created_at":"2026-05-18T14:58:25.801153Z","created_by":"cscheid","updated_at":"2026-05-18T14:58:25.801153Z","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T14:58:25.801153Z","created_by":"cscheid"},"bd-m0mu:discovered-from":{"depends_on_id":"bd-m0mu","type":"discovered-from","created_at":"2026-05-18T14:58:25.801153Z","created_by":"cscheid"}}} +{"id":"bd-4y8fd","title":"Reclaim disk space from stale worktrees + per-worktree target/ trees","description":"Stale .worktrees/ directories accumulate ~45G each (mostly from per-worktree cargo target/ trees), and disk-full conditions block tool execution. Recently observed: 5 worktrees consuming 220G; same machine ran out of space mid-session.\n\nTwo pieces of work:\n1. cargo xtask reap-worktrees — list worktrees with age/size/merged-status, remove stale ones (interactive by default; --force for batch).\n2. Update worktree-spawning skills (/investigate-beads, /triage, /upgrade-cargo-deps) so they end by suggesting git worktree remove once the work has landed.\n\nExplicit non-goal: shared CARGO_TARGET_DIR across worktrees. User has declined for cross-branch correctness risk.\n\nPlan: claude-notes/plans/2026-05-22-worktree-disk-reclamation.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T18:28:28.703065Z","created_by":"cscheid","updated_at":"2026-05-22T18:28:28.703065Z","labels":["disk-space","tooling","worktrees"]} +{"id":"bd-4zdf","title":"Draft-mode interaction with sitemap","description":"Phase 7 emits sitemap entries for every profiled page including drafts. When draft-mode YAML config lands (see bd-p4sc and friends from Phase 6), gate the sitemap emission so draft pages are omitted unless draft-mode == \"visible\". Originating phase: bd-b9mz; coordinate with bd-p4sc.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:03:22.529546Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.529546Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.529546Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.529546Z","created_by":"cscheid"},"bd-p4sc:related":{"depends_on_id":"bd-p4sc","type":"related","created_at":"2026-04-27T15:03:22.529546Z","created_by":"cscheid"}}} +{"id":"bd-501n","title":"Phase A.4: cargo xtask build-q2-preview-spa + build-all wiring","description":"New crates/xtask/src/build_q2_preview_spa.rs (mirror build_trace_viewer). Extend build-all to chain the SPA build before cargo build so include_dir! picks up the real bundle. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.4.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-13T16:53:28.180875Z","created_by":"cscheid","updated_at":"2026-05-13T18:08:07.598898Z","closed_at":"2026-05-13T18:08:07.598760Z","close_reason":"Phase A.4 landed on branch beads/bd-501n-phase-a4-cargo-xtask (commit 1d5fbc9b). New cargo xtask build-q2-preview-spa + extended build-all chain (q2-preview-spa step inserted before Rust workspace build). cargo xtask verify 11/11.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.180875Z","created_by":"cscheid"}}} +{"id":"bd-55n0g","title":"JSON-OUTPUT-SCHEMA.md describes a stale Q-1-XX numbering scheme that does not match the catalog or src/error.rs","description":"crates/quarto-yaml-validation/JSON-OUTPUT-SCHEMA.md lines 134-152 list Q-1-13 = 'String too short', Q-1-14 = 'String too long', Q-1-16 = 'Number out of range', etc. — but the actual mapping in src/error.rs::ValidationErrorKind::error_code and the catalog assigns those numbers to other kinds (Q-1-13 = ArrayLengthInvalid, Q-1-16 = ObjectPropertyCountInvalid). The file is broadly stale and would mislead anyone reading it. Needs a wholesale rewrite to match the current catalog.\n\nDiscovered while fixing bd-gdzlq (Q-1-20 double-allocation). Only the Q-1-20 → Q-1-29 line was updated in that fix; the rest of the file stays stale until this issue is taken.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-22T20:26:45.950001Z","created_by":"cscheid","updated_at":"2026-05-22T20:26:45.950001Z","labels":["documentation","error-reporting","yaml"],"dependencies":{"bd-gdzlq:discovered-from":{"depends_on_id":"bd-gdzlq","type":"discovered-from","created_at":"2026-05-22T20:26:45.950001Z","created_by":"cscheid"}}} +{"id":"bd-56b0","title":"Cross-doc dependency channel audit for q2 preview","description":"Enumerate every Quarto feature that creates a cross-document dependency the preview pipeline needs to react to: include shortcodes, listing content globs, bibliography/csl paths, theme SCSS imports, project-scoped resources, _extensions/ Lua filters, and anything else. For each: which DocumentProfile channel encodes it today (if any), which need to be added, which stay manual-refresh-only. Drives Phase B (channels already on DocumentProfile) and informs Phase D (new channels). Until this lands, the always-visible manual force-refresh button (Phase A.6) is the user escape hatch. See claude-notes/plans/2026-05-11-q2-preview-epic.md §Recommended next steps item 3 + Risk 2.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-11T15:40:54.896280Z","created_by":"cscheid","updated_at":"2026-05-11T15:40:54.896280Z","dependencies":{"bd-kw93:related":{"depends_on_id":"bd-kw93","type":"related","created_at":"2026-05-11T15:40:54.896280Z","created_by":"cscheid"}}} +{"id":"bd-57y4","title":"Vendor and integrate quarto-listing.scss with theme-CSS pipeline","description":"Per L3 D5 (decided 2026-05-06), the listing JS pair (list.min.js + quarto-listing.js) shipped via the artifact store as Project-scoped js: artifacts in the L3 phase 7 commit. The third asset, quarto-listing.scss, was deferred because it requires Bootstrap variable wiring + media-breakpoint mixins from the existing theme-CSS pipeline (CompileThemeCssStage / quarto_sass::SassLayer). That's a larger design task than the static JS bundling.\n\nThis issue: integrate the listing SCSS as a SassLayer that gets composed with the website's theme bundle. The Q1 source file lives at external-sources/quarto-cli/src/resources/projects/website/listing/quarto-listing.scss; copy to resources/listing/quarto-listing.scss per the External Sources Policy and add it to the theme bundle when at least one listing is rendered.\n\nWhile the SCSS isn't compiled, listings render with default browser styling — the markup and JS are unchanged. The list / grid / table layouts work but lack the polished card / table styling Q1 ships.\n\nDiscovered while shipping L3 phase 7 (bd-ml8z); see D5 in claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md.\n\nL5 (bd-5vsr) lands the markup that consumes this SCSS; merging bd-57y4 restores Q1 visual parity for category sidebars and per-item category chips.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T20:52:15.894830Z","created_by":"cscheid","updated_at":"2026-05-07T13:46:18.157025Z","dependencies":{"bd-ml8z:discovered-from":{"depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T20:52:15.894830Z","created_by":"cscheid"}}} +{"id":"bd-5ijtt","title":"User-facing docs for mermaid diagrams","description":"Add a user-facing docs page under docs/ explaining `{mermaid}` code blocks: syntax, what gets rendered, browser-runtime caveats (requires network access to jsdelivr; diagram appears after page load), known limitations (HTML output only in first cut). Render with cargo run --bin q2 -- render docs/ (Q2, not Q1) per CLAUDE.md.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-28T13:45:22.896182Z","created_by":"cscheid","updated_at":"2026-05-28T13:45:38.414661Z","dependencies":{"bd-gwfdo:blocks":{"depends_on_id":"bd-gwfdo","type":"blocks","created_at":"2026-05-28T13:45:38.414195Z","created_by":"cscheid"},"bd-je48v:parent-child":{"depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:22.896182Z","created_by":"cscheid"}}} +{"id":"bd-5qnj","title":"Manage trace size for use as replay/regression-test fixtures","description":"Spun out of bd-45yw (replay engine). Once traces double as replay fixtures (and as user-attached bug-report artifacts), trace size becomes a real constraint — they will be checked into the repo as regression fixtures and posted by users in issues.\n\nCurrent quarto-trace output captures per-stage pipeline state (see crates/quarto-trace/src/lib.rs and crates/quarto-core/src/stage/trace.rs::JsonTraceObserver), which is already on the heavy side for routine diagnostic use.\n\nInvestigate:\n- Where the bulk lives in current traces (per-stage AST snapshots? supporting_files content? something else?)\n- Which content is actually load-bearing for replay vs. diagnostics, and whether the two roles can share one artifact (the design preference noted in bd-45yw's plan)\n- Compression on disk; lazy loading on read\n- Whether per-stage AST snapshots can be elided/diffed when not needed\n- Size budgets — what is reasonable for (a) checked-in CI fixtures and (b) user-attached bug reports\n\nGoal: make 'one trace serves both diagnostic and replay roles' practical. If size cannot be bounded, fall back to two separate artifacts and document why.\n\nReferences:\n- crates/quarto-trace/src/lib.rs (TraceDocument, TraceEntry)\n- crates/quarto-core/src/stage/trace.rs (JsonTraceObserver)\n- claude-notes/plans/2026-05-03-replay-engine.md (open subquestion in Phase 1)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-03T21:11:19.859036Z","created_by":"cscheid","updated_at":"2026-05-03T23:29:05.405253Z","closed_at":"2026-05-03T23:29:05.405068Z","close_reason":"Phases 1, 2, 3, and 5 complete. End-to-end verified on bd-5qnj fixtures: big.qmd 16.3 MB pretty -> 62 KB gzipped+deduped (~265x). Unified-artifact promise realized post-merge with bd-45yw. Real-engine supporting_files re-measurement tracked as bd-sr73.","dependencies":{"bd-45yw:related":{"depends_on_id":"bd-45yw","type":"related","created_at":"2026-05-03T21:11:19.859036Z","created_by":"cscheid"}}} +{"id":"bd-5vsr","title":"L5 — Categories sidebar","description":"Right-margin category list emitted from L3's resolved item set, grouped by category. Three Q1-parity styles: category-default, category-unnumbered, category-cloud. Templates embedded as doctemplate via MemoryResolver. Click-to-filter interactivity scoped out of v1. See claude-notes/plans/2026-05-05-listings-epic.md §L5.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-05T19:53:32.333630Z","created_by":"cscheid","updated_at":"2026-05-07T16:00:41.250061Z","closed_at":"2026-05-07T16:00:41.249924Z","close_reason":"L5 — categories sidebar landed on feature/listings via merge 9e8afa0d (impl 2750546b + follow-on 67a985f4). Per-item chips + right-margin sidebar with three modes (default/unnumbered/cloud); Q-12-11 and Q-12-12 diagnostics; aggregate across multi-listing pages. End-to-end CLI verification recorded in plan §End-to-end CLI verification record. cargo xtask verify clean (Rust + hub-client + WASM). Test count 8570 → 8621 (+51). Discovered-from follow-ups filed: bd-99ru (localize labels), bd-754f (review encoding scheme), bd-ra5j (hub-client browser smoke deferred), bd-nwyp (PandocInlines parser audit).","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:32.333630Z","created_by":"cscheid"},"bd-ml8z:blocks":{"depends_on_id":"bd-ml8z","type":"blocks","created_at":"2026-05-05T19:53:32.333630Z","created_by":"cscheid"}}} +{"id":"bd-5yff4","title":"Sequential multi-engine execution (engine: [a, b, ...])","description":"Investigate and design support for running multiple Quarto 2 execution engines in sequence for a single document.\n\nTwo coupled changes:\n\n1. YAML config: allow 'engine:' to be an ordered array (e.g. engine: [knitr, mermaidjs]) in addition to the current singular string/map forms. Distinct engines only; order is significant (engine N may emit code cells consumed by engine N+1). Array merge across config layers uses the existing default (!concat); no engine-specific tag default for now.\n\n2. Pipeline: thread N engines through EngineExecutionStage. The AST->text->engine->text->AST->reconcile loop already type-checks end-to-end; each subsequent engine starts from the AST after the prior engine's results were reconciled in. Generalize the FileId/intermediate-file slot handling (currently 2 slots: .qmd + one .rmarkdown) to N+1 slots.\n\nTracing/replay/preview redesign: TraceDocument.engine_capture (single Option slot, name-keyed replay) becomes per-engine. Capture one AST snapshot + one EngineCapture per engine invocation within the stage, mirroring the existing transform:<name> sub-entry pattern. Preview record/replay (record_capture, with_replay, preview cache) generalize from one capture to an ordered list.\n\nValidation/testing uses a simple file-backed test engine (reads a results file and splices per-cell outputs in order) so multi-engine sequencing can be exercised deterministically without R/Python/Jupyter, and without committing to a real second engine (e.g. mermaidjs) yet.\n\nPlan: claude-notes/plans/2026-05-27-multi-engine-execution.md\n\nStatus: design/investigation. Implementation gated on user go-ahead after plan review.","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-27T14:07:37.941942Z","created_by":"cscheid","updated_at":"2026-05-27T14:33:39.118501Z"} +{"id":"bd-5ym51","title":"tree-sitter inline-multiline-attrs tests fail with 20 parse errors on main","description":"Running 'tree-sitter test' from crates/tree-sitter-qmd/tree-sitter-markdown/ reports 20 failing test cases in the inline-multiline-attrs corpus group (cases 95-104 plus a heading case), with 'Total parses: 508; successful parses: 488; failed parses: 20; success percentage: 96.06%'. This trips 'cargo xtask verify' at Step 4/12.\n\nConfirmed pre-existing on origin/main HEAD (3e781667 at time of report) by stashing all local changes and re-running the test — same failures. The failing cases overlap with the feature that landed in 1afd5a6ac95dd ('tree-sitter-qmd - allow multi-line attribute lists on inline images/spans (#209)', merged 2026-05-17).\n\nFailing case names include:\n- image with multi-line class-only attrs (quarto-web hero-banner case)\n- image with multi-line mixed class + key=value attrs\n- image with single-line class + leading and trailing whitespace inside braces\n- span with multi-line class attrs\n- span with multi-line key=value attrs\n- heading with leading whitespace inside block attribute_specifier braces\n- bulleted/ordered list item with multi-line span/image attrs\n- nested bulleted list with multi-line span attrs in inner item\n\nLikely causes (need investigation):\n1. The compiled parser.c committed in 1afd5a6a doesn't match the grammar.js changes — needs regeneration.\n2. The test corpus expectations were updated but the parser output diverged.\n3. The 'tree-sitter test' tool version disagrees with what was used at merge time.\n\nDiscovered-from: bd-j73yw (Phase 1 of bd-1tl09, code-block decorations) — surfaced while running cargo xtask verify after Phase 0 / Phase 1 commit 1 work. Not caused by that work; clean stash confirms regression on main.\n\nWorkaround for the dependent epic: run 'cargo xtask verify --skip-treesitter-tests' (or call cargo nextest / cargo build steps directly) until this is fixed.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-19T20:41:11.658379Z","created_by":"cscheid","updated_at":"2026-05-19T20:41:11.658379Z","dependencies":{"bd-j73yw:discovered-from":{"depends_on_id":"bd-j73yw","type":"discovered-from","created_at":"2026-05-19T20:41:11.658379Z","created_by":"cscheid"}}} +{"id":"bd-61cd","title":"Listings feature epic","description":"Implement Q1-feature-parity listings on Q2's DocumentProfile + 2-pass architecture. Sub-phases L0–L11. Plan: claude-notes/plans/2026-05-05-listings-epic.md. Discussion: claude-notes/plans/2026-05-05-listings-design-discussion.md. Settled decisions: C5 listing_item profile field, doctemplate-not-EJS, generate/render decomposition, L7 bracketed as CLI-only with mandatory L1 fallback.","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-05T19:52:42.035992Z","created_by":"cscheid","updated_at":"2026-05-05T19:52:42.035992Z"} +{"id":"bd-66nd","title":"CI disk-space cleanup: profile.ci + drop redundant cargo build","description":"Test-suite workflow hits 'No space left on device' on ubuntu-latest during cargo nextest run despite the existing free-disk-space step (run 25062065055 on PR #139, freed 18.8 GB but not enough). Add [profile.ci] Cargo profile to strip debuginfo, remove redundant cargo build step before nextest, enable remove_tool_cache: true on free-disk-space, and prune Docker images. Full rationale in claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md. Implemented on branch ci-disk-space-profile-ci (4 commits, not yet pushed).","status":"closed","priority":1,"issue_type":"chore","created_at":"2026-04-28T17:17:54.174452300Z","created_by":"cderv","updated_at":"2026-05-04T14:42:11.368436Z","closed_at":"2026-05-04T14:42:11.368004800Z","close_reason":"Merged in PR #141 (squash commit 7fb348e7)","comments":{"c-m02hdsoc":{"id":"c-m02hdsoc","author":"cderv","created_at":"2026-04-29T08:06:15Z","text":"Branch pushed and PR #141 opened https://github.com/quarto-dev/q2/pull/141 — CI verification pending on next workflow run. Will close when PR merges."}}} +{"id":"bd-6cme","title":"[websites] Sidebar search integration","description":"Add search tool support to sidebars. Depends on the separate search epic (which defines the client-side search infrastructure). Phase 2 parses the YAML but ignores it at render time.\n\n- Sidebar 'search: true' or 'search: \"overlay\"' metadata.\n- Render integration with whichever search backend we ship.\n- Sidebar layout accommodates the search input.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-24T17:52:19.276301Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:19.276301Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:19.276301Z","created_by":"cscheid"}}} +{"id":"bd-6qbto","title":"quarto-parse-errors produce_diagnostic_messages panics on invalid UTF-8 input (lossy-string / tree-sitter offset mismatch)","description":"## Symptom\n\n```\nthread 'tokio-rt-worker' panicked at crates/quarto-parse-errors/src/error_generation.rs:121:35:\nstart byte index 7748 is not a char boundary; it is inside '�' (bytes 7746..7749 of string)\n```\n\nTriggered today by feeding a PNG to the parse pipeline (sibling bd-i6jy4). Even with that upstream fixed, this function should not panic on any input — it is a diagnostic generator and must degrade gracefully.\n\n## Root cause\n\n`crates/quarto-parse-errors/src/error_generation.rs:112`:\n\n```rust\nlet input_str = String::from_utf8_lossy(input_bytes);\nlet byte_offset = calculate_byte_offset(&input_str, parse_state.row, parse_state.column);\nlet substring = &input_str[byte_offset..]; // line 121, panics\n```\n\n`from_utf8_lossy` replaces each invalid byte (or invalid sequence) with `U+FFFD` (3 bytes), so `input_str` is longer than `input_bytes` whenever the input is not valid UTF-8. Tree-sitter, however, reports `row` and `column` as byte offsets into the *original bytes*. `calculate_byte_offset` walks `input_str` using those numbers as if they referred to the lossy string, so the result can land inside a 3-byte `�` and the slice panics.\n\nThe same pattern repeats at `error_generation.rs:196` inside the per-note span-end loop, so any error with a successful note-emission path on UTF-8-invalid input would also panic.\n\n## Fix approach\n\nOperate on `input_bytes` directly for offset arithmetic (which is what tree-sitter's offsets describe), and only convert to a `Cow<str>` for the *small* slice that needs char-counted span-end advancement. Specifically:\n\n1. `calculate_byte_offset` should take `&[u8]` and walk byte-wise: count newlines, then add column. That maps 1:1 to tree-sitter's reported positions.\n2. The char-counted span-end loop (`size` chars, line ~120 and ~194) should slice `input_bytes[offset..]` first, then `from_utf8_lossy` only the slice, then advance by `ch.len_utf8()`. That keeps the byte-domain offsets honest while still handling multi-byte characters correctly when the input *is* valid UTF-8.\n3. `quarto_source_map::utils::offset_to_location` is called on `&input_str` — it likely expects a `&str`. Need to pass a lossy conversion at the call site or extend the source-map API to take bytes. Investigate which is less invasive.\n\nA blanket `floor_char_boundary` would silence the panic but produce incorrect locations under the same byte/string mismatch. Do not paper over.\n\n## Tests\n\nAdd a unit test in `quarto-parse-errors`:\n- `produce_diagnostic_messages` over a binary input (e.g., the embedded PNG fixture or any `vec![0xff, 0xfe, ...]`) must return a Vec without panicking. Content of the diagnostic is not asserted — only \"does not panic\".\n- Add a property-style test that feeds random byte sequences via `proptest` or hand-rolled corpus and asserts no panic.\n\n## Out of scope\n\nFiltering binaries out of the upstream callers — that is bd-i6jy4. This issue is purely the defensive contract that diagnostic generation never panics regardless of input.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-19T23:44:10.685110Z","created_by":"cscheid","updated_at":"2026-05-20T13:26:35.310641Z","closed_at":"2026-05-20T13:26:35.310472Z","close_reason":"Implemented in bd20002e (merged via 52de7fc2). error_diagnostic_from_parse_state now operates entirely in the input_bytes domain — calculate_byte_offset takes &[u8], new advance_chars + offset_to_location_bytes helpers keep all offsets honest, and the leading/trailing-space trim loops are byte-level. Regression test produce_diagnostic_messages_does_not_panic_on_invalid_utf8 reproduces the panic on parent commit; passes here. Full workspace 9187/9187 green; no snapshot drift on valid UTF-8 paths.","dependencies":{"bd-i6jy4:related":{"depends_on_id":"bd-i6jy4","type":"related","created_at":"2026-05-19T23:44:10.685110Z","created_by":"cscheid"},"bd-tnm3k:discovered-from":{"depends_on_id":"bd-tnm3k","type":"discovered-from","created_at":"2026-05-19T23:44:10.685110Z","created_by":"cscheid"}}} +{"id":"bd-732bn","title":"Author error-docs pages for theme subsystem (2 codes)","description":"Author stub-quality pages for all 2 theme subsystem error codes under docs/errors/theme/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:57.831390Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.969708Z","closed_at":"2026-05-24T21:15:22.969353Z"} +{"id":"bd-74qv","title":"Add Quoted inline node support to slides renderer","description":"ReactAstSlideRenderer doesn't handle Quoted nodes. Add QuotedInline type and render case using curly quotes. Plan: claude-notes/plans/2026-03-12-quoted-node-slides-renderer.md","status":"open","priority":3,"issue_type":"feature","created_at":"2026-03-12T13:51:27.585187Z","created_by":"cscheid","updated_at":"2026-03-12T13:51:27.585187Z"} +{"id":"bd-754f","title":"Review category click-handler encoding scheme (b64+percent-encoding)","description":"L5 (bd-5vsr) ships b64(percent-encoded UTF-8) on the Rust encoder side and inherits the matching decodeURIComponent(atob(...)) decoder on the JS side via the vendored quarto-listing.js. The scheme works but inherits Q1's choice without revisiting it. Open questions for the review: (a) is data-category better off carrying the raw category string instead, with the JS reading it directly (no encode/decode pair, simpler in both halves)? (b) if we keep an encoded form, should we move to a single Rust crate's idiom (e.g. base64-only on UTF-8 + matching Rust-style decoder in JS) and drop the percent-encoding round-trip? (c) does any reserved character in category names interact poorly with HTML attribute values, JS string literals, or URL hash routing — and would a different scheme avoid those edge cases? Out of scope for L5 (we want Q1 parity first); file when encoding lands so the discussion isn't lost. Plan: claude-notes/plans/2026-05-06-listings-L5-categories-sidebar.md §'Filing reminder' #2.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T13:45:52.536289Z","created_by":"cscheid","updated_at":"2026-05-07T13:45:52.536289Z","dependencies":{"bd-5vsr:discovered-from":{"depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T13:45:52.536289Z","created_by":"cscheid"}}} +{"id":"bd-78ud","title":"Empty {stem}_files/ cleanup for pages with no Page-scoped artifacts","description":"Today render_document_to_file calls prepare_html_resources which always creates {stem}_files/, even when the page emits no Page-scoped artifacts (which is the common case for prose-only pages under a website project — all theme/extension CSS lives in site_libs/). Result: every rendered website has empty {stem}_files/ directories scattered around. Opportunity: defer creation until the first Page-scoped write, or skip creation entirely when no Page artifacts exist. Tracked from Phase 5 as open question 5; see claude-notes/plans/2026-04-24-websites-phase-5.md.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-25T01:31:24.276058Z","created_by":"cscheid","updated_at":"2026-04-29T17:19:51.662612Z","closed_at":"2026-04-29T17:19:51.662200Z","close_reason":"Dropped eager dir_create from prepare_html_resources. {stem}_files/ is now created lazily by write_artifacts via dir_create(parent, true) on each artifact write — only when there's something to put inside. Prose-only website pages no longer leave empty per-page dirs in _site/. Single-doc renders still create the dir (theme CSS routes there for lib_dir == ''). New regression test website_render_omits_empty_stem_files_dirs in tests/artifact_scoping_pipeline.rs. End-to-end verified across 5 example projects: 0 empty dirs in any _site tree.","dependencies":{"bd-u5pr:discovered-from":{"depends_on_id":"bd-u5pr","type":"discovered-from","created_at":"2026-04-25T01:31:24.276058Z","created_by":"cscheid"}}} +{"id":"bd-79xl","title":"Surface FormatIdentifier::Custom discriminant in TS engine protocol","description":"TsEngine::execute (Plan 1a Phase 1) asserts !matches!(fmt.identifier, FormatIdentifier::Custom(_)) because Custom(u32).as_str() returns the literal \"custom\" and drops the u32 discriminant (crates/quarto-core/src/format.rs:44-58). The assert means TS engine extensions cannot run against any custom format.\n\nResolution path:\n- Decide where the per-Custom(u32) format name lives. Either add a registry that maps the discriminant to a name string, or include the discriminant in the protocol via a new field (e.g., add an optional \"custom-name\" field to TsFormatIdentifier).\n- Plumb it through TsFormatIdentifier.base-format (or a sibling) so the harness can pass it to TS engines correctly.\n- Remove the assert in TsEngine::execute.\n\nLand before the first custom format ships to production. No urgency today (no in-tree custom formats); urgency rises when a downstream extension defines one.\n\nContext: discovered during Plan 1a editorial review. See claude-notes/plans/2026-04-16-plan1a-protocol-and-core.md (\"Custom-format gotcha\" in the format.identifier mapping section).","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-06T19:06:56.710766Z","created_by":"gordon","updated_at":"2026-05-06T19:06:56.710766Z"} +{"id":"bd-7co9","title":"Clean up stale 'fork of tree-sitter-markdown' framing in tree-sitter-qmd","description":"tree-sitter-qmd is repo-native and has been developed independently for a long time, but several files still describe it as a fork of upstream tree-sitter-markdown. This misleads agents auditing for vendored dependencies (see claude-notes/research/vendored-dependencies-inventory.md entry H). Files to fix: crates/tree-sitter-qmd/README.md (line 3 fork claim); crates/tree-sitter-qmd/package.json (name/version/author/repository all upstream values); crates/tree-sitter-qmd/tree-sitter.json (metadata still upstream); crates/tree-sitter-qmd/README.tree-sitter-md.md (verbatim upstream README — delete or mark historical); the nested crates/tree-sitter-qmd/tree-sitter-markdown/ directory implies vendoring by layout (rename optional). tree-sitter-doctemplate was checked and is fine.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T21:24:05.479792Z","created_by":"cscheid","updated_at":"2026-05-04T21:39:51.600399Z","closed_at":"2026-05-04T21:39:51.600240Z","close_reason":"Cleaned up stale fork framing in tree-sitter-qmd: README.md rewritten, tree-sitter.json metadata replaced, README.tree-sitter-md.md and package.json/lock deleted. Committed on .worktrees/7co9-fork-framing-cleanup. Other multi-language scaffolding (pyproject.toml, setup.py, go.mod, Package.swift, binding.gyp, CMakeLists.txt, Makefile, bindings/{go,node,python,swift}/) left as a possible follow-up.","labels":["deps","docs"],"dependencies":{"bd-xm7l:discovered-from":{"depends_on_id":"bd-xm7l","type":"discovered-from","created_at":"2026-05-04T21:24:05.479792Z","created_by":"cscheid"}}} +{"id":"bd-7eohf","title":"Phase 4 — hub-mcp device-flow primitives (initiate + pollOnce)","description":"New module ts-packages/quarto-hub-mcp/src/auth/device-flow.ts on oauth4webapi + jose. Two primitives — initiateDeviceFlow, pollDeviceFlowOnce — not a single blocking flow.\n\nTDD: 14-test fixture-driven suite (msw or undici MockAgent — never live Google), then implement. Centralised redact() at every log site; process-level uncaughtException handlers scrub Google-token-shaped substrings.\n\nClient auth: oauth.ClientSecretPost(secret). client_id and client_secret sourced only from process.env (QUARTO_HUB_MCP_CLIENT_ID / _CLIENT_SECRET).\n\nPlan §Phase 4: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:05.380683Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:05.380683Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:05.380683Z","created_by":"shikokuchuo"}}} +{"id":"bd-7giz","title":"Add 'cargo xtask setup' for fresh clone/worktree bootstrap","description":"Fresh worktrees (and fresh clones) currently fail 'cargo xtask verify' because the hub-client TypeScript build depends on node_modules/ that isn't created by verify. Discovered while bootstrapping the issue-152 worktree on 2026-05-03 — verify ran the WASM build successfully, then hub-client's tsc step failed with 'Cannot find module' for every npm dep until 'npm install' was run manually from the worktree root.\n\nProposal: introduce 'cargo xtask setup' as a discrete bootstrap verb that runs 'npm install' (and any future first-run prerequisites like rustup component add). Then either:\n (a) have 'verify' detect a missing node_modules/ and exit with 'run cargo xtask setup first', or\n (b) have 'verify' call into the same setup logic when it detects first-run state.\n\nOther large Rust+JS monorepos (Deno, Tauri) keep these separate; rust-analyzer hard-fails with a hint. Keeping 'verify' semantically about checking (not network installs) seems preferable.\n\nCross-reference: this snag should also be documented in the upcoming triage/diagnose skill (.claude/skills/triage.md, not yet created) so that running the skill on a fresh worktree picks up bootstrap as a prerequisite step. Until 'cargo xtask setup' exists, the skill should explicitly run 'npm install' before 'cargo xtask verify'.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-03T16:21:43.847529Z","created_by":"cscheid","updated_at":"2026-05-12T12:29:01.546361500Z","dependencies":{"bd-f3pl:related":{"depends_on_id":"bd-f3pl","type":"related","created_at":"2026-05-03T16:27:22.098662Z","created_by":"cscheid"}},"comments":{"c-0yrana2f":{"id":"c-0yrana2f","author":"cderv","created_at":"2026-05-04T15:18:55Z","text":"cargo xtask dev-setup already exists — installs cargo-nextest and wasm-bindgen-cli (pinned, via cargo-binstall fallback to cargo install --locked). Consider extending dev-setup to also run npm install from repo root rather than introducing parallel 'setup' verb. Would unify Rust tool bootstrap + JS dep bootstrap behind one entry point. Skill .claude/skills/triage.md step 4 currently runs npm install manually — would switch to cargo xtask dev-setup once landed."},"c-2zg62nko":{"id":"c-2zg62nko","author":"chris","created_at":"2026-05-12T12:29:01Z","text":"Cross-ref from bd-spsv work (2026-05-12). `cargo xtask create-worktree`\nnow prints a per-worktree setup checklist on stdout that lists\n`cargo xtask dev-setup` and `npm install` as separate steps, with\n`npm install` flagged as \"only if hub-client work is in scope\". When\nthis issue lands (dev-setup also runs `npm install`), the create-worktree\noutput in `crates/xtask/src/create_worktree.rs::print_summary` should be\nupdated to drop the explicit `npm install` line. The relevant block to\nedit is the \"# Per worktree\" group inside print_summary."}}} +{"id":"bd-7h6a","title":"Per-page favicon override (meta.favicon beats website.favicon)","description":"User flagged 2026-04-27 as expected-soon. A document with its own meta.favicon should override website.favicon. Phase 7 deferred this; needs a small priority lookup in WebsiteFaviconTransform that prefers ast.meta.favicon over ast.meta.website.favicon. Sub-plan reference: claude-notes/plans/2026-04-27-websites-phase-7.md §Non-goals + §Follow-up beads. Originating phase: bd-b9mz.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:02:58.364038Z","created_by":"cscheid","updated_at":"2026-04-27T15:02:58.364038Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:02:58.364038Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:02:58.364038Z","created_by":"cscheid"}}} +{"id":"bd-7l1u","title":"Q-2-35: Reject 4-space indented code blocks with a custom parse error (issue #184)","description":"Indented (4-space) code blocks are currently parsed as paragraphs whose leading whitespace is dropped, corrupting documents on a qmd → qmd round-trip (GH issue #184). Per project policy (https://github.com/quarto-dev/q2/issues/184#issuecomment-4426182995) Quarto Markdown does not support indented code blocks; the parser must reject them with a high-quality error message instead.\n\nApproach: mirror the Q-2-32 (TRIPLE_STAR) pattern — emit an external token from scanner.c that is declared in grammar.js but consumed by no rule body, then map the resulting (state, sym) pair through the Merr-style error table in crates/quarto-parse-errors/ to a Q-2-35 diagnostic.\n\nPlan: claude-notes/plans/2026-05-14-q-2-35-indented-code-block-error.md (TDD, six error-corpus cases including a negative one, full xtask verify, no writer changes).\nTriage: claude-notes/issue-reports/184/triage.md\nBranch: issue-184 (worktree at .worktrees/issue-184/)\nRepro: claude-notes/issue-reports/184/repro.qmd\n\nScope confirmed with @cscheid (2026-05-14):\n- Error fires on >= 4 leftover indentation (after container matchers consume their share), so well-indented list continuations are unaffected but extra-indented ones are flagged.\n- Error code Q-2-35.\n- Message suggests fenced code blocks (```) as the replacement.\n- Documentation note added to tree-sitter-markdown CONTRIBUTING.md mirroring the Q-2-32 precedent.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-14T16:08:34.776338Z","created_by":"cscheid","updated_at":"2026-05-14T17:02:40.507132Z","closed_at":"2026-05-14T17:02:40.506948Z","close_reason":"Implemented and verified end-to-end on branch issue-184 (commit e2d224f6). Reporter's repro now produces Q-2-35 diagnostic spanning the full offending line. Full cargo xtask verify (Rust + WASM + hub-client) passes; tree-sitter test 480/480; pampa test suite 3687/3687; xtask lint clean. Conservative detection rule (ATX_H1_MARKER || BLANK_LINE_START) avoids false positives in multi-line shortcodes and lazy paragraph continuations — see the plan doc for the rationale and the rejected alternatives."} +{"id":"bd-7mpv","title":"qmd writer drops empty pipe-table header row, promotes first body row to header (issue #175)","description":"Round-trip bug: pipe table with all-empty header row parses as Table with TableHead [] [] (zero header rows). The qmd writer's write_table path unconditionally emits row_contents[0] as the header line, so it promotes the first body row, and the re-parser then reads that body row as the header. Silent data loss: head$rows goes 0→1 and the body loses a row.\n\nRoot cause: crates/pampa/src/writers/qmd.rs:1184-1190 (write_table). Predicate table_can_use_pipe_format at lines 870-910 also needs a multi-header guard if the fix touches it.\n\nFix scope: branch on table.head.rows.is_empty(); when zero, emit a synthetic empty header line (matches pandoc -t gfm) and treat every collected row as body. Add round-trip regression to tests/roundtrip_tests/qmd-json-qmd.\n\nFull triage record: claude-notes/issue-reports/175/triage.md on branch issue-175.\nReal-world impact: quarto-web docs/authoring/callouts.qmd, docs/output-formats/all-formats.qmd.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-11T20:26:54.784233Z","created_by":"cscheid","updated_at":"2026-05-11T20:35:36.602007Z","closed_at":"2026-05-11T20:35:36.601834Z","close_reason":"Fixed in 9457afe3 on branch issue-175. Adds synthetic empty header row in write_table when table.head.rows is empty; regression fixture pipe_table_empty_header.qmd in qmd-json-qmd/. cargo xtask verify passes."} +{"id":"bd-7sib","title":"Add webtex/gladtex/mathml/plain math methods","description":"bd-w5ov shipped MathJax + KaTeX. Pandoc and Quarto 1 also support 'webtex' (image rendering), 'gladtex' (alt-text), 'mathml' (pass-through), 'plain' (no rendering). Each has a different output markup contract.\n\nAdd these as additional MathEngine variants when there's user demand. Today, an unsupported method falls through to None and the math stage no-ops — the user's HTML still renders, just without typesetting.\n\nAcceptance: extend MathEngine::from_meta() to accept these strings, render appropriate markup in render_math_slot(), and add tests.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-04T23:58:23.111922Z","created_by":"cscheid","updated_at":"2026-05-04T23:58:23.111922Z","dependencies":{"bd-w5ov:discovered-from":{"depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:23.111922Z","created_by":"cscheid"}}} +{"id":"bd-7tvb","title":".quartoignore support in project file discovery","description":"Phase 1's discovery walker honors underscore/dot components, README names, output-dir, .quarto/, .git/, node_modules/ — but not a user-provided .quartoignore file. Q1 supports .quartoignore (gitignore-style patterns for files to exclude from render). Implement in crates/quarto-core/src/project/discovery.rs with tests.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T01:05:11.578909Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:11.578909Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:11.578909Z","created_by":"cscheid"}}} +{"id":"bd-81x4","title":"[websites] Multi-sidebar ambiguity diagnostic","description":"sidebar_for_page uses 'first match wins' containment. If the same page source-path appears in two sidebars without an explicit 'site-sidebar: <id>' override, the user gets surprising behavior silently. Add a diagnostic warning at Generate time when we detect multiple-containment and no explicit override.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T17:52:41.234718Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:41.234718Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:41.234718Z","created_by":"cscheid"}}} +{"id":"bd-82dn","title":"Empty-index.html filter for sitemap","description":"Q1's sitemap skips index.html files whose source qmd has no body (inputTargetIsEmpty). Q2 emits all pages. Defer until DocumentProfile carries an is_empty signal — coordinate with bd-r82e (DocumentProfile.includes follow-up which is the natural place to enrich the profile). Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.879323Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.879323Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.879323Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.879323Z","created_by":"cscheid"},"bd-r82e:related":{"depends_on_id":"bd-r82e","type":"related","created_at":"2026-04-27T15:03:22.879323Z","created_by":"cscheid"}}} +{"id":"bd-8356","title":"Cargo: upgrade quick-xml v0.37.5 → v0.39.2","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.37.5 is range-pinned in workspace; latest is 0.39.2. Type: pre-1.0 minor (semver-breaking); two minor steps. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.870931Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.213745Z","closed_at":"2026-05-04T20:30:45.213595Z","close_reason":"merged: de279916","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.942813Z","created_by":"cscheid"}}} +{"id":"bd-875x","title":"Phase 4: Upstream venv-aware kernelspec discovery to runtimed/runtimelib","description":"Open PR from cscheid/runtimelib:feat/venv-kernelspec-discovery against runtimed/runtimelib:main. **Intentionally last** in the plan: only after Phases 2 (bd-34wy) and 3 (bd-ij1l) are merged AND end-to-end validated on the original failing fixture from a venv shell. This is to avoid upstream PR thrash if validation surfaces fork-API tweaks.\n\nEntry criteria:\n- bd-34wy closed\n- bd-ij1l closed\n- End-to-end render of the original fixture succeeds from a venv shell (recorded in bd-ij1l close-out)\n- No outstanding 'we'll change the fork API' follow-ups\n\nIf accepted upstream and a release ships, replace [patch.crates-io] with a normal version bump. If rejected or stalled, leave the patch in place and document in CLAUDE.md.\n\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 4)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-04T15:50:01.991404Z","created_by":"cscheid","updated_at":"2026-05-04T17:25:44.218213Z","closed_at":"2026-05-04T17:25:44.218051Z","close_reason":"Opened https://github.com/runtimed/runtimed/pull/305 against runtimed/runtimed:main from cscheid:feat/venv-kernelspec-discovery (SHA fc58eb48). Title: 'feat(runtimelib)!: discover venv kernels via jupyter --paths'. Fixes runtimed/runtimed#304. Test plan, migration notes, and 'two changes in one PR' split-offer all included. PR awaits rgbkrk's review.","labels":["jupyter","upstream"],"dependencies":{"bd-34wy:blocks":{"depends_on_id":"bd-34wy","type":"blocks","created_at":"2026-05-04T15:50:01.991404Z","created_by":"cscheid"},"bd-fu0l:discovered-from":{"depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:50:01.991404Z","created_by":"cscheid"},"bd-ij1l:blocks":{"depends_on_id":"bd-ij1l","type":"blocks","created_at":"2026-05-04T15:59:49.066610Z","created_by":"cscheid"}}} +{"id":"bd-87fu","title":"Default-project theme artifacts not flushed in hub-client live preview","description":"After bd-h736 fixed default-project discovery, themes silently fail to render in hub-client for default projects unless the bytes are pre-cached in the VFS from a prior website-type render. Root cause: `RenderToHtmlRenderer.render` (WASM Pass-2) always drains Project-scope artifacts into the orchestrator accumulator, but `DefaultProjectType.post_render` is a no-op (only websites flush). Native works because `render_document_to_file` falls back to per-doc flush when `lib_dir` is empty. Fix proposal: mirror the lib_dir branch in `RenderToHtmlRenderer.render` (Option B in the plan) so default projects flush in-place via the per-page (vfs_root) resolver. Plan: claude-notes/plans/2026-05-01-default-project-theme-flush.md (open for user review before implementation starts).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T22:36:09.610620Z","created_by":"cscheid","updated_at":"2026-05-01T22:49:49.531487Z","closed_at":"2026-05-01T22:49:49.531334Z","close_reason":"Fixed by adding the lib_dir branch to RenderToHtmlRenderer.render: when lib_dir is empty (default projects), Project-scope artifacts are flushed in-place via the per-page (vfs_root) resolver instead of being drained into the orchestrator's accumulator (which DefaultProjectType.post_render would have ignored). Manually verified in hub-client at localhost:5173 — fresh themes (minty, materia) now render correctly with no console errors. Native default-project theme rendering unchanged. Follow-ups: bd-gdhk (extract shared helper) and bd-v8gx (rename flush_site_libs). Commit: c1af5b3b.","dependencies":{"bd-h736:discovered-from":{"depends_on_id":"bd-h736","type":"discovered-from","created_at":"2026-05-01T22:36:09.610620Z","created_by":"cscheid"}}} +{"id":"bd-87tr","title":"L8 follow-up: WASM/VFS-aware custom listing template loading","description":"Today (L8 D1) custom-template loading uses std::fs::read_to_string directly, so hub-client previews of `type: custom` listings fall back to the default built-in with Q-12-8. Plumb runtime through RenderContext (or pre-load template content during Pass-1) so VFS reads work in WASM. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §\"Out of scope\" / §\"Decisions log\" D1.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-08T14:56:49.244272Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:25.638507Z","closed_at":"2026-05-08T14:57:25.638365Z","close_reason":"Duplicate of bd-tmka","dependencies":{"bd-rqgx:discovered-from":{"depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:56:49.244272Z","created_by":"cscheid"}}} +{"id":"bd-8d6rk","title":"Migrate sidebar/navbar 'missing document information' warnings to structured diagnostics","description":"Today the missing-document and dropped-auto warnings in `crates/quarto-core/src/transforms/navigation_href.rs` (`resolve_href_for_html`, `resolve_doc_relative_href`) and `sidebar_auto.rs` (`strip_entries`, `expand_spec`) are emitted as plain `DiagnosticMessage::warning(format!(...))` strings: no error code, no SourceInfo, no catalog entry, no docs URL. Programmatic consumers (`--json`, hub-client) get a title-string only.\n\nGoal: migrate these warnings to structured `DiagnosticMessage` via the builder API. Allocate a new navigation subsystem in the error catalog (likely Q-13-*) for: missing referenced document (sidebar variant), missing referenced document (navbar variant), missing referenced document (page-footer variant), missing referenced document (body link variant), dropped `auto:` (no project index), unmatched `auto:` glob. Each gets a code, a title, a problem statement, a hint, and a catalog entry with `docs_url`.\n\nNote: this issue does NOT yet attach SourceInfo to the diagnostics — the parsers currently strip it. Initial diagnostics will set `location: None`. The follow-up (path-resolution / source-location plumbing) will fill in the location.\n\nPlan: claude-notes/plans/2026-05-20-bd-PLACEHOLDER-navigation-diagnostics.md (to be created)","notes":"Plan written: claude-notes/plans/2026-05-20-bd-8d6rk-navigation-diagnostics.md (draft, awaiting iteration before implementation)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-20T14:56:13.306265Z","created_by":"cscheid","updated_at":"2026-05-20T16:59:04.371379Z","closed_at":"2026-05-20T16:59:04.371196Z","close_reason":"Implementation complete on main. Q-13-1..7 navigation diagnostics live; all 9189 workspace tests pass; cargo xtask verify --skip-hub-build clean. End-to-end verified on docs/guide/index.qmd. Plan: claude-notes/plans/2026-05-20-bd-8d6rk-navigation-diagnostics.md (all phases checked). Changes uncommitted pending user review."} +{"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"} +{"id":"bd-8h3sn","title":"Precise cross-engine source attribution in EngineExecutionStage","description":"EngineExecutionStage threads the document's top-level source_context (constant) to every engine for error attribution. This is exact for engine 1; for engine 2+, offsets into content produced by an earlier engine don't resolve (their FileIds live only in the merged ASTContext), so error mapping is best-effort (None = no precise location). Matches the existing single-engine code's stated tolerance. A future refinement could thread the accumulating merged context. See engine_execution.rs run loop comment.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-27T16:24:40.252234Z","created_by":"cscheid","updated_at":"2026-05-27T16:24:40.252234Z","dependencies":{"bd-5yff4:discovered-from":{"depends_on_id":"bd-5yff4","type":"discovered-from","created_at":"2026-05-27T16:24:40.252234Z","created_by":"cscheid"}}} +{"id":"bd-8h9o","title":"L1 listings: filter unresolved shortcodes in image-src auto-fill","description":"ListingItemInfoStage (bd-izqh) runs after IncludeExpansionStage but BEFORE PreEngineSugaringStage. An Image node whose original src was a shortcode like '{{< meta thumbnail >}}.png' will still carry that literal text in target.0 at L1 time.\n\nL1 currently does not filter such cases when picking the first body image. When listings consume this field (L3+), unresolved shortcode markup could leak into rendered listings as the <img src=...>.\n\nInvestigate:\n- Real-world cases where image src is set via shortcode (Q1 examples worth grepping).\n- Whether the literal markers are limited to '{{<' / '>}}' or whether other deferred-substitution forms (e.g. '$var$') also reach this point.\n- Whether pre-engine sugaring resolves these in time for L1's data to be useful, or whether shortcode-bearing images need their own pass.\n- Resolution choice: skip such images entirely (use second image, or none); or store the unresolved form and have L3 strip; or wait for sugaring before extracting.\n\nOut of scope: L1 itself. This issue is the dedicated study; no behavior change in bd-izqh.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-06T13:40:57.410421Z","created_by":"cscheid","updated_at":"2026-05-06T13:40:57.410421Z","dependencies":{"bd-izqh:discovered-from":{"depends_on_id":"bd-izqh","type":"discovered-from","created_at":"2026-05-06T13:40:57.410421Z","created_by":"cscheid"}}} +{"id":"bd-8k4ny","title":"Author error-docs pages for internal subsystem (2 codes)","description":"Author stub-quality pages for all 2 internal subsystem error codes under docs/errors/internal/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:57.559596Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.865203Z","closed_at":"2026-05-24T21:15:22.864846Z"} +{"id":"bd-8kp3","title":"Implement include-in-header / include-before-body / include-after-body (HTML)","description":"Implement Q1-compatible document-include slot keys (file-path-based with smart-include {file:..} / {text:..} object form) for HTML output. Reuse the navbar/footer 'generate then render' pipeline pattern: an IncludeResolveTransform reads authored keys + folds engine PandocIncludes + resolves smart-includes, writes flat literal-text lists to a canonical 'rendered.includes.{header,before-body,after-body}' metadata location; the template reads from there. Migrates WebsiteFaviconTransform / WebsiteCanonicalUrlTransform off direct authored-meta writes onto the new contributor surface. Adds the file-include set to DocumentProfile for Phase-8 cache invalidation.\\n\\nPlan: claude-notes/plans/2026-05-04-includes-feature.md (draft for review).\\nRelated: bd-xfwx (IncludeExpansionStage shortcode form), bd-r82e (profile-includes cache invalidation), bd-b9mz (Phase-7 favicon/canonical-url transforms to migrate).","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-04T19:18:34.560486Z","created_by":"cscheid","updated_at":"2026-05-04T19:40:54.092659Z","dependencies":{"bd-r82e:related":{"depends_on_id":"bd-r82e","type":"related","created_at":"2026-05-04T19:18:37.299526Z","created_by":"cscheid"},"bd-xfwx:related":{"depends_on_id":"bd-xfwx","type":"related","created_at":"2026-05-04T19:18:37.412747Z","created_by":"cscheid"}}} +{"id":"bd-8lcm","title":"Writer: emit `\\'` for apostrophes in letter+whitespace context (issue #201)","description":"qmd writer drops the `\\'` escape on apostrophes that the reader would re-reject as a smart-quote open. Round-trip qmd → AST → qmd produces output that fails to re-parse with Q-2-10.\n\nTriage: claude-notes/issue-reports/201/triage.md (on branch issue-201).\nWorktree: .worktrees/issue-201\nGitHub: https://github.com/quarto-dev/q2/issues/201\n\nFix scope (per triage):\n\n1. TDD: add roundtrip fixture under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ — e.g. apostrophe_before_space.qmd containing 'reveal.js\\' jump-to-slide.'. Confirm it fails at HEAD.\n2. Implement: extend write_str / write_inline in crates/pampa/src/writers/qmd.rs (1379, 1414, 2159) to emit '\\'' instead of bare '\\'' when the char to the left in the Str body is a Unicode letter AND the next char the writer would emit is ASCII whitespace (Space / SoftBreak / etc.).\n3. Verify: cargo nextest run --workspace; round-trip the two quarto-web fixtures cited in the issue through 'pampa -t qmd | pampa' cleanly.\n\nOut of scope: reader changes; over-escaping safe contractions like project's, can't.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-15T14:16:43.621702Z","created_by":"cscheid","updated_at":"2026-05-15T15:08:59.745599Z","closed_at":"2026-05-15T15:08:59.745439Z","close_reason":"Fixed in commit 01e39ff1 on branch issue-201. Roundtrip test_qmd_roundtrip_consistency passes including two new fixtures. Full workspace tests green (8863 passed). cargo xtask verify --skip-hub-build --skip-hub-tests green."} +{"id":"bd-8nof7","title":"q2-preview Callout: implement interactive collapse toggle","description":"The q2-preview React Callout component\n(`ts-packages/preview-renderer/src/q2-preview/custom/Callout.tsx`)\nrenders the Bootstrap collapse markup (`callout-collapse collapse [show]`\nwrapper, header `bs-toggle/bs-target/aria-*` attrs, toggle button)\nbut the toggle is **non-interactive** — clicking the header does\nnothing. The wrapper's \\`show\\` class is derived once from\n\\`plain_data.collapse_starts_collapsed\\` at render time.\n\nThe HTML render path is fine (Bootstrap JS handles the toggle once\nthe theme JS is loaded). The q2-preview SPA doesn't ship Bootstrap\nJS, so this needs a React-side state hook:\n\n\\`\\`\\`tsx\nconst [expanded, setExpanded] = useState(!startsCollapsed);\n// onClick handler on header that flips expanded\n// className toggles 'show' based on expanded\n// header gets aria-expanded={expanded}\n\\`\\`\\`\n\nDiscovered during: callout class-vocabulary alignment (claude-notes/\nplans/2026-05-22-callout-class-vocabulary-fix.md). Explicitly scoped\nout of that plan — Phase 3 emits the markup but no interactive\nstate. UX: minor — most q2-preview users see the body open by\ndefault (the common case in TS Quarto fixtures is \\`collapse=\\\"false\\\"\\`\nor no collapse attr at all).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-26T13:44:01.979969Z","created_by":"gordon","updated_at":"2026-05-26T13:44:01.979969Z"} +{"id":"bd-8oe4","title":"Audit all hand-written scanners for non-ASCII byte handling","description":"Audit *every* hand-written scanner in the workspace for predicates that reject or misclassify non-ASCII bytes. In scope: tree-sitter-qmd (block + inline), tree-sitter-doctemplate, pampa, quarto-yaml, quarto-yaml-validation, quarto-xml, quarto-csl, quarto-doctemplate, quarto-parse-errors, plus a sweep of remaining crates for straggler tokenizer/scanner code. Classify each site as (a) inline-text accumulator (should accept non-ASCII bytes — Pandoc-compat) or (b) block-structural predicate (stays ASCII-only, matching Pandoc). Output: a table in the plan doc. Plan: claude-notes/plans/2026-04-30-unicode-whitespace-handling.md. Discovered from bd-rmx3.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-30T21:39:34.751203Z","created_by":"cscheid","updated_at":"2026-04-30T22:22:14.891041Z","closed_at":"2026-04-30T22:22:14.890895Z","close_reason":"Audit complete. Defensive ASCII-only predicate changes landed at all relevant pampa + quarto-xml sites. Policy doc at claude-notes/instructions/parser-whitespace-policy.md.","dependencies":{"bd-rmx3:discovered-from":{"depends_on_id":"bd-rmx3","type":"discovered-from","created_at":"2026-04-30T21:39:34.751203Z","created_by":"cscheid"}}} +{"id":"bd-8ohm","title":"Kanban: Calendar view for cards with deadlines","description":"A new view tab that shows cards with deadlines organized by date in a month-grid calendar. Include month navigation (prev/next) and a view switcher between Board and Calendar views. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-11T18:32:41.963637Z","created_by":"cscheid","updated_at":"2026-02-11T18:37:23.155449Z","closed_at":"2026-02-11T18:37:23.155432Z","close_reason":"Implemented - calendar view with month grid and navigation"} +{"id":"bd-8oqw","title":"[websites] Refactor compile_theme_css cache_key to a structured CompileInputs value type","description":"Background: Phase 2 of bd-k8y0 (sidebar vertical border) extended cache_key in CompileThemeCssStage to hash doc-derived SCSS variables in addition to theme config + custom file contents + minified flag. Hand-assembling these hash inputs is fragile: future ports (sidebar bg/fg, navbar bg/fg, footer bg/fg, brand colors, ...) each have to remember to add their input to BOTH the compile call AND the cache key. Forgetting one path produces a silently stale cache (the regression class that motivated the SCSS_RESOURCES_HASH + CSS_BUILD_ID work).\n\nProposed shape: introduce a CompileInputs struct that holds every piece of state that affects the compiled CSS (theme_config, doc_vars, minified, future fields). compile_with_doc_vars takes &CompileInputs; cache_key takes the same. Adding a new input is a single struct field, and the type system enforces both sites see it.\n\nAlternative considered: hash the assembled SCSS string directly. Rejected because assemble-failure paths become awkward and we'd assemble even on the cache-hit-precompute path.\n\nPre-req: bd-k8y0 (Phases 1-4) lands first. Plan reference: claude-notes/plans/2026-04-30-sidebar-vertical-border.md (see 'Code-quality flag' section in Phase 2).","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-30T20:31:09.775487Z","created_by":"cscheid","updated_at":"2026-04-30T20:31:09.775487Z","labels":["refactor","scss","websites"],"dependencies":{"bd-k8y0:discovered-from":{"depends_on_id":"bd-k8y0","type":"discovered-from","created_at":"2026-04-30T20:31:09.775487Z","created_by":"cscheid"}}} +{"id":"bd-8otua","title":"Error-docs tooling: cargo xtask error-docs (audit / health / new)","description":"Add a cargo xtask error-docs subcommand for managing error-page documentation health.\n\nSubcommands:\n- audit (default): diff error_catalog.json against docs/errors/, report missing/stale/inconsistent entries; exit non-zero for missing pages by default (configurable via flags); intended for CI use.\n- health: percentages by subsystem and by status; human-readable summary.\n- new <Q-X-Y>: generate a stub qmd from the catalog entry, fully populated front-matter, body sections present as TODO placeholders.\n- (stretch) validate: schema-check front-matter of existing pages.\n\nDepends on: bd-foundation (front-matter schema must exist).\n\nPlan: claude-notes/plans/2026-05-22-error-docs-tooling.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-22T17:09:33.467657Z","created_by":"cscheid","updated_at":"2026-05-22T17:09:40.678343Z","labels":["documentation","error-reporting","tooling"],"dependencies":{"bd-94x8a:parent-child":{"depends_on_id":"bd-94x8a","type":"parent-child","created_at":"2026-05-22T17:09:33.467657Z","created_by":"cscheid"},"bd-nvlxn:blocks":{"depends_on_id":"bd-nvlxn","type":"blocks","created_at":"2026-05-22T17:09:40.677849Z","created_by":"cscheid"}}} +{"id":"bd-8pmq3","title":"Thread title source_info onto DocumentProfile for nav-text ValueSource anchors","description":"Plan 6 Phase 5 (claude-notes/plans/2026-05-04-q2-preview-plan-6-provenance-audit.md) fixes three ConfigValue navigation sites (sidebar_generate.rs:228, sidebar_auto.rs:311, navigation_enrich.rs:59) that build sidebar/navbar entries from DocumentProfile.title. Plan 6 ships them with Generated{by: nav_text, from: smallvec![]} (empty from) because DocumentProfile.title is currently Option<String> with no source-info link.\n\nThis follow-up adds the source-info threading so those sites can attach an Anchor::value_source(title_source_info) anchor, enabling proper attribution back to the source qmd's title metadata bytes (e.g. a sidebar entry can be git-blamed back to the frontmatter line that produced it).\n\n## Scope\n\n1. Add title_source_info: Option<SourceInfo> field to DocumentProfile (crates/quarto-core/src/document_profile.rs:271+, also the Default impl at :487).\n - Use #[serde(default, skip_serializing_if = \"Option::is_none\")] — same pattern as `order: Option<i32>`.\n - NO DOCUMENT_PROFILE_VERSION bump required (additive Option<_> with default; per document-profile-contract §\"Serialization and versioning\").\n - Update the contract's §Change log.\n\n2. Update DocumentProfile::extract (line 529): replace `title: plain_text_field(meta, \"title\")` with code that also captures `meta.get(\"title\")?.source_info.clone()`. Either:\n - Add a sibling helper `fn plain_text_field_with_source(meta, key) -> (Option<String>, Option<SourceInfo>)`, or\n - Inline the two-field extraction at the call site.\n\n3. Update the three Plan-6 Phase-5 consumer sites to read both fields and attach the ValueSource anchor when title_source_info is Some:\n - sidebar_generate.rs:228\n - sidebar_auto.rs:311 (only when reading from profile.title; the file-stem fallback at :318 keeps `from: smallvec![]`)\n - navigation_enrich.rs:59\n\n4. Test: extend Plan 6's multi-page audit-completion fixture to assert that nav-text ConfigValues built from profile.title carry a ValueSource anchor whose source_info chain-walks to the source qmd's title metadata range.\n\n## Out of scope\n\n- subtitle, description, date, image, etc. (not consumed by nav sites today; can be added when needed).\n- Inline-rich titles (title: \"**Bold**\" → ConfigValue::PandocInlines). Today plain_text_field handles only flat strings; this follow-up preserves that contract.\n\n## Why a follow-up, not part of Plan 6\n\nPlan 6 is already ~1150 LOC across 7 phases. This is forward-compatible — once the field lands, the three Phase-5 sites get an extra ValueSource anchor without changing their by-kind or stamping shape. Small enough to be a single self-contained PR.\n\n## Estimated scope\n\n~30-50 LOC + 1 fixture extension. No version bump, no contract semantics change.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-22T15:08:59.251411Z","created_by":"gordon","updated_at":"2026-05-22T15:09:13.163191Z","labels":["follow-up","plan6","provenance"],"dependencies":{"bd-129m3:related":{"depends_on_id":"bd-129m3","type":"related","created_at":"2026-05-22T15:09:13.163113Z","created_by":"gordon"}}} +{"id":"bd-8zim0","title":"Author error-docs pages for xml subsystem (16 codes)","description":"Author stub-quality pages for all 16 xml subsystem error codes under docs/errors/xml/. Follow the template established in docs/errors/yaml/Q-1-10.qmd and docs/errors/README.md. Stub quality minimum: What this means / Why this happens / How to fix sections. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T20:53:32.864379Z","created_by":"cscheid","updated_at":"2026-05-24T20:58:38.581588Z","closed_at":"2026-05-24T20:58:38.581174Z"} +{"id":"bd-91da","title":"Phase B.4: Acceptance Playwright spec for Phase B re-render coverage","description":"Single Playwright spec pinning the three Phase B acceptance criteria together: editing _quarto.yml re-renders the active page, editing posts/_metadata.yml re-renders only its siblings, and editing any sibling re-renders the active page (relaxed from 'only when dep-graph has an edge' per the optimisation deferral — document this).\n\nMirror q2-preview-spa/e2e/basic-preview.spec.ts's shape; reuses previewServer.ts for setup.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-13T19:34:52.929002Z","created_by":"cscheid","updated_at":"2026-05-13T19:34:58.379525Z","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T19:34:52.929002Z","created_by":"cscheid"},"bd-z529:blocks":{"depends_on_id":"bd-z529","type":"blocks","created_at":"2026-05-13T19:34:58.379193Z","created_by":"cscheid"}}} +{"id":"bd-94x8a","title":"Error-code documentation pages in the website (epic)","description":"Set up a /docs/errors/ section in the Q2 website with one page per error code in error_catalog.json (133 codes today across 12 subsystems), backed by tooling that audits coverage and validates front-matter health. Per-page content is hand-authored — generation produces stubs, not finished pages.\n\nThree children:\n1. Foundation: directory layout, front-matter schema, page template, index/listing, navbar/sidebar wiring.\n2. Tooling: cargo xtask error-docs subcommand for audit/health/stub-generation.\n3. Content (umbrella): author pages for the 133 existing catalog entries, opened on demand per subsystem.\n\nPlan: claude-notes/plans/2026-05-22-error-docs-website-epic.md","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-22T17:09:21.193438Z","created_by":"cscheid","updated_at":"2026-05-22T17:09:21.193438Z","labels":["documentation","error-reporting","website"]} +{"id":"bd-97yc","title":"Brand-aware favicon fallback","description":"Q1 falls back to brand.light.favicon when website.favicon is unset. Q2 doesn't have brand support yet — file once brand lands. Q1 reference: external-sources/quarto-cli/src/project/types/website/website.ts:185-205. Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.190072Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.190072Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.190072Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.190072Z","created_by":"cscheid"}}} +{"id":"bd-98k6","title":"Syntax highlighting: investigate native tree-sitter-highlight event-stream end-byte behavior for same-start nested captures","description":"Surfaced during Phase 4.4 native-vs-browser parity work (2026-04-21).\n\nNative collect_spans in crates/quarto-highlight/src/{registry,user_grammar}.rs uses tree-sitter-highlight's HighlightEvent stream with cursor-based span boundaries. When two captures open at the same start byte (e.g. (bare_key) @type + (pair (bare_key)) @property on a TOML pair), tree-sitter-highlight emits HighlightStart events back-to-back with no intervening Source event. collect_spans records both spans with the outer capture's end byte, because the cursor only advances on Source events.\n\nResult: [0, 14, \"type\"] for a (bare_key) @type capture that should cover 0-4. Both the browser golden (via web-tree-sitter Query.captures, which gives node-exact ranges) and the query pattern say 0-4.\n\nFor HTML rendering this means the native path wraps the inner capture's CSS class around the whole outer range, not the actual capture's range. For the TOML fixture: .hl-type wraps the whole 'name = \"value\"' pair instead of just 'name'.\n\nImpact: cosmetic; users see hl-* classes applied to broader ranges than intended for nested same-start captures. Not a correctness regression (classes are all applied; just overlap more than necessary).\n\nFix path: replace the cursor-based collect_spans with node-range-aware span extraction. tree-sitter-highlight's event stream doesn't carry node ranges, so we'd either need to (a) use Query::captures() directly (bypassing tree-sitter-highlight's event stream, but losing its precedence resolution) or (b) augment the collect_spans walker to track per-nesting-level cursors.\n\nRegenerating the golden at crates/quarto-highlight/tests/snapshots/golden__user_grammar_toml.snap will be part of the fix.\n\nOut of scope for Phase 4.4; parity test documents and bounds the divergence.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-21T16:15:01.295175Z","created_by":"cscheid","updated_at":"2026-04-21T16:15:01.295175Z","dependencies":{"bd-n7x2:related":{"depends_on_id":"bd-n7x2","type":"related","created_at":"2026-04-21T16:15:01.295175Z","created_by":"cscheid"}}} +{"id":"bd-99ru","title":"Localize listing category sidebar labels (Categories, All)","description":"L5 (bd-5vsr) hardcodes English 'Categories' and 'All' in the categories sidebar markup. Localize via whatever pattern Q2 settles on (cf. crossref_render.rs's localization comment). Q1 reads from language.listing-page-field-categories / language.listing-page-category-all. Plan: claude-notes/plans/2026-05-06-listings-L5-categories-sidebar.md §'Filing reminder' #1.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T13:45:41.502283Z","created_by":"cscheid","updated_at":"2026-05-07T13:45:41.502283Z","dependencies":{"bd-5vsr:discovered-from":{"depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T13:45:41.502283Z","created_by":"cscheid"}}} +{"id":"bd-9brz","title":"staleness integration test fails on macOS — FSEvents starved by hub-server boot","description":"The integration test \\`cell_edit_flips_staleness_in_sidecar\\` in\n\\`crates/quarto-preview/tests/staleness.rs\\` fails reliably (15.6 s\ntimeout, \"staleness never flipped\") on cscheid's machine\n(macOS 26.4.1 Tahoe, Darwin 25.4.0, Apple Silicon).\n\n## Reproduces at\n\n- Merge tip \\`feature/q2-preview-command\\` (4cd5a5ff)\n- Pre-merge tip (0df1f0ea)\n- The very commit that added the test (\\`cc180477\\`, where bd-u3ze\n closed with \"5/5 stable reruns\")\n\nSo it is NOT a regression introduced by any later commit on the\nbranch. Something about the environment changed since the test\nlanded on May 14 — but per the user, the laptop has not rebooted\nsince (so it is not an OS version bump).\n\n## What was tried and what was learned\n\n1. The hub-server's \\`FileWatcher\\` task starts (\\`run_file_watcher\\`\n entered), but the \\`notify-debouncer-mini\\` callback **never\n fires** during the 15 s window. FSEvents is not delivering events\n to the consumer.\n\n2. Adding a control \\`FileWatcher::new\\` in the *test* code just\n before the file edit works around it: 5/5 pass in ~2.3 s.\n\n3. Adding the same kicker pattern *inside* \\`FileWatcher::new\\` (or\n in a background thread after a 500 ms delay, or as a permanent\n secondary debouncer kept alive in the FileWatcher struct) does\n NOT work: 5/5 still fail.\n\n4. Sentinel write/delete of a throwaway file in the watched root\n does NOT kick the stream: 5/5 still fail.\n\n5. An isolated probe (plain tokio + notify + notify-debouncer-mini,\n no hub, no axum, no samod) reliably delivers events for\n single-watcher, two-watchers-immediate, and two-watchers-delayed\n modes. So FSEvents on this machine works in isolation.\n\n6. The real \\`q2 preview\\` binary works in normal user workflows\n (verified with /tmp fixture + 3 sequential edits): every edit is\n detected and \\`recompute_staleness\\` runs. The bug does not break\n user-facing behavior — likely because real user edits come after\n the periodic-sync tick at T+5 s.\n\n## Updated theory\n\nThe bug is not an FSEvents stream-startup warm-up issue (the probe\ndisproves that). It looks like *something specific that runs during\nhub-server boot* — samod init, axum listener setup, eager-capture\nspawn, periodic-sync task spawn, or some interaction among them —\nsilences the FSEvents stream until another stream is created late\nin the boot sequence, after that disruptive thing has settled.\n\nThe throwaway-in-test-code workaround happens to run after all the\ndisruptive boot work; a kicker inside FileWatcher::new runs before\nit and is therefore ineffective.\n\n## Next steps\n\nBisect through the hub-server boot path to identify which specific\nstep silences FSEvents. Candidates: samod runtime construction,\naxum::serve listener, the spawn_blocking eager-capture driver,\ntokio::time::interval setup in run_periodic_sync. Recommended\nmethod: progressively strip down the integration test to find the\nminimum boot configuration that reproduces.\n\nUntil root cause is found, the test is \\`#[ignore]\\`d. The plan is\nto NOT patch production code blindly — a kicker watcher in\nFileWatcher::new is harmless cargo-culting if we don't understand\nwhy the real fix has to live somewhere else.\n\n## Files\n\n- crates/quarto-preview/tests/staleness.rs (the test)\n- crates/quarto-hub/src/watch.rs (FileWatcher impl)\n- crates/quarto-hub/src/server.rs:run_file_watcher (event consumer)\n- crates/quarto-preview/src/lib.rs:run_with_on_ready (boot path)\n\n## Related\n\n- bd-u3ze: the issue that added this test, claimed-stable at cc180477\n- \\`.config/nextest.toml\\`: serializes the three preview integration\n tests to work around an earlier (different) FSEvents flake","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-15T14:46:46.969857Z","created_by":"cscheid","updated_at":"2026-05-15T14:46:46.969857Z","labels":["flake","fsevents","macos"],"dependencies":{"bd-u3ze:discovered-from":{"depends_on_id":"bd-u3ze","type":"discovered-from","created_at":"2026-05-15T14:46:46.969857Z","created_by":"cscheid"}}} +{"id":"bd-9eltv","title":"Profile q2 render on a large website (quarto-web)","description":"Use external-sources/quarto-web as a large-project fixture to characterize q2's render performance. Follow the native-proxy-first workflow in claude-notes/instructions/performance-profiling.md: flamegraph, env-gated counters, geometric scaling, then synthesis. Produces a written analysis and per-hotspot follow-up issues; not a fix.\n\nPlan: claude-notes/plans/2026-05-21-q2-render-website-profile.md","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-21T21:13:06.218065Z","created_by":"cscheid","updated_at":"2026-05-22T00:46:09.548081Z","dependencies":{"bd-wlza2:blocks":{"depends_on_id":"bd-wlza2","type":"blocks","created_at":"2026-05-21T21:13:06.218065Z","created_by":"cscheid"}}} +{"id":"bd-9h2g","title":"Cargo: upgrade scraper v0.22.0 → v0.26.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.22.0 is range-pinned in workspace; latest is 0.26.0. Type: pre-1.0 minor (semver-breaking); four minor steps. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.070022Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.306184Z","closed_at":"2026-05-04T20:30:45.306039Z","close_reason":"merged: 86464160","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.270861Z","created_by":"cscheid"}}} +{"id":"bd-9hlja","title":"Coalesce per-page diagnostics by source location","description":"Add a coalescing pass in the render-summary printer: same-(code, source-location, title) diagnostics across pages collapse into one DiagnosticMessage emission with an 'Affected files: a, b, c (and N others)' tail. Default cap: 3 names + count.\n\nAPI lives in quarto-error-reporting (proposed coalesce.rs module). Call site is print_render_diagnostics in crates/quarto/src/commands/render.rs:704-735, which today walks pass2_failures and outputs[i].render_output.diagnostics independently and emits each verbatim.\n\nNon-coalescable shapes (SourceInfo::Concat, FilterProvenance) pass through as singletons in the first cut.\n\nThis is one of two children of the theme-diagnostic overhaul epic. Companion issue makes the theme error structured so this coalescer has something to coalesce.\n\nPlan: claude-notes/plans/2026-05-22-diagnostic-coalescing.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T13:43:11.958574Z","created_by":"cscheid","updated_at":"2026-05-22T15:05:25.328709Z","closed_at":"2026-05-22T15:05:25.328553Z","close_reason":"Implemented. Theme errors across all pages collapse into 1 ariadne block + 'Affected files: …' line. Verified end-to-end against quarto-web: 345 -> 1 emission.","labels":["diagnostics","website"],"dependencies":{"bd-l26u6:parent-child":{"depends_on_id":"bd-l26u6","type":"parent-child","created_at":"2026-05-22T13:43:11.958574Z","created_by":"cscheid"},"bd-pgczr:related":{"depends_on_id":"bd-pgczr","type":"related","created_at":"2026-05-22T13:43:11.958574Z","created_by":"cscheid"}}} +{"id":"bd-9kzfi","title":"Scroll sync missing for q2-preview format (only HTML preview works)","description":"ReactPreview/q2-preview path never wires scroll sync: rendered DOM carries no data-loc attributes and Q2PreviewIframe exposes no scrollToLine/getScrollRatio/onScroll. Fix: emit data-loc on q2-preview block leaves from the node 'l' field, and wire useScrollSync through ReactPreview -> ReactRenderer -> Q2PreviewIframe (direct same-origin DOM access, mirroring MorphIframe). Block-level scope only.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-29T22:23:00.942842Z","created_by":"shikokuchuo","updated_at":"2026-05-29T22:58:59.796081Z","closed_at":"2026-05-29T22:58:59.796038Z","close_reason":"Implemented q2-preview scroll sync: data-loc emission on block leaves + useScrollSync wiring through ReactPreview/ReactRenderer/Q2PreviewIframe"} +{"id":"bd-9m8p","title":"Navbar pinned-on-scroll JS (ride with site_libs/)","description":"The Navbar data model has navbar.pinned (sticky-on-scroll). Phase 3 stores it but there's no JS to wire up the behavior. Ride with Phase 5 (site_libs/) when the theme/JS plumbing lands. See 2026-04-24-websites-phase-3.md §Follow-up beads.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T19:43:01.119436Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:10.324092Z","dependencies":{"bd-fqyg:discovered-from":{"depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:43:01.119436Z","created_by":"cscheid"}}} +{"id":"bd-9mgd","title":"Quiet default logging in q2 preview and q2 hub","description":"Demote per-tick automerge sync logs from info! to debug! and add a -v/--verbose accumulator flag to both the q2 (root) and quarto-hub binaries so users can opt back in. Default floor moves to quarto=warn; RUST_LOG still overrides. Three phases: (1) demote chatty log sites, (2) -v on the q2 root command (global, applies to all subcommands), (3) same wiring on standalone quarto-hub. Plan: claude-notes/plans/2026-05-15-quiet-default-logging.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-15T15:55:25.418064Z","created_by":"cscheid","updated_at":"2026-05-15T16:16:08.294357Z","closed_at":"2026-05-15T16:16:08.294237Z","close_reason":"Demoted per-tick automerge/sync info! to debug! across quarto-hub; added has_changes() gate to skip summary-line emit when only no_changes are nonzero; added -v/--verbose accumulator on q2 and standalone hub (warn→info→debug+samod=info→trace+samod=debug+tower_http=debug). RUST_LOG still wins. Verified end-to-end via q2 hub + standalone hub (q2 preview path is in feature/q2-preview-command and will inherit on next merge of main). cargo xtask verify --skip-hub-build green; 8864 workspace tests pass.","labels":["logging","ux"]} +{"id":"bd-9ofu","title":"Find a proper home for Q2 CLI user docs","description":"Phase D.5 (bd-kw93.11) shipped user-facing docs for q2 preview at docs/q2-preview.qmd, the most natural existing home — but docs/ is titled 'Quarto-markdown' and is pitched as a reference for the markdown dialect + library internals (Syntax / Writers / Library Docs sections). It is not currently designed as a front door for Q2 CLI commands.\n\nAs more Q2 commands gain user-facing surface area (q2 render, q2 trace-view, future q2 hub, etc.), they will face the same placement question. Some options to consider:\n\n- A dedicated 'CLI' or 'Q2 Commands' section under docs/ with its own landing page.\n- A separate site (e.g. q2.quarto.org or similar) wholly oriented to Q2 users.\n- Fold Q2 CLI docs into the existing quarto-dev/quarto-cli docs site when that catches up to Q2.\n\nDiscussion settled with carlos@ during D.5: docs/q2-preview.qmd lives in the existing site for now (single-page, single-decision); structural reorganization deferred to this issue. The page itself is fine; the question is whether the IA around it should change.\n\nExisting related pages worth considering when designing the home: docs/quarto-hub/preview.qmd (in-browser live preview, different surface). q2 preview --help (always-accurate inline reference; less discoverable than a docs site).","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-14T19:48:06.708981Z","created_by":"cscheid","updated_at":"2026-05-14T19:48:06.708981Z"} +{"id":"bd-9svl","title":"[websites phase 2] Sidebar: data model, generate, render, template","description":"Implement sidebar feature for website projects. Delivers:\n- Sidebar data model in quarto-navigation (Sidebar, SidebarEntry, SidebarContents enums)\n- SidebarGenerateTransform (format-agnostic; reads website.sidebar, resolves auto:, sets active/expanded)\n- SidebarRenderTransform (HTML-specific; rewrites .qmd -> .html hrefs via ProjectIndex)\n- New template slot $rendered.navigation.sidebar$ in full HTML template\n- Active-item highlighting by source-path equality (format-agnostic)\n- Sidebar-for-page selection (Q1 sidebarForHref equivalent by source-path containment)\n- DocumentProfile gains additive 'order: Option<i32>' field for auto-sort\n\nPlan: claude-notes/plans/2026-04-24-websites-phase-2.md\nParent epic: bd-0tr6 (websites epic)\nBlocked by: bd-w5os (phase 1, closed)\n\nFormat-agnostic Generate vs HTML-specific Render split is load-bearing:\nnavigation.sidebar keeps source paths so a future non-HTML per-page\nformat could reuse it with its own rewrite.\n\nDeferred to follow-ups: search, tools, logo/subtitle/header/footer slots,\ninteractive collapse JS (rides with Phase 5), draft-mode option.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-24T17:11:48.884350Z","created_by":"cscheid","updated_at":"2026-04-24T17:57:26.598128Z","closed_at":"2026-04-24T17:57:26.597171Z","close_reason":"Phase 2 sidebar complete: data model in quarto-navigation, Generate+Render transforms (format-agnostic/HTML split), sidebar_for_page + active-state helpers, auto expansion, template slot, AstTransformsStage project_index bridge fix, text enrichment from ProjectIndex. 1063 quarto-core tests + 81 quarto-navigation tests + 5 pipeline integration tests + manual 3-page CLI smoke all pass. cargo xtask verify green. Follow-ups filed: bd-6cme (search), bd-fod3 (tools), bd-ht0n (logo/subtitle), bd-49ar (collapse JS), bd-w0o9 (draft-mode), bd-l6f0 (explicit expanded), bd-81x4 (multi-sidebar diagnostic), bd-tfy0 (deep-dir grouping), bd-2quy (bridge audit). Epic follow-ups: bd-n9dr (nav config unification), bd-4g6g (sidebar-left template).","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-24T17:12:21.865157Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-24T17:11:48.884350Z","created_by":"cscheid"}}} +{"id":"bd-a1qb3","title":"Migrate q2 issue tracking from beads_rust to braid","description":"Replace beads_rust (br) with braid as q2's issue tracker. braid stores issues in a single automerge CRDT (a 'skein') synced via a sync server; no git involvement, no daemon. This epic and its plan deliberately stay in beads so they survive if the migration is abandoned.\n\nPlan: claude-notes/plans/2026-06-08-braid-migration.md\nBraid-side prerequisite work (hand off to a braid-repo agent): claude-notes/plans/2026-06-08-braid-0.3.0-features-for-migration.md\n\nValidated in-session 2026-06-08: import of the live 1145-issue JSONL preserves all bd- ids verbatim, round-trips all 1051 dependencies, produces a 460 KB doc, and runs sub-second. ID preservation is the critical property (412 distinct bd- ids referenced across 1141 tracked locations) and is ironclad via braid import's upsert-by-id.\n\nDecisions locked: (1) public relay sync server for the experiment; (2) committed braid export snapshot is backup-only and strictly one-directional, never re-imported; (3) build 4 braid 0.3.0 features first (dep tree, create --deps, import skip-tombstones, agents-info skill installer).","status":"in_progress","priority":2,"issue_type":"epic","created_at":"2026-06-08T14:16:40.897622Z","created_by":"cscheid","updated_at":"2026-06-08T15:58:39.544908Z","labels":["braid","migration"],"dependencies":{"bd-sjk4t:blocks":{"depends_on_id":"bd-sjk4t","type":"blocks","created_at":"2026-06-08T14:16:41.193177Z","created_by":"cscheid"}},"comments":{"c-ugn2q98u":{"id":"c-ugn2q98u","author":"claude","created_at":"2026-06-08T15:58:39.544908Z","text":"Cutover executed 2026-06-08: Phases 0-4 complete and verified (cargo xtask verify --skip-hub-build green); beads frozen (.beads/README.md marked FROZEN); braid is now the canonical tracker. Remaining: Phase 6 settling / exit-criterion before fully archiving beads. From here this epic is maintained in braid, not beads."}}} +{"id":"bd-a3we","title":"WASM VFS: populate PathMetadata.modified from Automerge change history","description":"Today crates/quarto-system-runtime/src/wasm.rs::path_metadata returns modified: None with a 'VFS doesn't track modification times' comment. Hub-client and the future quarto preview need this populated so listings, blog-style 'last changed on:' displays, and other date-modified consumers work in Automerge-backed projects.\n\nDesign notes:\n- Native (filesystem): already works — modified comes from std::fs::metadata().modified().\n- WASM (Automerge VFS): each document path lives in an Automerge CRDT; every change op has a wall-clock timestamp attached (peer-local clock, not authoritative across peers). Candidate semantics: 'most recent local-or-remote change op affecting this path's document.'\n- Edge cases: project just synced from peer with no local edits (use peer timestamp), document never edited (use creation time, or None and let consumers fall back to listing-item.date), Lamport vs wall-clock ordering, peer clock skew.\n- Test surface: unit-test the WASM VFS impl with synthetic Automerge histories; smoke-test in hub-client that a sibling-page edit updates the listing host's date-modified column.\n\nSurfaced during L1 sub-plan review (bd-izqh) on 2026-05-06. L1 ships using the existing path_metadata API; on WASM date_modified just stays None until this issue lands. No L1 code change needed when this issue resolves.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-06T13:27:44.973104Z","created_by":"cscheid","updated_at":"2026-05-06T13:27:44.973104Z"} +{"id":"bd-af1e","title":"Tree-sitter parser splits paragraph at line starting with backtick","description":"Lines beginning with a single backtick (inline code span) are incorrectly treated as paragraph-interrupters by the tree-sitter scanner, splitting one paragraph into two pandoc_paragraph nodes. Should only interrupt when 3+ consecutive backticks (fenced code block start).\n\nPlan: claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md\n\nRoot cause: crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c lines 2263-2272 and 2291-2315 unconditionally exclude backtick from soft-line-break candidates. CommonMark only treats >=3 backticks as a fence; <3 is an inline code span and should soft-break.\n\nPure tree-sitter repro (from crates/tree-sitter-qmd/tree-sitter-markdown):\n printf 'foo bar\\n`code` more text\\n' | tree-sitter parse -\n=> two pandoc_paragraph nodes (bug). Should be one with pandoc_soft_break.","notes":"See plan file for full reproduction set, fix sketch (peek_paragraph_interrupting_backticks helper), and test plan.","status":"closed","priority":1,"issue_type":"bug","assignee":"cscheid","created_at":"2026-04-30T17:31:21.164223Z","created_by":"cscheid","updated_at":"2026-04-30T18:38:47.754468Z","closed_at":"2026-04-30T18:38:47.754304Z","close_reason":"Fixed: peek-count backticks in scanner line-break handler; <3 → soft break, >=3 → paragraph break (fence). All 456 tree-sitter tests pass; 8125 workspace tests pass; pampa output now matches pandoc."} +{"id":"bd-afwg","title":"Fix unix-only code in pampa json_filter.rs that breaks Windows compilation","description":"pampa/src/json_filter.rs uses std::os::unix::fs::PermissionsExt and set_mode() unconditionally. This fails to compile on Windows. Need cfg(unix) guards or cross-platform permission handling. 5 call sites at lines 190, 208, 240, 257, 482, 514.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-03-23T23:49:17.936478300Z","created_by":"cderv","updated_at":"2026-03-23T23:58:02.799741300Z","closed_at":"2026-03-23T23:58:02.799509300Z","close_reason":"Fixed: extracted make_executable() helper with cfg(unix)/cfg(not(unix)) variants. Commit 8bf71db7."} +{"id":"bd-an6z4","title":"Error-docs content authoring (umbrella): populate pages for the 133 current catalog entries","description":"Author /docs/errors/Q-X-Y.qmd pages for each entry in error_catalog.json. Open one sub-issue per subsystem when ready to work on it; closing a sub-issue requires all pages in that subsystem at status=stub or better.\n\nSubsystem sizes (133 total):\n- markdown: 36\n- yaml: 21\n- writer: 21\n- xml: 16\n- listing: 16\n- template: 7\n- navigation: 7\n- project: 3\n- theme: 2\n- internal: 2\n- lua: 1\n- cli: 1\n\nEach page is hand-authored; tooling (bd-tooling) generates stubs but does NOT generate prose. Per-page quality bar is in the foundation plan.\n\nPlan: claude-notes/plans/2026-05-22-error-docs-content.md","status":"closed","priority":3,"issue_type":"epic","created_at":"2026-05-22T17:09:37.728930Z","created_by":"cscheid","updated_at":"2026-05-24T21:16:46.562313Z","closed_at":"2026-05-24T21:16:46.561908Z","labels":["content","documentation","error-reporting"],"dependencies":{"bd-4ltdl:blocks":{"depends_on_id":"bd-4ltdl","type":"blocks","created_at":"2026-05-24T21:07:57.094765Z","created_by":"cscheid"},"bd-732bn:blocks":{"depends_on_id":"bd-732bn","type":"blocks","created_at":"2026-05-24T21:07:57.904153Z","created_by":"cscheid"},"bd-8k4ny:blocks":{"depends_on_id":"bd-8k4ny","type":"blocks","created_at":"2026-05-24T21:07:57.632775Z","created_by":"cscheid"},"bd-8zim0:blocks":{"depends_on_id":"bd-8zim0","type":"blocks","created_at":"2026-05-24T20:54:12.747207Z","created_by":"cscheid"},"bd-94x8a:parent-child":{"depends_on_id":"bd-94x8a","type":"parent-child","created_at":"2026-05-22T17:09:37.728930Z","created_by":"cscheid"},"bd-bj5yp:blocks":{"depends_on_id":"bd-bj5yp","type":"blocks","created_at":"2026-05-22T20:01:42.876087Z","created_by":"cscheid"},"bd-c263g:blocks":{"depends_on_id":"bd-c263g","type":"blocks","created_at":"2026-05-24T21:07:58.176873Z","created_by":"cscheid"},"bd-gkqxl:blocks":{"depends_on_id":"bd-gkqxl","type":"blocks","created_at":"2026-05-24T21:07:57.361666Z","created_by":"cscheid"},"bd-lgxdr:blocks":{"depends_on_id":"bd-lgxdr","type":"blocks","created_at":"2026-05-22T20:27:57.887826Z","created_by":"cscheid"},"bd-nvlxn:blocks":{"depends_on_id":"bd-nvlxn","type":"blocks","created_at":"2026-05-22T17:09:41.059965Z","created_by":"cscheid"},"bd-oqbpi:blocks":{"depends_on_id":"bd-oqbpi","type":"blocks","created_at":"2026-05-24T20:35:56.160185Z","created_by":"cscheid"},"bd-s9emf:blocks":{"depends_on_id":"bd-s9emf","type":"blocks","created_at":"2026-05-24T21:07:56.828284Z","created_by":"cscheid"},"bd-tep4x:blocks":{"depends_on_id":"bd-tep4x","type":"blocks","created_at":"2026-05-24T20:24:43.820419Z","created_by":"cscheid"},"bd-uhmzq:blocks":{"depends_on_id":"bd-uhmzq","type":"blocks","created_at":"2026-05-24T21:07:56.562544Z","created_by":"cscheid"}}} +{"id":"bd-anhg","title":"Cargo: upgrade comrak v0.50.0 → v0.52.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.50.0 is range-pinned in workspace; latest is 0.52.0. Type: pre-1.0 minor (semver-breaking); two minor steps. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.717242Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.398021Z","closed_at":"2026-05-04T20:30:45.397884Z","close_reason":"merged: 0a75e8e4","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.700823Z","created_by":"cscheid"}}} +{"id":"bd-anxz","title":"Upload dialog: editable filenames with whitespace sanitization","description":"Add ability to edit filenames in the upload dialog before uploading. Default names should replace all whitespace characters (tabs, newlines, non-breaking spaces, etc.) with hyphens so files are easily referenceable in markdown. Plan: claude-notes/plans/2026-02-13-upload-filename-editing.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-02-13T21:52:18.638260Z","created_by":"cscheid","updated_at":"2026-02-13T21:57:42.099346Z"} +{"id":"bd-apudk","title":"citeproc: locale load failure silently degrades to English citations","description":"When a CSL locale fails to load, quarto-citeproc silently produces English output (terms, quotes, date formats) with no diagnostic. A document requesting fr-FR/de-DE/etc. citations can render with English 'and', curly quotes, and English date formats and the user is never told. See GitHub issue (linked) for the full write-up; code refs: crates/quarto-citeproc/src/locale.rs load_embedded_locale (240-266) swallows file-not-found AND parse errors via .ok()?/None; load_locale (41-62) gives up silently; get_term (79-86) and get_quote_config (165-185, e.g. unwrap_or_else(|| \"\\u{201C}\")) substitute hardcoded English. Locales are rust-embed compiled-in, so a None for a known-embedded locale is a build/bug signal, not a normal 'unshipped locale' case. Fix: distinguish unshipped-locale (warn + en-US fallback via DiagnosticMessage) from embedded-locale-load-failure (surface loudly); emit a diagnostic whenever rendered language != requested language. Discovered 2026-06-02 during bd-ooleh when stale-cache pollution (bd-gpyup) made a dead-path locale load return English, surfacing only because a test asserted on French.","notes":"GitHub: https://github.com/quarto-dev/q2/issues/255","status":"open","priority":1,"issue_type":"bug","created_at":"2026-06-02T14:30:59.720364Z","created_by":"cscheid","updated_at":"2026-06-02T14:31:50.760803Z","labels":["bug","citeproc","correctness"],"dependencies":{"bd-gpyup:related":{"depends_on_id":"bd-gpyup","type":"related","created_at":"2026-06-02T14:30:59.720364Z","created_by":"cscheid"}}} +{"id":"bd-apv23","title":"Import a project from a ZIP archive (hub-client)","description":"Add an 'Import from ZIP' action to the hub-client project selector that creates a NEW project from an uploaded .zip — the inverse of the existing 'Export to ZIP' (ts-packages/quarto-sync-client/src/export-zip.ts).\n\nDesign: parse ZIP (fflate unzipSync) into a file list in the shape createNewProject already accepts (base64 binary, plain-string text), then reuse the existing onProjectCreated path (App.handleProjectCreated -> createNewProject -> IDB + project set + navigate). No Automerge-layer changes needed.\n\nNew code:\n- ts-packages/quarto-sync-client/src/import-zip.ts (parseProjectZip, pure, mirrors export-zip.ts)\n- preview-runtime wrapper importProjectFromZip -> ProjectFile[]\n- ProjectSelector 'Import from ZIP' button + form (title default from filename, sync server, file picker)\n\nEdge cases: strip common top-level dir (GitHub zips), skip __MACOSX/.DS_Store/dirs, zip-slip guard, binary-vs-text via isBinaryExtension (+ optional UTF-8 sniff), empty/invalid zip errors, export->import round-trip fidelity.\n\nTDD: unit tests for parse (round-trip headline test), preview-runtime shape conversion test, ProjectSelector component test, Playwright e2e + manual browser verification. hub-client change -> npm run build:all + changelog two-commit workflow.\n\nPlan: claude-notes/plans/2026-06-01-import-from-zip.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-06-01T21:54:21.009894Z","created_by":"cscheid","updated_at":"2026-06-02T11:31:37.056638Z","closed_at":"2026-06-02T11:31:37.056456Z","close_reason":"Implemented import-from-zip: parser + wrapper + UI + tests + e2e; verified end-to-end in real browser.","labels":["hub-client"]} +{"id":"bd-apvo","title":"project.lib-dir: user-config override","description":"Phase 5 hardcodes WebsiteProjectType::lib_dir() = 'site_libs' as a String return. The trait signature is owned String specifically so the override can plumb through without API churn — the implementation just needs to read project.config.metadata['project.lib-dir'] when present. Tracked from Phase 5 D4. See claude-notes/plans/2026-04-24-websites-phase-5.md.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-25T01:31:29.127942Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:29.127942Z","dependencies":{"bd-u5pr:discovered-from":{"depends_on_id":"bd-u5pr","type":"discovered-from","created_at":"2026-04-25T01:31:29.127942Z","created_by":"cscheid"}}} +{"id":"bd-ascs","title":"LSP outline: include cross-referenceable elements (fig, thm, tbl)","description":"Cross-referenceable divs (#fig-, #thm-, #tbl-, etc.) do not appear in the LSP document outline. Headers that semantically belong to a cross-ref target (e.g. '## Line' inside ::: {#thm-line}) currently appear as standalone outline entries instead of being folded into their owning theorem/figure. See claude-notes/plans/2026-04-17-crossref-outline.md for the full plan.","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-04-17T18:42:58.811042Z","created_by":"cscheid","updated_at":"2026-04-17T22:17:28.658125Z"} +{"id":"bd-ayj6","title":"[websites phase 9] Hub-client project rendering","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 9.\n\nDeliverables:\n- New WASM API entry points:\n - build_project_nav(project_dir) -> ProjectNavState\n - render_page_in_project(file_path, project_nav_state) -> HTML\n- Hub-client state: project-scoped nav cache, invalidation on profile-affecting edits (title, frontmatter, draft flag, _quarto.yml sidebar changes).\n- Live preview: editing a page title updates sibling sidebars within one render cycle.\n- API shape must leave room for future Q2 'quarto preview' (local hub-client instance).\n- End-to-end smoke test in a real browser session per CLAUDE.md § End-to-end verification.\n\nBlocked by Phases 2, 3, 5.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-23T18:43:28.398865Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:38.160801Z","closed_at":"2026-04-29T00:31:38.160419Z","close_reason":"Phase 9 implemented: Pass2Renderer trait extraction (9.0), ProjectPipeline un-gate for WASM (9.1), WASM Pass-2 renderer + cross-platform flush_site_libs (9.2), render_page_in_project WASM entry point with RenderMode::ActivePage (9.3), hub-client renderToHtml switch + Preview useEffect deps (9.4), hub-smoke fixture + native integration tests (9.5), close-out (9.6). Plan: claude-notes/plans/2026-04-27-websites-phase-9.md. 8072 workspace tests pass; cargo xtask verify (Rust + hub-client WASM build + tests) passes. Browser smoke GIF deferred to a follow-up session.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:28.398865Z","created_by":"cscheid"},"bd-h4l6:blocks":{"depends_on_id":"bd-h4l6","type":"blocks","created_at":"2026-04-23T18:43:50.534096Z","created_by":"cscheid"},"bd-mre3:blocks":{"depends_on_id":"bd-mre3","type":"blocks","created_at":"2026-04-23T18:43:48.471854Z","created_by":"cscheid"},"bd-mw7x:blocks":{"depends_on_id":"bd-mw7x","type":"blocks","created_at":"2026-04-23T18:43:49.497210Z","created_by":"cscheid"},"bd-xee1:blocks":{"depends_on_id":"bd-xee1","type":"blocks","created_at":"2026-04-23T18:44:39.567807Z","created_by":"cscheid"}}} +{"id":"bd-b0f2","title":"Fix <anonymous> filenames in pipeline trace astContext","description":"Pipeline trace JSON files always show astContext.files as [{name: \"<anonymous>\"}] instead of the real filename. Root cause: serialize_pandoc_ast in crates/quarto-core/src/stage/trace.rs:417-432 discards doc_ast.ast_context and passes ASTContext::anonymous() to the JSON writer. Secondary issue: EngineExecutionStage rebuilds a single-file context after reconciliation, losing track of both the original .qmd and the intermediate .rmarkdown file. Plan: claude-notes/plans/2026-04-17-trace-anonymous-filenames.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-17T22:34:43.872061Z","created_by":"cscheid","updated_at":"2026-04-17T23:29:22.136643Z","closed_at":"2026-04-17T23:29:22.136049Z","close_reason":"Fixed trace astContext filenames. Phase 1: trace serializer now threads the real ASTContext through serialize_pipeline_data and on_transform_data. Phase 2: engine_execution builds a two-file merged context (.qmd + .rmarkdown) and pre-remaps the executed AST's FileIds via a new quarto-ast-reconcile::remap_file_ids helper. Plan: claude-notes/plans/2026-04-17-trace-anonymous-filenames.md. 9 new tests, 7444 workspace tests pass, cargo xtask verify passes."} +{"id":"bd-b2vk","title":"SPA getBinaryDocById missing automerge: URL prefix → binary capture docs never reach WASM","description":"ts-packages/quarto-sync-client/src/client.ts:getBinaryDocById passes the bare docId from the IndexDocument capture sidecar straight to repo.find(). The samod TS library rejects this with 'Error: Invalid AutomergeUrl: <id>' because it requires the 'automerge:' scheme prefix. The text-doc loader (loadFileDocuments) prepends the prefix explicitly (lines 305-307); getBinaryDocById doesn't. Net effect: every project-mode q2 preview render falls back to the default registry because captureGzJson is undefined, and code cells render as inert source — the exact user-reported bug. Diagnosed end-to-end on 2026-05-18 against the fixture website. Trivial fix: same 'automerge:' prefix-normalize pattern as loadFileDocuments. Critical because it makes the entire Phase C.4 replay path silently inert for real users.","status":"open","priority":0,"issue_type":"bug","created_at":"2026-05-18T14:58:18.131028Z","created_by":"cscheid","updated_at":"2026-05-18T14:58:18.131028Z","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T14:58:18.131028Z","created_by":"cscheid"},"bd-m0mu:discovered-from":{"depends_on_id":"bd-m0mu","type":"discovered-from","created_at":"2026-05-18T14:58:18.131028Z","created_by":"cscheid"}}} +{"id":"bd-b5hf","title":"Phase A.6: Always-visible force-refresh button in q2-preview-spa","description":"Persistent UI affordance that re-runs the WASM render pipeline against current automerge state. The user's escape hatch for cross-doc dep channels the dep graph doesn't yet encode (epic resolution #4). Phase A is engine-less, so this is purely client-side; Phase C extends it to trigger server-side re-execution. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.6.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-13T16:53:28.379674Z","created_by":"cscheid","updated_at":"2026-05-13T19:19:33.560290Z","closed_at":"2026-05-13T19:19:33.560147Z","close_reason":"Phase A.6 complete: always-visible refresh button (↻) at top-right of preview pane, bumps contentTick to re-fire render. Integration test pins click→renderPageForPreview.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.379674Z","created_by":"cscheid"}}} +{"id":"bd-b5jm","title":"L4 — quarto-doctemplate enhancements (pipes, ConfigValue bridge, project resolver)","description":"Implement pipe evaluator (TODO in render_variable + evaluate_partial). MVP pipe set: escape, escape_xml, date_format <fmt>, first, rest. Add ConfigValue → TemplateValue bridge in quarto-core. Add project-scoped partial resolver (ChainedResolver: MemoryResolver for built-ins + FileSystemResolver rooted at host-page dir). Independent of listings; unblocks L3 and L8. See claude-notes/plans/2026-05-05-listings-epic.md §L4.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-05T19:53:14.789389Z","created_by":"cscheid","updated_at":"2026-05-07T13:35:17.667986Z","closed_at":"2026-05-07T13:35:17.667624Z","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:14.789389Z","created_by":"cscheid"}}} +{"id":"bd-b9kzg","title":"q2 preview: surface render diagnostics & warnings in PreviewErrorOverlay (Phase D.4 follow-up)","description":"q2 preview today shows render *failures* via PreviewErrorOverlay (Phase D.4, bd-kw93.10) but does not surface the structured warnings and diagnostics that q2 render prints on stdout. Examples missing from the preview UI: [Q-13-4] body-link-references-missing-document, [Q-1-20] failed-to-parse-metadata-as-markdown — emitted by the WASM render pipeline (arrive in result.warnings) and by three server-side callsites (capture_driver.rs, deps.rs, re_execute.rs) that tracing::warn!() to stderr today.\n\nScope (post user sign-off 2026-05-21):\n(1) Per-page WASM-render diagnostics threaded into a forked PreviewDiagnosticsOverlay (in q2-preview-spa/, not the shared @quarto/preview-renderer one — keeps the two surfaces free to evolve independently). Collapsed by default for warnings.\n(2) Server-side infrastructure: DiagnosticSink in crates/quarto-preview/ + GET /api/preview/diagnostics endpoint + migration of the three existing tracing::warn!() callsites. Avoids paying the plumbing tax every time someone adds a new warning.\n(3) Out of scope: project-wide aggregation UI, richer engine diagnostics, CLI parity, re-converging the forked overlay.\n\nPlan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-surface.md (DESIGN APPROVED — ready for TDD implementation).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-21T16:34:54.151829Z","created_by":"cscheid","updated_at":"2026-05-21T18:24:33.512040Z","closed_at":"2026-05-21T18:24:33.511891Z","close_reason":"Implemented: render diagnostics + warnings now surface in q2 preview via the forked PreviewDiagnosticsOverlay; server-side DiagnosticSink + /api/preview/diagnostics endpoint + migration of capture_driver / deps / re_execute tracing::warn callsites in place so future server-side warnings are a one-liner. End-to-end verified against docs/ — both [Q-13-4] body-link and [Q-1-20] metadata-as-markdown warnings from the original problem statement surface in the overlay. Merged to main as merge commit. Plan: claude-notes/plans/2026-05-21-q2-preview-diagnostics-surface.md","dependencies":{"bd-kw93.10:discovered-from":{"depends_on_id":"bd-kw93.10","type":"discovered-from","created_at":"2026-05-21T16:34:54.151829Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-21T16:34:54.151829Z","created_by":"cscheid"}}} +{"id":"bd-b9mz","title":"Phase 7 — Post-render (sitemap, favicon, site-url/title)","description":"Phase 7 of bd-0tr6. Per-page transforms (title prefix, favicon link, canonical URL) + post_render writes (favicon copy, sitemap, robots.txt). Sub-plan: claude-notes/plans/2026-04-27-websites-phase-7.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-27T14:25:29.580640Z","created_by":"cscheid","updated_at":"2026-04-27T15:04:40.508208Z","closed_at":"2026-04-27T15:04:40.507943Z","close_reason":"Implemented on feature/websites: per-page transforms (title prefix, favicon, canonical URL), website_post_render module (favicon copy, sitemap, robots.txt). 7922 workspace tests pass; cargo xtask verify all 9 steps green. Sub-plan: claude-notes/plans/2026-04-27-websites-phase-7.md","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T14:25:29.580640Z","created_by":"cscheid"}}} +{"id":"bd-b9za","title":"Extension-dep site_libs/ dedup integration test (Phase 5 deferred)","description":"Phase 5 plan called for tests 19 (extension dep dedup) and 22 (byte-mismatch hard error). The unit-level coverage exists (drain/merge tests in artifact.rs) but an integration test that drives a website with two pages each using the kbd extension and verifies a single _site/site_libs/libs/kbd/kbd.css would close the gap. See claude-notes/plans/2026-04-24-websites-phase-5.md §Tests 19/22.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-25T01:31:17.461606Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:17.461606Z","dependencies":{"bd-u5pr:discovered-from":{"depends_on_id":"bd-u5pr","type":"discovered-from","created_at":"2026-04-25T01:31:17.461606Z","created_by":"cscheid"}}} +{"id":"bd-bays","title":"Phase A.7: Playwright smoke test for q2 preview","description":"q2-preview-spa/e2e/basic-preview.spec.ts: spawn quarto preview against a fixture, drive a chromium session, assert (a) initial render contains expected content, (b) editing the .qmd on disk produces a visible change within 2s, (c) force-refresh button works, (d) DOM-stability invariant: a data-stable-id element keeps the same DOM node identity across an edit (===, not just structural equality). See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.7.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T16:53:28.477270Z","created_by":"cscheid","updated_at":"2026-05-14T19:54:43.720171Z","closed_at":"2026-05-14T19:54:43.720047Z","close_reason":"Duplicate of bd-vpsy (closed 2026-05-13). Both filed Phase A.7 Playwright smoke for q2 preview with identical descriptions; bd-vpsy is the canonical record.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.477270Z","created_by":"cscheid"}}} +{"id":"bd-be2f7","title":"Q-10-* code collision: citeproc and doctemplate emit the same Q-10-* codes for different errors","description":"While authoring template subsystem error-docs (bd-4ltdl) the following code collision surfaced.\n\nThe catalog assigns Q-10-1 through Q-10-7 to the 'template' subsystem with these titles:\n- Q-10-1: Template Parse Error\n- Q-10-2: Undefined Variable\n- Q-10-3: Partial Not Found\n- Q-10-4: Recursive Partial\n- Q-10-5: Unresolved Partial Reference\n- Q-10-6: Unknown Pipe\n- Q-10-7: Invalid Pipe Arguments\n\nThese match the doctemplate emit sites in crates/quarto-doctemplate (Q-10-2 at evaluator.rs:224, Q-10-5 at evaluator.rs:336, Q-10-6 at pipes.rs:64, Q-10-7 at pipes.rs:209+).\n\nHOWEVER, crates/quarto-citeproc/src/error.rs also emits Q-10-1 through Q-10-5 for completely different errors:\n- citeproc Q-10-1: Locale Parse Error\n- citeproc Q-10-2: Reference Not Found\n- citeproc Q-10-3: Invalid Reference\n- citeproc Q-10-4: Missing Required Field\n- citeproc Q-10-5: Invalid Date\n\nThis is a code collision. Q-10-2 and Q-10-5 are emitted by BOTH crates with different meanings, and Q-10-1/3/4 are emitted by citeproc with meanings that contradict the catalog.\n\nAdditionally, Q-10-1, Q-10-3, Q-10-4 from the catalog (template subsystem) have no doctemplate emit site at all — only the contradictory citeproc emit sites.\n\nResolution options:\n1. Reassign citeproc to a new subsystem range (e.g., Q-10b-* or rename to citation subsystem with Q-NN-*).\n2. Reassign template to a new subsystem range.\n3. Audit which interpretation is canonical and add catalog entries for the unclassified emit sites.\n\nThe docs/errors/template/Q-10-*.qmd pages document the catalog's template meanings (doctemplate); they will be misleading for users who hit the citeproc errors.\n\nSibling drift issues: bd-xly8b (markdown), bd-fiv9u (writer).","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-24T21:15:16.164362Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:16.164362Z","dependencies":{"bd-4ltdl:discovered-from":{"depends_on_id":"bd-4ltdl","type":"discovered-from","created_at":"2026-05-24T21:15:16.164362Z","created_by":"cscheid"}}} +{"id":"bd-bj5yp","title":"Author error-docs pages for yaml subsystem (21 codes)","description":"Author docs/errors/yaml/Q-X-Y.qmd pages for all 21 entries in error_catalog.json under subsystem=yaml.\n\nCatalog codes (21 total): Q-1-1, Q-1-10 (DONE — seed page at status=complete), Q-1-11 through Q-1-19 (validation errors from quarto-yaml-validation), Q-1-20 through Q-1-28 (config/tag errors from quarto-config), Q-1-99 (generic validation fallback).\n\nPer-page workflow (from plan): grep emit site → understand call site → author stub-quality body (What/Why/How sections) → set status=stub → render-check with cargo run --bin q2 -- render docs/.\n\nClosing criteria (from bd-an6z4):\n- Every yaml code present in docs/errors/yaml/.\n- Every page at status=stub or better.\n- Audit (bd-8otua, not yet implemented — verify manually) reports zero missing and zero mismatched.\n\nPlan: claude-notes/plans/2026-05-22-error-docs-content.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-22T19:50:35.737Z","created_by":"cscheid","updated_at":"2026-05-22T20:02:08.215214Z","closed_at":"2026-05-22T20:02:08.214829Z","labels":["content","documentation","error-reporting"],"dependencies":{"bd-an6z4:parent-child":{"depends_on_id":"bd-an6z4","type":"parent-child","created_at":"2026-05-22T20:01:42.771537Z","created_by":"cscheid"}}} +{"id":"bd-bobp","title":"Index-forgiveness for page-source matching in page-nav","description":"Phase 4 uses strict source-path equality (page_source == flat_entry.href) to find the current page in the sidebar flat list. Mirrors the framing of bd-jbml (Phase 3 navbar index-forgiveness): if real content hits about/ vs about/index.qmd drift, allow the same equivalence here.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:48:03.376282Z","created_by":"cscheid","updated_at":"2026-04-24T22:48:03.376282Z","dependencies":{"bd-jbml:related":{"depends_on_id":"bd-jbml","type":"related","created_at":"2026-04-24T22:48:03.376282Z","created_by":"cscheid"},"bd-nwun:discovered-from":{"depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:48:03.376282Z","created_by":"cscheid"}}} +{"id":"bd-bpdz","title":"Reader extension surface for L9 (RSS feed extraction)","description":"L7 ships the listings-only subset of Q1's `readRenderedContents` in `crates/quarto-core/src/project/listing/post_render_upgrade/reader.rs`. The `ReaderOptions` struct has two flags (`remove_links`, `remove_images`) currently no-op in v1's plain-text output.\n\nL9 (RSS feeds, `bd-o90m`) will need:\n- math handling\n- syntax-highlight class maps\n- urls-to-absolute (configurable base URL)\n- anchor stripping\n\nEach is opt-in via a new `ReaderOptions` field. Implement as private functions in the same file gated by their flag. Do not introduce a trait-based plugin architecture (Q1's single-function reader has been stable for years).\n\nFiled at L7 close-out per the L7 plan §\"Filing reminder\" follow-up #2.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T19:51:17.456755Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:17.456755Z","dependencies":{"bd-qf7r:discovered-from":{"depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:17.456755Z","created_by":"cscheid"}}} +{"id":"bd-bqf2","title":"Listings: shared shape walker for parse_listings + extract_content_globs","description":"Today extract_content_globs (project/listing/config.rs) calls parse_listings and discards diagnostics, then plucks Glob entries from each Listing.contents. This re-runs the full listing parse just to read the glob strings.\n\nCleaner approach: factor a shared 'walk_listing_shape' helper that both parse_listings and extract_content_globs can use, so the dep-graph extractor only does the work it needs (walk shapes, collect content globs) and never produces diagnostics.\n\nThis is option 3 from L6 (bd-xbnf) planning. We chose option 1 for L6 because it gives a single source of truth on shape with minimal new code; this issue tracks the refactor for when someone has a reason (perf hot spot, or a second narrow extractor lands).\n\nOrigin: discussed in claude-notes/plans/2026-05-07-listings-L6-dep-graph.md §'Where the globs come from' and during L6 planning.\n\nReference: extract_content_globs in crates/quarto-core/src/project/listing/config.rs has a pointer comment back to this issue.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T17:15:52.991267Z","created_by":"cscheid","updated_at":"2026-05-07T17:15:52.991267Z","dependencies":{"bd-xbnf:discovered-from":{"depends_on_id":"bd-xbnf","type":"discovered-from","created_at":"2026-05-07T17:15:52.991267Z","created_by":"cscheid"}}} +{"id":"bd-brn3","title":"Phase 9 follow-up: vitest unit tests for render_page_in_project","description":"Plan tests 8-14 (vitest under hub-client) deferred from sub-phase 9.3. The native integration test (crates/quarto-core/tests/render_page_in_project.rs) covers the same code path; vitest tests would add JSON-shape assertions on the wasm-bindgen boundary. Lower priority since the native test catches regressions earlier in the dev cycle.\n\nTests to add (under hub-client/src/services/ as projectRender.wasm.test.ts):\n- render_page_in_project on a single-file fixture returns the same shape as render_qmd\n- render_page_in_project on a website fixture includes the sibling sidebar entry\n- editing about.qmd via vfs_add_file and re-rendering index.qmd reflects the new title\n- render_page_in_project on a project without website.sidebar config returns HTML with no sidebar block\n- cross-document link rewriting: [link](b.qmd) renders as href ending in b.html\n- project artifacts land in VFS at /.quarto/project-artifacts/...\n- per-page Phase-7 transforms still fire (title prefix, favicon link)","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-29T00:32:12.688603Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:12.688603Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:12.688603Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:12.688603Z","created_by":"cscheid"}}} +{"id":"bd-bsut","title":"Match Quarto 1 page-navigation default + styling + icons","description":"Tweak prev/next page-navigation behavior in websites to match Quarto 1:\n\n1. Default visibility: Q1 defaults website page-navigation to false (books default to true). Today PageNavGenerateTransform always populates the strip when a sidebar exists, so links appear unbidden in minimal websites. Add config support for top-level / website.page-navigation, default false for websites, with document-level override.\n\n2. Styling: Q1's .page-navigation is display:flex; justify-content:space-between, putting prev on the left and next on the right of one row. Q2 currently emits the markup but has no horizontal layout rule, so each link wraps onto its own row, left-aligned. Port the Q1 SCSS rules.\n\n3. Arrow icons: Q2 emits <i class=\"bi bi-arrow-left-short\"></i> and bi-arrow-right-short, but Bootstrap Icons CSS is not bundled into Q2 output, so the glyphs render blank. Bundle bootstrap-icons (or a minimal subset) and add the <link rel=\"stylesheet\"> to the head.\n\nReference fixture: examples/websites/06-site-metadata. Plan: claude-notes/plans/2026-04-30-page-nav-q1-parity.md.\n\nPhases:\n- Phase 0: tests + fixture, capture current Q2 output for regression baselines\n- Phase 1: project-config gate (page-navigation default false for websites)\n- Phase 2: Q1 .page-navigation flex SCSS\n- Phase 3: bundle Bootstrap Icons + link in head\n- Phase 4: docs (link bd-nf50)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-30T13:14:56.003176Z","created_by":"cscheid","updated_at":"2026-04-30T13:54:01.336227Z","closed_at":"2026-04-30T13:54:01.336080Z","close_reason":"All four phases complete: project-config gate (default off for websites), Q1 page-nav layout SCSS ported, Bootstrap Icons vendored + auto-emitted, docs + examples updated. Full CI verify passes. End-to-end browser screenshot recorded at /tmp/q2-page-nav-after.png shows single-row strip with visible arrow glyphs. Plan: claude-notes/plans/2026-04-30-page-nav-q1-parity.md"} +{"id":"bd-but3","title":"Hub-client math rendering blocked by iframe sandbox","description":"bd-w5ov shipped MathJax + KaTeX for HTML output. Live Chromium smoke confirmed correctness on the native CLI render path. However, a post-implementation regression test in hub-client preview shows raw \\(e=mc^2\\) text — math is NOT typesetting there.\n\nRoot cause: the hub-client preview iframe is sandboxed without 'allow-scripts'. Set in DoubleBufferedIframe.tsx:347,355 and MorphIframe.tsx:564 (sandbox='allow-same-origin allow-popups'). iframePostProcessor.ts:149-167 documents that script inlining is disabled for the same reason. No <script> in the iframe executes today, so MathJax/KaTeX CDN loaders never run, and our inline window.MathJax config block also doesn't execute.\n\nThe WASM pipeline IS correctly wired to MathJsStage and meta.math IS populated; the iframe sandbox just drops everything on the floor.\n\nResolution: blocked on the existing (separate) plan to isolate the preview iframe on a subdomain via service workers, which would let us re-enable allow-scripts safely. Once that lands, math typesetting in hub-client should 'just work' with no changes to MathJsStage.\n\nAlternatives considered (not pursued in v1):\n- Add allow-scripts unconditionally — strictly weaker security model; rejected by user.\n- Server-side pre-typesetting (KaTeX renderToString or MathJax Node) on the WASM pipeline — non-trivial and not needed once scripts run.\n- Switch hub-client default to Temml/MathML (no JS runtime needed) — bd-si8b tracks this independently; would not fix MathJax/KaTeX users.\n\nAcceptance: when service-worker iframe isolation is in place, set sandbox='allow-scripts allow-same-origin allow-popups' (and re-enable script handling in iframePostProcessor.ts), then re-run a hub-client smoke against the user's reproducer doc:\n\n---\nformat: html\ntitle: Math maybe?\n---\nHello, world. Will this work? $e=mc^2$.\n\n— and confirm typeset output in the preview.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-05T00:11:28.712023Z","created_by":"cscheid","updated_at":"2026-05-05T00:11:28.712023Z","dependencies":{"bd-w5ov:discovered-from":{"depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-05T00:11:28.712023Z","created_by":"cscheid"}}} +{"id":"bd-bwwv","title":"Navbar sub-row (book-style secondary navbar)","description":"Epic-excluded for MVP but worth tracking. Q1 renders a second row on book sites for chapter/part navigation. Requires ProjectType-specific extension to WebsiteProjectType (or its book successor). See 2026-04-24-websites-phase-3.md §Follow-up beads.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-24T19:43:00.017912Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:00.017912Z","dependencies":{"bd-fqyg:discovered-from":{"depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:43:00.017912Z","created_by":"cscheid"}}} +{"id":"bd-c05x6","title":"Plumb SourceInfo into Q-13-4 body-link 'missing document' warnings","description":"Today the Q-13-4 'Body link references missing document' warning is emitted without a source location, so a user running 'q2 render' on a website sees only the missing target — not which file or line introduced the broken link.\n\nExample, running 'cargo run --bin q2 -- render docs/' on this repo's docs site today:\n\n Warning [Q-13-4]: Body link references missing document\n 'authoring/markdown/markdown-basics.qmd' is not in the project index.\n i Check the spelling, or confirm the target file is included in the render set.\n\nThere is no 'at file:row:col' line, even though the body-link rewriter has the full Link node in hand and Link.target_source.url already carries a SourceInfo populated by the parser (crates/pampa/src/pandoc/treesitter_utils/span_link_helpers.rs:109).\n\nbd-qor9a already plumbed source-info into the nav-surface Q-13-* diagnostics (sidebar / navbar / footer / page-nav) via the paired href_source field. bd-hjv5o lists this body-link follow-up as item #1 — 'lightweight follow-up' because resolve_doc_relative_href already takes an Option<SourceInfo> location parameter; the body-link callsite just passes None at crates/quarto-core/src/transforms/link_rewrite.rs:224.\n\nScope:\n\n1. Pass link.target_source.url.clone() to resolve_doc_relative_href in LinkRewriter::visit_inline.\n2. Extend the Q-13-4 unit test (link_rewrite_diagnostic_uses_body_link_label) to assert d.location.is_some() and that the location maps back to the URL substring.\n3. Extend the integration test in crates/quarto-core/tests/link_rewriting_pipeline.rs that exercises Q-13-4 to assert on location.\n4. End-to-end: re-run 'q2 render docs/' and confirm the warning gains an 'at file:row:col' line under each Q-13-4.\n\nOut of scope:\n- Other Q-13-* surfaces (already covered by bd-qor9a).\n- Image href diagnostics (images aren't checked against the index).\n- RawHtml links (no SourceInfo on the URL portion).\n\nPlan: claude-notes/plans/2026-05-20-bd-PLACEHOLDER-body-link-source-location.md","notes":"Plan written at claude-notes/plans/2026-05-20-bd-c05x6-body-link-source-location.md (draft — awaiting user iteration before implementation begins).","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-21T00:25:11.017118Z","created_by":"cscheid","updated_at":"2026-05-21T00:37:25.978349Z","closed_at":"2026-05-21T00:37:25.978171Z","close_reason":"Implementation complete. link_rewrite.rs:224 now passes link.target_source.url.clone() instead of None to resolve_doc_relative_href, so the Q-13-4 'Body link references missing document' warning carries the link URL's SourceInfo. End-to-end verified on docs/ — Q-13-4 warnings now render with Ariadne source excerpts pointing at the offending .qmd:line:col. Three new/updated tests: link_rewrite_diagnostic_carries_source_location (unit, new), pipeline_body_link_broken_qmd_emits_diagnostic + pipeline_body_link_unresolvable_in_website_warns (integration, extended). cargo xtask verify --skip-hub-build clean (all 12 steps green). Doc-comments on missing_document_warning, resolve_href_for_html, resolve_doc_relative_href updated to reflect post-bd-c05x6 reality. Plan: claude-notes/plans/2026-05-20-bd-c05x6-body-link-source-location.md (all phases checked). Changes uncommitted pending user review.","dependencies":{"bd-hjv5o:discovered-from":{"depends_on_id":"bd-hjv5o","type":"discovered-from","created_at":"2026-05-21T00:25:11.017118Z","created_by":"cscheid"}}} +{"id":"bd-c083","title":"Cargo: upgrade tree-sitter v0.25.10 → v0.26.8","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.25.10 is range-pinned in workspace; latest is 0.26.8. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.321199Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.759296Z","closed_at":"2026-05-04T20:30:44.759137Z","close_reason":"merged: 61b01cd4","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.692502Z","created_by":"cscheid"}}} +{"id":"bd-c1et2","title":"Source-pointing diagnostics for resource-path errors","description":"Convert ResourceError into a quarto-error-reporting DiagnosticMessage with Ariadne source spans pointing to the offending YAML scalar (in _quarto.yml or doc header). ConfigValue already carries SourceInfo; the change is threading it through extract_resource_patterns and expand_patterns into the error variant.\n\nPlan: claude-notes/plans/2026-05-21-resource-path-diagnostic.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-21T21:12:37.994020Z","created_by":"cscheid","updated_at":"2026-05-21T22:18:26.530602Z","closed_at":"2026-05-21T22:18:26.530437Z","close_reason":"Source-pointing diagnostics for resource-path errors landed. ResourceError variants now carry SourceInfo; RawResourcePattern threads source-info through ProjectConfig.resources, DocumentProfile.resources (v5→v6), extract_resource_patterns, and expand_patterns. resource_error_to_parse_error + collect_static_resources_with_diagnostics build a tidyverse-shaped DiagnosticMessage with Ariadne span; orchestrator now wraps with QuartoError::Parse. 4 new tests (T1, T1', T2, T3). End-to-end demo confirms Ariadne span on _quarto.yml:5. Follow-up bd-z2j7o filed for WithSourceInfo<T> audit.","dependencies":{"bd-wlza2:blocks":{"depends_on_id":"bd-wlza2","type":"blocks","created_at":"2026-05-21T21:12:58.249795Z","created_by":"cscheid"}}} +{"id":"bd-c263g","title":"Author error-docs pages for lua subsystem (1 codes)","description":"Author stub-quality pages for all 1 lua subsystem error codes under docs/errors/lua/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:58.103168Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:23.074966Z","closed_at":"2026-05-24T21:15:23.074602Z"} +{"id":"bd-c3jh","title":"Phase 9 follow-up: GC stale VFS artifacts at session end","description":"When the hub-client preview re-renders, the WASM Pass-2 produces new artifact paths (theme-css fingerprints change when content changes) but the *old* artifacts under /.quarto/project-artifacts/... linger in VFS storage. The new HTML never references them — so they don't poison the page — but they do leak.\n\nGC pass at session-end (or periodically): walk /.quarto/project-artifacts/, drop any entry whose path doesn't appear in a 'live' set (the union of artifact paths from the most-recent project render).\n\nPhase 9 plan §Risks: 'Add a follow-up to GC /.quarto/project-artifacts/... entries with no live references at session end. Not a Phase-9 blocker.'","status":"open","priority":4,"issue_type":"task","created_at":"2026-04-29T00:32:31.194561Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:31.194561Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:31.194561Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:31.194561Z","created_by":"cscheid"}}} +{"id":"bd-c5u2g","title":"Cache engine-discovery so we don't re-spawn per document","description":"Replace JupyterEngine::find_executable's sh -c subprocess spawn with which::which (parity with KnitrEngine), and memoize both find_jupyter and find_rscript with OnceLock<Option<PathBuf>>. Per-doc engine-registry construction is 37% of main-thread CPU on quarto-web (bd-9eltv profile).\n\nPlan: claude-notes/plans/2026-05-22-engine-discovery-cache.md\nProfile: claude-notes/research/2026-05-21-quarto-web-render-profile.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-22T01:07:27.123486Z","created_by":"cscheid","updated_at":"2026-05-22T01:26:59.991346Z","closed_at":"2026-05-22T01:26:59.991170Z","close_reason":"Implemented and verified — per-process engine-discovery cache. quarto-web wall time 3.28s -> 2.30s (-30%); perf.engine-discover gauge added as regression tripwire.","dependencies":{"bd-9eltv:discovered-from":{"depends_on_id":"bd-9eltv","type":"discovered-from","created_at":"2026-05-22T01:07:27.123486Z","created_by":"cscheid"}}} +{"id":"bd-c6h96","title":"Mermaid engine design session: resolve architectural questions","description":"Design session to resolve the open questions in claude-notes/plans/2026-05-28-mermaidjs-engine-design.md.\n\n**v2 (post PR #238 review):**\n\n- **Q-A — RESOLVED.** PR #238 lands engine: [knitr, mermaidjs] sequencing. Mermaid is a first-class ExecutionEngine impl. Cell-class ownership disjoint (`{r}` vs `{mermaid}`) so the two compose cleanly. The v1 'AST transform' framing is obsolete.\n\n- **Q-B — sharper.** With engines as first-class citizens, the format-agnostic vs HTML-specific split becomes: does the engine emit RawBlock(HTML) (B1, format-locked), a marker Div + HTML writer special-case (B2a, ugly coupling), a marker Div + dedicated MermaidHtmlEmitStage in the canonical pipeline (B2c, recommended for first ship), or a marker Div + engine-declared per-format AST pass (B2e, requires bd-mqk49)?\n\n- **Q-C — unchanged.** Recommend C1 (inline RawBlock(HTML) for the jsdelivr script tag at end of body, encoded into the engine's markdown output). Survives bd-cp3em (capture-splice aux drop).\n\n- **Q-D — redirected.** PR #238 documents bd-iq0hp ('no browser E2E of multi-engine preview was possible'). Mermaid + knitr is the first real-engine pair with disjoint cell ownership; our preview-e2e task (bd-my0o5) effectively closes bd-iq0hp.\n\nOutput: plan doc has v2 with these decisions recorded. User confirmation of B2c recommendation needed before impl.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T13:44:52.754334Z","created_by":"cscheid","updated_at":"2026-05-28T17:09:57.153827Z","closed_at":"2026-05-28T17:09:57.153681Z","close_reason":"Design ratified by user (2026-05-28). All four questions resolved in plan v2.1: Q-A=A1 (MermaidEngine as ExecutionEngine in sequence per PR #238), Q-B=B1 (direct RawBlock HTML emission with bd-mqk49 TODO comment), Q-C=C1 (inline script RawBlock in engine markdown output), Q-D=close PR #238's bd-iq0hp via bd-my0o5 preview e2e. Plan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","dependencies":{"bd-je48v:parent-child":{"depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:44:52.754334Z","created_by":"cscheid"}}} +{"id":"bd-cfl67","title":"q2 render truncates source images referenced in qmd documents","description":"ResourceCollectorTransform stores image source paths as artifacts with empty content; write_artifacts then opens the source path for writing and truncates it to 0 bytes. Confirmed via 'q2 render docs/authoring/markdown/index.qmd' which truncates docs/authoring/markdown/elephant.png from 126124 bytes to 0. Plan doc: claude-notes/plans/2026-05-20-render-truncates-source-images.md","status":"open","priority":0,"issue_type":"bug","created_at":"2026-05-21T00:53:50.747194Z","created_by":"cscheid","updated_at":"2026-05-21T00:53:50.747194Z","labels":["bug","data-loss"]} +{"id":"bd-cjxlb","title":"Keyring error messages must not leak credential blob","description":"Plan §Phase 5 calls this out as a specifically-flagged risk: when CredentialStore.write/read/clear surfaces a backend error, the error message must NOT contain the credential blob (or any token-shaped substring).\n\nTest name: keyring_error_does_not_leak_blob_in_message in ts-packages/quarto-hub-mcp/test/auth/credential-store.test.ts.\n\nImplementation: wrap keyring errors via redact(err.message) at every site that touches a blob.\n\nPlan §Phase 5: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:27:50.747041Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:50.747041Z","dependencies":{"bd-sfr5l:parent-child":{"depends_on_id":"bd-sfr5l","type":"parent-child","created_at":"2026-05-20T14:27:50.747041Z","created_by":"shikokuchuo"}}} +{"id":"bd-cmp48","title":"hub-mcp Google device-flow auth (Design C')","description":"Implements Design C' (Google as device-flow AS) for hub-mcp ↔ quarto-hub authentication over WebSocket. Hub-mcp persists Google ID + refresh tokens locally (OS keyring); hub keeps existing JWKS validator with audience allowlist.\n\nPlan: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md\n\nPer the plan's Beads section: one issue per phase (1-10) parent-child to this epic, plus separate bug-tagged issues for the dual-credential CVE test (Phase 2), keyring-leak test (Phase 5), and canonical-URL constant test (Phase 7).","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-20T14:26:43.587791Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:26:43.587791Z"} +{"id":"bd-coffj","title":"q2 preview: Div with class='section' emits <div>, not <section> — breaks Quarto's :has(+ section) margin rules","description":"The native HTML writer (crates/pampa/src/writers/html.rs:1129-1142) emits <section>...</section> for Pandoc Div blocks whose class list contains 'section'; the React Div component in ts-packages/preview-renderer/src/q2-preview/blocks/Div.tsx always emits <div>. Consequence: Quarto theme CSS rules keyed on the <section> tag (e.g. 'main.content > p:has(+ section) { margin-bottom: 2rem }') don't apply to preview, causing visible spacing drift. Concrete repro: the 'This is an extremely basic website' paragraph in the fixture has 17px bottom margin in preview vs 34px in render. Fix: mirror the native writer — emit <section> when classes contains SECTION ('section').","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-18T17:53:40.764259Z","created_by":"cscheid","updated_at":"2026-05-18T17:58:07.422417Z","closed_at":"2026-05-18T17:58:07.422276Z","close_reason":"Implementation complete: Pandoc Divs with class='section' now render as <section> in q2 preview, matching the native HTML writer. Visible result: 'This is an extremely basic website' paragraph margin-bottom now 34px (was 17px), matching q2 render exactly. Quarto theme's main.content > p:has(+ section) selector now matches in preview. 2 new SPA tests; 152/152 green; cargo xtask verify 12/12 green.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T17:53:40.764259Z","created_by":"cscheid"}}} +{"id":"bd-cp3em","title":"CaptureSpliceStage drops includes/filters/supporting_files from recorded ExecuteResult","description":"crates/quarto-core/src/stage/stages/capture_splice.rs explicitly only consumes `result.markdown` from the captured ExecuteResult JSON. Comment in the code:\n\n> We don't need the rest of the ExecuteResult shape here (filters, includes, supporting_files) — those are engine-side concerns the splice doesn't reproduce in the AST.\n\n**Verified still present in PR #238 (`feature/multi-engine` branch)** — the new fold-over-Vec<EngineCapture> path drops aux fields per-iteration, same comment. So this is a multi-engine bug as well as a single-engine bug.\n\nEngines emitting side effects via `ExecuteResult.includes` (e.g. CSS/JS injection) work on `q2 render` but silently fail on `q2 preview`. Same shape as the CodeHighlightStage incident in CLAUDE.md.\n\nFor the mermaid first ship (bd-gwfdo), the plan v2 routes the jsdelivr <script> via the engine's `markdown` output (Q-C → C1) which dodges this gap. Fixing bd-cp3em would let us migrate to the cleaner ExecuteResult.includes path (Q-C → C2/C3) in a follow-up.\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G6.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-28T13:46:02.824396Z","created_by":"cscheid","updated_at":"2026-05-28T16:16:32.036257Z","dependencies":{"bd-c6h96:discovered-from":{"depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:46:02.824396Z","created_by":"cscheid"}}} +{"id":"bd-cpzp","title":"qmd writer: implicit-figure path drops trailing newline, collapses next block (issue #180)","description":"Triage doc: claude-notes/issue-reports/180/triage.md on branch issue-180.\n\nRoot cause: write_figure (crates/pampa/src/writers/qmd.rs:759) implicit-figure branch returns directly from write_image without emitting the trailing \\n that every block writer is expected to produce. When such a Figure is followed by another block (top-level or inside a Div), the inter-block separator collapses to a single \\n instead of a blank line, and the re-parser glues the two blocks into one Para. Affects every layout/subfigure div in the docs corpus.\n\nReports covered (both same root cause):\n- Bug A: top-level Figure followed by Para -> one Para after round-trip\n- Bug B: Div with multiple Figure children + caption -> one Para inside the Div after round-trip\n\nFix (TDD-first per crates/pampa/CLAUDE.md):\n1. Add failing roundtrip tests under tests/roundtrip_tests/qmd-json-qmd/\n - figure_implicit_then_para.qmd\n - layout_div_subfigures.qmd\n - figure_implicit_then_figure.qmd (extra coverage)\n2. Verify they fail.\n3. Fix write_figure: replace 'return write_image(...)' with 'write_image(...)?; writeln!(buf)?; Ok(())'.\n4. Verify tests pass.\n5. cargo nextest run --workspace to catch downstream snapshot updates.\n\nNot a duplicate of bd-emr4 — that is about non-implicit Figure shapes hitting the fallback fenced-div path. This bug is in the implicit-figure code path; different code, different fix.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-12T18:39:12.847875Z","created_by":"cscheid","updated_at":"2026-05-12T18:39:15.853892Z","dependencies":{"bd-emr4:related":{"depends_on_id":"bd-emr4","type":"related","created_at":"2026-05-12T18:39:15.853594Z","created_by":"cscheid"}}} +{"id":"bd-cqkts","title":"Phase 7 — hub-mcp MCP-tool exposure (authenticate_start / authenticate_finish)","description":"New module ts-packages/quarto-hub-mcp/src/auth/auth-tools.ts. Exposes two tools: authenticate_start (returns verification_uri, canonical_url, user_code, expires_in_seconds) and authenticate_finish (one poll per call, returns pending/slow_down/success/typed-error).\n\nCanonical URL https://www.google.com/device is a hard-coded module constant — never copied from Google's response. Sibling bug bd-XXXX tracks the canonical-URL-constant test specifically.\n\nRFC 8628 §3.5 rate-limiting: nextPollAllowedAt cached state, bumped 5 s per slow_down. Short-circuit on already-authenticated and lastObservedAuthMode === 'no-auth'.\n\nRegistered before registerTools so read/write tools can name authenticate_start in their error text.\n\nPlan §Phase 7: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:19.527539Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:19.527539Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:19.527539Z","created_by":"shikokuchuo"}}} +{"id":"bd-creo","title":"quarto render: fail strictly on Pass-1 failures (CI-friendly contract)","description":"Sibling of bd-rqba. Once Pass-1 failures are wired through as a dedicated pass1_failures field on the render summary surfaces (D1 in plan), give 'quarto render' a strict policy: any pass1_failures entry causes a non-zero exit. Remove the current string-matching of 'profile-pass skipped …' warning text in favor of the structured field.\n\nRationale: 'quarto render' is often used in headless CI; partial-progress leniency belongs to 'quarto preview' / hub-client, not render. The engine stays policy-free; consumers choose strict (render) vs lenient (preview).\n\nAlso: document the strict-vs-lenient contract in claude-notes/designs/document-profile-contract.md so future consumers (e.g., the planned hub-client-based 'quarto preview' binary) inherit it.\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Decision D1).","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-01T14:16:43.115104Z","created_by":"cscheid","updated_at":"2026-05-01T14:16:43.115104Z","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T14:16:43.115104Z","created_by":"cscheid"},"bd-rqba:related":{"depends_on_id":"bd-rqba","type":"related","created_at":"2026-05-01T14:16:43.115104Z","created_by":"cscheid"}}} +{"id":"bd-cxara","title":"Phase 9 — end-to-end verification","description":"CRITICAL per CLAUDE.md: tests passing alone is insufficient. Phase 9 runs the full verification matrix and records exact invocations + observed output in the plan's Verification log.\n\nCoverage: full cargo xtask verify; SPA cookie-path regression; clean-machine device-flow E2E (with per-platform credential-store inspection); no-auth-hub regression + explicit-authenticate short-circuit + observation-requirement check; allowlist parity for cookie 403 and bearer 403 (byte-identical detail); insecure-bearer dev-mode interaction (loopback + non-loopback with/without env flag); force-refresh; force-reauth; dual-credential CVE + WS-upgrade-with-no-Origin sanity check; audit-log spot-check; plaintext-leak grep.\n\nPlan §Phase 9: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"in_progress","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:31.218633Z","created_by":"shikokuchuo","updated_at":"2026-05-21T16:58:00.348922Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:31.218633Z","created_by":"shikokuchuo"}}} +{"id":"bd-d8fo","title":"q2-preview chrome: replace HTML injection with React components","description":"Phase F (q2-preview website chrome) ships Strategy A: include the *-render transforms (navbar-render, sidebar-render, page-nav-render, footer-render, toc-render) in the q2-preview pipeline so meta.rendered.navigation.* is populated with Bootstrap HTML; the React PreviewDocument injects via dangerouslySetInnerHTML.\n\nThis is the pragmatic first cut — shippable in days, byte-identical to q2 render. The tradeoff is DOM stability inside the chrome: open dropdowns, sidebar collapse state, scroll position inside the sidebar, etc., are blown away every time the chrome re-renders. In practice the chrome only re-renders on _quarto.yml edits, page switches, or sidebar reorderings — uncommon during normal authoring — so the cost is bounded.\n\nThis follow-up tracks the proper Strategy B: replace the HTML-injection path with React components that render from the structured meta.navigation.* (the ConfigValue form populated by the *-generate transforms before *-render runs). Each component mirrors the Bootstrap HTML the corresponding render transform emits.\n\nWhat this unlocks:\n- Stateful chrome (open Bootstrap dropdowns, collapsed sidebar sections, scroll position inside the sidebar) survives chrome re-renders.\n- React owns the click handlers natively rather than going through iframePostProcessor's after-the-fact .qmd-link rewriting.\n- The drift risk between server HTML emission and React component output goes away (the React components ARE the renderer; q2-render's HTML stays the source of truth for non-preview pipelines).\n\nScope:\n- Mirror Navbar / Sidebar / PageNav / Footer / Toc / Breadcrumbs from the Bootstrap HTML the *-render transforms emit today.\n- TypeScript types matching the structured ConfigValue shape each *-generate transform writes.\n- Remove the corresponding entries from Q2_PREVIEW_TRANSFORM_EXCLUDED in pipeline.rs — those transforms become unused in the preview pipeline, so the *-render Rust modules either stay (for q2 render) or get factored to a shared HTML emitter consumed only by the q2 render pipeline.\n- Snapshot tests asserting the React components emit markup matching the *-render Rust HTML output.\n\nFiled during Phase F planning (2026-05-14). Parent edge to the F epic to be added once F itself is filed.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-14T20:36:07.754117Z","created_by":"cscheid","updated_at":"2026-05-14T20:52:21.580312Z","dependencies":{"bd-kw93.15:discovered-from":{"depends_on_id":"bd-kw93.15","type":"discovered-from","created_at":"2026-05-14T20:52:21.579976Z","created_by":"cscheid"}}} +{"id":"bd-d8go","title":"L9 follow-up: date_format doctemplate pipe","description":"Originally specified as part of L9's L4 enhancements; deferred at impl-start because L9's RFC 822 pubDate is computed server-side in feed/binding.rs (no template-level need). Adding the pipe later requires a tree-sitter grammar change in crates/tree-sitter-doctemplate/grammar/grammar.js (the pipe set is grammar-fixed; the existing date_format must be a custom rule like pipe_left/pipe_center/pipe_right because it takes an argument), plus a match arm in crates/quarto-doctemplate/src/pipes.rs. Useful for L8's existing custom-template authors who want to format dates in the host page.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:55.509676Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:55.509676Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:55.509676Z","created_by":"cscheid"}}} +{"id":"bd-dhtw","title":"Phase 1: gh-pages provider end-to-end","description":"Phase 1 of bd-t3ny. Implement the gh-pages provider end-to-end on top of the Phase 0 scaffolding: common::git wrappers, common::github context discovery, _publish.yml reader, GhPagesProvider (prepare/commit/verify with .nojekyll poll), --dry-run cleanup with no residue, mkdocs-style summary, and an end-to-end test against a bare local remote (dry-run + real-run + json-run).\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md (Phase 1 section)\n\nBlocked on Phase 0 (bd-068k).","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-03T14:37:39.274734Z","created_by":"cscheid","updated_at":"2026-05-03T15:18:38.648426Z","dependencies":{"bd-068k:blocks":{"depends_on_id":"bd-068k","type":"blocks","created_at":"2026-05-03T14:37:39.274734Z","created_by":"cscheid"},"bd-t3ny:parent-child":{"depends_on_id":"bd-t3ny","type":"parent-child","created_at":"2026-05-03T14:37:39.274734Z","created_by":"cscheid"}}} +{"id":"bd-djpt","title":"Ship Bootstrap Icons font + CSS with Quarto 2 HTML output","description":"Quarto 2 HTML renders Bootstrap-icon markup (`<i class=\\\"bi bi-github\\\"></i>`) for navbar tools and footer nav items, but the Bootstrap Icons package (font file + icon CSS that maps class names to glyphs) is not shipped, so the icons render as empty boxes. Quarto 1 handles this via a separate bootstrap-icons dependency.\n\nScope: vendor vs CDN decision (prefer vendor, to match SCSS strategy); where the font file lives in artifact storage; template link (`<link rel=\\\"stylesheet\\\" href=\\\"...bootstrap-icons.css\\\">`); interaction with the planned JS-deps mechanism (bd-ulgr).\n\nCompanion to bd-ulgr (Bootstrap JS). Both issues concern static Bootstrap-ecosystem resources that Q2 needs to ship to match Q1 UX; worth designing them together.\n\nSurfaced during bd-imiw visual testing — navbar/footer DOM is correct, icons are invisible.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-18T20:00:13.337791Z","created_by":"cscheid","updated_at":"2026-04-18T20:00:13.337791Z","dependencies":{"bd-imiw:discovered-from":{"depends_on_id":"bd-imiw","type":"discovered-from","created_at":"2026-04-18T20:00:13.337791Z","created_by":"cscheid"},"bd-ulgr:related":{"depends_on_id":"bd-ulgr","type":"related","created_at":"2026-04-18T20:00:13.337791Z","created_by":"cscheid"}}} +{"id":"bd-dsco4","title":"Port _brand.yml integration to Q2 Typst format once available","description":"Q1 has src/resources/filters/quarto-post/typst-brand-yaml.lua. Q2's typst format is too immature for this today; revisit when typst-format work picks up.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-21T02:31:31.019793Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.019793Z"} +{"id":"bd-dy97y","title":"D7: Default HTML format ships Bootstrap-derived stylesheet","description":"## What\n\n`q2 render`'s default HTML format ships a minimal `tables_files/styles.css` (from `crates/quarto-core/resources/styles.css`). For tables to actually look styled even with `class=\"caption-top table\"` applied, the CSS bundle must include Bootstrap's `.table` and `.caption-top` rules.\n\nThe project already has Bootstrap SCSS sources at `resources/scss/bootstrap/`. This task wires the SCSS compilation/loading into the default HTML format so the produced HTML links a stylesheet containing those rules.\n\n## Scope\n\nJust enough to make a default render's tables look like Q1's tables. Custom themes, dark mode toggle, font scales etc. are out of scope.\n\n## Tests\n\nEnd-to-end test via `render_document_to_file` (per CLAUDE.md end-to-end requirement) that renders `tables.qmd` and asserts the produced HTML links a stylesheet whose contents contain `.table` selector + the expected rules (border, padding, font-weight on th).\n\nVisual re-verification in Chrome required before closing.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D7 section). Phase 2 work — blocks on D1-D6 only for visual verification, not for code.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-20T20:55:25.109513Z","created_by":"cscheid","updated_at":"2026-05-20T22:51:48.063407Z","closed_at":"2026-05-20T22:51:48.063242Z","close_reason":"No code change needed. CompileThemeCssStage already ships the full Bootstrap 5.3.1 bundle as _files/styles.css for default renders. The original 'unstyled table' symptom was 100% markup-side — once D1/D2 added the caption-top/table class hooks and thead/th promotion, the existing CSS styled the table identically to Quarto 1. Visual verification 2026-05-20 confirms byte-identical computed styles to Q1.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:25.109513Z","created_by":"cscheid"}}} +{"id":"bd-e7b7","title":"Q2 website JS library loading (native + hub-client incremental-stable)","description":"Q2 doesn't yet have a story for shipping JS modules with website renders. The hub-client live-preview path adds an additional constraint: JS modules must not be re-parsed/re-executed on every incremental HTML re-render (debounced renders fire on every keystroke; a Bootstrap collapse module that re-initializes per-render would lose state and likely break event handlers).\n\nRequired for: bd-f5yi-followup full Q1 sidebar rollup parity (hamburger toggle = Bootstrap collapse JS), and any future website feature that needs interactive JS (search, copy-button, etc.).\n\nDesign space:\n- Where do JS bundles live in the rendered HTML? (Currently no <script> tags emitted for site libs.)\n- How does hub-client's iframe lifecycle preserve module state across renders? Options: (a) load scripts in the iframe's outer wrapper that persists; (b) keep the iframe document but only swap inner-body innerHTML; (c) use a separate stable script-host iframe.\n- For native render, scripts should be self-contained under site_libs/ and emitted as <script src=\"site_libs/...\"> tags.\n\nPlan: claude-notes/plans/2026-05-01-website-sidebar-breakpoints.md (Resolved Decision 2 records the dependency chain).\n\nParent epic: bd-0tr6 (websites).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-01T17:00:33.914305Z","created_by":"cscheid","updated_at":"2026-05-01T17:00:33.914305Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:00:33.914305Z","created_by":"cscheid"},"bd-f5yi:related":{"depends_on_id":"bd-f5yi","type":"related","created_at":"2026-05-01T17:00:33.914305Z","created_by":"cscheid"}}} +{"id":"bd-e9m6","title":"Fix json_filter to invoke Python scripts via interpreter on Windows","description":"Command::new(filter_path) fails on Windows for .py files with OS error 193 (not a valid Win32 application). Need to detect script extensions and invoke via interpreter, like Pandoc does.","notes":"PR #89 created. Pandoc-style exists-then-dispatch pattern with find_python/find_bash caching.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-28T11:41:01.990041300Z","created_by":"cderv","updated_at":"2026-03-30T15:20:29.633028Z","closed_at":"2026-03-30T15:20:29.632662400Z","close_reason":"PR #89 merged into main"} +{"id":"bd-ea5tl","title":"Phase 0: CodeBlock decoration skeleton (Generate + Render transforms)","description":"Phase 0 of bd-1tl09. End-to-end skeleton with no behavioral change. Sets the architectural shape that Phases 1-3 will fill in.\n\n## Work\n\n1. Add a CodeBlockDecoration payload struct (empty to start; fields land in later phases).\n2. Add CodeBlockGenerateTransform: walks every CodeBlock, produces a default (empty) decoration. Lives in the Normalization Phase of build_transform_pipeline.\n3. Add CodeBlockRenderTransform: consumes decorations. Empty implementation today. Lives in the Finalization Phase.\n4. Decide where decorations live (open question 1 in the plan). Recommendation in plan: sideband map on RenderContext (option b), keyed by source location / block id. Listings does this — model after ListingGenerate / ListingRender.\n5. Tests: pipeline builds; the existing build_transform_pipeline ordering tests still pass; a new test demonstrates that the no-op Generate/Render pair leaves the AST byte-for-byte identical.\n\n## Open questions to lock down during Phase 0\n\nPer plan §\"Open questions to resolve before Phase 0\":\n- Q1: decoration storage. Recommendation: sideband map (b).\n- Q2: inline Code scope. Answer per plan: no — block CodeBlock only.\n- Q3: document-default resolution. Recommendation: resolve in Generate.\n- Q5/Q6 are for phases 5/6 (deferred) — not in scope here.\n\n## Acceptance\n\n- cargo xtask verify --skip-hub-build passes.\n- New transforms appear in build_transform_pipeline tests.\n- No existing test changes shape.\n\nPlan: claude-notes/plans/2026-05-19-code-block-features.md","notes":"Closed by commit (TBD). Skeleton in place: CodeBlockDecoration (empty struct), CodeBlockGenerateTransform (walker, no-op), CodeBlockRenderTransform (no-op). Wired into build_transform_pipeline (Normalization Phase after metadata-normalize, Finalization Phase alongside crossref-render). Two new tests pin ordering and presence in both HTML and q2-preview pipelines. cargo xtask verify passes. Storage decision (CustomNode vs sideband map vs serialized kv) deferred to Phase 1 where there's a data consumer.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T20:12:46.331654Z","created_by":"cscheid","updated_at":"2026-05-19T20:26:29.677664Z","closed_at":"2026-05-19T20:26:15.423083Z","dependencies":{"bd-1tl09:parent-child":{"depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:12:46.331654Z","created_by":"cscheid"}}} +{"id":"bd-ee4z","title":"Pass-2 resumption from cached AtProfile (websites phase 1 follow-up)","description":"Phase 1 of the website epic re-runs the head pipeline inside Pass 2 of ProjectPipeline (parse + metadata merge per file). The DocumentProfile checkpoint was designed to be resumable — we clone at AtProfile, Pass 1 extracts the profile, Pass 2 should resume from the cloned AtProfile instead of re-running the head stages. Requires threading a pre-built PipelineData::AtProfile through render_document_to_file. See claude-notes/plans/2026-04-23-websites-phase-1.md §Pass 2 resumption strategy.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T01:05:05.496137Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:05.496137Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:05.496137Z","created_by":"cscheid"}}} +{"id":"bd-eips","title":"L9 follow-up: format.metadata.description as channel description fallback","description":"Q1 cascades feed.description → format.metadata.description → website.description for the channel description. v1 cascades feed.description → website.description (skips the per-format layer). The simpler cascade matches Q2's configuration model. File this if a user needs the third level. Site: feed/binding.rs::website_description helper.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-08T17:33:26.773014Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:26.773014Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:26.773014Z","created_by":"cscheid"}}} +{"id":"bd-eity","title":"Generic file uploader dialog for hub-client","description":"Hub-client currently only supports dropping images onto the editor or sidebar. Users need to be able to upload arbitrary binary files (PDFs, CSVs, fonts, tree-sitter grammar .wasm files, etc.) into their Automerge-backed projects. The ingestion pipeline is already generic (processFileForUpload → createBinaryFile → VFS); what's missing is the UI affordance — a non-image-specific uploader dialog + triggers.\n\nPlan: claude-notes/plans/2026-04-21-generic-file-uploader.md\n\nBlocks: real-browser end-to-end verification for syntax-highlighting Phase 4 (loading a user tree-sitter grammar from _quarto/grammars/). See claude-notes/plans/2026-04-21-syntax-highlighting-phase-4.md step 4.6.\n\nScope (see plan for full details):\n- Generalize NewFileDialog's file-input accept filter (currently image/*,.pdf,.svg)\n- Route non-image editor drops to the upload dialog instead of discarding them\n- Add a '+' / 'Add files' entry point in the FileSidebar\n- Destination-path picker\n- Preserve existing image-drop markdown-insertion UX\n\nMostly UI-layer work; the binary ingestion pipeline stays unchanged.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-21T13:38:41.407334Z","created_by":"cscheid","updated_at":"2026-04-21T14:55:28.078909Z","closed_at":"2026-04-21T14:55:28.078161Z","close_reason":"Implemented in b0177b8d (plan 2026-04-21-generic-file-uploader)","dependencies":{"bd-n7x2:related":{"depends_on_id":"bd-n7x2","type":"related","created_at":"2026-04-21T13:38:41.407334Z","created_by":"cscheid"}}} +{"id":"bd-elgxx","title":"D4/D5 react: preview Table.tsx emits header/odd/even row classes","description":"## What\n\nD4/D5 in pampa's HTML writer (closed as bd-12fpz, commit c02a405a) emit `<tr class=\"header\">`, `<tr class=\"odd\">`, `<tr class=\"even\">` on rendered HTML. `q2 preview` does not benefit because it doesn't go through the pampa HTML writer — its iframe renders directly from AST JSON via the React Table component at `ts-packages/preview-renderer/src/q2-preview/blocks/Table.tsx`. That component currently emits bare `<tr>`.\n\n## Fix\n\nIn Table.tsx, extend `RowNode` to accept the row's class (\"header\" / \"odd\" / \"even\" / null). Caller (`Table`) computes it based on:\n- head rows: always \"header\"\n- body rows: alternating \"odd\" / \"even\" per TableBody, starting at \"odd\"\n- foot rows: null (no class)\n\nMirrors the pampa writer change (bd-12fpz) exactly.\n\n## Tests\n\nVitest test for Table.tsx that builds a minimal Table AST and asserts on the rendered DOM.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md — discovered during preview e2e verification on the table-rendering-parity epic.","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T22:38:08.670498Z","created_by":"cscheid","updated_at":"2026-05-20T22:42:26.405667Z","closed_at":"2026-05-20T22:42:26.405504Z","close_reason":"Implemented in this commit: row classes emitted in React Table component, mirroring pampa writer.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T22:38:08.670498Z","created_by":"cscheid"}}} +{"id":"bd-emr4","title":"qmd writer/reader: explicit Figure shapes don't round-trip (caption ≠ alt, multi-block content, etc.)","description":"Discovered while implementing bd-f5qd. The implicit-figure round-trip is fixed (write_figure now detects the implicit shape and emits bare image syntax). Figures with shapes other than the implicit one have no syntax in qmd that round-trips back to a Figure: the writer's fallback emits a fenced `::: {}` div with the caption as a sibling block, and the reader has no rule that turns that back into a Figure.\n\nConcrete minimal repro (caption text differs from image alt):\n\n $ cat > /tmp/explicit_fig.json <<'EOF'\n {\n \"pandoc-api-version\": [1, 23, 1],\n \"meta\": {},\n \"blocks\": [{\"t\":\"Figure\",\"c\":[\n [\"\",[],[]],\n [null,[{\"t\":\"Plain\",\"c\":[{\"t\":\"Str\",\"c\":\"A different caption.\"}]}]],\n [{\"t\":\"Plain\",\"c\":[{\"t\":\"Image\",\"c\":[[\"\",[\"lightbox\"],[]],[{\"t\":\"Str\",\"c\":\"Image alt\"}],[\"image.png\",\"\"]]}]}]\n ]}]\n }\n EOF\n $ cat /tmp/explicit_fig.json | cargo run --bin pampa -- -f json -t qmd\n ::: {}\n\n ![Image alt](image.png){.lightbox}\n\n A different caption.\n\n :::\n\n $ cat /tmp/explicit_fig.json | cargo run --bin pampa -- -f json -t qmd | cargo run --bin pampa -- -t native\n [ Div ( \"\" , [] , [] ) [\n Figure ( \"\" , [] , [] ) (Caption Nothing [Plain[Str \"Image\",Space,Str \"alt\"]]) [...],\n Para [Str \"A\",Space,Str \"different\",Space,Str \"caption.\"]\n ] ]\n\nThe original caption is gone (replaced by the implicit-figure rule firing on\nthe inner image-only paragraph, which copies the alt text into the caption).\nThe original caption text becomes a free-standing sibling Para. The outer\nDiv wraps the whole thing.\n\nOther shapes that hit the same fallback:\n- Figure with caption.short set\n- Figure with multiple content blocks\n- Figure with classes or kvs on the figure itself (not just the image)\n- Figure whose content isn't a single Plain[Image]\n\nFix needs reader-side support: design a qmd syntax for explicit figures and\nadd a reader rule that converts it back to a Figure block. Likely shape:\nfenced div with a recognizable class/id marker plus a convention for which\nblock is the caption (TS Quarto uses crossref-style `#fig-id` divs).\n\nFor now the writer's fallback path stays as-is; users get a structurally\nincorrect div until this is fixed.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-01T00:49:16.022173Z","created_by":"cscheid","updated_at":"2026-05-01T00:49:48.575674Z","dependencies":{"bd-f5qd:discovered-from":{"depends_on_id":"bd-f5qd","type":"discovered-from","created_at":"2026-05-01T00:49:16.022173Z","created_by":"cscheid"}}} +{"id":"bd-expy","title":"Pipe table parser commits to caption when ':::' follows a row (issue #206)","description":"Parse error when a fenced-div close `:::` directly follows a pipe table row without an intervening blank line. The first `:` of `:::` is shifted by the parser as the start of a `caption` rule (the caption first-token literal is `:`); once shifted, tree-sitter cannot back out, and the second `:` produces 'unexpected character or token here'.\n\nTriage doc: claude-notes/issue-reports/206/triage.md\nWorktree branch: issue-206\nGitHub issue: https://github.com/quarto-dev/q2/issues/206\nReporter: @rundel\nReal-world example: quarto-dev/quarto-web docs/websites/website-navigation.qmd L155-L159\n\nConfirmed not a fenced-div bug — bare pipe table + `:::` reproduces identically. The fenced div in the reporter's example is incidental.\n\nRecommended fix shape: introduce an external `_caption_start` scanner token that only matches a `:` not immediately followed by another `:` (and followed by inline whitespace). Re-key the `caption` rule on `_caption_start` instead of the literal `:`. Add tree-sitter corpus tests for `:::`-after-table, `: caption`-after-table, bare `:::` after table, and a pampa round-trip test for the repro fixture. Re-test on quarto-web after fix.\n\nOut of scope here, file separately if desired: pipe-table parser also silently absorbs trailing headings/paragraphs as one-cell rows when no blank line intervenes (see triage doc 'Adjacent finding').","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-15T18:48:39.090203Z","created_by":"cscheid","updated_at":"2026-05-15T21:35:28.981270Z","closed_at":"2026-05-15T21:35:28.981068Z","close_reason":"Fixed by PR #208 (merged as f0a1fd53)"} +{"id":"bd-f0h89","title":"Phase 3 — Audit logging (minimal v1)","description":"Inline tracing::event! on auth_ok / auth_fail carrying sub, credential_kind, action, outcome, plus detail on failure. Gate is Phase 2's three audit tests + redaction test.\n\nSchema-lock, dedicated audit.rs module, jti correlation, OTEL conventions, and the doc deferred to a follow-up plan.\n\nPlan §Phase 3: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-20T14:27:00.051312Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:00.051312Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:00.051312Z","created_by":"shikokuchuo"}}} +{"id":"bd-f3jc","title":"[websites phase 0] Foundations: snapshot type, pipeline checkpoint, naming","description":"First phase of website epic. Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 0.\n\nDeliverables:\n- Final names for the static-document snapshot type (working name DocumentProfile), the ProjectType trait, and the checkpoint stage.\n- Typed snapshot struct, serde-serializable.\n- PipelineData checkpoint variant with Clone/serialization.\n- Round-trip serialization tests + a clone-and-resume test that produces byte-identical output to end-to-end.\n- Decide crate placement (quarto-core vs new quarto-project crate).\n- Decide checkpoint position: after merge, or after merge + pre-engine sugaring.\n- Documentation of the static contract: what is guaranteed, under what conditions.\n\nNo user-visible behavior change in this phase.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:42:37.750604Z","created_by":"cscheid","updated_at":"2026-04-23T20:53:23.807873Z","closed_at":"2026-04-23T20:53:23.807149Z","close_reason":"DocumentProfile type + checkpoint stage + UnwrapProfile stage shipped. Resumability verified: clone-and-resume test produces byte-identical HTML to end-to-end; 3 real-fixture CLI renders byte-identical pre/post-change (MD5 match). 7654/7654 workspace tests + cargo xtask verify pass. Commit b8b72fc2 on feature/websites-phase-0. Contract doc at claude-notes/designs/document-profile-contract.md.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:37.750604Z","created_by":"cscheid"}}} +{"id":"bd-f3pl","title":"qmd writer drops table caption attributes (issue #152)","description":"GitHub: https://github.com/quarto-dev/q2/issues/152\nTriage: claude-notes/issue-reports/152/triage.md\nWorktree: .worktrees/issue-152 (branch issue-152, based on main @ 132c13c8)\n\nThe pipe-table branch of write_table (crates/pampa/src/writers/qmd.rs:1120-1239) ignores Table.attr entirely. A caption-attached attribute block like ': caption {tbl-colwidths=\"[30,70]\"}' is parsed correctly into Table.attr.2 (verified via 'cargo run --bin pampa --' on claude-notes/issue-reports/152/repro.qmd) but is dropped by 'pampa -t qmd', producing a lossy round-trip.\n\nThe list-table branch (write_list_table at lines 928-1118) already handles id/classes/keyvals correctly. The pipe-table branch needs analogous handling at the caption emission point (lines 1217-1235): after writing ': <caption-text>', emit ' {<attrs>}' via the existing write_attr helper (qmd.rs:396) when is_empty_attr(&table.attr) is false.\n\nOpen questions resolved during triage:\n 1. Empty-id auto-suppression NOT NEEDED. The reader (pipe_table.rs:148-200) only sets Table.attr.0 from explicit {#id} in the caption attr block; no implicit tbl-foo numbering exists.\n 2. Caption-suffix is the only valid placement for table attributes. Verified against pandoc 3.9.0.2: prefix form '{attrs}<newline>table<newline>: caption' is not parsed as a table by pandoc OR pampa (pampa raises Q-0-99 + Q-3-32). Suffix form ': caption {attrs}' produces byte-identical AST in both engines, including the mixed id+classes+keyvals shape.\n\nFix workflow per crates/pampa/CLAUDE.md:\n 1. Add failing fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ (table-caption-with-keyval.qmd, table-caption-with-id.qmd, table-caption-with-classes.qmd, table-caption-with-mixed-attrs.qmd).\n 2. Verify each fixture fails the round-trip equality check.\n 3. Implement: emit write_attr(&table.attr, buf, ctx) after the caption text (qmd.rs:1228-1234), guarded by !is_empty_attr(&table.attr). No id-suppression guard needed.\n 4. Verify new fixtures pass and existing table-caption.qmd snapshot is unchanged (its Table.attr is empty).\n 5. cargo xtask verify --skip-hub-build (Rust-only, no quarto-core/pandoc-types touched).\n\nExisting parser-side snapshot covering this fixture: crates/pampa/tests/snapshots/json/table-caption-attr.qmd. Read-side contract: docs/syntax/desugaring/table-captions.qmd.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-03T16:27:17.949705Z","created_by":"cscheid","updated_at":"2026-05-03T17:12:42.027337Z","closed_at":"2026-05-03T17:12:42.027211Z","close_reason":"Fixed in PR #154 / commit 688ac678. Pipe-table writer now appends Table.attr via write_attr() on the caption line; 4 round-trip fixtures cover id, classes, keyval, and mixed-attr shapes."} +{"id":"bd-f5qd","title":"qmd writer: Figure node emits empty div wrapper and duplicates caption","description":"From issue #150 (item 2): The qmd writer for Figure nodes produces an empty `::: {}` div wrapper and emits the caption text after the image as a separate paragraph, duplicating it. Round-tripping qmd -> ast -> qmd -> ast produces different ASTs.\n\nRepro:\n printf '![Webpage](image.png){.lightbox}\\n' | cargo run --bin pampa -- -t qmd\n ::: {}\n\n ![Webpage](image.png){.lightbox}\n\n Webpage\n\n :::\n\nExpected: round-trip should be stable; for an Image with caption inside a Figure with no extra attrs, output should likely just be the bare image syntax (`![Webpage](image.png){.lightbox}`) since pandoc auto-wraps it in a Figure. Plan in claude-notes/plans/ to follow.","notes":"Plan: claude-notes/plans/2026-04-30-figure-qmd-roundtrip.md\nDiscussion needed before implementing — see plan's 'Proposed fix — discussion needed' section.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T00:01:55.558223Z","created_by":"cscheid","updated_at":"2026-05-01T00:51:41.517422Z","closed_at":"2026-05-01T00:51:41.517262Z","close_reason":"Fixed implicit-figure round-trip via match_implicit_figure_shape in write_figure. When Figure shape matches what the reader's implicit-figure rule produces (single Plain[Image] content, caption=alt, attr split between figure id and image classes/kvs), the writer now emits bare image syntax. Non-implicit Figure shapes continue to fall through to the existing fenced-div form which does not round-trip — tracked in bd-emr4 with concrete repro. See claude-notes/plans/2026-04-30-figure-qmd-roundtrip.md."} +{"id":"bd-f5rpd","title":"verbose_to_filter directives match no first-party tracing targets","description":"The `-v` flag on `q2` and `hub` does not actually surface any first-party `tracing` events from the workspace.\n\n`quarto_util::verbose_to_filter` emits directives like `quarto=info` / `quarto=trace`, but every first-party crate that uses `tracing` emits events under a different target prefix:\n\n- `q2` binary (from `quarto` package): target prefix `q2::…`\n- `hub` binary (from `quarto-hub` package): target prefix `hub::…`\n- `quarto-core` library: target prefix `quarto_core::…`\n- `quarto-preview` library: target prefix `quarto_preview::…`\n\n`EnvFilter` matches by `::`-separated path segments. `quarto=info` only matches a target of exactly `quarto` or one starting with `quarto::`. It matches none of the above.\n\nEmpirical confirmation (commit 2b21ee60): `q2 render docs/ -vvv` shows zero per-file `Output: …` lines; `RUST_LOG=q2=info q2 render docs/` shows all 148.\n\nConsequences:\n- `-v` is effectively a no-op for first-party observability today.\n- Newly added `info!` calls have no audience and may be migrated to `eprintln!` (or a workaround like `quarto_util::user_status!` introduced 2026-05-24) without anyone noticing the filter is the problem.\n- `pampa`, `qmd-syntax-helper`, etc. do not install a subscriber at all — separate issue in the same family.\n\nFix requires design work:\n1. Audit which `tracing` calls in `quarto` / `quarto-core` / `quarto-hub` / `quarto-preview` are intended for user visibility vs developer telemetry.\n2. Decide structural shape: curated target list, custom `Filter` predicate over `metadata().target()`, or explicit `target: \"quarto::…\"` on every macro call.\n3. Coordinate with the hub binary (110 call sites, different audience than the CLI).\n4. Decide what `--quiet` means for `tracing` (today it's only checked at explicit call sites).\n\nFull audit + design questions: claude-notes/research/2026-05-24-tracing-envfilter-mismatch.md","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-24T22:20:10.516533Z","created_by":"cscheid","updated_at":"2026-05-24T22:20:32.104533Z"} +{"id":"bd-f5yi","title":"Hub-client: sidebar missing from website preview","description":"Even when the render succeeds (no parse errors), the hub-client preview for examples/websites/08-hub-preview/index.qmd does not show the website sidebar that the CLI render produces in _site/.\n\nCause not yet confirmed; needs in-browser repro via Chrome DevTools MCP. Pre-investigation rules out:\n- Sidebar transform gating: SidebarRenderTransform runs unconditionally in Pass-2, no RenderMode gate (crates/quarto-core/src/transforms/sidebar_render.rs:71-143).\n- Body-extract: hub-client passes the full rendered HTML to the iframe via srcDoc (hub-client/src/components/render/DoubleBufferedIframe.tsx:338,346), so the sidebar markup is in the DOM if the pipeline produced it.\n\nPlausible causes (ordered):\n1. Bootstrap / theme CSS not loaded in the iframe — sidebar element exists but unstyled / collapsed. Check link[href='/.quarto/...'] resolution in useIframePostProcessor.\n2. Project not detected — render_page_in_project falls through to single-doc branch when no _quarto.yml ancestor is found (race with VFS hydration on first load?).\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Bug 3 section). Reproduce, decide hypothesis, then split fix into its own ticket if needed.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T13:58:28.807896Z","created_by":"cscheid","updated_at":"2026-05-01T13:58:28.807896Z","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:28.807896Z","created_by":"cscheid"}}} +{"id":"bd-fegm","title":"Phase 8 — Incremental rebuilds (websites epic)","description":"Sub-plan: claude-notes/plans/2026-04-27-websites-phase-8.md\n\nPhase 8 of the websites epic. Implements:\n- DocumentProfile v2 (includes from bd-r82e + nav_dependencies + always_render + body_link_targets)\n- Profile cache under .quarto/cache/profiles/ keyed by source+metadata+includes hash\n- ProjectDependencyGraph (forward + reverse edges) built from sidebar membership + prev/next + body links + user-declared project.nav-dependencies\n- Two render modes: Mode A (full project, always re-renders Pass-2) and Mode B (subset render, walks deps for Pass-1 only)\n- Sitemap incremental merge (closes bd-pphv)\n- --clean flag\n\nbd-r82e (DocumentProfile.includes) lands as sub-phase 8.0 along with the three other v2 fields and the lifted Pass-1 helpers.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-27T22:20:58.290051Z","created_by":"cscheid","updated_at":"2026-04-28T00:43:11.605684Z","closed_at":"2026-04-28T00:43:11.605316Z","close_reason":"Phase 8 complete: sub-phases 8.0 (DocumentProfile v2), 8.1 (cache infrastructure), 8.2 (dependency graph + Mode B), 8.3 (sitemap merge), 8.4 (CLI surface + --clean-cache), 8.5 (integration tests + smoke), 8.6 (WASM/hub-client audit). Closes bd-pphv (sitemap merge) and bd-r82e (DocumentProfile.includes). Follow-ups: bd-par3, bd-nv5c, bd-pp89, bd-k8ol, bd-nqcv, bd-3a0o, bd-o505.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T22:20:58.290051Z","created_by":"cscheid"}}} +{"id":"bd-fiv9u","title":"Q-3-* writer subsystem catalog/code drift","description":"While authoring writer error-docs pages (bd-tep4x) the following drift surfaced:\n\nCODES EMITTED IN PRODUCTION BUT MISSING FROM CATALOG:\n- Q-3-2 (incremental.rs: \"Block ID re-used\" — see crates/pampa/src/writers/incremental.rs:462)\n- Q-3-37 (native.rs: \"Custom inline node in native writer\" — see crates/pampa/src/writers/native.rs:486)\n- Q-3-39 (json.rs: emitted twice — see crates/pampa/src/writers/json.rs:1511, 3284)\n- Q-3-56 (ansi.rs: \"Custom block not supported in ANSI format\" — see crates/pampa/src/writers/ansi.rs:745)\n\nCODES IN CATALOG BUT NEVER EMITTED:\n- Q-3-12 (\"Unresolved Note Reference\") — apparently superseded by Q-3-31 which says the same thing as a defensive guard\n- Q-3-30 (\"Shortcode Not Supported\") — may be emitted by a path not yet exercised, but no grep hit in src/writers/\n\nALSO: catalog message_template for Q-3-33..36 uses incorrect bracket syntax (e.g. [++...]) but production code uses CriticMarkup syntax {++...++}. Doc pages document the actual user-facing syntax.\n\nResolution options to discuss:\n1. Add missing catalog entries (Q-3-2, Q-3-37, Q-3-39, Q-3-56)\n2. Decide whether Q-3-12, Q-3-30 should be removed from catalog or kept as reserved\n3. Fix Q-3-33..36 message_template strings\n\nSibling drift issues: bd-xly8b (markdown subsystem).","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-24T20:31:29.743671Z","created_by":"cscheid","updated_at":"2026-05-24T21:26:40.037009Z","dependencies":{"bd-tep4x:discovered-from":{"depends_on_id":"bd-tep4x","type":"discovered-from","created_at":"2026-05-24T20:31:29.743671Z","created_by":"cscheid"}},"comments":{"c-i9vqu9ch":{"id":"c-i9vqu9ch","author":"cscheid","created_at":"2026-05-24T21:26:40Z","text":"Update from user correction (2026-05-24): actual Q2 editorial-markings syntax is {++ insertion}, {-- deletion}, {== highlight}, {>> comment} — no right-hand symbols. Catalog message_template AND production .problem strings in native.rs:413/432/450/468 both use wrong syntax. Q-3-33..36 pages corrected on main. Also: Q2 metadata-as-markdown parser (Q-1-20 path) does not parse editorial-markings even with correct syntax — body parser does. Inline-parser inconsistency between body and metadata paths."}}} +{"id":"bd-fo1r","title":"Body-link index-forgiveness ('docs/' matches 'docs/index.qmd')","description":"Mirror Phase 3's bd-jbml (navbar) and Phase 4's bd-bobp (page-nav). Body link [X](docs/) should resolve to docs/index.qmd → docs/index.html. Originally deferred from Phase 6 (bd-v30t). Consider unifying the three under a single epic-wide bead.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T13:36:38.223422Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:38.223422Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:38.223422Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:38.223422Z","created_by":"cscheid"}}} +{"id":"bd-fod3","title":"[websites] Sidebar tools: reader, dark toggle, language selector","description":"Implement Q1 sidebar 'tools:' entries — reader-mode toggle, dark/light toggle, language selector, custom tool links. Phase 2 parses them but ignores at render time. Most of these want the Phase-5 site_libs/ JS infrastructure to be useful.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T17:52:21.534867Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:21.534867Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:21.534867Z","created_by":"cscheid"}}} +{"id":"bd-fqyg","title":"Phase 3 — Navbar / footer project integration","description":"Wire Navbar and Page-Footer transforms into the website project model: consume ProjectIndex for text enrichment, active-marking, and .qmd→.html rewriting. Adds to NavigationItem (unifying sidebar/navbar/footer); extracts shared navigation_href, navigation_enrich, navigation_active modules; adds navbar brand fallback chain navbar.title → website.title → doc.title. Sub-plan: claude-notes/plans/2026-04-24-websites-phase-3.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-24T18:55:53.307957Z","created_by":"cscheid","updated_at":"2026-04-24T19:44:13.990704Z","closed_at":"2026-04-24T19:44:13.989885Z","close_reason":"Phase 3 complete: navbar + page-footer now consume ProjectIndex for enrichment, active-marking, and .qmd→.html rewriting. active: bool unified onto NavigationItem. Three shared modules extracted (navigation_href, navigation_enrich, navigation_active). Brand fallback chain via website.title. YAML surface unchanged (navbar / page-footer stay at top level per Decision 1). 7801 workspace tests pass; cargo xtask verify green. Sub-plan claude-notes/plans/2026-04-24-websites-phase-3.md.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-24T18:56:08.071732Z","created_by":"cscheid"}}} +{"id":"bd-ft03","title":"Reorder MetadataMergeStage before EngineExecutionStage","description":"Swap pipeline ordering so metadata merge runs before engine execution. Currently engine detection only sees document-level metadata, not project/directory layers. Plan: claude-notes/plans/2026-04-13-metadata-merge-reorder.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-13T21:17:55.460133Z","created_by":"cscheid","updated_at":"2026-04-13T21:46:20.430098Z","closed_at":"2026-04-13T21:46:20.428961Z","close_reason":"Done in commit 58f69dca"} +{"id":"bd-fu0l","title":"Jupyter engine: discover venv kernels and improve 'kernelspec not found' diagnostics","description":"Quarto 2's Jupyter engine cannot find kernelspecs installed in Python virtualenvs (e.g. `/Users/.../venv/share/jupyter/kernels/python3`), even when `jupyter kernelspec list` finds them. Root cause: `runtimelib::list_kernelspecs()` searches a fixed set of dirs (JUPYTER_PATH, ~/Library/Jupyter, /usr/[local/]share/jupyter) and ignores sys.prefix; the runtimelib source even has a TODO acknowledging this. Confirmed unchanged in 2.0.0 (dirs.rs is byte-identical to 1.6.0).\n\nStrategy: fix in our fork of runtimelib (cscheid/runtimelib), patch our Cargo.toml to use the fork, validate end-to-end against the original failing fixture from a venv shell, THEN open the upstream PR. Quarto-side wraps the runtimelib error with a remediation hint.\n\nOrdering principle: finish all Quarto-side work first to avoid upstream PR thrash if validation reveals fork-API tweaks. Phase 4 (upstream) is intentionally last and blocked by both bd-34wy and bd-ij1l.\n\nPhases tracked as discovered-from children. Plan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md\nReported via render of /Users/cscheid/Desktop/daily-log/2026/05/04/convert-test-3.qmd on 2026-05-04.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-04T15:33:40.843005Z","created_by":"cscheid","updated_at":"2026-05-04T16:15:19.950823Z","closed_at":"2026-05-04T16:15:19.950674Z","close_reason":"User-visible failure resolved end-to-end via Phases 1-3 (bd-maz5, bd-34wy, bd-ij1l). Original failing render of convert-test-3.qmd now succeeds; missing-kernel error renders an actionable diagnostic. Tracking the remaining upstream-PR step in bd-875x.","labels":["bug","dx","jupyter"],"dependencies":{"k-684e:related":{"depends_on_id":"k-684e","type":"related","created_at":"2026-05-04T15:33:40.843005Z","created_by":"cscheid"}}} +{"id":"bd-fuep","title":"[websites phase 8] Incremental rebuilds","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 8.\n\nDeliverables:\n- Content hashing: source + relevant metadata contributions (_quarto.yml, _metadata.yml).\n- On-disk cache in .quarto/cache/ per project: serialized DocumentProfile + pass-2 output stubs.\n- CLI detects unchanged files and reuses cached profiles; rebuilds nav state cheaply; re-renders only changed pages.\n- Sitemap update in place.\n- Tests: edit one page body -> only that page re-renders; edit _quarto.yml sidebar -> sidebars rebuild but bodies don't.\n\nBlocked by Phases 0, 1, 2, 7.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-23T18:43:22.709886Z","created_by":"cscheid","updated_at":"2026-04-23T18:43:54.682877Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:22.709886Z","created_by":"cscheid"},"bd-f3jc:blocks":{"depends_on_id":"bd-f3jc","type":"blocks","created_at":"2026-04-23T18:43:51.568201Z","created_by":"cscheid"},"bd-mre3:blocks":{"depends_on_id":"bd-mre3","type":"blocks","created_at":"2026-04-23T18:43:53.644437Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:52.601046Z","created_by":"cscheid"},"bd-yu16:blocks":{"depends_on_id":"bd-yu16","type":"blocks","created_at":"2026-04-23T18:43:54.681887Z","created_by":"cscheid"}}} +{"id":"bd-fvuy","title":"Q-12-10 catalog title/message inconsistency","description":"Catalog title for Q-12-10 is 'Listing Markdown Re-parse Diagnostics' but emitter uses it for both compile errors and re-parse diagnostics. Either split into two codes or broaden the title. Pre-existing; surfaced again during L8 review (custom-template compile errors flow through Q-12-10). See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §Diagnostic codes.","status":"open","priority":4,"issue_type":"chore","created_at":"2026-05-08T14:57:53.767681Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:53.767681Z","dependencies":{"bd-rqgx:discovered-from":{"depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:57:53.767681Z","created_by":"cscheid"}}} +{"id":"bd-fx23","title":"Defensive percent-encoding of listing.id in L7 image marker","description":"L7's image-placeholder begin marker embeds `listing.id` unescaped between `:` separators:\n\n`<!-- img-begin(<TOKEN>)[<attrs>]:<id>:<idx>:<href>:<b64-default> -->`\n\nToday the schema implicitly constrains listing ids to identifier-shape (no `:`, no whitespace). If a future schema change permits richer ids, the regex (`([^:]*)`) silently mis-parses.\n\nDefensive options:\n1. Validate listing ids at parse time, rejecting `:` / whitespace.\n2. Percent-encode the id segment in the marker, percent-decode at L7 substitution time.\n\nQ1 is silent here too. File only if a real user complaint surfaces, OR if the schema gains permissive id syntax.\n\nFiled at L7 close-out per L7 plan §D19.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-07T19:51:33.323112Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:33.323112Z","dependencies":{"bd-qf7r:discovered-from":{"depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:33.323112Z","created_by":"cscheid"}}} +{"id":"bd-fyb4z","title":"D1: list-table defaults header-rows to 1 (not 0)","description":"## What\n\nChange `transform_list_table_div` default for `header-rows` from 0 to 1 so a list-table with no explicit `header-rows` attribute promotes the first row to `<thead>` with `<th>` cells — matching Quarto 1 behavior.\n\n## Where\n\n`crates/pampa/src/pandoc/treesitter_utils/postprocess.rs:308`\n\n```rust\nlet header_rows: usize = div\n .attr\n .2\n .get(\"header-rows\")\n .and_then(|v| v.parse().ok())\n .unwrap_or(0); // <- change to 1\n```\n\n## Tests (TDD)\n\nAdd fixtures under `crates/pampa/tests/`:\n\n1. `list_table_default_header.qmd` — bare `::: list-table`, no `header-rows` attr. Assert JSON output has `TableHead` with one row of cells.\n2. `list_table_no_header_rows.qmd` — same with explicit `header-rows: 0`. Assert `TableHead` is empty.\n3. `list_table_two_header_rows.qmd` — explicit `header-rows: 2`. Assert `TableHead` has 2 rows.\n\nRun failing first, then implement, then re-run.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D1 section)","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T20:54:58.730903Z","created_by":"cscheid","updated_at":"2026-05-20T21:09:46.220920Z","closed_at":"2026-05-20T21:09:46.220751Z","close_reason":"Implemented in 87b5f236: bare list-table now defaults header-rows=1, matching Quarto 1. Tests added and green.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:54:58.730903Z","created_by":"cscheid"}}} +{"id":"bd-fyuo","title":"Cargo: upgrade hmac v0.12.1 → v0.13.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.12.1 is range-pinned in workspace; latest is 0.13.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.818590Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.122298Z","closed_at":"2026-05-04T20:30:45.122157Z","close_reason":"merged: 0812812e","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.861706Z","created_by":"cscheid"}}} +{"id":"bd-fztki","title":"Audit PR #238 multi-engine state before mermaid impl","description":"Audit PR #238 (https://github.com/quarto-dev/q2/pull/238) and its plan claude-notes/plans/2026-05-27-multi-engine-execution.md (on feature/multi-engine branch). Confirm before MermaidEngine impl:\n\n1. Where MermaidEngine would register in the EngineRegistry — native + WASM. Mermaid is subprocess-free (pure-Rust transform), so it should be registrable in the WASM build too, unlike Knitr/Jupyter.\n2. The per-engine FileId provenance scheme (`<stem>.<engine>.rmarkdown`) and what intermediate name mermaid should use.\n3. That `result.markdown` is QMD text re-parsed for the next engine — i.e. the mermaid engine emits QMD, not Pandoc-JSON.\n4. That capture_splice on feature/multi-engine still drops includes/filters/supporting_files (already spot-checked in plan v2; reconfirm at impl time).\n\nWrite findings back into claude-notes/plans/2026-05-28-mermaidjs-engine-design.md under Phase 1. Unblocks bd-gwfdo together with the design task.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T13:45:08.254090Z","created_by":"cscheid","updated_at":"2026-05-28T17:14:00.844590Z","closed_at":"2026-05-28T17:14:00.844402Z","close_reason":"Audit complete (2026-05-28). Findings F1-F8 recorded in claude-notes/plans/2026-05-28-mermaidjs-engine-design.md Phase 1. Key results: (1) MermaidEngine registers in EngineRegistry::new always-block — works in both native and WASM; (2) per-engine FileId provenance is loop-driven, no engine participation needed; (3) result.markdown is QMD re-parsed for next engine — literal HTML round-trips via pampa's QMD reader; (4) capture-splice still drops aux fields but mermaid sidesteps the issue by registering directly in WASM (live in-browser execution); (5) BIG finding: in-process engine convention is text-level fence scanning per FixtureEngine, not AST parse-walk-serialize — Phase 2 refined accordingly; (6) jsdelivr script tag goes in engine markdown output not includes; (7) KNOWN_ENGINES should gain 'mermaidjs' for the top-level shortcut form; (8) bd-cp3em verified still present in feature/multi-engine.","dependencies":{"bd-je48v:parent-child":{"depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:08.254090Z","created_by":"cscheid"}}} +{"id":"bd-g18wu","title":"D8: q2 preview CSS bundle has same table rules as render","description":"## What\n\n`q2 preview`'s SPA bundles its own CSS (`assets/q2-preview-*.css`) that doesn't include Bootstrap table rules. After D7, render output looks correct; preview must match.\n\n## Approach (per plan)\n\nPrefer single-source-of-truth: have the preview server serve the same stylesheet the render pipeline produces, rather than bundling separately. Coordinate with `k-giyy` (Investigate style differences between WASM and CLI rendering) — its artifact-replacement approach may deliver this for free.\n\n## Tests\n\nChrome DevTools-driven e2e against a running `q2 preview` serving `tables.qmd`. Assert computed `font-weight: 700` on first `<th>` and `padding: 8.5px` on cells.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D8 section). Phase 3 — likely absorbed by k-giyy.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-05-20T20:55:25.188489Z","created_by":"cscheid","updated_at":"2026-05-20T22:51:48.168577Z","closed_at":"2026-05-20T22:51:48.168428Z","close_reason":"No code change needed. q2-preview SPA's bundled CSS already includes Bootstrap table rules. After bd-elgxx (D4/D5 react) and bd-tkamn (D6 react) added the markup hooks on the React side, the preview's computed table styles match Q1 byte-for-byte. The 'coordinate with k-giyy' concern was based on a wrong premise (the CSS was never missing; only the class hooks were).","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:25.188489Z","created_by":"cscheid"},"k-giyy:related":{"depends_on_id":"k-giyy","type":"related","created_at":"2026-05-20T20:55:25.188489Z","created_by":"cscheid"}}} +{"id":"bd-g1prx","title":"Phase 3: code folding decoration","description":"Phase 3 of bd-1tl09 (blocked by Phase 0 skeleton; should be sequenced after Phase 1 so the composition with filename is exercised).\n\n## Trigger\n\n`#| code-fold: true` (collapsed by default) or `#| code-fold: show` (expanded by default). Optional `#| code-summary: \"Custom Label\"` (default: \"Code\").\n\n## Output (HTML)\n\n<details class=\"code-fold\" [open]><summary>Code</summary><div class=\"sourceCode\">…</div></details>\n\nImportant composition rule (from Q1's DecoratedCodeBlock pattern): when both filename AND fold are present, the fold's <details> wraps OUTSIDE the filename header, like this:\n\n<details class=\"code-fold\"><summary>Code</summary>\n <div class=\"code-with-filename\">\n <div class=\"code-with-filename-file\">…</div>\n <div class=\"sourceCode\">…</div>\n </div>\n</details>\n\nThis means the Render transform applies the fold wrapper LAST, after filename wrapping.\n\n## Work\n\n1. Add fold: FoldMode { Off, Hide, Show } and summary: Option<String> to CodeBlockDecoration.\n2. Generate transform: read per-block attrs. No doc default in Q1 — keep that.\n3. Render transform (HTML): emit <details> wrapper. Order with filename so the composition rule holds.\n4. CSS: port the .code-fold rules from _quarto-rules.scss.\n5. Mirror on React side.\n6. Composition test: a fixture with BOTH filename and code-fold renders with the correct nesting.\n\n## Tests\n\n- Native: single-feature snapshot (fold only).\n- Native: composition snapshot (fold + filename).\n- React: integration test for both single-feature and composed cases.\n- Visual: browser screenshot showing the <details> twirl works and the filename is visible inside it.\n\n## Acceptance\n\n- All tests pass.\n- cargo xtask verify passes.\n- Manual: clicking the disclosure triangle reveals/hides the code, filename header included.","notes":"Phase 2 (bd-j1trh) closed; Phase 3 unblocked. Read claude-notes/plans/2026-05-19-code-block-features.md §'Hand-off to next session — Phase 3 (code folding), bd-g1prx' FIRST. Key facts: (1) Render's wrap_in_place is now a single-pass cumulative wrap; just add wrap_with_fold_details as the outermost layer. (2) Q1 supports BOTH doc-default and per-block override for code-fold (different from Phase 2's doc-only mirror). (3) <details> RawBlock structuring (single vs split) needs to be cleared with user at kickoff — see plan open question. (4) SCSS is embedded via include_dir; rebuild q2 after .scss edits. (5) Pre-existing tree-sitter regression still trips xtask verify step 4/12 — use --skip-treesitter-tests --skip-treesitter-crlf-tests.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-19T20:13:25.088564Z","created_by":"cscheid","updated_at":"2026-05-19T21:59:37.528460Z","dependencies":{"bd-1tl09:parent-child":{"depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:13:25.088564Z","created_by":"cscheid"},"bd-ea5tl:blocks":{"depends_on_id":"bd-ea5tl","type":"blocks","created_at":"2026-05-19T20:13:59.762892Z","created_by":"cscheid"}}} +{"id":"bd-gdhk","title":"Extract drain-and-flush-or-merge helper out of pass2 renderers","description":"Native `render_document_to_file` (`crates/quarto-core/src/render_to_file.rs:264-297`) and WASM `RenderToHtmlRenderer.render` (`crates/quarto-core/src/project/pass2_renderer.rs:343-355`) now have parallel logic: drain Project-scope artifacts, then either flush in-place via the per-page resolver (when `lib_dir` is empty) or merge into the orchestrator's accumulator (when non-empty). Extract a shared helper to dedupe — pure code-cleanup, no behavior change. Discovered while fixing bd-87fu.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-01T22:49:06.984792Z","created_by":"cscheid","updated_at":"2026-05-01T22:49:06.984792Z","dependencies":{"bd-87fu:discovered-from":{"depends_on_id":"bd-87fu","type":"discovered-from","created_at":"2026-05-01T22:49:06.984792Z","created_by":"cscheid"}}} +{"id":"bd-gdrv","title":"Body-link cross-format URL resolution (HTML→PDF, etc.)","description":"When a doc's format: pdf is set per-doc, body links from HTML pages targeting that doc should produce .pdf hrefs (not .html). Out of website-epic scope; multi-format projects are a future epic. Originally deferred from Phase 6 (bd-v30t). Related to bd-0tr6 (websites epic) via shared resolver substrate.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T13:37:00.443647Z","created_by":"cscheid","updated_at":"2026-04-27T13:37:00.443647Z","dependencies":{"bd-0tr6:related":{"depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-27T13:37:00.443647Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:37:00.443647Z","created_by":"cscheid"}}} +{"id":"bd-gdzlq","title":"Q-1-20 is double-allocated: pampa meta.rs uses it for markdown-parse failure (matches catalog); quarto-yaml-validation/error.rs uses it for StringLengthInvalid","description":"The catalog (error_catalog.json) defines Q-1-20 as 'Failed to parse metadata value as markdown' and pampa/src/pandoc/meta.rs:64,76 emits with that meaning.\n\nBut quarto-yaml-validation/src/error.rs:162 also maps ValidationErrorKind::StringLengthInvalid to Q-1-20, and that variant is emitted from validator.rs:356,371 for schema minLength/maxLength violations.\n\nTwo different errors share one docs_url. The catalog is authoritative for the user-facing page, so the validation side needs a new code (probably Q-1-29) and the StringLengthInvalid → Q-1-20 mapping should be updated.\n\nDiscovered while authoring docs/errors/yaml/Q-1-20.qmd (bd-bj5yp). The page will document the catalog meaning (markdown-parse failure) for now; once this bug is fixed, the page text stays accurate.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-22T19:51:52.739963Z","created_by":"cscheid","updated_at":"2026-05-22T20:26:46.062602Z","closed_at":"2026-05-22T20:26:46.062226Z","labels":["error-reporting","yaml"],"dependencies":{"bd-bj5yp:discovered-from":{"depends_on_id":"bd-bj5yp","type":"discovered-from","created_at":"2026-05-22T19:51:52.739963Z","created_by":"cscheid"}}} +{"id":"bd-gk74","title":"WASM build: exception-handling unstable feature warning and missing wasm-bindgen","description":"npm run build:all in hub-client shows warning spam from unstable exception-handling target feature on every crate, and fails due to missing wasm-bindgen CLI. Plan: claude-notes/plans/2026-03-30-wasm-build-warnings.md","status":"open","priority":2,"issue_type":"bug","created_at":"2026-03-30T17:17:39.857777Z","created_by":"cscheid","updated_at":"2026-03-30T17:17:39.857777Z"} +{"id":"bd-gkqxl","title":"Author error-docs pages for project subsystem (3 codes)","description":"Author stub-quality pages for all 3 project subsystem error codes under docs/errors/project/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:57.290373Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.761525Z","closed_at":"2026-05-24T21:15:22.761176Z"} +{"id":"bd-gpyup","title":"Worktrees can poison the main target/ with dead-path build artifacts","description":"Observed 2026-06-02 while running 'cargo nextest run --workspace' from the main checkout: deterministic test failures in crates I never touched (quarto-citeproc locale::tests, quarto-error-reporting::schema_drift). Root cause: ~26k objects in target/debug/deps had env!(CARGO_MANIFEST_DIR) baked to a DELETED worktree path '.worktrees/bd-3klmk-flaky-test-passoneusesmultiplethreads-asserts/...'. Cargo reused these stale binaries on fingerprint match. Tests that read files via CARGO_MANIFEST_DIR (schema_drift -> 'no file on disk') or rust-embed dynamic/debug loading (locale -> silent English fallback) failed; they pass the moment the crate is recompiled, and 'cargo clean' + rebuild makes the full workspace green (9515/9515). The only way the MAIN target/ gets binaries with a worktree's CARGO_MANIFEST_DIR is if a build run from that worktree wrote into the main target/ (shared/redirected target dir or a target symlink). No CARGO_TARGET_DIR env or .cargo/config.toml target-dir is set, so the sharing was likely ad-hoc in that (now-deleted) worktree. Work: (1) determine how a worktree can end up writing into the main target/ and prevent it (git worktrees should each get their own target/ by default); (2) add a note to .claude/rules/worktrees.md warning that a shared/symlinked target across worktrees poisons the cache with dead-path artifacts, and that 'cargo clean' is the recovery; (3) consider a doctor/lint check that greps target/*/deps for paths under .worktrees/ that no longer exist. Recovery for anyone hitting this now: 'cargo clean'.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-06-02T14:21:01.109215Z","created_by":"cscheid","updated_at":"2026-06-02T14:21:01.109215Z"} +{"id":"bd-gucj","title":"hub-client: thread project _quarto.yml into ProjectContext","description":"wasm-quarto-hub-client/src/lib.rs::create_wasm_project_context creates a single-file ProjectContext with default (empty) ProjectConfig. This means custom crossref types defined in a project's _quarto.yml (crossref.custom) are not applied to either render or outline. Fix: read the project's _quarto.yml content from the Automerge document set and populate ProjectContext.config.metadata before running the pipeline. Once fixed, both the render path and the new LSP analysis pipeline (added in bd-ascs) pick up custom ref types automatically.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-17T22:16:27.550804Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:27.550804Z","dependencies":{"bd-ascs:discovered-from":{"depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:27.550804Z","created_by":"cscheid"}}} +{"id":"bd-gvhe","title":"Block-crossref HTML output parity with Quarto 1","description":"Implement Q1-parity HTML rendering for theorems, lemmas, and sibling block-level crossref targets. See claude-notes/plans/2026-04-17-theorem-html-q1-parity.md. Two-step fix: (1) extend TheoremSugarTransform to match id-prefix in addition to class; (2) rewrite render_theorem / render_resolved_ref to emit theorem-title span + nbsp.","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-04-17T17:11:23.700466Z","created_by":"cscheid","updated_at":"2026-04-17T17:11:32.888516Z","dependencies":{"bd-jsbg:parent-child":{"depends_on_id":"bd-jsbg","type":"parent-child","created_at":"2026-04-17T17:11:23.700466Z","created_by":"cscheid"}}} +{"id":"bd-gwfdo","title":"Implement MermaidEngine (B1: direct RawBlock HTML emission)","description":"Implement mermaid handling per the ratified v2 design (see bd-c6h96 outcome and plan v2, Q-B → B1). **Gated on PR #238 merging.**\n\nAdd MermaidEngine implementing ExecutionEngine in crates/quarto-core/src/engine/mermaid/ (mirror engine/markdown.rs shape — closest precedent for a no-subprocess engine):\n\n- name() == 'mermaidjs'.\n- execute(input, ctx): parse input as QMD, walk for code cells with class 'mermaid', replace each with RawBlock(HTML, '<pre class=\"mermaid\">...</pre>') (B1 — direct HTML emission), append a once-per-doc RawBlock(HTML, '<script type=\"module\">...mermaid.esm.min.mjs...initialize({startOnLoad: true})...</script>') at end of body (C1). Serialize back to QMD; return as ExecuteResult { markdown, ..Default }.\n- **Add a source-code comment** at the RawBlock-emission site pointing at bd-mqk49: 'when engines can declare per-format AST passes, route this through a format-conditional transform instead of emitting HTML inline. Today Quarto 2 only renders HTML so the format-locked emission is acceptable.'\n- Register in native + WASM EngineRegistry.\n\nTests: unit (engine on fixture) + pipeline (full HTML render) + end-to-end per CLAUDE.md verification policy (cargo run --bin q2 -- render fixture.qmd; grep output; record in plan).\n\nThe B2c/B2e (dedicated HTML-emit stage / engine-declared per-format pass) path was rejected for the first ship — Quarto 2 is HTML-only today, so format-agnostic decomposition would be hypothetical correctness against a future cost. The follow-up lives on bd-mqk49.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","notes":"Topic branch: beads/bd-gwfdo-implement-mermaidengine-b1-direct (commit 93418945). Working tree clean. cargo nextest run --workspace passes (9496 tests). End-to-end verified via cargo run --bin q2 -- render. cargo xtask verify --skip-hub-build in flight (background).","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-28T13:45:14.944001Z","created_by":"cscheid","updated_at":"2026-05-28T17:36:29.529560Z","dependencies":{"bd-c6h96:blocks":{"depends_on_id":"bd-c6h96","type":"blocks","created_at":"2026-05-28T13:45:35.978499Z","created_by":"cscheid"},"bd-fztki:blocks":{"depends_on_id":"bd-fztki","type":"blocks","created_at":"2026-05-28T13:45:36.396009Z","created_by":"cscheid"},"bd-je48v:parent-child":{"depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:14.944001Z","created_by":"cscheid"}}} +{"id":"bd-gz6k","title":"Cargo: upgrade sha1 v0.10.6 → v0.11.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.10.6 is range-pinned in workspace; latest is 0.11.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.170269Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.941246Z","closed_at":"2026-05-04T20:30:44.941104Z","close_reason":"merged: 0812812e","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.443720Z","created_by":"cscheid"}}} +{"id":"bd-h4l6","title":"[websites phase 5] Scoped artifact store and site_libs/ dedup","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 5.\n\nDeliverables:\n- Add scope (Page | Project) to artifact entries in ArtifactStore.\n- Project-aware artifact writer: Project-scoped artifacts emitted once to _site/site_libs/{name}/...\n- Relocator: rewrite per-page HTML to point at shared site_libs/ paths correctly (handles subdirs, offset computation).\n- Migrate theme CSS, Bootstrap, quarto-nav JS, etc. to Project scope when inside a website project.\n- Preservation: single-doc renders unchanged (both scopes resolve under {stem}_files/).\n- Sequence the change in two steps: (a) pure refactor introducing scope with identical behavior, (b) switch websites to use Project scope.\n\nBlocked by Phase 1.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:43:08.936956Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.479325Z","closed_at":"2026-04-29T00:31:30.479019Z","close_reason":"Phase 5 (scoped artifact store + site_libs) implemented (commit dc4e81b0). Closed as part of Phase 9 cleanup.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:08.936956Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:44.336998Z","created_by":"cscheid"}}} +{"id":"bd-h5l7","title":"Diagnose and fix SourceInfo::eq hotspot in hub-client preview","description":"Chrome profile of hub-client on a moderately-sized document shows a large hotspot on <quarto_source_map::source_info::SourceInfo as core::cmp::PartialEq>::eq, entered from parse_qmd_to_ast (crates/wasm-quarto-hub-client/src/lib.rs:757). Likely cause: SourceInfoSerializer::intern in crates/pampa/src/writers/json.rs:229 linearly scans content_map (Vec<(SourceInfo, usize)>) on every pointer-lookup miss, and SourceInfo is held by-value in AST nodes so pointer lookups almost always miss — giving O(n²) behavior per document. Also the first perf-profiling session on Quarto 2, so the plan deliberately establishes a repeatable native-side workflow (Criterion bench + samply flamegraph on the pampa binary) before any fix, since Chrome-side before/after is too noisy to iterate on. Plan: claude-notes/plans/2026-04-22-sourceinfo-eq-hotspot.md. Currently in draft — awaiting user review before any measurement work begins.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-22T20:00:48.019984Z","created_by":"cscheid","updated_at":"2026-04-22T23:23:38.315697Z","closed_at":"2026-04-22T23:23:38.315082Z","close_reason":"Landed on perf/2026-04-22-json-sourcemap in commit 8f6f21d9. Browser cross-validation confirmed SourceInfo::eq no longer a hotspot."} +{"id":"bd-h736","title":"Default project render regression and project-level diagnostics","description":"Post-websites-merge: presence of `_quarto.yml` with `project: { type: default }` causes `q2 render` to silently produce zero output, and `q2 render index.qmd` to fail with a misleading 'excluded from render list' error. Root cause: `default_output_dir` returns the project root for default projects, so the discovery walker's output_dir-exclusion check rejects every file. Three goals: (1) fix the discovery regression so default projects walk the tree like websites do; (2) add a clear project-level diagnostic when the render set is empty so we no longer silently no-op; (3) add a project-level diagnostic surface that both the CLI and hub-client can render, since today only file-level diagnostics flow to hub-client. Plan: claude-notes/plans/2026-05-01-default-project-render-diagnostics.md (open design questions inside, awaiting user input before implementation starts).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T21:40:15.795872Z","created_by":"cscheid","updated_at":"2026-05-01T22:08:43.216214Z","closed_at":"2026-05-01T22:08:43.216070Z","close_reason":"Fixed default-project discovery regression (output_dir == project_dir) and added Q-PROJECT-EMPTY project-level diagnostic with non-zero exit. Plumbing reuses existing ProjectRenderSummary.project_diagnostics infrastructure, so hub-client surfaces the diagnostic via the existing warnings array. End-to-end verified against the user's fixture in claude-notes/plans/2026-05-01-default-project-render-diagnostics.md. Commits: dd959bdd (Phase 1: discovery fix + tests), fd06b8da (Phase 2: empty-set diagnostic + CLI exit policy).","dependencies":{"bd-0tr6:discovered-from":{"depends_on_id":"bd-0tr6","type":"discovered-from","created_at":"2026-05-01T21:40:15.795872Z","created_by":"cscheid"}}} +{"id":"bd-hb8h","title":"Design: cargo-dependency-upgrade skill for periodic dependency maintenance","description":"Design and implement an on-demand /upgrade-cargo-deps skill for periodic (bi-weekly) Rust dependency maintenance. Design settled 2026-05-04: skill-only (no scheduling); applies patch/minor upgrades automatically in a worktree, surfaces major upgrades for human judgment via plan doc + per-major beads issues; runs full 'cargo xtask verify' after applying; uses only built-in cargo tooling (cargo update, cargo tree --duplicates); npm equivalent deferred to v2. See claude-notes/plans/2026-05-04-cargo-dependency-upgrade-skill.md for full design and work items.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-04T15:49:18.455915Z","created_by":"cscheid","updated_at":"2026-05-04T16:19:43.493917Z"} +{"id":"bd-hfjj","title":"Hub-client decomposition: shared preview-pane package for hub-client + q2 preview SPA","description":"Design sprint + implementation of the React-component decomposition that lets hub-client's preview pane and the q2 preview SPA share components — same source files, same imports, same tests. Drawing the package boundary correctly is what makes new preview features land in both surfaces by construction (no second copy to maintain). Blocks Phase A of bd-kw93. See claude-notes/plans/2026-05-11-q2-preview-epic.md (§Build-time concerns, §Crate / SPA layout invariant, §Recommended next steps item 1). Open: exact package count + names (one shared package for render-time primitives? two for render + sync? more?), workspace layout, build-script wiring.","status":"closed","priority":1,"issue_type":"epic","created_at":"2026-05-11T15:40:51.137344Z","created_by":"cscheid","updated_at":"2026-05-13T16:58:37.200378Z","closed_at":"2026-05-13T16:58:37.200248Z","close_reason":"All 7 phases complete on branch feature/bd-hfjj-hub-client-decomposition-shared (commits 12347a54..06d03730). hub-client + preview-renderer + preview-runtime + q2-preview-spa green; cargo xtask verify 11/11 steps pass; end-to-end browser smoke verified by user."} +{"id":"bd-hir7j","title":"Default table rendering parity with Quarto 1 (render + preview)","description":"## Problem\n\n`q2 render` and `q2 preview` produce visually-bare `<table>` markup that does not match Quarto 1's output. A doc as simple as a 3-row `::: list-table` renders with no Bootstrap styling, no `<thead>`/`<th>`, no row striping, a collapsed (content-width) table, and an empty `<colgroup>`. Same behavior in both render and preview pipelines (they share the HTML writer).\n\n## Evidence (2026-05-20)\n\nCompared three renders of `~/Desktop/daily-log/2026/05/20/tables.qmd` in Chrome DevTools:\n\n- Q1 (target): `<table class=\"caption-top table\">` with proper `<thead>`, `<th>`, `tr.odd/.even`, Bootstrap CSS, `body.quarto-light`. Cells: 8.5px padding, header font-weight 700, border-bottom on header.\n- Q2 render: bare `<table>`, no thead, no th, no row classes, empty `<colgroup>`, body just `fullcontent`. Browser-default cell padding (1px).\n- Q2 preview: identical DOM to render; different (also minimal) CSS bundle.\n\nScreenshots and computed-style dumps captured under `/var/folders/.../T/{q1-render,q2-render,q2-preview}.png`.\n\n## Plan\n\n`claude-notes/plans/2026-05-20-table-default-rendering-parity.md`\n\nPhased: markup parity (D1-D6) → render-side CSS (D7) → preview-side CSS (D8). Sub-issues to be filed under this epic as each phase is started.\n\n## Related\n\n- k-giyy (Investigate style differences between WASM and CLI rendering) — same gap from the WASM/preview side; D8 likely absorbed.\n- bd-ulgr (JS dependency handling) — JS analog; not blocking.\n- claude-notes/plans/2025-12-05-list-table-implementation.md — D1 amends a default chosen there.\n\n## Fixture\n\n```\n---\ntitle: Table test\n---\n\n::: list-table\n\n* * `qmd` syntax\n * Output\n\n* * ```qmd\n <https://quarto.org>\n ```\n * <https://quarto.org>\n\n* * ```qmd\n [Quarto](https://quarto.org)\n ```\n * [Quarto](https://quarto.org)\n\n:::\n```","status":"closed","priority":2,"issue_type":"epic","created_at":"2026-05-20T20:51:25.202168Z","created_by":"cscheid","updated_at":"2026-05-20T22:52:01.278439Z","closed_at":"2026-05-20T22:52:01.278267Z","close_reason":"Epic complete. All 9 sub-tasks closed: D1/D2/D3/D4-5/D6 (render path) + D4-5/D6 react mirrors + D7/D8 (no-op verifications). The daily-log fixture now renders byte-identically across q2 render, q2 preview, and Quarto 1 — confirmed via Chrome DevTools 2026-05-20. Implementation lives on feature/table-rendering-parity (13 commits)."} +{"id":"bd-hixmy","title":"D3: HTML writer suppresses empty <colgroup>","description":"## What\n\n`crates/pampa/src/writers/html.rs:1383` emits `<colgroup>` whenever `table.colspec` is non-empty, even if every entry is `(Alignment::Default, ColWidth::Default)`. Quarto 1 / Pandoc HTML writer omits the colgroup in that case (no information to convey).\n\n## Fix\n\nAdd a check: skip the colgroup if every colspec entry is fully default. Still emit when any alignment or width is non-default.\n\n## Tests (TDD)\n\n1. Snapshot: list-table with no widths/aligns → no `<colgroup>` in output.\n2. Snapshot: list-table with explicit `widths: 1,2` → `<colgroup>` present with the appropriate `<col>` widths.\n3. Snapshot: pipe table with `:---` alignment → `<colgroup>` present with alignment attrs.\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D3 section)","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T20:54:58.879402Z","created_by":"cscheid","updated_at":"2026-05-20T21:25:38.642354Z","closed_at":"2026-05-20T21:25:38.642185Z","close_reason":"Implemented in this commit: writer skips colgroup when every colspec entry is default.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:54:58.879402Z","created_by":"cscheid"}}} +{"id":"bd-hjv5o","title":"Audit other navigation/metadata surfaces for source-location-driven path resolution","description":"bd-qor9a applied source-location-driven path resolution to navigation surfaces (sidebar / navbar / page-footer / page-nav) — paths declared in a doc's frontmatter now resolve relative to the doc's directory, not the project root.\n\nOther YAML positions that still treat hrefs as project-root-relative regardless of authoring location:\n\n1. **Body links** — `[text](foo.qmd)` in markdown body. Already source-aware via `resolve_doc_relative_href` (source_relative parameter) but does not yet plug `SourceInfo` into the Q-13-4 diagnostic. Lightweight follow-up.\n\n2. **`AutoSpec::Paths` / `AutoSpec::Path`** — sidebar `auto:` scope paths. Today treated as project-root-relative; could be source-aware.\n\n3. **`format.html.css` / `theme` / `template` / `include-in-header` / `bibliography`** — already largely covered by `adjust_paths_to_document_dir` when authored with `!path` tags. Audit which still use bare strings in doc frontmatter.\n\n4. **Listing `contents:` paths** — `listing.contents: foo/` could be source-aware.\n\n5. **Crossref absolute-file references** — `{#fig-x}` references that point at sibling docs.\n\nScope each surface separately if non-trivial. Sub-issues are fine.\n\nOut of scope: changing the project-root-relative interpretation of values declared in `_quarto.yml`. Those keep working because `_quarto.yml`'s hash-based FileId isn't in any document's SourceContext, so the helper degrades to today's behaviour for them — exactly what we want.\n\nPlan: to be written when work begins.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-20T17:25:03.120968Z","created_by":"cscheid","updated_at":"2026-05-20T17:25:03.120968Z","dependencies":{"bd-qor9a:discovered-from":{"depends_on_id":"bd-qor9a","type":"discovered-from","created_at":"2026-05-20T17:25:03.120968Z","created_by":"cscheid"}}} +{"id":"bd-hp3tx","title":"Wire brand navbar logo / brand image into website navbar","description":"Brand data has logo (small/medium/large + images.*). Website navbar should be able to use brand.small or brand.images.<name> as the navbar brand-image. Quarto 1 reference: external-sources/quarto-cli/src/project/types/website/website-navigation.ts (navbar.logo). Q2 has the data model in place (quarto-brand crate); just needs the navbar emission to consult it.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:30.944971Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:30.944971Z"} +{"id":"bd-ht0n","title":"[websites] Sidebar logo / subtitle / header / footer","description":"Render the sidebar's logo (with light/dark variants + logo-href + logo-alt), subtitle (parsed but not rendered in Phase 2), and the 'header:' / 'footer:' freeform content slots Q1 supports. All are parsed by Sidebar::from_config_value today but ignored in sidebar_to_html.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-24T17:52:25.088205Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:25.088205Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:25.088205Z","created_by":"cscheid"}}} +{"id":"bd-hva0","title":"Local-vendor opt-in for MathJax/KaTeX (offline rendering)","description":"bd-w5ov shipped CDN-default for math (parity with Pandoc / Quarto 1). Users who need offline / air-gapped rendering must today set 'html-math-method.url:' pointed at a self-hosted mirror.\n\nMake this easier: ship a 'quarto install mathjax' (and 'quarto install katex') CLI helper that downloads the bundle into a project resources dir and writes the URL override into _quarto.yml. This is 'we're better than Q1' territory — Q1 offers no equivalent automation.\n\nOut of scope for this issue: vendoring bytes by default in the binary (rejected in bd-w5ov §4.5 because of binary-size cost and parity with Q1).\n\nAcceptance: 'quarto install mathjax' downloads, lays out under project resources, configures override; 'quarto render' uses the local URL; offline rendering works.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-04T23:58:29.291389Z","created_by":"cscheid","updated_at":"2026-05-04T23:58:29.291389Z","dependencies":{"bd-w5ov:discovered-from":{"depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:29.291389Z","created_by":"cscheid"}}} +{"id":"bd-hwdlq","title":"Non-deterministic diagnostic output: HashMap iteration in produce_diagnostic_messages (issue #222)","description":"GitHub issue #222 (reported by @rundel): pampa emits a different second diagnostic across runs of the same binary on the same input (`printf -- 'The \"_blank\" word.' | cargo run --bin pampa -- --no-prune-errors`).\n\nRoot cause: crates/quarto-parse-errors/src/tree_sitter_log.rs:48 declares `processes: HashMap<usize, TreeSitterProcessLog>`. crates/quarto-parse-errors/src/error_generation.rs:44 iterates `parse.processes.values()` and a (row, column) dedupe at lines 46-49 picks whichever GLR version's error state arrives first. Default RandomState means iteration order varies per process.\n\nTriage: claude-notes/issue-reports/222/triage.md\nPlan: claude-notes/plans/2026-05-20-issue-222-deterministic-diagnostics.md\n\nFix scope: swap HashMap for hashlink::LinkedHashMap in tree_sitter_log.rs (one import swap + Cargo.toml dep add); add a regression test that parses the issue-222 input N times and asserts byte-identical diagnostic output across runs. LinkedHashMap matches the convention already used in pampa/src/readers/json.rs and 7 other crates in the workspace.\n\nBranch: issue-222 (worktree at .worktrees/issue-222).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T03:03:07.138308Z","created_by":"cscheid","updated_at":"2026-05-21T13:53:34.714598Z","closed_at":"2026-05-21T13:53:34.714437Z","close_reason":"Fixed in PR #227 (squash-merged as bed7f5ed): swapped HashMap for hashlink::LinkedHashMap in tree_sitter_log.rs to make GLR diagnostic emission deterministic. Regression test in crates/pampa/tests/test_diagnostic_determinism.rs (50 iterations, asserts byte-identical output) lands on main. Follow-up audit: bd-x5tx2."} +{"id":"bd-hytl","title":"Phase B.4: Acceptance bundle — _quarto.yml + posts/_metadata.yml propagation to preview","description":"Single Playwright spec pinning the two observable plan acceptance criteria for q2 preview (Phase B):\n\n1. Editing _quarto.yml (title:) re-renders the active page; new title visible in DOM within 5 s.\n2. Editing posts/_metadata.yml (subtitle:) re-renders pages under posts/; new subtitle visible in DOM within 5 s.\n\nFixture (single, dual-purpose): _quarto.yml + posts/_metadata.yml + posts/post1.qmd (no frontmatter, inherits both). Empirically verified both knobs flow through to the rendered title-block (2026-05-13 probe with target/debug/q2 render).\n\nReuses the multi-file fixture helper generalised in bd-pf63 (B.3).\n\nPlan acceptance criterion 3 ('unrelated sibling re-renders the active page') is deferred and tracked separately — its relaxed-contract form (any edit fires a re-render) is invisible at the DOM without SPA instrumentation. See discovered-from follow-up.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid","updated_at":"2026-05-13T21:16:15.516971Z","closed_at":"2026-05-13T21:16:15.516850Z","close_reason":"Duplicate of bd-mrx1 — created by an accidental double-run during B.4 setup (jq parse error masked the first create's output). No work done against this ID; all B.4 work tracked under bd-mrx1.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid"},"bd-pf63:discovered-from":{"depends_on_id":"bd-pf63","type":"discovered-from","created_at":"2026-05-13T21:11:22.459798Z","created_by":"cscheid"}}} +{"id":"bd-hzsi","title":"L10 — Q1 → Q2 listing template migration docs + LLM skill","description":"User-facing migration doc in docs/ covering EJS → doctemplate mapping (<%= … %> → $…$, control flow, helper-function → server-pre-rendered fields, item.extra). LLM skill in .claude/skills/ that suggests Q2 doctemplate equivalents from Q1 EJS templates. Worked examples for each built-in shape and a representative custom template. See claude-notes/plans/2026-05-05-listings-epic.md §L10.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid","updated_at":"2026-05-05T19:53:59.836077Z","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid"},"bd-rqgx:blocks":{"depends_on_id":"bd-rqgx","type":"blocks","created_at":"2026-05-05T19:53:59.836077Z","created_by":"cscheid"}}} +{"id":"bd-i1df","title":"Kanban: Card detail view on title click","description":"Clicking a card title opens a detail modal showing all card information: title, type, status, created/deadline dates, priority, full body text. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-11T18:32:37.650902Z","created_by":"cscheid","updated_at":"2026-02-11T18:36:06.274831Z","closed_at":"2026-02-11T18:36:06.274814Z","close_reason":"Implemented - card detail modal on title click"} +{"id":"bd-i4wv","title":"L9 follow-up: real version string in feed generator (replace quarto-2)","description":"L9 v1 emits <generator>quarto-2</generator>. Q1 emits quarto-<version> from quartoConfig.version(). Replace with the actual Q2 version string when the version story stabilizes. Site: feed/binding.rs::FEED_GENERATOR.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:33:39.786912Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:39.786912Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:39.786912Z","created_by":"cscheid"}}} +{"id":"bd-i6jy4","title":"Preview eager-capture driver iterates all files (binaries, configs), causing thread panic on first binary","description":"## Symptom\n\n```\n$ q2 preview # in a project containing any image/binary\nthread 'tokio-rt-worker' panicked at crates/quarto-parse-errors/src/error_generation.rs:121:35:\nstart byte index 7748 is not a char boundary; it is inside '�' (bytes 7746..7749 of string)\n```\n\nReproduces deterministically with the project at `docs/` (contains `quarto.png`).\n\n## Root cause\n\n`crates/quarto-preview/src/capture_driver.rs:55` (record_eager_captures) calls `ctx.index().get_all_files()` and iterates every entry. The index map covers *all* tracked project files: qmd, config (`_quarto.yml`), binaries (images), extension files, etc.\n\nThe doc comment on the function says: *\"Walk the project's .qmd files and record engine captures for any file that has code cells but no existing sidecar entry yet.\"* The code does not match the comment — it never filters by file kind. Each non-qmd file is shoved through `compute_input_qmd → parse-document`. Two distinct failure modes result:\n\n- `_quarto.yml` → parse-document errors out with \"Indented code blocks are not supported\". `record_one` returns `Err`, caught at line 109, logged as a WARN — visible noise but not crashing.\n- `quarto.png` → tree-sitter parses binary bytes, produces parse errors, then `produce_diagnostic_messages` panics on a non-UTF-8 byte (the lossy-string offset bug tracked in the sibling issue).\n\nThe PNG path also tells us the warning-only soft-fail at L109-115 doesn't catch panics — `compute_input_qmd` runs on a tokio worker, and the panic propagates as a worker-thread panic, not an `Err`.\n\n## Fix\n\nIterate `project_files().qmd_files` instead of `index.get_all_files()`. The currently-unused `_doc_id` from the index map can be looked up if needed, or dropped entirely if the downstream code doesn't need it (check `record_one` — `abs_path` and `rel_path` are the only inputs derived from the iteration item, both reconstructible from a qmd path).\n\nTests:\n- Regression test for the eager driver: project containing both a qmd and a binary, assert no panic and no spurious WARN for the binary.\n- Unit test that walks all `ProjectFiles` field combinations to confirm only `.qmd` files reach `record_one`.\n\nEnd-to-end verification: `q2 preview` on a fixture project with image asset must boot cleanly with no thread panic.\n\n## Out of scope\n\nDefensive hardening of `error_generation.rs` so that even a bug like this one cannot panic the worker. Tracked in sibling issue (link via discovered-from once filed). With the upstream filter in place, the panic still requires bad input to even reach that function.\n\n## Plan file\n\nTo be created at `claude-notes/plans/2026-05-19-bd-XXXX-capture-driver-qmd-filter.md` once issue ID is assigned.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-19T23:43:44.009707Z","created_by":"cscheid","updated_at":"2026-05-20T13:05:02.222953Z","closed_at":"2026-05-20T13:05:02.222785Z","close_reason":"Implemented in 408f4025 (merged via c8b4ab0b). record_eager_captures now iterates project_files().qmd_files. Verified by regression test capture_driver::tests::binary_files_are_not_fed_to_parse_pipeline and end-to-end: q2 preview on docs/ boots cleanly (no thread panic, no spurious _quarto.yml WARN). Defensive hardening of error_generation.rs tracked separately as bd-6qbto.","dependencies":{"bd-tnm3k:discovered-from":{"depends_on_id":"bd-tnm3k","type":"discovered-from","created_at":"2026-05-19T23:43:44.009707Z","created_by":"cscheid"}}} +{"id":"bd-i992","title":"WASM hub-client recompiles default Bootstrap SCSS on every keystroke","description":"After bd-imiw landed the Q1-parity default theme behavior, hub-client renders re-compile the full Bootstrap + Quarto SCSS layer on every keystroke because the new no-theme code path in CompileThemeCssStage bypasses the runtime cache (unlike the themed path), and the WASM version of compile_default_css has no in-memory cache (unlike the native version, which uses a OnceLock). Users report the editor freezing for tenths of a second after every keystroke on documents with no theme/navbar/footer.\n\nRoot cause evidence:\n- crates/quarto-core/src/stage/stages/compile_theme_css.rs:175-195 — no-theme path calls compile_default() without any cache_get check.\n- crates/quarto-core/src/stage/stages/compile_theme_css.rs:206-279 — themed path DOES use ctx.runtime.cache_get(\"sass\", ...) then cache_set.\n- crates/quarto-sass/src/compile.rs:55,239-276 — native compile_default_css uses DEFAULT_CSS_CACHE OnceLock.\n- crates/quarto-sass/src/compile.rs:357-384 — WASM compile_default_css deliberately has no in-memory cache (comment defers to JS SassCacheManager / IndexedDB).\n\nPlan: claude-notes/plans/2026-04-18-wasm-scss-cache-regression.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-18T20:30:49.365984Z","created_by":"cscheid","updated_at":"2026-04-18T21:16:33.355871Z","closed_at":"2026-04-18T21:16:33.355017Z","close_reason":"Fixed in commit d89d1514 on feature/navigation. Four-item bundle: (1) OnceLock in WASM compile_default_css, (2) stage routes no-theme path through runtime cache, (3) generational purge on SCSS_RESOURCES_HASH mismatch (ensure_namespace_version helper), (4) per-namespace LRU size cap with 10 MB sass budget. 16 new tests, 7550 workspace tests pass, cargo xtask verify green, manually confirmed on hub-client.","dependencies":{"bd-imiw:discovered-from":{"depends_on_id":"bd-imiw","type":"discovered-from","created_at":"2026-04-18T20:30:49.365984Z","created_by":"cscheid"}}} +{"id":"bd-iey8o","title":"q2 render: add --json-errors for machine-readable diagnostics","description":"Add a --json-errors flag to `q2 render` so agents (Claude Code first) and other programs driving the binary can consume diagnostics (errors, warnings, info, project-level) in a structured form instead of scraping ariadne text out of stderr.\n\nScope (per planning conversation 2026-05-22):\n- Just `q2 render` in this issue. Pampa's existing --json-errors stays as-is; harmonizing the two CLIs is out of scope.\n- Emit the richer JsonDiagnostic shape from quarto-error-reporting (1-based line/col, pre-rendered ariadne snippet, source_file field) — the same wire format hub-client and the preview /api/preview/diagnostics endpoint already use.\n- NDJSON on stderr (one JSON object per line). Stdout left free for a possible future RenderOutcome object (deferred).\n- Exit codes unchanged. The strict pass-1 contract from bd-creo is unaffected.\n\nImplementation TDD-driven; tests modeled on crates/pampa/tests/test_json_errors.rs. End-to-end verification (real `cargo run --bin q2` invocation, observed JSON lines recorded in the plan file) is required before close per CLAUDE.md.\n\nPlan: claude-notes/plans/2026-05-22-q2-render-json-errors.md\n\nRelated: bd-creo (strict pass-1 exit), k-lckc (uniform error-reporting in render), bd-rqba (JsonPass1Failure shape).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-22T19:26:51.591582Z","created_by":"cscheid","updated_at":"2026-05-22T20:23:11.728062Z","closed_at":"2026-05-22T20:23:11.727852Z","close_reason":"Implemented on feature/q2-render-json-errors: --json-errors flag, JsonDiagnostic/JsonPass1Failure JSON Schemas, Q-7-2..8 catalog entries, drift test, and 7 integration tests. cargo xtask verify --skip-hub-build green; full workspace 9425/9425 pass.","labels":["agent-ux","error-reporting"],"dependencies":{"bd-creo:related":{"depends_on_id":"bd-creo","type":"related","created_at":"2026-05-22T19:26:55.899025Z","created_by":"cscheid"},"k-lckc:related":{"depends_on_id":"k-lckc","type":"related","created_at":"2026-05-22T19:26:56.009277Z","created_by":"cscheid"}}} +{"id":"bd-ij1l","title":"Phase 3: Wire forked runtimelib into Quarto, expose diagnostic error","description":"Add [patch.crates-io] entry pointing runtimelib at cscheid/runtimelib feat/venv-kernelspec-discovery branch (pin to a rev once stable). Switch crates/quarto-core/src/engine/jupyter/kernelspec.rs to list_kernelspecs_with_jupyter_paths(). Replace JupyterError::KernelspecNotFound { name } with { name, searched: Vec<PathBuf>, available: Vec<String> } and update Display to render searched paths, available kernels, and a remediation hint pointing at jupyter kernelspec list and JUPYTER_PATH.\n\nEnd-to-end verification per CLAUDE.md: render convert-test-3.qmd from a venv shell and confirm success; record invocation + output snippet.\n\nBlocked by: bd-34wy (fork must exist first).\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 3)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid","updated_at":"2026-05-04T16:15:19.841987Z","closed_at":"2026-05-04T16:15:19.841852Z","close_reason":"Wired runtimelib fork into Quarto via [patch.crates-io] (path patch — will become git rev before push). list_kernelspecs/find_kernelspec route through *_with_jupyter_paths variants. JupyterError::KernelspecNotFound now carries searched: Vec<PathBuf> and available: Vec<String>; Display renders a multi-line diagnostic with searched paths, available kernels, and a remediation hint. From<runtimelib::RuntimeError> pattern-matches KernelNotFound and forwards fields.\n\nEnd-to-end verified in commit 03e8cab2:\n- Original failing fixture (convert-test-3.qmd) now renders with kernel output, when run from the venv shell.\n- Ruby fixture (no kernel installed) produces the new multi-line diagnostic.\n- cargo build --workspace clean, cargo nextest run --workspace 8360 passed, cargo xtask verify --skip-hub-build all green.\n\nCloses the user-visible bug for bd-fu0l. Phase 4 (bd-875x, upstream PR) is now unblocked.","labels":["dx","feature","jupyter"],"dependencies":{"bd-34wy:blocks":{"depends_on_id":"bd-34wy","type":"blocks","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid"},"bd-fu0l:discovered-from":{"depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:56.240599Z","created_by":"cscheid"}}} +{"id":"bd-ilv8p","title":"tree-sitter qmd: allow line breaks inside inline code spans and inline math","description":"Pampa rejects multi-line inline code spans that pandoc accepts as a single Code element. Example: `A simple ``code\\nspan`` test.` errors at the opening backtick. See claude-notes/plans/2026-05-24-multiline-inline-code-spans.md for diagnosis and implementation plan.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-24T21:12:25.161104Z","created_by":"cscheid","updated_at":"2026-05-24T22:27:40.235371Z","closed_at":"2026-05-24T22:27:40.235225Z","close_reason":"Implemented in commit (pending). Scanner+grammar+post-processor changes for code spans and math spans; full E2E parity with pandoc verified on 11 fixtures; cargo xtask verify green (12/12 steps); 9425/9425 workspace tests pass. Plan: claude-notes/plans/2026-05-24-multiline-inline-code-spans.md"} +{"id":"bd-imiw","title":"Design and implement YAML-controlled top-level navbars and page footers for Quarto 2 HTML output","description":"Quarto 1 supports website navbars and page footers only as project-level (website/book) features. Quarto 2 already allows user-controlled TOCs via YAML metadata at the document level. This issue extends that pattern to top-level navbars and page footers: HTML documents should be able to declare and customize navbar/footer contents via YAML metadata, mirroring the TOC mechanism. Includes design proposal (YAML schema, familiar to Quarto 1 users), pipeline integration (Generate + Render transforms, mirroring TocGenerateTransform/TocRenderTransform), and template wiring.\n\nPlan: claude-notes/plans/2026-04-18-navbar-footer-design.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-04-18T17:13:52.866569Z","created_by":"cscheid","updated_at":"2026-04-18T18:17:33.919378Z"} +{"id":"bd-iq0hp","title":"Multi-engine preview: browser E2E + composing test engines","description":"A browser end-to-end test of MULTI-engine q2 preview was not possible during bd-5yff4: the preview server uses the default engine registry (real engines), the test-only FixtureEngine isn't registered there, and knitr/jupyter don't compose cleanly (knitr claims python cells). Single-engine preview is unchanged + unit-tested; the capture-sequence transport round-trips via quarto-preview integration tests. Options: (a) wire a flag-gated fixture engine into the preview server for tests, (b) build a real second engine, (c) hand-construct a two-capture sidecar and drive a browser session. Plan: claude-notes/plans/2026-05-27-multi-engine-execution.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-27T16:24:40.064471Z","created_by":"cscheid","updated_at":"2026-05-27T16:24:40.064471Z","dependencies":{"bd-5yff4:discovered-from":{"depends_on_id":"bd-5yff4","type":"discovered-from","created_at":"2026-05-27T16:24:40.064471Z","created_by":"cscheid"}}} +{"id":"bd-ir8n","title":"L9 follow-up: inline-code-style syntax-highlight class maps in full feeds","description":"Port Q1's inline-code-style transform: maps highlight classes (token comment, etc.) to inline style=\"color: ...\" so feeds render with colors when the subscriber's stylesheet doesn't include Quarto's CSS. v1 leaves highlight classes verbatim; readers without the CSS render code blocks in default mono. Reader extension lives in feed/reader_ext.rs; gated behind an RssReaderOptions flag.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:16.610890Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:16.610890Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:16.610890Z","created_by":"cscheid"}}} +{"id":"bd-itj9","title":"Add WASM test execution to CI","description":"Add real wasm32 smoke tests and CI job for pampa Lua WASM code paths. 6 tests in crates/pampa/tests/wasm_lua.rs verify restricted Lua VM, filter/shortcode execution, error handling, and synthetic io/os on wasm32-unknown-unknown. Includes wasm-c-shim shared crate, dev-dep gating, and wasm-tests CI job. Blocked by JS bridge raw_module paths in quarto-system-runtime needing feature-gate. Cfg proxy fix and cleanup shipped separately in PR #116.","notes":"PR #109 rebased on #116, base branch changed. PR #116 (cfg fix + cleanup) is CI green and ready to merge. PR #109 now focused solely on WASM CI test infrastructure. JS bridge blocker documented, recommended fix is feature-gating raw_module extern blocks in quarto-system-runtime.","status":"in_progress","priority":3,"issue_type":"task","created_at":"2026-04-02T10:43:59.896261300Z","created_by":"cderv","updated_at":"2026-04-24T17:13:49.430217800Z","comments":{"c-27lonmrb":{"id":"c-27lonmrb","author":"cderv","created_at":"2026-04-03T09:09:11Z","text":"Important: this project does NOT use wasm-pack. It uses cargo build --target wasm32-unknown-unknown + wasm-bindgen CLI directly because -Zbuild-std=std,panic_unwind is needed for Lua error handling (setjmp/longjmp to panic/catch_unwind). See hub-client/scripts/build-wasm.js. This means wasm-pack test wont work — WASM testing would need cargo test --target wasm32-unknown-unknown -Zbuild-std plus wasm-bindgen-test-runner, mirroring the custom build approach."},"c-6eurr4gk":{"id":"c-6eurr4gk","author":"cderv","created_at":"2026-04-14T12:34:20Z","text":"PR restructured (2026-04-14): PR #116 (fix/wasm-cfg-proxy-and-cleanup) opened for Branch A, CI green. PR #109 rebased onto #116 and base changed to fix/wasm-cfg-proxy-and-cleanup. PR #109 diff now shows only WASM CI test additions. When #116 merges to main, GitHub auto-updates #109 base to main."},"c-dtl18kdd":{"id":"c-dtl18kdd","author":"cderv","created_at":"2026-04-23T14:05:04Z","text":"PR #116 merged to main (squash commit 52968801) on 2026-04-23. Ships cfg proxy removal from filter.rs/shortcode.rs, dofile_wasm test skip on native, and updated docs (dev-docs/wasm.md, .claude/rules/wasm.md, testing.md). PR #109 remains open with WASM CI smoke test infrastructure; auto-rebased to main. Remaining blocker: JS bridge raw_module paths in quarto-system-runtime need feature-gating before wasm-bindgen-test-runner can work."},"c-im58nk9x":{"id":"c-im58nk9x","author":"cderv","created_at":"2026-04-24T17:13:49Z","text":"2026-04-24 session: Rebased PR #109 onto latest origin/main (50+ commits since Gordon's prior rebase on Apr 17). 2 conflicts resolved (Cargo.toml + Cargo.lock). Docs audit found 3 drifts, fixed in b2e88ec1. cargo fmt on shim.rs in 1f080db5. Verified wasm-c-shim/src/shim.rs byte-identical to main's c_shim.rs modulo CRLF. Build succeeds after cmake install (bd-n7x2 introduced cmake as a hard requirement via tree-sitter wasm feature). Pending: cargo xtask verify + force-push to update PR. Dev-setup improvements split to bd-tjbr; tree-sitter CRLF Windows failures split to bd-ntnx (pre-existing, not caused by #109)."},"c-jlp2ag0d":{"id":"c-jlp2ag0d","author":"cderv","created_at":"2026-04-02T15:10:34Z","text":"WASM test coverage analysis: npm run test:wasm (TS side) tests rendering, templates, format detection via compiled WASM module — does NOT cover Lua filter traversal. The test cfg proxy in Rust is the ONLY thing catching WASM-incompatible Lua code in filter tests. So the proxy has value on Linux/macOS — just not on Windows. wasm-pack test would be the proper replacement: compiles Rust to wasm32, runs #[wasm_bindgen_test] in browser/Node on the real WASM target. build-wasm.yml already installs wasm-pack but only runs build, not test. Infrastructure needed: wasm-pack test in CI, test harness crate with wasm_bindgen_test, possibly browser driver. Approach: (1) Remove test from cfg guard in filter.rs/shortcode.rs, (2) Add wasm-pack test to build-wasm.yml or new workflow with #[wasm_bindgen_test] versions of key filter tests, (3) Gate io_wasm/os_wasm unit tests to wasm32 target only."},"c-wupjt0nn":{"id":"c-wupjt0nn","author":"cderv","created_at":"2026-04-13T20:48:28Z","text":"Branch split decision (2026-04-13): PR #109 grew too large mixing cfg proxy fix with WASM CI test infrastructure. Split into two branches: (1) fix/wasm-cfg-proxy-and-cleanup ships the cfg proxy removal, dead crate cleanup, dtolnay replacement, and doc updates. (2) feature/wasm-testing-and-cleanup retains the WASM smoke tests, wasm-c-shim crate, CI job, and related infrastructure for a future PR. Known blocker for Branch B: quarto-system-runtime/src/wasm.rs has 4 raw_module extern blocks (/src/wasm-js-bridge/{template,sass,cache,fetch}.js) that get baked into any wasm32 binary. wasm-bindgen-test-runner generates require() calls for these absolute paths which fail in Node.js. Recommended fix: feature-gate the JS bridge (add js-bridge feature to quarto-system-runtime, gate the 4 extern blocks, provide stub impls when off, wasm-quarto-hub-client enables it, pampa test builds dont)."},"c-wwjo8ud5":{"id":"c-wwjo8ud5","author":"cderv","created_at":"2026-04-03T09:11:25Z","text":"wasm-bindgen-test infrastructure already exists: wasm-qmd-parser/tests/web.rs has a placeholder #[wasm_bindgen_test] test with run_in_browser config. The crate already depends on wasm-bindgen-test 0.3.34. Pattern is ready to extend with real filter tests. Note: wasm-qmd-parser uses wasm-pack (simpler build), wasm-quarto-hub-client uses custom cargo build + wasm-bindgen (needs -Zbuild-std). Test runner choice depends on which crate hosts the WASM filter tests."}}} +{"id":"bd-iuzmk","title":"q2 preview: set browser-tab title to '<doc-title> (Quarto Preview)' from the active AST's meta.title","description":"Today the q2-preview SPA's browser tab always reads 'Quarto Preview' regardless of which doc is active. With a real doc title in YAML frontmatter we should surface it as '<title> (Quarto Preview)' so users with the live site + preview open side-by-side can tell tabs apart. Implementation: useEffect in q2-preview-spa/src/PreviewApp.tsx watching state.astJson, parse meta.title (handle MetaString / MetaInlines / bare Inlines), set document.title. Fall back to 'Quarto Preview' when no title. Acceptance: integration test asserting title updates on AST change; browser verification against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website (should show 'Hello, world (Quarto Preview)').","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-18T16:20:13.444289Z","created_by":"cscheid","updated_at":"2026-05-18T16:30:32.982406Z","closed_at":"2026-05-18T16:30:32.982262Z","close_reason":"Implementation complete: AST meta.title surfaces in document.title as '<title> (Quarto Preview)'. Verified end-to-end against the fixture website; live-edit case (retitle on disk → tab updates) also confirmed. 3 new SPA integration tests; cargo xtask verify 12/12 green.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T16:20:13.444289Z","created_by":"cscheid"}}} +{"id":"bd-izfv","title":"Phase 9 follow-up: thread user_grammars through RenderToHtmlRenderer","description":"Today render_page_in_project's project-rendering branch drops user_grammars on the floor — the RenderToHtmlRenderer constructs its own per-page RenderContext and there's no path to attach user_grammars there. Single-file projects still wire user_grammars correctly via render_single_doc_to_response.\n\nThreading user grammars through the renderer is straightforward: add a field to RenderToHtmlRenderer holding an Arc<Mutex<Option<JsUserGrammars>>> (or similar) and have its render() method install the provider on the per-page RenderContext.\n\nFiled as discovered-from-bd-ayj6 and tagged P3 since most user-grammar use is for code-block highlighting which still works on the active page's first render — the gap is just for project renders where the hub-client passes a grammars handle but it gets ignored.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid","updated_at":"2026-05-12T13:41:25.597279Z","closed_at":"2026-05-12T13:41:25.597259Z","close_reason":"Threaded user_grammars through RenderToHtmlRenderer (Rc<RefCell<…>>); re-enabled e2e fixture by dropping SKIP_WASM_UNSUPPORTED entry on chore/e2e-ci, and fixed two test-harness gaps (binary fixture forwarding + getPreviewHtml userGrammars context) so the hub-client e2e suite can actually verify the fixture. Rust unit test crates/quarto-core/tests/render_to_html_user_grammars.rs passes; e2e fixture highlighting/03-user-grammar-toml.qmd passes when run in isolation. See claude-notes/plans/2026-05-10-thread-user-grammars-renderer.md for the verification artifact.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:31:56.879941Z","created_by":"cscheid"}}} +{"id":"bd-izh3","title":"Add PR trigger to hub-client E2E workflow for WASM build verification","description":"hub-client-e2e.yml only runs on push to main. PR changes to workflows or WASM build deps are not caught until merge. Add pull_request trigger with path filter so the WASM build runs on PRs. Playwright and visual regression steps should be gated to push-to-main only (expensive, auto-commits baselines). Open question: whether default ubuntu runner can handle the WASM build or if 8x is needed for the cargo build with -Zbuild-std. Discovered during PR #116 review when removing wasm-pack left wasm-bindgen-cli missing.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-14T15:47:10.281Z","created_by":"cderv","updated_at":"2026-05-25T02:11:19.651349Z","closed_at":"2026-05-25T02:11:19.651328Z","close_reason":"Closed by PR #231 (commit 016894a2 on feature/provenance): drops the path filter outright rather than expanding it, so e2e fires on every PR like the sibling heavy workflows. Catches the upstream-crate case the original path-filter proposal would still have missed (Carlos's 5/22 WASM regression on f96f56df; PR #231 itself)."} +{"id":"bd-izqh","title":"L1 — ListingItemInfoStage (auto-fill, pre-checkpoint)","description":"New pre-checkpoint stage between IncludeExpansionStage and DocumentProfileStage. Auto-fills unset listing_item fields: reading-time, word-count, date-modified, description (first paragraph plain-text from post-include AST, truncated), image (first body Image src). Author values always win. Always populates description+image as L7-fallback safeguards (mandatory contract). See claude-notes/plans/2026-05-05-listings-epic.md §L1.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid","updated_at":"2026-05-06T14:30:09.263877Z","closed_at":"2026-05-06T14:30:09.263724Z","close_reason":"L1 ListingItemInfoStage implemented per claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md. Merged in 38749998 / merge commit. 25 unit + 3 integration tests; cargo xtask verify clean. Follow-up bd-8h9o filed for shortcode-bearing image src.","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid"},"bd-n8a4:blocks":{"depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:52:56.218941Z","created_by":"cscheid"}}} +{"id":"bd-j1trh","title":"Phase 2: code copy button decoration","description":"Phase 2 of bd-1tl09 (blocked by Phase 0 skeleton).\n\n## Trigger\n\nDocument/format metadata `code-copy: true | false | hover` — default in Quarto 1 is hover-only (button shown on hover via SCSS $code-copy-selector).\n\n## Output (HTML)\n\n<div class=\"code-copy-outer-scaffold\"><div class=\"sourceCode\">…<pre class=\"code-with-copy\">…</pre></div><button class=\"code-copy-button\" aria-label=\"Copy code\"><i class=\"bi bi-clipboard\"></i></button></div>\n\nQ1 implements this in TypeScript post-DOM (format-html.ts:746-772), not Lua. We move it to the Render transform.\n\n## Work\n\n1. Add copy: CopyMode { Off, Hover, Always } to CodeBlockDecoration.\n2. Generate transform: resolve from per-block attr (override) or doc default. Default to Hover when nothing set (matches Q1).\n3. Render transform (HTML): emit the outer scaffold + button structure. Add code-with-copy class to the inner <pre>.\n4. Inject clipboard.js as an HTML dependency. Port the relevant SCSS:\n - _quarto-rules-copy-code.scss (button styling)\n - _quarto-variables-copy-code.scss (color variables)\n5. Mirror on React side.\n6. Port the JS handler that flashes the \"Copied!\" tooltip on success (Q1 inlines this in the HTML; for Q2 it should be a small standalone script in resources/js/).\n\n## Tests\n\n- Native: snapshot.\n- React: integration test asserting the wrapper + button.\n- Doc-default off: code blocks rendered without copy=true don't get the scaffold.\n\n## Acceptance\n\n- All tests pass.\n- cargo xtask verify passes.\n- Manual: click the copy button in a real browser; clipboard contains the code text.","notes":"Phase 0 (bd-ea5tl) and Phase 1 (bd-j73yw) have closed; Phase 2 is unblocked.\n\nHand-off context for the next session lives at the bottom of\nclaude-notes/plans/2026-05-19-code-block-features.md under\n'Hand-off to next session — Phase 2 (copy button), bd-j1trh'.\nRead that first; it covers:\n\n- Load-bearing architectural facts proven on Phase 1 (sideband\n shape, pipeline placement, AST rewrite pattern, native/React\n parity-for-free)\n- The Q1 reference for the copy button (TypeScript post-DOM, not\n Lua) — relevant when porting\n- Suggested 3-commit breakdown matching Phase 1's rhythm\n- Open questions to resolve up front (per-block override?\n hover/always default? clipboard.js dependency injection\n mechanism?)\n- Known blockers (bd-tnm3k single-file preview, pre-existing\n tree-sitter regression, expected_hashes.txt baseline drift)\n- Verification commands with skip flags for the pre-existing\n failures\n\nPinned design decision for this epic: decoration storage is the\nsideband HashMap on RenderContext, NOT a CustomNode wrapper\n(plan §Resolved decisions, cleared with the user 2026-05-19).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T20:13:13.013456Z","created_by":"cscheid","updated_at":"2026-05-19T21:59:32.279792Z","closed_at":"2026-05-19T21:59:32.279626Z","close_reason":"Phase 2 complete. Commits f3974cf2 + abc94e7d + 0e85f954 land the CopyMode payload, the Generate→Render data flow (code-with-copy class + scaffold + button), the ClipboardJsStage (vendors clipboard.min.js + ships the init handler), the SCSS port (copy-button visibility, icons, hover/checked states + the load-bearing div.code-copy-outer-scaffold{position:relative} rule from Q1's _quarto-rules.scss), and full browser e2e verification via Chrome DevTools MCP (hover shows icon, click swaps to checkmark + Bootstrap Tooltip 'Copied!', state reverts after 1s). 9177/9177 workspace tests pass. cargo xtask verify green. Phase 3 hand-off in claude-notes/plans/2026-05-19-code-block-features.md §'Hand-off to next session — Phase 3 (code folding), bd-g1prx'.","dependencies":{"bd-1tl09:parent-child":{"depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:13:13.013456Z","created_by":"cscheid"},"bd-ea5tl:blocks":{"depends_on_id":"bd-ea5tl","type":"blocks","created_at":"2026-05-19T20:13:59.635875Z","created_by":"cscheid"}}} +{"id":"bd-j30t7","title":"Q-2-32 not emitted for `***` inside pipe-table cells (generic parse error instead)","description":"When a pipe-table cell contains `***hello` (e.g. `| ***hello |`), pampa returns the generic 'unexpected character or token here' parse error instead of the structured Q-2-32 'Triple star emphasis disallowed. Consider `*__` instead.' diagnostic that fires at the paragraph level. Verified to be pre-existing (reproduces on main pre-bd-qhb2o); discovered while sanity-checking the bd-qhb2o fix and intentionally left out of scope. Likely cause: Q-2-32.json's `prefixesAndSuffixes` corpus does not enumerate a pipe-table-cell context, so the LR state the parser reaches when it sees `***` inside a cell isn't in the merr-style state->Q-code table (resources/error-corpus/_autogen-table.json) and the diagnostic falls through to the generic path. Probable fix: add a pipe-table prefix/suffix pair like [\"| col |\\n|---|\\n| \", \" |\"] to Q-2-32.json and rerun crates/pampa/scripts/build_error_table.ts. Worth scoping as part of a broader Q-2-32 coverage audit — same gap may exist for other inline-receptive contexts not yet enumerated (e.g. footnote definitions, table captions, fenced-div contents, etc.).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-24T23:24:05.227777Z","created_by":"cscheid","updated_at":"2026-05-24T23:24:05.227777Z","dependencies":{"bd-qhb2o:discovered-from":{"depends_on_id":"bd-qhb2o","type":"discovered-from","created_at":"2026-05-24T23:24:05.227777Z","created_by":"cscheid"}}} +{"id":"bd-j3a0","title":"Body-link diagnostic dedup by (page, href)","description":"If a site has many broken .qmd links, the warning list grows fast (one per occurrence per page). A simple first-occurrence-wins dedupe per (page, href) tuple would tame the output. Originally deferred from Phase 6 (bd-v30t).","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:54.339618Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:54.339618Z","created_by":"cscheid"}}} +{"id":"bd-j4fe","title":"Q-2-36: clean parse error for knitr-style chunk options (issue #152)","description":"Upgrade old-style knitr chunk headers ('{r echo=FALSE}', '{r test}', '{r, label=\"foo\"}', any engine) from the current Q-2-8 *warning* to a clean Q-2-36 *error* that points users at the '#| key: value' body syntax. The Pandoc class form '{.r echo=FALSE}' stays valid (negative control).\n\nApproach 1 (confirmed with user, 2026-05-14): upgrade the existing Q-2-8 warning site in crates/pampa/src/pandoc/treesitter.rs:1121-1144 to emit a Q-2-36 error (no scanner.c change, no grammar.js change), plus add Q-2-36.json corpus entries to Merr-map the parse-error forms (bare label, comma form).\n\nTriage doc: claude-notes/issue-reports/152/q236-triage.md (worktree branch issue-152, based on bugfix/issue-184 @ e2d224f6)\nFixtures: claude-notes/issue-reports/152/q236-repro.qmd, q236-repro-variants.qmd\nPlan: claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md (to be written)\n\nGitHub: https://github.com/quarto-dev/q2/issues/152\nTemplate (mechanics only, NOT structure): bd-7l1u / PR #194 (Q-2-35). Q-2-36 diverges because it has no silent-acceptance case to detect — see triage doc 'Approach' section.\n\nPhases (TDD):\n1. Test scaffolding: rewrite test_code_block_with_header_options_produces_warning to expect Q-2-36 error; add Q-2-36.json with bare-label / comma-args cases; run build_error_table.ts; confirm tests fail.\n2. Upgrade Q-2-8 site to Q-2-36 error (level + code + message + header-line clip).\n3. Wire up Merr for the parse-error forms; apply widen_diagnostic_to_line.\n4. End-to-end: pampa on q236-repro.qmd shows clean Q-2-36; cargo nextest workspace; cargo xtask verify (full).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-14T19:08:04.698114Z","created_by":"cscheid","updated_at":"2026-05-14T20:42:57.524647Z","closed_at":"2026-05-14T20:42:57.524487Z","close_reason":"Q-2-36 implemented across Phase 0-3 on branch issue-152 (commits 9bbb1de1, bd93ffa2, e848e47e, ee4195ce). Path A (treesitter.rs site) emits Q-2-36 error with inline-clipped header-line highlight. Path B (Merr-mapped knitr parse-error forms) emits Q-2-36 via Q-2-36.json corpus + widen_diagnostic_to_line gate. Full pampa suite + cargo xtask verify green. Reporter's case fires the new diagnostic; Pandoc-class form {.r ...} stays valid. Discovered-from: bd-jvxg (pre-existing reader limitation re: parse-error + warning-collector interaction in same doc).","labels":["error-messages","readers-writers"]} +{"id":"bd-j60g","title":"L2 — Listing data model + YAML schema","description":"Port Q1's Listing, ListingItem, ListingDescriptor, ListingType, ListingSort, ListingFeedOptions, ListingSharedOptions to Rust (new crates/quarto-core/src/project/listing/ module). YAML schema in quarto-yaml-validation port from Q1's website-listing definitions. listing: as document-frontmatter key. template: path; .ejs.md accepted with deprecation diagnostic. No rendering yet. See claude-notes/plans/2026-05-05-listings-epic.md §L2.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-05T19:53:07.098182Z","created_by":"cscheid","updated_at":"2026-05-07T13:35:13.849288Z","closed_at":"2026-05-07T13:35:13.848933Z","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:07.098182Z","created_by":"cscheid"}}} +{"id":"bd-j73yw","title":"Phase 1: filename header decoration","description":"Phase 1 of bd-1tl09 (blocked by Phase 0 skeleton). Smallest end-to-end slice that exercises the Generate → Render plumbing.\n\n## Trigger\n\n`{r filename=\"hello.R\"}` or `#| filename: hello.R` (chunk option).\n\n## Output (HTML)\n\nWrap the code block in <div class=\"code-with-filename\"><div class=\"code-with-filename-file\"><pre><strong>hello.R</strong></pre></div>…</div>. Matches Q1's customnodes/decoratedcodeblock.lua + quarto-pre/code-filename.lua.\n\n## Work\n\n1. Add `filename: Option<String>` to CodeBlockDecoration.\n2. Generate transform: read attr.filename or kvs[\"filename\"]. Resolve doc-level default if any (Q1 has none; check).\n3. Render transform (HTML branch): emit the wrapper Div block around the existing CodeBlock node.\n4. Port the matching SCSS from external-sources/quarto-cli/src/resources/formats/html/_quarto-rules-code-filename.scss to resources/scss/. Match the dark-mode handling.\n5. Mirror on the React side: ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx will need either a parent component or the transform output to already include the wrapper Divs (which the React Div renderer will handle).\n6. End-to-end: q2 render + q2 preview both show the filename header. Browser screenshot for both.\n\n## Tests\n\n- Native: snapshot test asserting the wrapper structure for a CodeBlock with filename kv.\n- React: integration test (q2-preview.integration.test.tsx) asserting the same shape.\n- Cross-pipeline: render the same fixture through both and assert the rendered HTML's div.code-with-filename subtree is identical (modulo whitespace).\n\n## Acceptance\n\n- All listed tests pass.\n- cargo xtask verify passes.\n- Visual diff between q2 render and q2 preview shows identical filename header.","notes":"Phase 1 complete via 3 commits:\n1. Sideband infrastructure (CodeBlockDecorationKey, code_block_decorations on RenderContext, filename field on CodeBlockDecoration)\n2. Generate→Render data flow (Generate populates sideband from kvs['filename'], Render replaces CodeBlock with code-with-filename wrapper Div around a RawBlock filename header + the original block)\n3. SCSS port + e2e verification (ported filename rules from Q1's _quarto-rules-code-filename.scss into _bootstrap-rules.scss; no React-side code change needed because q2-preview's Div + RawBlock renderers already handle both cases). Visual parity verified between q2 render and q2 preview.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T20:13:00.847471Z","created_by":"cscheid","updated_at":"2026-05-19T21:01:58.912079Z","closed_at":"2026-05-19T21:01:58.911924Z","close_reason":"done","dependencies":{"bd-1tl09:parent-child":{"depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T20:13:00.847471Z","created_by":"cscheid"},"bd-ea5tl:blocks":{"depends_on_id":"bd-ea5tl","type":"blocks","created_at":"2026-05-19T20:13:59.480776Z","created_by":"cscheid"}}} +{"id":"bd-j9cf","title":"Recognize bare `<` as a Str token (currently a parse error)","description":"Today a literal `<` outside math/code/HTML produces a parse error. Minimal trigger: a single-line document containing `1 < 2`. Goal: bare `<` should parse as Str \"<\" when not the start of a recognized HTML element / autolink / raw-specifier / HTML comment. Plan: claude-notes/plans/2026-05-18-bare-lt-as-str.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-18T20:54:00.031438Z","created_by":"cscheid","updated_at":"2026-05-18T21:01:37.931022Z"} +{"id":"bd-jakt","title":"Investigate cargo xtask dev-setup --locked causing externref mismatch in TS Test Suite","description":"cargo xtask dev-setup installs wasm-bindgen-cli with --locked flag. When used in ts-test-suite.yml instead of the hardcoded cargo install wasm-bindgen-cli --version 0.2.108 (without --locked), the hub-client WASM tests fail with: CompileError: WebAssembly.instantiate(): call[0] expected type externref, found local.get of type i32. Reverted in PR 109. Root cause unknown — the --locked flag may produce a subtly different binary.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-09T17:59:23.500651300Z","created_by":"cderv","updated_at":"2026-04-09T17:59:23.500651300Z"} +{"id":"bd-jbml","title":"Navbar index-forgiveness (about/ == about/index.html)","description":"Phase 3 Navbar active-state uses strict source-path equality. Q1's itemHasNavTarget additionally treats 'about/' and 'about/index.html' as equivalent for active-marking. Revisit if a real site hits the edge case. See 2026-04-24-websites-phase-3.md follow-ups.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T19:42:58.920114Z","created_by":"cscheid","updated_at":"2026-04-24T19:42:58.920114Z","dependencies":{"bd-fqyg:discovered-from":{"depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:42:58.920114Z","created_by":"cscheid"}}} +{"id":"bd-jby1i","title":"Highlighted code blocks render a stray empty line at the bottom (trapped pre margin inside div.sourceCode)","description":"Highlighted code blocks (e.g. ```ts) in both `q2 render` HTML output and `q2 preview` show ~one line-height of extra background below the last code line.\n\nRoot cause (verified in-browser with Chrome DevTools): Bootstrap's `pre { margin-bottom: 1rem }` survives on `pre.sourceCode`, and `div.sourceCode { overflow-y: hidden }` (resources/scss/bootstrap/_bootstrap-rules.scss) creates a block formatting context that traps that 17px margin INSIDE the gray box. Measured: div bottom - pre bottom = 18px in Q2 vs 1px (border only) in Q1.\n\nQ1 avoids this via Pandoc's baseline highlighting CSS, which Q2 never emits:\n div.sourceCode { margin: 1em 0; }\n pre.sourceCode { margin: 0; }\n\nFix: add the two rules to resources/scss/html/templates/highlight.scss (Q2's pandoc-baseline equivalent, embedded via quarto-sass load_highlight_layer, so it covers native render AND the WASM preview client).\n\nPlan: claude-notes/plans/2026-06-03-codeblock-trailing-margin.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-06-03T19:58:06.834662Z","created_by":"cscheid","updated_at":"2026-06-03T20:16:01.734322Z","closed_at":"2026-06-03T20:16:01.734179Z","close_reason":"Fixed: added div.sourceCode{margin:1em 0} + pre.sourceCode{margin:0} to highlight.scss (Pandoc-baseline parity). Regression test in quarto-sass compile_all_themes_test.rs; verified e2e in q2 render and q2 preview (gap inside div: 18px -> 1px, matching Q1)."} +{"id":"bd-je48v","title":"Add mermaid diagram engine to Quarto 2","description":"Design + ship a minimal mermaid engine that handles `{mermaid}` code blocks. First cut: HTML-only, defers actual diagram rendering to the browser via jsdelivr mermaid.js script. Architectural goal: maintain Q2's format-agnostic AST processing vs. format-specific emission decomposition so the engine doesn't need to be reworked when non-HTML formats are added.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md\n\nThis epic is intentionally also a design session — the mermaid case forces us to confront several engine-API gaps (see follow-up issues filed as discovered-from the design task).","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-28T13:44:39.930118Z","created_by":"cscheid","updated_at":"2026-05-28T13:44:39.930118Z"} +{"id":"bd-jfyl","title":"Footer Text-region project-link rewriting","description":"Phase 3 decision 8 excluded footer Text regions (string-valued left/center/right) from .qmd → .html rewriting — that's Phase 6's body-content link rewrite territory. Once Phase 6 lands, audit whether footer Text regions should get the same treatment or stay as literal markdown. Decision to defer was recorded in 2026-04-24-websites-phase-3.md plan §Decision 8 and §Risks.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-24T19:42:43.935902Z","created_by":"cscheid","updated_at":"2026-04-24T19:42:43.935902Z","dependencies":{"bd-fqyg:discovered-from":{"depends_on_id":"bd-fqyg","type":"discovered-from","created_at":"2026-04-24T19:42:43.935902Z","created_by":"cscheid"}}} +{"id":"bd-jgeu","title":"Home-link relativization for sidebar title + navbar brand","description":"Two related hardcoded fallbacks in crates/quarto-navigation/src/render_html.rs emit project-root-relative or current-dir-relative hrefs that don't account for the rendering page's depth:\n\n1. Sidebar title (line 211): hardcoded <a href=\"./\">. From posts/aardvark.html, points back to posts/ instead of the site root. Reproduces in examples/websites/02-auto-sidebar (compare _site/ vs q1-site/).\n\n2. render_brand (line 297): navbar.logo_href.as_deref().unwrap_or(\"/\") falls back to absolute /, which is deployment-fragile (only works for domain-rooted hosts; breaks on file://, GitHub Pages project sites, sub-path deployments).\n\nPlus an adjacent gap in NavbarRenderTransform (crates/quarto-core/src/transforms/navbar_render.rs:114): rewrite_navigation_item_hrefs walks navbar.left/right/dropdown menus through resolve_href_for_html but doesn't touch navbar.logo_href, so user-supplied logo-href: about.qmd doesn't get the .qmd->.html rewrite or page-relative URL treatment.\n\nSame root-cause family as bd-swpy (closed). Sweep of render_html.rs + main HTML template confirmed these are the only home-link-style hardcodes; other unwrap_or(\"#\")/unwrap_or(\"\") fallbacks are correct no-op anchors and out of scope.\n\nFix plan: claude-notes/plans/2026-04-30-sidebar-title-home-link-relativize.md. Add ResourceResolverContext::page_url_for_site_root_dir; thread home_url: &str through sidebar_to_html and navbar_to_html; compute home_url from ctx.resource_resolver in SidebarRenderTransform and NavbarRenderTransform; add navbar.logo_href to the navbar transform's resolver-rewrite walk.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T19:31:25.256931Z","created_by":"cscheid","updated_at":"2026-04-30T19:52:29.349611Z","closed_at":"2026-04-30T19:52:29.349437Z","close_reason":"Fixed in feature/websites. Added ResourceResolverContext::page_url_for_site_root_dir; threaded home_url through sidebar_to_html and navbar_to_html (default ./ for no-resolver/single-doc); SidebarRenderTransform and NavbarRenderTransform compute home_url from ctx.resource_resolver; navbar.logo_href now goes through resolve_href_for_html (same .qmd->.html + page-relative treatment as ordinary nav items). 17 new unit tests pass. End-to-end verified on 02-auto-sidebar (sidebar-title: ./ at root, ../ in posts/), 04-navbar-footer (navbar-brand: ./ at root, ../ at depth-1), and 03-nested-sidebar (depth-1 sidebars all emit ../). 8140/8140 workspace tests pass; cargo xtask verify (full) passes.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-30T19:31:28.472953Z","created_by":"cscheid"},"bd-swpy:discovered-from":{"depends_on_id":"bd-swpy","type":"discovered-from","created_at":"2026-04-30T19:31:25.256931Z","created_by":"cscheid"}}} +{"id":"bd-jjep","title":"q2: website.navbar / website.page-footer (nested form) not recognised by chrome transforms","description":"Discovered while smoke-testing Phase F.2 against docs/_quarto.yml. q2 NavbarGenerateTransform reads top-level meta.navbar (and FooterGenerateTransform reads top-level meta.page-footer), but TS Quarto and the docs site author these nested under website.navbar / website.page-footer (the historical schema). Result: docs/index.qmd renders without a navbar or footer under both q2 render AND q2 preview.\n\nTwo options:\n1. Add a metadata-normalize step that hoists website.navbar → navbar / website.page-footer → page-footer when the top-level form is absent.\n2. Update NavbarGenerateTransform / FooterGenerateTransform to also check the website.* nested paths.\n\nOption 1 is the smaller change. Path: crates/quarto-core/src/transforms/metadata_normalize.rs.\n\nEmpirical evidence (this worktree, 2026-05-14): running cargo run --bin q2 -- render docs/about.qmd produces an HTML file with 0 occurrences of 'navbar' or 'footer.footer'. The same fixture renders correctly under TS Quarto.\n\nNot a Phase F regression — q2 has never supported the nested form. Filed so the docs site authoring loop isn't blocked indefinitely.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-14T22:28:53.901801Z","created_by":"cscheid","updated_at":"2026-05-19T15:13:00.358360Z","closed_at":"2026-05-19T15:13:00.358215Z","close_reason":"Implemented in d66ff31c: quarto_config::resolve_website_value() merges meta.<key> and meta.website.<key> with top-level winning on conflicts. Rewired resolve_navbar, resolve_page_footer, resolve_sidebar_membership, SidebarGenerateTransform, and derive_doc_scss_layer. End-to-end verified against docs/_quarto.yml.","dependencies":{"bd-kw93.15:discovered-from":{"depends_on_id":"bd-kw93.15","type":"discovered-from","created_at":"2026-05-14T22:28:53.901801Z","created_by":"cscheid"}}} +{"id":"bd-jsbg","title":"Implement crossref functionality for Quarto 2","description":"Port crossref functionality to Quarto 2 with improved architecture. Single-file first, with foundations for multi-file (books/websites). Fixes Q1 structural limitations (engine responsibilities, FloatRefTarget underutilization, theorems.lua front-end/back-end mixing). See plan: claude-notes/plans/2026-04-15-crossref-design.md","status":"open","priority":1,"issue_type":"epic","created_at":"2026-04-15T16:38:42.165655Z","created_by":"cscheid","updated_at":"2026-04-15T16:38:42.165655Z"} +{"id":"bd-jvxg","title":"Reader skips warning-collector diagnostics when parse errors are present in the same document","description":"In crates/pampa/src/readers/qmd.rs:144, when tree-sitter parsing produces errors, `read` returns `Err(diagnostics)` *before* invoking `treesitter_to_pandoc` (line 167). The latter is where the warning-collector pass runs — including the Q-2-36 path-A diagnostic site in `treesitter.rs::process_fenced_code_block`.\n\nEffect: a document with **both** a parse-error form (e.g. `\\`\\`\\`{r test}`) and a warning-collector-emitted form (e.g. `\\`\\`\\`{r echo=FALSE}`) reports only the parse error. The user has to fix the parse error and re-run to discover the second issue.\n\nReproduction (from Q-2-36 Phase 3 verification, 2026-05-14):\n\n\\`\\`\\`\n$ printf '%s\\n' '\\`\\`\\`{r test}' '1+1' '\\`\\`\\`' '' '\\`\\`\\`{python echo=FALSE}' 'print()' '\\`\\`\\`' | cargo run --bin pampa --\n[31mError:[0m [Q-2-36] Old-style knitr chunk options are not supported\n ... (only the {r test} error; the {python echo=FALSE} block is silent)\n\\`\\`\\`\n\nCompare to single-block variants — each individually fires Q-2-36 correctly (verified with /tmp/q236-cases/case2-7 individually).\n\nWhy this is pre-existing (NOT a Phase 1 regression): the code at qmd.rs:144 has not changed in the bd-j4fe work. At HEAD (`e2d224f6`), the same behavior held — the Q-2-8 *warning* would have been silently dropped when a parse error was present elsewhere in the document. The shape of the limitation just becomes more noticeable now that the path-A site produces an *error* rather than a warning, because users now expect both halves of a 'do not use knitr syntax' diagnostic to fire together.\n\nPossible fixes (not designed yet — needs scoping):\n\n1. Run `treesitter_to_pandoc` regardless of parse-error presence. Risk: the function may panic or produce garbage on ERROR-node-containing trees. Needs an audit + likely some defensive plumbing.\n\n2. A two-pass approach: separate AST construction (which can fail) from warning-collector emission (which is independent). Refactor.\n\n3. Limited fix: walk the tree once for warning emission, then run `treesitter_to_pandoc` only if `had_errors()` is false. Conceptually clean but requires factoring out the warning pass from `process_fenced_code_block`.\n\nThis is scope-creep relative to bd-j4fe (Q-2-36); filing as `discovered-from` so it doesn't block the Q-2-36 ship.\n\nDiscovered during: bd-j4fe Phase 3 verification (claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-14T20:36:20.915148Z","created_by":"cscheid","updated_at":"2026-05-14T20:36:20.915148Z","dependencies":{"bd-j4fe:discovered-from":{"depends_on_id":"bd-j4fe","type":"discovered-from","created_at":"2026-05-14T20:36:20.915148Z","created_by":"cscheid"}}} +{"id":"bd-jxs5","title":"Refactor filter traversal-order tests to not depend on io.open","description":"8 filter integration tests use io.open to write traversal order to a temp file. This was fine when tests used real Lua io, but the test cfg proxy forces them through synthetic WASM io which only handles POSIX paths. Two options: (A) Refactor tests to collect order in a Lua table instead of writing files — removes io.open dependency entirely. (B) Part of the larger fix in bd-itj9: remove test from the WASM cfg guard so native tests use real Lua io — these tests would just work without changes. Option B is preferred since it fixes the root cause. This issue becomes unnecessary if bd-itj9 is resolved.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-04-02T13:35:34.988582Z","created_by":"cderv","updated_at":"2026-04-03T09:30:44.806290500Z","closed_at":"2026-04-03T09:30:44.799534200Z","dependencies":{"bd-itj9:related":{"depends_on_id":"bd-itj9","type":"related","created_at":"2026-04-02T13:48:51.679858600Z","created_by":"cderv"}},"comments":{"c-sgd85rni":{"id":"c-sgd85rni","author":"cderv","created_at":"2026-04-02T15:16:36Z","text":"After investigation: this issue is only needed if bd-itj9 is NOT done. If the test cfg proxy is removed (bd-itj9), native tests use Lua::new() with real C io library and these 8 tests just work on all platforms without refactoring. The io.open usage is a test harness detail, not a feature dependency. Current stopgap: #[cfg_attr(windows, ignore)] on the 8 tests — they still run on Linux/macOS CI where the proxy works."}}} +{"id":"bd-k4ahh","title":"q2 render <large-non-project-dir> also walks the tree before erroring","description":"Symmetric to bd-nmkmi but on the with-arguments path: `q2 render <dir>` where `<dir>` has no ancestor `_quarto.yml` walks the directory tree for `.qmd` files before deciding it's not a project. In `crates/quarto/src/commands/render.rs::classify_inputs` (lines ~206-235), each resolved input is passed to `ProjectContext::discover`, which falls through to the recursive walk on directory inputs without a project marker. The walk's output is discarded by the subsequent `is_real_project` check, then the `is_dir` branch returns `NoRenderableMatches`.\n\nSame fix pattern as bd-nmkmi: short-circuit the \"directory input, no ancestor `_quarto.yml`\" case using `find_project_root_upward` before calling `ProjectContext::discover`.\n\nLower priority (P3) than bd-nmkmi (P2) because the user has to explicitly point `q2 render` at a directory to hit it — much less common than the bare `q2 render`. Filed as discovered-from to keep the fix scope-disciplined.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-20T14:53:19.291221Z","created_by":"cscheid","updated_at":"2026-05-20T14:53:19.291221Z","labels":["cli","perf","render"],"dependencies":{"bd-nmkmi:discovered-from":{"depends_on_id":"bd-nmkmi","type":"discovered-from","created_at":"2026-05-20T14:53:19.291221Z","created_by":"cscheid"}}} +{"id":"bd-k8ol","title":"Mode B: partial Pass-1 walk to skip non-target profile re-extraction","description":"Phase 8.2 originally planned partial Pass-1 in Mode B: only profile the user-named targets plus their dependency closure. Implementation discovered a chicken-and-egg with sidebar auto: expansion (the membership resolver consults the index, which doesn't yet exist for non-target pages until they've been profiled). v1 ships full Pass-1 in both modes; the cache makes it cheap on the warm path. Decoupling the auto: resolver from index existence lets us land the partial walk and amortize Pass-1 cost on truly cold runs of huge projects. See claude-notes/plans/2026-04-27-websites-phase-8.md §'Sub-phase 8.2 — Deviation from plan'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:47.359008Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:47.359008Z","created_by":"cscheid"}}} +{"id":"bd-k8y0","title":"[websites] Sidebar vertical border missing (Q1 parity) — needs doc-derived SCSS variables seam","description":"Quarto 1 renders a faint vertical line between a docked sidebar and main content; Quarto 2 does not. Verified visually in examples/websites/03-nested-sidebar (q1-site has it, _site does not). \n\nRoot cause: two missing pieces in Q2.\n\n1. The SCSS rule '.sidebar.sidebar-navigation:not(.rollup) { border-right: 1px solid $table-border-color !important; }' (gated by '@if $sidebar-border') exists in Q1 (quarto-cli/src/resources/projects/website/navigation/quarto-nav.scss:552-556) but was never ported to resources/scss/bootstrap/_bootstrap-rules.scss in Q2.\n\n2. Q2 has no mechanism to inject per-document SCSS variables before the framework defaults. CompileThemeCssStage only reads theme config from doc.ast.meta; it never threads website.sidebar info into the SCSS bundle. Q1's format-html-scss.ts:631-642 synthesizes '$sidebar-border: <bool>;' per-document, defaulting to (style == 'docked').\n\nCustomization: end users override via 'sidebar.border: true|false' in YAML (Q1). Color follows the active Bootstrap/Bootswatch theme via $table-border-color (no special handling needed — themes already override it).\n\nPhased plan in claude-notes/plans/2026-04-30-sidebar-vertical-border.md:\n- Phase 1: port the @if $sidebar-border SCSS rule.\n- Phase 2: introduce derive_doc_scss_layer hook in CompileThemeCssStage; emit $sidebar-border per-document. Generic enough to reuse for sidebar/navbar/footer bg+fg later.\n- Phase 3: add 'border: Option<bool>' field to Sidebar struct for full Q1 parity.\n- Phase 4: end-to-end verification + docs.\n\nPhase 2 also tightens the theme CSS cache key to include the doc-vars layer so two docs with different sidebar configs don't collide on the generic 'default_minified' key.\n\nPlan file: claude-notes/plans/2026-04-30-sidebar-vertical-border.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-30T20:16:52.060454Z","created_by":"cscheid","updated_at":"2026-04-30T20:36:56.920069Z","closed_at":"2026-04-30T20:36:56.919907Z","close_reason":"Implemented across 4 phases: Phase 1 ported the @if $sidebar-border SCSS rule from quarto-cli quarto-nav.scss:552-556 into resources/scss/bootstrap/_bootstrap-rules.scss. Phase 2 introduced derive_doc_scss_layer() in CompileThemeCssStage and quarto_sass::compile_with_doc_vars() to thread per-document SCSS variables through the bundle ahead of framework defaults. Phase 3 added Sidebar.border (Option<bool>) for full Q1 parity on the sidebar.border knob. Phase 4 verified end-to-end via cargo run --bin q2 -- render on examples/websites/03-nested-sidebar — the rule now appears in the emitted CSS — and documented the knob in docs/navigation.qmd. Follow-up bd-8oqw filed for refactoring cache_key into a structured CompileInputs value type.","labels":["scss","sidebar","websites"],"dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-30T20:16:52.060454Z","created_by":"cscheid"}}} +{"id":"bd-k9i1","title":"project.resources support for non-renderable site resources","description":"Q1 supports project.resources: [patterns...] in _quarto.yml, which are globs for files to copy to the output dir alongside rendered HTML but not passed through the render pipeline (e.g. CNAME, robots.txt, images not referenced from qmds). Phase 1 of the website epic does not support this. Implement in ProjectPipeline (probably a third phase after Pass 2) or WebsiteProjectType::post_render.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T01:05:17.897545Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:17.897545Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:17.897545Z","created_by":"cscheid"}}} +{"id":"bd-khuj","title":"Hub-client UI smoke for template diagnostics","description":"After bd-xdnk plumbed doctemplate diagnostics through quarto render, the hub-client side rides the existing diagnostics_to_json -> JsonDiagnostic.warnings rails. No code changes were needed there, but a live browser smoke test would confirm a Q-10-2 warning shows up in the hub-client diagnostics panel and as a Monaco marker on the template file.\n\nSteps:\n1. Open hub-client against a project containing a custom template that references an undefined variable.\n2. Confirm the warning appears in the diagnostics panel with the correct file/line/column.\n3. Confirm Monaco shows a marker on the template's variable position when that file is open.\n4. Capture screenshots or notes in the bd-xdnk plan.\n\nDiscovered while doing bd-xdnk; not blocking that fix because the data flow uses well-tested rails.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-05T16:36:08.563749Z","created_by":"cscheid","updated_at":"2026-05-05T16:36:08.563749Z","dependencies":{"bd-xdnk:discovered-from":{"depends_on_id":"bd-xdnk","type":"discovered-from","created_at":"2026-05-05T16:36:08.563749Z","created_by":"cscheid"}}} +{"id":"bd-kk0a","title":"qmd writer: position-dependent escapes (`:`, `'`/`\"` unbalanced, `1.`/`-`/`+` line-start list markers)","description":"Discovered during the bd-21gu Phase 2 audit (claude-notes/plans/2026-04-30-at-escape-qmd-roundtrip.md). The qmd writer's escape_markdown helper is char-by-char and has no position context, so it can't fix escapes that depend on whether a char is at line-start or in unbalanced-quote position. The Phase 2 audit identified four bug classes that all need the same shape of fix:\n\n1. `:` at line start — triggers fenced div parser. Mid-line `:` is fine.\n Repro: a Str body containing \":word\" at the start of a line round-trips\n to a parse error.\n\n2. `'` and `\"` unbalanced — when a Str body coming from JSON contains a\n literal `'` or `\"` (not part of a Quoted node), the writer emits it\n unescaped and the re-parser produces an unclosed-quote error. Mid-word\n apostrophe (`a'b`) round-trips fine via smart-quote handling.\n\n3. `1.`/`-`/`+` followed by Space at line start — Str \"1.\" + Space + Str\n \"foo\" round-trips to OrderedList. Same for unordered list markers `-` /\n `+` followed by space at line start. The dot/dash itself is innocuous\n mid-word but becomes a list-marker trigger only at line-start with a\n following space.\n\n Repro:\n printf '1\\\\. foo\\n' | cargo run --bin pampa -- -t qmd | cargo run --bin pampa -- -t native\n → OrderedList (1, Decimal, Period) [[Plain [Str \"foo\"]]]\n Expected: Para [Str \"1.\", Space, Str \"foo\"]\n\nCommon requirement: writer needs (a) line-start tracking and (b) lookahead\nacross adjacent inline nodes to know whether escaping is needed for the\ncurrent character. This is a larger refactor than escape_markdown can\nabsorb — likely a new pass over the inline sequence in write_para or a\nposition-aware writer-context flag that get_str consults.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-01T00:31:59.051282Z","created_by":"cscheid","updated_at":"2026-05-01T00:32:14.786935Z","dependencies":{"bd-21gu:discovered-from":{"depends_on_id":"bd-21gu","type":"discovered-from","created_at":"2026-05-01T00:31:59.051282Z","created_by":"cscheid"}}} +{"id":"bd-kw93","title":"q2 preview epic: ephemeral local hub-client as Q2 replacement for quarto preview","description":"Implement `q2 preview` as a native CLI wrapping an ephemeral local hub-client instance. Uses samod for sync, the q2-preview React format for incremental DOM-stable rendering, and engine: replay for server-records / browser-replays code execution. See claude-notes/plans/2026-05-11-q2-preview-epic.md for architecture, phasing (A: skeleton + standalone SPA serving, B: file-watcher and remap broadening, C: engine execution via replay-on-server, D: polish + parity, E: stretch), and open questions awaiting user sign-off before phase plans are drafted. Branch: feature/q2-preview.","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-11T14:14:19.736224Z","created_by":"cscheid","updated_at":"2026-05-11T15:41:14.986644Z","dependencies":{"bd-hfjj:blocks":{"depends_on_id":"bd-hfjj","type":"blocks","created_at":"2026-05-11T15:41:14.986468Z","created_by":"cscheid"}}} +{"id":"bd-kw93.1","title":"Phase C.3: IndexDocument capture sidecar schema + WASM signature widen","description":"Foundational schema change for Phase C engine execution. Lands the sidecar map on IndexDocument that C.1/C.2/C.4/C.5 all consume, and widens the WASM render_page_for_preview signature to accept an optional EngineCapture.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.3 for the full test plan and acceptance criteria.\n\nPer Q-C1 the schema is additive (sidecar map keyed by path, not migration of files):\n\n interface IndexDocument {\n files: Record<string, string>;\n captures?: Record<string, CaptureRef>;\n version?: number; // bumped to 2\n identities?: Record<string, ActorIdentity>;\n }\n interface CaptureRef {\n captureDocId: string;\n staleness?: boolean;\n state?: 'idle' | 'running' | 'error';\n lastError?: string;\n }\n\nPer Q-C4 the state field is reserved (not just an 'executing' boolean) so we can grow to a status enum without another migration.\n\nAffects: ts-packages/quarto-automerge-schema/src/index.ts, crates/quarto-hub/src/index.rs, ts-packages/quarto-sync-client/src/{types,client}.ts, and crates/wasm-quarto-hub-client/src/lib.rs:1171 + ts-packages/preview-runtime/src/wasmRenderer.ts:436.\n\nAcceptance: schema roundtrip + migration tests pass; full workspace remains green; SPA build unaffected for the (no-capture) case.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:02.968438Z","created_by":"cscheid","updated_at":"2026-05-14T14:52:55.421565Z","closed_at":"2026-05-14T14:52:55.421417Z","close_reason":"Phase C.3 schema lands across three commits on beads/bd-kw93.1-phase-c3-indexdocument-capture:\n\n 2bdd6a5e — TS schema: CaptureRef + captures? sidecar, CURRENT_SCHEMA_VERSION 1→2, migrateIndexDocument staged V0→V1→V2 (47 tests pass)\n 6a0af0e2 — sync-client wire-up: CaptureRef re-export, onCapturesChange callback, notifyCapturesIfChanged fires on connect/change/createProject (70/70 tests, typecheck clean)\n 804b8338 — Rust IndexDocument mirror: CaptureState enum, CaptureRef struct, set/get/has/remove/get_all_captures, files+captures independent maps test pins plan §Risks #3 cleanup obligation (186/186 quarto-hub tests)\n\ncargo xtask verify --skip-hub-build all 12 steps green.\n\nWASM signature widening (originally in the C.3 dep-graph summary) deferred to bd-kw93.3 (C.4) where the dispatch logic actually lives; doing it here without EngineRegistry::with_replay wiring would have been a half-finished parameter. bd-kw93.3 description updated to absorb it.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.3","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:02.968438Z","created_by":"cscheid"}}} +{"id":"bd-kw93.10","title":"Phase D.4: Diagnostics surface — render + engine errors in PreviewErrorOverlay","description":"PreviewErrorOverlay already handles connection errors (PreviewApp.tsx:291). D.4 extends it to (a) catch WASM-renderer exceptions in the active-page render useEffect and surface the message; (b) surface CaptureRef.lastError from C.5's re-execute path when state === 'error', so engine failures aren't invisible.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.4.\n\nAcceptance: 2 unit (SPA) + 1 e2e.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:37:54.466643Z","created_by":"cscheid","updated_at":"2026-05-14T19:03:56.199388Z","closed_at":"2026-05-14T19:03:56.199257Z","close_reason":"Phase D.4 complete: render-pipeline failures now overlay PreviewErrorOverlay on top of the last-good iframe render instead of flipping to terminal boot:error. New renderError state slot, distinct from boot error. Engine errors continue to surface via StaleCaptureOverlay (pinned with new integration test). Drive-by fix: pre-existing TS error in StaleCaptureOverlay test that was breaking npm run build. 3 new SPA integration tests; workspace nextest 8938/8938; production build clean. Merged to feature/q2-preview-command as commit 1d5c6c6e.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:54.466643Z","created_by":"cscheid"}}} +{"id":"bd-kw93.11","title":"Phase D.5: User-facing documentation for q2 preview","description":"New docs/q2-preview.qmd (or similar) covering: what q2 preview does, basic usage, flags, preview.engine config, staleness affordance, and known limitations. Add to docs/_quarto.yml navigation. Mirror TypeScript Quarto's preview docs in tone.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.5.\n\nAcceptance: docs build cleanly; manual review of rendered page.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-14T18:37:57.132290Z","created_by":"cscheid","updated_at":"2026-05-14T19:49:42.417213Z","closed_at":"2026-05-14T19:49:42.417063Z","close_reason":"Phase D.5 complete: docs/q2-preview.qmd covers usage, preview.engine config, error UX, flags, limitations. clap --help tightened to user voice. bd-9ofu filed to track the deferred 'find a proper home for Q2 CLI docs' IA question. quarto render of the page produces clean HTML; workspace nextest 8951/8951. Merged to feature/q2-preview-command as commit f5a5fac7.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:57.132290Z","created_by":"cscheid"}}} +{"id":"bd-kw93.12","title":"Phase D.6: Dep-graph filter for re-renders","description":"Every content change today bumps contentTick + re-renders the active page, even for unrelated sibling edits. This is the relaxed criterion from Phase B.4 (criterion 3). D.6 uses the existing ProjectDependencyGraph to filter: only signal the SPA's contentTick when the edited file is the active page OR a dependency of it.\n\nSettled: filter runs server-side. SPA tells the server its active path; the server's existing watcher → sync_file hook becomes filter-aware. Restores Phase B.4's strict criterion.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.6. Unblocks bd-0mji's regression tests.\n\nAcceptance: unit + 2 e2e (positive and negative cases).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:38:00.690236Z","created_by":"cscheid","updated_at":"2026-05-14T19:25:32.286028Z","closed_at":"2026-05-14T19:25:32.285894Z","close_reason":"Phase D.6 complete: GET /api/preview/deps?page=<rel> returns single-hop include-shortcode deps. SPA filters onFileContent — drops sibling .qmd edits not in the active page's dep set; non-qmd edits (CSS, _quarto.yml, .tsx, images) pass through. Restores Phase B.4's deferred strict criterion. 11 unit + 2 Playwright tests; B.3's include-shortcode spec still passes. Workspace nextest 8949/8949; SPA 21/21+8/8; Playwright 13/13. Out-of-scope follow-ups: transitive includes, image/bibliography deps. Merged to feature/q2-preview-command as commit 7310d44b.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:38:00.690236Z","created_by":"cscheid"}}} +{"id":"bd-kw93.13","title":"Phase D.2: Initial-path resolution (project index vs file)","description":"Today 'q2 preview foo.qmd' opens the SPA, which picks firstQmd from the file index (PreviewApp.tsx:199-203). The user's requested file isn't honored. D.2 threads the requested path from CLI -> URL query (?page=foo.qmd) -> SPA seeds activeFile from it. In project mode without a path, prefer index.qmd over firstQmd.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.2 for seams + tests.\n\nAcceptance: 1 unit (Rust) + 1 unit (TS) + 1 integration test.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:38:11.988045Z","created_by":"cscheid","updated_at":"2026-05-14T18:54:59.098690Z","closed_at":"2026-05-14T18:54:59.098418Z","close_reason":"Phase D.2 complete: CLI threads requested path via ?page=<rel> through to SPA. resolve_project_and_initial_page walks up for _quarto.yml so 'q2 preview <proj>/posts/intro.qmd' indexes the whole project and seeds activeFile. pickInitialPage on SPA side validates against index and rejects .. traversal. 9 Rust + 8 SPA unit + 2 SPA integration tests. Workspace nextest 8938/8938; SPA 26/26. Binary smoke against /tmp/q2-d2-smoke confirms three URL shapes. Merged to feature/q2-preview-command as commit f9e23762.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:38:11.988045Z","created_by":"cscheid"}}} +{"id":"bd-kw93.14","title":"Phase F.1: Cross-page navigation + link-rewriting + Bootstrap JS","description":"Foundational sub-task for Phase F (q2-preview website chrome). Three things land together because they're co-dependent:\n\n1. Include link-rewrite in q2-preview pipeline. Removes 'link-rewrite' from Q2_PREVIEW_TRANSFORM_EXCLUDED at crates/quarto-core/src/pipeline.rs:1057. After this, body and chrome hrefs alike are .html URLs.\n\n2. Cross-page click navigation in the SPA. Extend iframePostProcessor.ts to recognize .html URLs that map back to project .qmd files (check against project file index — NOT just the .html suffix, so external https://example.com/foo.html stays untouched). Wire onNavigateToDocument in PreviewApp.tsx — invocation calls setState to switch activeFile. history.pushState so browser back/forward walks the in-SPA navigation. popstate listener to handle back/forward. After activeFile changes and the render fires, scroll the iframe to window.location.hash if present (coordinate with iframe's post-render hook, not the state change, to avoid the race).\n\n3. Bootstrap JS in the iframe. The chrome HTML emitted by navbar-render etc. uses Bootstrap dropdowns/collapses. The WASM pipeline currently excludes BootstrapJsStage (crates/quarto-core/src/stage/stages/bootstrap_js.rs). Two options to evaluate during implementation:\n (a) Include BootstrapJsStage in the WASM pipeline by removing the cfg gate, if state-preservation concerns the original gate guarded against don't apply to q2-preview's iframe model.\n (b) Statically inject bootstrap.bundle.min.js into the iframe template alongside the existing Bootstrap CSS — cleaner for preview because it bypasses any state concerns and lets Bootstrap 5's data-bs-* auto-init handle freshly-rendered chrome DOM.\nPick whichever's cleaner; document the choice.\n\nReference: math_js.rs at crates/quarto-core/src/stage/stages/math_js.rs — MathJsStage ships on both native and WASM pipelines because the engine 'typesets once on DOMContentLoaded' and holds no cross-reinit state. Bootstrap can ride the same pattern.\n\nAcceptance (per plan §F.1):\n- Playwright spec navigates a multi-page fixture via body link clicks + window.history.back() — back-button works. Anchor links scroll to the right section. Missing-page link shows the D.4 error overlay.\n- Playwright spec verifies a Bootstrap-driven element actually toggles when clicked.\n- Existing tests + workspace nextest 8952/8952 don't regress.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-f.md §F.1 for full seams + test plan. Settled decisions baked into the plan: F-D1 (HTML injection), F-D2 (full SPA-style routing), F-D3 (all hrefs become .html), F-D4 (chrome scope = whatever q2 render emits today), F-D5 (structural assertions, not snapshot parity).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T20:51:59.453550Z","created_by":"cscheid","updated_at":"2026-05-14T21:54:47.981900Z","closed_at":"2026-05-14T21:54:47.981771Z","close_reason":"Phase F.1 implemented + verified. See feature/q2-preview-command merge commit 1c104916; plan §F.1 closeout for diff summary.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T20:51:59.453550Z","created_by":"cscheid"}}} +{"id":"bd-kw93.15","title":"Phase F.2: All chrome injection + favicon + docs closeout","description":"Bundles the five chrome injections (navbar, sidebar, page-nav, TOC, footer) + favicon polish + docs/q2-preview.qmd truthing-up + Phase F closeout. Each chrome item follows the same pattern, so they bundle cheaply.\n\nServer side: remove from Q2_PREVIEW_TRANSFORM_EXCLUDED at crates/quarto-core/src/pipeline.rs:1057:\n- 'navbar-render'\n- 'sidebar-render'\n- 'page-nav-render'\n- 'toc-render'\n- 'footer-render'\n- 'website-favicon'\n\nReact side: in ts-packages/preview-renderer/src/q2-preview/PreviewDocument.tsx, add five dangerouslySetInnerHTML slots reading meta.rendered.navigation.{navbar,sidebar,page-nav,toc,footer}. Use React.memo + prop-equality on the string so React only re-renders the slot when the chrome HTML actually changes (mostly: _quarto.yml edits and page switches). The wrapper structure (where each chrome slot lives in PreviewDocument) should mirror what q2 render emits for the same fixture — read examples/websites/04-navbar-footer/_site/index.html for a reference and copy the wrapper divs.\n\nImplementation pattern from the plan:\n\nconst navbarHtml = extractMetaString(meta.rendered?.navigation?.navbar);\nreturn <NavbarSlot html={navbarHtml ?? ''} />;\n\n// NavbarSlot.tsx\nconst NavbarSlot = memo(({ html }: { html: string }) => (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n));\n\nDocs: update docs/q2-preview.qmd to remove the limitations bullet about missing chrome; update the 'what live means' section to mention chrome re-render semantics (chrome re-renders on _quarto.yml change or page switch).\n\nPlan housekeeping: mark Phase F done in claude-notes/plans/2026-05-11-q2-preview-epic.md and claude-notes/plans/2026-05-14-q2-preview-phase-f.md.\n\nAcceptance (per plan §F.2):\n- Playwright specs against examples/websites/04-navbar-footer/, examples/websites/02-auto-sidebar/, examples/websites/03-nested-sidebar/:\n - Navbar renders + clickable + clicking switches active page (proves F.1 ↔ F.2 integration).\n - Sidebar renders; active page highlighted; clicking other pages re-highlights.\n - Page-nav renders on pages with sidebar ordering.\n - TOC renders on pages with sections; entry clicks scroll to section.\n - Footer renders on projects configuring page-footer:.\n - Bootstrap-driven chrome elements (navbar dropdown menus, sidebar collapse toggles) actually open/close.\n- Manual smoke against the q2 docs site fixture (the user's in-flight authoring target): full chrome visible, navigation works.\n- docs/q2-preview.qmd renders cleanly.\n- Workspace nextest 8952/8952 green; Playwright N+5 green.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-f.md §F.2 for full seams + test plan. The eventual React-components-replacing-HTML-injection follow-up is tracked separately as bd-d8fo (carlos@ asked it be filed at planning time).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid","updated_at":"2026-05-14T22:30:55.140008Z","closed_at":"2026-05-14T22:30:55.139881Z","close_reason":"Phase F.2 implemented + verified. Merged on feature/q2-preview-command. Discovered bd-jjep (website.navbar nested-form schema gap) — not a Phase F regression.","dependencies":{"bd-kw93.14:blocks":{"depends_on_id":"bd-kw93.14","type":"blocks","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T20:52:16.629298Z","created_by":"cscheid"}}} +{"id":"bd-kw93.2","title":"Phase C.1: Server-side first-time eager engine capture","description":"When q2 preview opens a doc with code cells and no existing capture, the server runs the engine once and writes the resulting EngineCapture into automerge as a binary doc, with a sidecar entry pointing at it.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.1 for the full test plan and acceptance criteria.\n\nPer Q-C2 the implementation reuses the existing pipeline, capped at EngineExecutionStage (a 'preview-record' sub-pipeline). New module crates/quarto-core/src/engine/preview_record.rs exports a record_capture(path, project, runtime) -> Result<Option<EngineCapture>> function. None means no code cells.\n\nPer Q-C3 the input_qmd recorded is the whole serialized post-include-expansion QMD (matches what EngineExecutionStage feeds to engines today and what ReplayEngine validates on).\n\nAffects: crates/quarto-preview/src/lib.rs (capture driver), crates/quarto-hub/src/server.rs (sync_file hook), new crates/quarto-core/src/engine/preview_record.rs.\n\nAcceptance: unit + integration tests pass; end-to-end smoke against a markdown-engine fixture (no R/Python needed in CI) shows 'Executing code…' overlay between mount and capture landing, then captured output in the rendered DOM.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid","updated_at":"2026-05-14T15:38:54.938362Z","closed_at":"2026-05-14T15:38:54.938187Z","close_reason":"Phase C.1 server-side eager engine-capture lands across four commits on beads/bd-kw93.2-phase-c1-server-side:\n\n be7898a1 — preview_record sub-pipeline + CaptureCollector observer in quarto-core (4 unit tests).\n 342a18c9 — capture_driver in quarto-preview: gzipped-JSON binary doc + sidecar write, sequential per-file, server hook via new on_ready callback in run_server_with (5 unit tests).\n 1b9c6443 — run_with_on_ready API + end-to-end integration test that drives the full server lifecycle against a passthrough-engine fixture, polls sidecar, round-trips binary doc (2 integration tests). Binary smoke confirms boot path.\n 31bfebb7 — plan checklist for C.1 marked complete.\n\nTotal: 11 tests pass (4 preview_record unit + 5 capture_driver unit + 2 integration); cargo xtask verify --skip-hub-build all 12 steps green.\n\nArchitectural notes:\n- is the only quarto-hub change. Engine awareness stays in quarto-preview (the engine-aware app).\n- Pipeline futures are ?Send by the project's async_trait convention; driver runs on spawn_blocking + pollster::block_on so the multi-threaded tokio runtime stays free.\n- Sequential per-file processing caps plan §C.1 Risk #2.\n- Real-engine end-to-end (jupyter/knitr) not run this session; integration test uses a passthrough engine via PreviewConfig::engine_registry.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.1","dependencies":{"bd-kw93.1:blocks":{"depends_on_id":"bd-kw93.1","type":"blocks","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:31.045522Z","created_by":"cscheid"}}} +{"id":"bd-kw93.3","title":"Phase C.4: Browser-side replay wiring through render_page_for_preview","description":"Widen render_page_for_preview (and render_page_in_project) to accept an optional EngineCapture; inside WASM, construct EngineRegistry::with_replay(capture) when present, fall through to default otherwise.\n\nScope absorbed from C.3 (2026-05-14): the WASM signature widen was originally listed in the C.3 dependency-graph summary but its detailed Affects list + test plan in plan §C.4 own it; doing it in C.3 without the dispatch logic would be a half-finished implementation. C.3 (bd-kw93.1) closed without touching WASM; this issue now covers both the signature AND the dispatch.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.4 for the full test plan and acceptance criteria.\n\nThe capture flows from the binary doc (samod-stored gzipped JSON of EngineCapture) through the SPA, into the WASM renderer. Sidecar entry from C.3 (now landed) supplies the captureDocId; sync-client onCapturesChange callback (also landed in C.3) gives the SPA the path -> captureDocId map without further plumbing.\n\nAffects: crates/wasm-quarto-hub-client/src/lib.rs:1171 (render_page_for_preview), ts-packages/preview-runtime/src/wasmRenderer.ts:436, q2-preview-spa/src/PreviewApp.tsx:202.\n\nAcceptance: WASM unit tests with a hand-authored EngineCapture pass; SPA renders cleanly in both (capture supplied) and (no capture) paths.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid","updated_at":"2026-05-14T15:57:12.278221Z","closed_at":"2026-05-14T15:57:12.278057Z","close_reason":"Phase C.4 browser-side capture replay lands as 2f97c27b + 36816ca7 on beads/bd-kw93.3-phase-c4-browser-side.\n\nWiring:\n- WASM render_page_for_preview widened to take Option<Vec<u8>> (gzipped JSON EngineCapture bytes); internal build_replay_registry_from ungzips + parses + constructs EngineRegistry::with_replay.\n- render_qmd_to_preview_ast widened to accept engine_registry; threads through build_q2_preview_pipeline_stages -> EngineExecutionStage::with_registry.\n- TS surface: getBinaryDocById on the sync client + preview-runtime; CaptureRef re-exported from sync-client; renderPageForPreview takes the optional capture as Uint8Array.\n- SPA: PreviewApp listens for onCapturesChange, looks up the active page's captureDocId, fetches the binary doc, passes bytes to renderPageForPreview.\n\nTests: 2 new SPA integration tests (10/10 SPA tests pass), 70/70 sync-client tests, all 12 cargo xtask verify steps green (incl. real WASM build + hub-client tests).\n\nEnd-to-end loop is now closed: server records (C.1) -> automerge sidecar (C.3) -> browser replays (C.4).\n\nAcceptance gap: Playwright + real WASM smoke against a live preview with a hand-authored capture not run (substantial harness setup; not blocking).\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.4","dependencies":{"bd-kw93.1:blocks":{"depends_on_id":"bd-kw93.1","type":"blocks","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:35.303084Z","created_by":"cscheid"}}} +{"id":"bd-kw93.4","title":"Phase C.2: Staleness detection on doc-content change","description":"On every doc-content change, if a capture exists for that doc, compare the freshly-serialized input_qmd byte-for-byte against the capture's input_qmd. If different, set staleness: true on the sidecar entry. Do NOT re-execute (unless preview.engine: auto — see C.6).\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2 for the full test plan and acceptance criteria.\n\nPer Q-C3 v1 uses whole-QMD byte-equality, matching ReplayEngine's validation. This means prose-only edits also flip staleness: true; documented as a known v1 limitation, refinement is a follow-up.\n\nAffects: crates/quarto-hub/src/server.rs:1040 (run_file_watcher → sync_file), reuses canonicalization function exported from C.1's preview_record module.\n\nAcceptance: unit + 2 integration tests pass (one for code-cell edit, one documenting the prose-edit known limitation).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid","updated_at":"2026-05-14T16:26:38.814900Z","closed_at":"2026-05-14T16:26:38.814761Z","close_reason":"Phase C.2 staleness detection lands across three commits on beads/bd-kw93.4-phase-c2-staleness-detection:\n\n 6c3b1ea9 — compute_input_qmd canonicalization function in quarto-core (4 unit tests).\n e0cc639b — capture_driver recompute_staleness + OnFileChangedCallback wiring through run_server_with (5 unit tests).\n 7caf027e — plan checklist for C.2 marked complete.\n\nTotal: 9 new unit tests; cargo xtask verify --skip-hub-build all 12 steps green.\n\nArchitecture:\n- compute_input_qmd truncates the q2-preview pipeline at PreEngineSugaringStage and serializes the AST to QMD. Same output EngineExecutionStage would hand to the engine; byte-equality vs the recorded capture's input_qmd is the staleness signal.\n- recompute_staleness reads existing sidecar entry, ungzips + parses the capture binary doc, runs compute_input_qmd on the current file, compares bytes, flips CaptureRef.staleness when needed. Idempotent.\n- New OnFileChangedCallback type on quarto_hub::server. quarto-preview registers it from run_with_on_ready alongside the existing on_ready. Pipeline futures are ?Send; dispatches via spawn_blocking + pollster::block_on.\n- Canonicalizes both project_root and the watcher's absolute path for macOS /tmp vs /private/tmp.\n\nPlan §Q-C3 v1 limitation pinned in tests: whole-QMD byte-equality means prose-only edits also flip staleness. A future cell-only diff lands as a deliberate behaviour change.\n\nAcceptance gap: an in-process Rust integration test for the full watcher→staleness loop was drafted but flaky under cargo nextest run on macOS (suspected notify-rs/FSEvents + nextest stdout capture interaction). Filed as bd-u3ze. Coverage by:\n- 9 unit tests + 4 prior compute_input_qmd tests.\n- Binary smoke (q2 preview against /tmp/c2-smoke with RUST_LOG=debug) confirms the watcher → sync_file → on_file_changed → recompute_staleness path fires.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2","dependencies":{"bd-kw93.2:blocks":{"depends_on_id":"bd-kw93.2","type":"blocks","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:42.505909Z","created_by":"cscheid"}}} +{"id":"bd-kw93.5","title":"Phase C.5: Stale-capture UX overlay + /api/preview/re-execute endpoint","description":"When staleness: true, the SPA still renders using the previous capture (preview remains responsive) and shows a fixed-position overlay 'Code has changed. Re-execute?' with a button. The button POSTs to a new /api/preview/re-execute endpoint, which validates the path, kicks off the engine driver from C.1, and returns 202 Accepted.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.5 for the full test plan and acceptance criteria.\n\nPer Q-C5: POST body { path }; server returns 202 with { captureDocId } — capture flows back via samod sync, not HTTP body. Concurrent re-execute requests for the same path get 409 Conflict; UI button is disabled while state == 'running'. Auth is loopback-only (carried from Phase A).\n\nAffects: q2-preview-spa/src/PreviewApp.tsx + new StaleCaptureOverlay component (mirror PreviewErrorOverlay), crates/quarto-preview/src/lib.rs (register route alongside extend_with_spa), server-side handler that re-uses C.1's capture driver.\n\nAcceptance: SPA unit tests, API unit tests for 400/409/403 error paths, and end-to-end Playwright spec for the full edit→overlay→click→new-capture flow.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid","updated_at":"2026-05-14T16:42:10.987517Z","closed_at":"2026-05-14T16:42:10.987362Z","close_reason":"Phase C.5 stale-capture UX + re-execute endpoint lands across cf33c604 + 8d31a320 on beads/bd-kw93.5-phase-c5-stale-capture.\n\nSurface: POST /api/preview/re-execute (400/409/202 semantics), new <StaleCaptureOverlay /> component, integrated into PreviewApp via the existing onCapturesChange channel. Hub router refactored to delay with_state(ctx) so extensions can register State<SharedContext>-extracting routes.\n\nTests: 3 new Rust unit tests (path validation, 202 happy path, 409 concurrent) + 6 SPA integration tests (button states, POST shape, error handling). 2118/2118 Rust tests, 16/16 SPA integration tests.\n\nEnd-to-end UX loop now closes: server records (C.1) → sidecar (C.3) → browser replays (C.4) → file edit flips staleness (C.2) → SPA overlay shows + Re-execute POSTs (C.5) → server records new capture → SPA picks it up via samod sync.\n\nAcceptance gap: Playwright e2e (edit cell on disk → overlay → click → new capture renders) deferred — depends on the broader e2e harness Phase D/E will introduce.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.5","dependencies":{"bd-kw93.3:blocks":{"depends_on_id":"bd-kw93.3","type":"blocks","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid"},"bd-kw93.4:blocks":{"depends_on_id":"bd-kw93.4","type":"blocks","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:50.335598Z","created_by":"cscheid"}}} +{"id":"bd-kw93.6","title":"Phase C.6: preview.engine config (manual | auto | off)","description":"Read preview.engine from merged metadata. Three values:\n- manual (default): C.5 behaviour — server detects staleness, user must opt in via the overlay button.\n- auto: server re-executes on every code-cell change (no overlay needed).\n- off: server never executes. Code cells render as inert source; C.1's eager run is also skipped.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.6 for the full test plan and acceptance criteria.\n\nThe metadata flows through MetadataMergeStage like any other key. The consumer is the new preview-record driver (not the pipeline). Config is read at session start and on _quarto.yml changes (à la Phase B.4 propagation).\n\nAffects: crates/quarto-preview/src/config.rs (or similar) — read merged metadata; the existing C.1/C.5 driver branches on this.\n\nAcceptance: 1 unit + 3 integration tests (auto re-executes; off skips eager + suppresses code-cell exec; manual unchanged from C.5).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid","updated_at":"2026-05-14T17:16:42.583327Z","closed_at":"2026-05-14T17:16:42.583165Z","close_reason":"Phase C.6 complete: preview.engine config (manual|auto|off) parsed from _quarto.yml, EnginePolicy threaded through capture driver, Off skips eager + suppresses staleness, Auto kicks off re-execute via shared claim_and_spawn helper. 9 config unit tests + 3 driver tests + binary smoke against /tmp/q2-c6-smoke/{manual,auto,off}. Workspace nextest: 8913/8913. Merged into feature/q2-preview-command as commit 9fc4c984.","dependencies":{"bd-kw93.5:blocks":{"depends_on_id":"bd-kw93.5","type":"blocks","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:17:57.267986Z","created_by":"cscheid"}}} +{"id":"bd-kw93.7","title":"Phase C.7: Per-doc capture filesystem cache","description":"Filesystem cache at <tempdir>/captures/<content-hash>.bin (gzipped EngineCapture). When the server is about to run the engine, check the cache; if present, skip the engine and write the cached capture directly to automerge.\n\nSee claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.7 for the full test plan and acceptance criteria.\n\nPer Q-C6 the cache key is the full input_qmd bytes (same canonicalization function as C.2's staleness check, kept in sync to prevent drift).\n\nAffects: new crates/quarto-preview/src/cache.rs; the C.1 capture driver wraps engine invocation with cache lookup/insert.\n\nOpen follow-up (noted in plan §C.7): cache lives in per-session tempdir for MVP; per-project location would be friendlier for cross-session reuse. Mark for review.\n\nAcceptance: round-trip unit test + 2 integration tests (revert-edit cache hit; cross-session reuse if applicable).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:30.638380Z","closed_at":"2026-05-14T17:35:30.638250Z","close_reason":"Phase C.7 complete: per-doc filesystem cache at <data_dir>/captures/<sha256(input_qmd)>.bin. record_capture_cached wrapper integrated into all three drivers (eager, Auto re-execute, HTTP /api/preview/re-execute). 8 cache primitives + 4 wrapper unit tests with counting engine + 1 integration test in tests/cache_hit.rs. cargo nextest run --workspace: 8926/8926 pass. Binary smoke against /tmp/q2-c7-smoke clean. Open follow-up: cache in per-session tempdir; per-project location for cross-session reuse is future work. Merged into feature/q2-preview-command as commit 3bac5e93.","dependencies":{"bd-kw93.5:blocks":{"depends_on_id":"bd-kw93.5","type":"blocks","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid"},"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T14:18:02.202382Z","created_by":"cscheid"}}} +{"id":"bd-kw93.8","title":"Phase D.1: Browser-tab-on-startup + port-conflict retry","description":"Auto-open the boot URL in the user's default browser when --no-browser is unset (today the CLI prints a 'not implemented' note at crates/quarto/src/commands/preview.rs:107). Add a clear error when an explicit --port is bound (raw bind failure today). Use the 'open' (or 'webbrowser') crate; failure to open is logged + non-fatal.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.1 for the full test plan and acceptance criteria.\n\nAcceptance: unit + 1 integration test; manual smoke recorded.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-14T18:37:46.024702Z","created_by":"cscheid","updated_at":"2026-05-14T18:45:18.917558Z","closed_at":"2026-05-14T18:45:18.917426Z","close_reason":"Phase D.1 complete: open crate auto-opens browser tab on q2 preview boot; --no-browser short-circuits cleanly. validate_explicit_port pre-probes user-pinned ports and returns a friendly 'port N already in use; pass --port 0' error. Side fix: --port 0 now picks an OS-assigned port instead of printing http://127.0.0.1:0/. 3 unit tests + binary smoke recorded in commit body. Workspace nextest: 8929/8929. Merged to feature/q2-preview-command as commit c91abd27.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:46.024702Z","created_by":"cscheid"}}} +{"id":"bd-kw93.9","title":"Phase D.3: Verify static-file resources sync end-to-end","description":"Add Playwright e2e specs proving CSS in _extensions/, images, and theme files round-trip through samod binary-doc sync and re-render the preview within ~2s of a disk edit. Hub already syncs binary docs (Phase B.1 broadened the watcher), but the end-to-end 'edit foo.css -> preview reflects new colour' is unverified.\n\nSee claude-notes/plans/2026-05-14-q2-preview-phase-d.md §D.3.\n\nAcceptance: at least one new spec in q2-preview-spa/e2e/. Any bugs surfaced fix-in-scope or file follow-up.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-14T18:37:50.917226Z","created_by":"cscheid","updated_at":"2026-05-14T19:15:32.981970Z","closed_at":"2026-05-14T19:15:32.981822Z","close_reason":"Phase D.3 complete: e2e Playwright spec for static-file sync (CSS in _extensions/, image SVG). Surfaced two real bugs and fixed in scope: (1) .css missing from WatchFilter::PreviewBroad allow-list, (2) SPA's setSyncHandlers wasn't wiring onBinaryContent so image edits never bumped contentTick. Added window.__renderTicks counter to PreviewApp (also closes item #1 of bd-0mji). 11/11 Playwright; 8938/8938 workspace; SPA 21/21+8/8. Merged to feature/q2-preview-command as commit 1ddcbeaf.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-14T18:37:50.917226Z","created_by":"cscheid"}}} +{"id":"bd-ky14a","title":"Migrate pampa to hash-based FileIds for cross-parser interop","description":"Discovered while wiring bd-1pwy8 (SassError::UnknownTheme structured diagnostic): pampa's ASTContext uses sequential FileIds (always FileId(0) for the document's primary file), while quarto_yaml uses hash(filename) FileIds. The two schemes are incompatible — same FileId means different files depending on the producer.\n\nSymptoms / workarounds already in the tree:\n\n- crates/quarto-core/src/theme_diagnostic.rs takes (FileId, &Path) candidate pairs because the caller has to declare which scheme each candidate uses.\n- crates/quarto-core/src/stage/stages/include_expansion.rs:162-211 maintains TWO parallel SourceContexts and explicitly remaps FileId(0) → new_sequential_id for every included sub-document (with a debug_assert_eq! to catch desync).\n\nProposed fix: have pampa adopt quarto_yaml::file_id_for_filename so its FileIds are globally meaningful. Eliminates the workarounds and makes any future cross-context diagnostic consumer (hub-client, q2 preview, JSON endpoint) work without out-of-band FileId knowledge.\n\nCoordinate with the parallel source-location workstream before implementing — this touches ~50 hardcoded FileId(0) call sites in pampa. PR review needed, not direct-to-main.\n\nPlan: claude-notes/plans/2026-05-22-pampa-hash-fileids.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-22T16:13:27.241803Z","created_by":"cscheid","updated_at":"2026-05-22T16:13:27.241803Z","labels":["diagnostics","refactor","source-location"],"dependencies":{"bd-1pwy8:discovered-from":{"depends_on_id":"bd-1pwy8","type":"discovered-from","created_at":"2026-05-22T16:13:27.241803Z","created_by":"cscheid"}}} +{"id":"bd-l173","title":"Match Quarto 1 page-navigation default + styling + icons","description":"see plan","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-30T13:14:59.620901Z","created_by":"cscheid","updated_at":"2026-04-30T13:15:09.163538Z","closed_at":"2026-04-30T13:15:09.163374Z","close_reason":"duplicate of bd-bsut (created twice due to initial command parse issue)"} +{"id":"bd-l26u6","title":"Theme-config diagnostic overhaul (epic)","description":"Two issues bundled together: (1) make theme-config errors use the structured DiagnosticMessage + ariadne renderer like our other errors, and (2) coalesce per-page diagnostics so one bad _quarto.yml key produces one report listing affected pages rather than N copies.\n\nReproducer: cargo run --bin q2 -- render external-sources/quarto-web — today emits ~280 plain 'error: <path>: Invalid theme configuration' lines.\n\nPlan: claude-notes/plans/2026-05-22-theme-diagnostic-epic.md","status":"closed","priority":2,"issue_type":"epic","created_at":"2026-05-22T13:42:54.816887Z","created_by":"cscheid","updated_at":"2026-05-22T15:05:31.634700Z","closed_at":"2026-05-22T15:05:31.634520Z","close_reason":"Both children landed: bd-pgczr (theme errors use Q-14-1 ariadne diagnostics) and bd-9hlja (cross-page coalescing). User-visible: hundreds of plain-text 'error: <path>: Invalid theme configuration' lines on quarto-web now collapse into one ariadne block + 'Affected files: …' line listing the pages.","labels":["diagnostics","theme","website"]} +{"id":"bd-l6f0","title":"[websites] Honor explicit 'expanded: true' through active resolution","description":"Today resolve_active_state always sets expanded=true on ancestors of an active item, overriding any user-supplied 'expanded: false'. The YAML 'expanded: true' override is parsed but active-state unconditionally sets it to true — which is the right default but means a user cannot force a section collapsed when it contains the active page (rare but legitimate). Fix: honor the YAML value where it is 'true', but treat 'false' as a default that active-state can override up, never down.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-04-24T17:52:38.504797Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:38.504797Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:38.504797Z","created_by":"cscheid"}}} +{"id":"bd-lekl","title":"Phase 9 follow-up: deprecate render_qmd in favor of render_page_in_project","description":"Phase 9 sub-phase 9.4 switched the hub-client's renderToHtml from renderQmd to renderPageInProject. render_qmd remains as the single-file fallback inside render_page_in_project plus as a backward-compat surface. After the new entry point has bedded in (one or two release cycles), deprecate render_qmd and remove it.\n\nSteps:\n1. Mark render_qmd with #[deprecated] + console.warn-style notice in the TS wrapper.\n2. Audit all hub-client + tests for direct render_qmd calls; migrate to render_page_in_project.\n3. Wait one release.\n4. Delete the public render_qmd export, fold its remaining body fully into render_single_doc_to_response (private).","status":"open","priority":4,"issue_type":"task","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:40.067893Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:40.067893Z","created_by":"cscheid"}}} +{"id":"bd-lgxdr","title":"Author error-docs pages for markdown subsystem (36 codes)","description":"Author docs/errors/markdown/Q-2-X.qmd pages for all 36 entries in error_catalog.json under subsystem=markdown.\n\nCatalog codes (36 total): Q-2-1 through Q-2-35 plus Q-2-39 (gap at 36-38).\n\nPer-page workflow:\n- 29 of 36 codes have rich data in crates/pampa/resources/error-corpus/Q-2-X.json (code, title, message, notes, cases with example triggering content) — use those as the basis for stub content.\n- 7 codes lack corpus files (Q-2-4, Q-2-6, Q-2-8, Q-2-9, Q-2-14, Q-2-30, Q-2-39); grep emit sites in crates/ for these.\n\nClosing criteria:\n- 36 pages present in docs/errors/markdown/\n- All at status=stub or better\n- Front-matter matches catalog (title, since_version)\n- Cross-references inside markdown subsystem are real links\n- End-to-end render exits 0\n\nPlan: claude-notes/plans/2026-05-22-error-docs-content.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-22T20:27:53.321997Z","created_by":"cscheid","updated_at":"2026-05-22T20:38:37.352927Z","closed_at":"2026-05-22T20:38:37.352554Z","labels":["content","documentation","error-reporting"],"dependencies":{"bd-an6z4:parent-child":{"depends_on_id":"bd-an6z4","type":"parent-child","created_at":"2026-05-22T20:27:53.321997Z","created_by":"cscheid"}}} +{"id":"bd-lk66","title":"Hub-client website rendering UX issues (parse-error routing, missing sidebar, debug API)","description":"Track three hub-client UX problems uncovered while exercising examples/websites/08-hub-preview/ plus a debug-API enabler. See plan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md\n\nChildren:\n- Pass-1 parse error on the active page surfaces as a generic 'no output' message\n- Pass-1 parse error in another file is misattributed as 'Sidebar/Body link references unknown document'\n- Sidebar missing from hub-client website preview (cause TBD)\n- Console debug API enabler (window.quartoDebug for read/write/rerender)\n\nParent: bd-0tr6 (websites epic).","status":"open","priority":1,"issue_type":"epic","created_at":"2026-05-01T13:57:50.869653Z","created_by":"cscheid","updated_at":"2026-05-01T13:57:50.869653Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T13:57:50.869653Z","created_by":"cscheid"}}} +{"id":"bd-lnd3","title":"Hub-client: cross-doc link clicks don't switch editor in website projects","description":"Reproduced 2026-05-01 against the dev server.\n\nIn hub-client, clicking a cross-document link inside the preview iframe should switch the active editor file to the link's target. This works in non-website projects (link href ./another.qmd → editor switches) but is broken in website projects.\n\nIn a website project, the body-link / nav-href transforms rewrite [About](about.qmd) → <a href=\"/.quarto/project-artifacts/about.html\">. The rewrite is correct for deployed websites and is shared with the hub-client preview so artifact (CSS / image) resolution stays uniform. But the iframe click handler in hub-client/src/utils/iframePostProcessor.ts:140-158 only intercepts hrefs ending in .qmd; the rewritten .html URLs slip through and the click is a no-op inside the about:srcdoc iframe.\n\nSame defect applies to sidebar entries (when the sidebar is visible at vp >= 992 px) — they share the same artifact-rooted .html shape.\n\nRepro:\n- localhost:5173 'test website' (project ID prefix 25a55Noy, copy of examples/websites/08-hub-preview/).\n- Open index.qmd. Click [About] in body. Hash unchanged at …/file/index.qmd.\n- Compare to 'No website' (3ZcKVsWZ): clicking [page](./another.qmd) in index correctly switches the route to …/file/another.qmd.\n\nPlan: claude-notes/plans/2026-05-01-website-link-navigation.md (Option A recommended: reverse-map artifact-rooted .html → source .qmd at click time using the project file list as the source of truth).\n\nParent epic: bd-0tr6 (websites).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-01T17:05:53.926460Z","created_by":"cscheid","updated_at":"2026-05-01T18:00:39.879438Z","closed_at":"2026-05-01T18:00:39.879283Z","close_reason":"Fixed in 2441ad8d: reverseMapArtifactHref + new postProcessIframe pass intercepts artifact-rooted .html links and reverse-maps to source .qmd. Strict scope (only intercepts when source exists). 10 unit + 7 integration tests; verified end-to-end via Chrome DevTools MCP on test website (about.html / posts/first.html → switch editor) and No website (./another.qmd regression check).","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:05:53.926460Z","created_by":"cscheid"}}} +{"id":"bd-ltmn","title":"Fix toc: false semantics to be an affirmative disable (uniform with navbar/page-footer)","description":"Currently crates/quarto-core/src/transforms/toc_generate.rs only matches toc: true and toc: 'auto' for should_generate; toc: false falls through to 'don't generate', same as absent key. This means a document cannot override inherited toc: true from _quarto.yml with toc: false — users have to write toc: !prefer false.\n\nFix: treat toc: false after metadata merge as an affirmative disable. Apply identical logic across toc/navbar/page-footer so the rule is uniform.\n\nTracked alongside bd-imiw (navbar/footer design). See claude-notes/plans/2026-04-18-navbar-footer-design.md Phase 0.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-18T18:03:47.179494Z","created_by":"cscheid","updated_at":"2026-04-18T18:22:51.947379Z","closed_at":"2026-04-18T18:22:51.946590Z","close_reason":"Fixed: added is_feature_disabled helper and applied to toc_generate/toc_render. Tests in crates/quarto-core/src/transforms/{toc_generate.rs,toc_render.rs,config.rs}. Commit pending as part of bd-imiw work.","dependencies":{"bd-imiw:discovered-from":{"depends_on_id":"bd-imiw","type":"discovered-from","created_at":"2026-04-18T18:03:47.179494Z","created_by":"cscheid"}}} +{"id":"bd-lucp","title":"ReplayEngine miss in q2 preview: server's recorded input_qmd != WASM-produced input_qmd (mtime-derived listing-item.date-modified)","description":"After bd-m0mu (project registry plumbing) and bd-4uvv (samod automerge: URL prefix) are fixed, the SPA delivers the recorded capture bytes to the WASM. EngineExecutionStage now constructs ReplayEngine successfully — but ReplayEngine's strict byte-equality miss policy fires: 'replay miss: input QMD does not match recorded input (recorded 579 bytes, got 551 bytes).' 28-byte delta. The recorded input_qmd includes 'listing-item.date-modified: 2026-05-18' (server reads file mtime via NativeRuntime). The WASM-side q2-preview pipeline, running over the same source under WasmRuntime, doesn't have the same mtime in VFS so the listing-item.date-modified line is absent (or different). Net: every q2 preview render of a project with a website-type _quarto.yml hits a replay miss and shows the error overlay instead of rendered output. Repro fixture: ~/Desktop/daily-log/2026/05/15/q2-preview-test-website. Diagnosed end-to-end on 2026-05-18. Design space (pick one, needs user judgment): (a) compute_input_qmd strips mtime-derived metadata before serialization on server; (b) WasmRuntime populates mtimes in VFS so listing-item.date-modified surfaces in WASM too; (c) ReplayEngine loosens miss policy under preview mode (probably wrong — replay is a regression-testing tool); (d) cell-only diff for input_qmd canonicalization (the Phase-C polish path the C.3 plan flagged as Q-C3 v2). Plan §Q-C3 originally accepted whole-QMD byte-equality as a known v1 limitation; this surfaces it as a hard user-facing blocker.","status":"open","priority":0,"issue_type":"bug","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid","updated_at":"2026-05-18T16:00:50.554693Z","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid"},"bd-m0mu:discovered-from":{"depends_on_id":"bd-m0mu","type":"discovered-from","created_at":"2026-05-18T15:07:11.786286Z","created_by":"cscheid"}},"comments":{"c-9wgq5m1e":{"id":"c-9wgq5m1e","author":"cscheid","created_at":"2026-05-18T16:00:50Z","text":"Implementation complete 2026-05-18 on branch beads/m0mu-preview-project-replay-engine. The splice path landed exactly as designed: `quarto_core::engine::capture_splice` (9 unit tests green) + `stage::stages::capture_splice::CaptureSpliceStage` (inserted before EngineExecutionStage in `build_q2_preview_pipeline_stages`) + WASM `render_page_for_preview` deserializing capture_gz_json into a typed EngineCapture and threading it through. E2E verified against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website: iframe DOM now contains `<div class=\"cell\">` with `<div class=\"cell-output cell-output-stdout\"><pre><code>Hello, world</code></pre></div>` for the R cell. Live-edit case (appending a new prose paragraph) verified: the captured engine output survives the edit (which byte-equality replay never could). Awaiting user review for merge."},"c-huwep91o":{"id":"c-huwep91o","author":"cscheid","created_at":"2026-05-18T15:41:13Z","text":"Design pivoted 2026-05-18 after user clarification: preview should NOT consume captures through ReplayEngine (which is a deterministic regression-testing tool with intentionally strict miss policy). Instead, derive an AST-level transformation from (parse(input_qmd), parse(result.markdown)) and splice it onto the live-edited pre-engine AST. Full design at claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md. Supersedes bd-m0mu (closed). bd-4uvv stays valid. Key shape per user note: (structural_hash(cell_content), occurrence_index_in_doc_order) to disambiguate repeated identical cells."}}} +{"id":"bd-m0mu","title":"q2 preview: project-mode WASM render path drops engine_registry → cell output missing in iframe","description":"When q2 preview runs against a project (`_quarto.yml` present), the project-mode WASM render path in `render_project_active_page_to_response` (crates/wasm-quarto-hub-client/src/lib.rs:1431) takes `_engine_registry: Option<EngineRegistry>` and never threads it into the pass-2 renderer. `RenderToPreviewAstRenderer::render` (crates/quarto-core/src/project/pass2_renderer.rs:593) then calls `render_qmd_to_preview_ast(.., None)` with a hardcoded `None`. The ReplayEngine built from the capture binary doc is built and discarded — code cells render as raw `<pre><code class=\"{r}\">` source instead of the captured `<div class=\"cell\">` + `.cell-output-stdout` output. Single-file mode is fine; only project mode is broken. Reproduced 2026-05-18 against ~/Desktop/daily-log/2026/05/15/q2-preview-test-website/. Plan: claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md. Documented as 'known gap tracked alongside C.4 polish' in the WASM source comment.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid","updated_at":"2026-05-18T15:41:13.792874Z","closed_at":"2026-05-18T15:40:52.418984Z","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid"},"bd-z529:discovered-from":{"depends_on_id":"bd-z529","type":"discovered-from","created_at":"2026-05-18T14:27:31.237443Z","created_by":"cscheid"}},"comments":{"c-xkx1c70v":{"id":"c-xkx1c70v","author":"cscheid","created_at":"2026-05-18T15:41:13Z","text":"Closed as superseded by bd-lucp. The engine_registry-on-renderer plumbing was correct for an architecture that doesn't apply: preview-side capture consumption should be AST-splice, not ReplayEngine-as-drop-in. See claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md §'Why this supersedes bd-m0mu'. Reverting the Rust changes; keeping bd-4uvv (samod URL prefix) since that's needed regardless."}}} +{"id":"bd-m2w7a","title":"Migrate remaining unstructured DiagnosticMessage warnings in transforms to builder API","description":"Audit follow-up flagged in claude-notes/plans/2026-05-20-bd-8d6rk-navigation-diagnostics.md.\n\nbd-8d6rk migrates the navigation-surface warnings (`navigation_href.rs`, `sidebar_auto.rs`) to the structured `DiagnosticMessageBuilder` API with error codes, problem statements, and hints. The same anti-pattern (`DiagnosticMessage::warning(format!(...))` or `::error(format!(...))`) appears in other transforms and should get the same treatment:\n\n- `crates/quarto-core/src/transforms/theorem.rs:178` — 1 warning call site\n- `crates/quarto-core/src/transforms/crossref_resolve.rs:249,267` — 2 warning call sites\n- `crates/quarto-core/src/transforms/crossref_index.rs:374` — 1 error call site (duplicate crossref identifier)\n- `crates/quarto-core/src/transforms/attribution_render.rs:113` — 1 warning call site\n\nFor each:\n1. Allocate an error code in `error_catalog.json` under the appropriate subsystem (crossref likely gets a new subsystem; theorem and attribution may belong under `markdown` or get their own).\n2. Replace the inline `format!(...)` with builder construction (title / problem / hint / location).\n3. Update any tests asserting on the old title-string shape.\n\nLikely surfaces `SourceInfo` plumbing gaps in each subsystem (similar to bd-qor9a for navigation). Scope each transform separately if the plumbing turns out to be non-trivial — this issue is the umbrella; sub-issues are fine.\n\nOut of scope: behaviour changes. This is a shape-only migration. Any newly-discovered bugs in the underlying logic get separate issues.\n\nPlan: to be written when work begins (defer until bd-8d6rk lands, so the pattern is fully established).","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-20T16:08:53.537652Z","created_by":"cscheid","updated_at":"2026-05-20T16:08:53.537652Z","dependencies":{"bd-8d6rk:discovered-from":{"depends_on_id":"bd-8d6rk","type":"discovered-from","created_at":"2026-05-20T16:08:53.537652Z","created_by":"cscheid"}}} +{"id":"bd-m7x9s","title":"Parallelize Pass-1 across project files","description":"Pass-1 (profile extraction over every file in a project) is currently a sequential async loop in ProjectPipeline::pass_one. The 2026-05-22 quarto-web profile (post-engine-discovery fix, bd-c5u2g) shows the remaining wall time is dominated by per-doc CPU work (tree-sitter parsing + AST traversal). Pass-1 is embarrassingly parallel from a data-dependency standpoint, so a multi-thread fan-out should give a near-linear speedup up to the number of cores.\n\nPlan: claude-notes/plans/2026-05-22-parallelize-pass-one.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-22T17:05:18.473643Z","created_by":"cscheid","updated_at":"2026-05-22T18:01:16.824739Z","closed_at":"2026-05-22T18:01:16.824569Z","close_reason":"Pass-1 parallelized via rayon (Option D). Cold-cache quarto-web: Pass-1 2230→1280 ms (1.74×), total 3.73→2.81 s (1.33×). Warm-cache: 800→520 ms (1.54×). QUARTO_JOBS env override + sequential fallback for WASM/single-doc. All 9348 workspace tests pass, cargo xtask verify --skip-hub-build clean. Pass-2 parallelization (the next obvious win) deferred — no clean end-to-end test bed yet since quarto-web doesn't fully render under Q2.","dependencies":{"bd-9eltv:discovered-from":{"depends_on_id":"bd-9eltv","type":"discovered-from","created_at":"2026-05-22T17:05:18.473643Z","created_by":"cscheid"}}} +{"id":"bd-m9rm","title":"Default project render regression and project-level diagnostics","description":"Post-websites-merge: presence of `_quarto.yml` with `project: { type: default }` causes `q2 render` to silently produce zero output, and `q2 render index.qmd` to fail with a misleading 'excluded from render list' error. Root cause: `default_output_dir` returns the project root for default projects, so the discovery walker's output_dir-exclusion check rejects every file. Three goals: (1) fix the discovery regression so default projects walk the tree like websites do; (2) add a clear project-level diagnostic when the render set is empty so we no longer silently no-op; (3) add a project-level diagnostic surface that both the CLI and hub-client can render, since today only file-level diagnostics flow to hub-client. Plan: claude-notes/plans/2026-05-01-default-project-render-diagnostics.md (open design questions inside, awaiting user input before implementation starts).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T21:40:11.505417Z","created_by":"cscheid","updated_at":"2026-05-01T21:40:11.505417Z","dependencies":{"bd-0tr6:discovered-from":{"depends_on_id":"bd-0tr6","type":"discovered-from","created_at":"2026-05-01T21:40:11.505417Z","created_by":"cscheid"}}} +{"id":"bd-mae2","title":"L9 follow-up: custom feed templates (feed.template:)","description":"L9's three feed templates (preamble/item/postamble) are embedded built-ins. L8's listing.template config affects the listing render, not the feed render. A new feed.template: config field would let authors swap in custom XML templates for the feed itself. New feature; not in the L9 scope.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:46.431634Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:46.431634Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:46.431634Z","created_by":"cscheid"}}} +{"id":"bd-maz5","title":"Phase 1: Upgrade runtimelib 1.4 → 2.0 in quarto-core","description":"Bump runtimelib and jupyter-protocol from 1.4 to 2.0 in crates/quarto-core/Cargo.toml. Adds a wildcard arm in media_type_to_mime_entry (jupyter-protocol 2.0 makes MediaType #[non_exhaustive]).\n\nStatus: implementation complete in session 2026-05-04, verified with cargo build --workspace, cargo nextest run --workspace (8360 passed), cargo xtask verify --skip-hub-build. End-to-end render still produces 'kernelspec python3 not found' (expected: dirs.rs is unchanged 1.6 → 2.0). Awaiting commit.\n\nPlan: claude-notes/plans/2026-05-04-jupyter-kernelspec-discovery-and-errors.md (Phase 1)","status":"closed","priority":1,"issue_type":"chore","created_at":"2026-05-04T15:49:39.408919Z","created_by":"cscheid","updated_at":"2026-05-04T15:50:40.465475Z","closed_at":"2026-05-04T15:50:40.465325Z","close_reason":"runtimelib 1.4 -> 2.0 upgrade landed in 378d2d54. Workspace builds, all tests pass, end-to-end confirms the bug persists (venv discovery is the next phase, bd-34wy).","labels":["chore","jupyter"],"dependencies":{"bd-fu0l:discovered-from":{"depends_on_id":"bd-fu0l","type":"discovered-from","created_at":"2026-05-04T15:49:39.408919Z","created_by":"cscheid"}}} +{"id":"bd-mflk","title":"Phase A.5: End-to-end boot integration test","description":"crates/quarto-preview/tests/boot.rs: spawn 'q2 preview --no-browser --port 0' against a fixture project; assert SPA served, WS handshake succeeds, tempdir created+deleted, launch URL is http://<host>:<port>/#/preview/<indexDocId>. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.5.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-13T16:53:28.279760Z","created_by":"cscheid","updated_at":"2026-05-13T19:09:52.165059Z","closed_at":"2026-05-13T19:09:52.164919Z","close_reason":"Phase A.5 complete: q2 preview boots, renders, and applies theme styling end-to-end. See merge commit on feature/q2-preview-command.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.279760Z","created_by":"cscheid"}}} +{"id":"bd-mgoh","title":"Sidebar renders below page content — body class & grid placement wrong","description":"Q2 website rendering places the sidebar at the bottom of the page (below `<main>` and below the prev/next strip) instead of in a left column.\n\nRoot cause (verified against examples/websites/01-minimal rendered with q2 vs q1):\n1. Body class is hardcoded `fullcontent` in crates/quarto-core/src/template.rs:162. The website pipeline never sets the `body-classes` template variable, so we never get `nav-sidebar` or `floating`/`docked`.\n2. resources/scss/bootstrap/_bootstrap-rules.scss keys the grid layout off body classes: `body.floating .page-columns { @include page-columns-float-wide(); }` produces a 150px sidebar column on the left, while `body.fullcontent:not(.floating):not(.docked)` produces no sidebar column.\n3. Without that column, the sidebar wrapper (`#quarto-sidebar-container` placed at `grid-column: body-content-start / body-content-end`, `grid-row: auto`) gets auto-placed in an implicit row after `<main>`, so it appears below the page content.\n4. Secondary structural difference: Q1 places `<nav id=quarto-sidebar>` directly as a grid child; Q2 wraps it in `#quarto-sidebar-container`. The SCSS in resources/scss expects the Q1 layout.\n\nPlan: claude-notes/plans/2026-04-29-website-sidebar-layout.md\n\nOut of scope: search bar (Q1 default that we are not adding yet).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-29T20:20:57.275263Z","created_by":"cscheid","updated_at":"2026-04-29T20:20:57.275263Z","dependencies":{"bd-2jwk:discovered-from":{"depends_on_id":"bd-2jwk","type":"discovered-from","created_at":"2026-04-29T20:20:57.275263Z","created_by":"cscheid"}}} +{"id":"bd-ml8z","title":"L3 — ListingResolveTransform (Pass-2, built-ins via doctemplate)","description":"New Pass-2 transform inside AstTransformsStage. Reads host's listing: config + ProjectIndex; resolves contents: globs; filters/sorts; truncates by max-items. Builds per-item TemplateValue::Map with curated profile fields, server-pre-rendered helpers (image_html, metadata_attrs), and listing_item.extra. Renders via doctemplate against built-in default/grid/table templates embedded with MemoryResolver. Emits placeholders for L7 alongside L1 fallback content. See claude-notes/plans/2026-05-05-listings-epic.md §L3.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid","updated_at":"2026-05-07T13:35:17.550573Z","closed_at":"2026-05-07T13:35:17.550209Z","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid"},"bd-b5jm:blocks":{"depends_on_id":"bd-b5jm","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid"},"bd-izqh:blocks":{"depends_on_id":"bd-izqh","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid"},"bd-j60g:blocks":{"depends_on_id":"bd-j60g","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid"},"bd-n8a4:blocks":{"depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:53:22.859719Z","created_by":"cscheid"}}} +{"id":"bd-mlj6","title":"Conditional render lists / _quarto-*.yml profiles","description":"Q1 supports profile-specific renders via _quarto-<profile>.yml (e.g. _quarto-prod.yml vs _quarto-dev.yml). Phase 1 of the website epic ignores profile files entirely — discovery excludes them because of the leading underscore, and config parsing only reads _quarto.yml. Follow-up: decide how profiles compose with the base config, add CLI flag for selecting profile, thread through ProjectContext::discover. See claude-notes/plans/2026-04-23-websites-phase-1.md §Decisions log.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T01:05:24.479391Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:24.479391Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:24.479391Z","created_by":"cscheid"}}} +{"id":"bd-mot7","title":"qmd reader drops whitespace between code_span and html_element (issue #182)","description":"(see triage doc)","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T13:42:59.836284Z","created_by":"cscheid","updated_at":"2026-05-12T13:43:26.216838Z","closed_at":"2026-05-12T13:43:26.216709Z","close_reason":"Duplicate, accidental second create. Keeping bd-nkx4."} +{"id":"bd-mqa4j","title":"Phase 8 — quarto-sync-client header pass-through + connection-manager integration","description":"Add auth?.getBearer option to client.connect(); new Node-only NodeWebSocketClientAdapter inside quarto-sync-client that constructs new WebSocket(url, [], { headers }). Browser path unchanged.\n\nConnection-manager try-then-fallback policy: read bundle, attempt WS with Bearer if present, on 401-with-creds forceRefresh+retry-once then ReauthRequired, on 401-without-creds AuthRequired.\n\nlastObservedAuthMode state machine ({no-auth, requires-auth, unknown}, process-local) drives Phase 7's short-circuit.\n\nInsecure-Bearer gate: refuse to send Bearer over plain HTTP/WS to non-loopback without QUARTO_HUB_MCP_ALLOW_INSECURE_AUTH=1; loud warning on every connect when set.\n\nFollow-up: upstream PR to thread headers through BrowserWebSocketClientAdapter — file separately.\n\nPlan §Phase 8: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:25.451968Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:25.451968Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:25.451968Z","created_by":"shikokuchuo"}}} +{"id":"bd-mqk49","title":"Design: how should engines/extensions declare additional pipeline stages?","description":"build_html_pipeline_stages() in crates/quarto-core/src/pipeline.rs is a hardcoded ~19-stage list. Stages can be gated by config (e.g. native-only), but no engine, extension, or plugin can register a new stage.\n\n**More relevant after PR #238 (sequential multi-engine execution).** With engines as first-class pipeline citizens, the natural mechanism for 'format-agnostic engine output + format-specific emission' is to let an engine declare a per-format AST pass on its output. For mermaid: 'when emitting HTML, run this transform on my output blocks.' For graphviz/plantuml/dot later: same shape.\n\nA proper extension API would let engines/extensions declare:\n- a stage name + input/output kinds\n- a position (after-X / before-Y, or by precedence)\n- a per-format applicability predicate\n- a per-engine attribution back-reference (so trace events name the engine that contributed the stage)\n\n**Known beneficiary: the mermaid engine (bd-gwfdo).** Mermaid ships first under B1 (the engine emits RawBlock(HTML, '<pre class=\"mermaid\">...</pre>') directly — format-locked but acceptable while Q2 is HTML-only). A source-code comment in crates/quarto-core/src/engine/mermaid/ flags the TODO. **When bd-mqk49 lands, follow up on the mermaid engine** to refactor: the engine should emit a marker Div (e.g. Div.mermaid wrapping the source code block) and declare an HTML-conditional AST pass that turns the marker into the <pre class=\"mermaid\"> output. This removes the format coupling and makes the mermaid engine PDF-ready.\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G3.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-28T13:45:56.898020Z","created_by":"cscheid","updated_at":"2026-05-28T17:05:01.753171Z","dependencies":{"bd-c6h96:discovered-from":{"depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:56.898020Z","created_by":"cscheid"}}} +{"id":"bd-mre3","title":"[websites phase 2] Sidebar data model, generate, render, template","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 2.\n\nDeliverables:\n- Schema parsing for website.sidebar: Vec<Sidebar> with id, title, contents, style, collapse-level.\n- Contents supports: string (path), {href, text, icon}, {section, contents}, {auto: ...}.\n- quarto-navigation data types: Sidebar, SidebarEntry, SidebarContents.\n- SidebarGenerateTransform: reads YAML config + ProjectIndex to resolve auto and expand entries.\n- SidebarRenderTransform: emits Bootstrap-5 HTML matching Q1 class names where possible.\n- Template slot: $rendered.navigation.sidebar$.\n- Sidebar-for-page selection logic.\n- Integration tests with manual, auto, and nested contents.\n\nBlocked by Phase 1 (needs ProjectIndex).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-23T18:42:49.915763Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.148471Z","closed_at":"2026-04-29T00:31:30.148151Z","close_reason":"Phase 2 (sidebar) implemented — see git log Phase 2 sub-phase commits and claude-notes/plans/2026-04-24-websites-phase-2.md (closed as part of Phase 9 cleanup; this should have been closed earlier).","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:49.915763Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:42.284820Z","created_by":"cscheid"}}} +{"id":"bd-mrx1","title":"Phase B.4: Acceptance bundle — _quarto.yml + posts/_metadata.yml propagation to preview","description":"Single Playwright spec pinning the two observable plan acceptance criteria for q2 preview (Phase B):\n\n1. Editing _quarto.yml (title:) re-renders the active page; new title visible in DOM within 5 s.\n2. Editing posts/_metadata.yml (subtitle:) re-renders pages under posts/; new subtitle visible in DOM within 5 s.\n\nFixture (single, dual-purpose): _quarto.yml + posts/_metadata.yml + posts/post1.qmd (no frontmatter, inherits both). Empirically verified both knobs flow through to the rendered title-block (2026-05-13 probe with target/debug/q2 render).\n\nReuses the multi-file fixture helper generalised in bd-pf63 (B.3).\n\nPlan acceptance criterion 3 ('unrelated sibling re-renders the active page') is deferred and tracked separately — its relaxed-contract form (any edit fires a re-render) is invisible at the DOM without SPA instrumentation. See discovered-from follow-up.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.4.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid","updated_at":"2026-05-13T21:15:09.863020Z","closed_at":"2026-05-13T21:15:09.862892Z","close_reason":"Phase B.4 complete; zero production-code changes — new Playwright spec at q2-preview-spa/e2e/config-edits.spec.ts pins _quarto.yml + posts/_metadata.yml propagation. See commit df2f5f55 on beads/bd-mrx1-phase-b4-acceptance-bundle.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid"},"bd-pf63:discovered-from":{"depends_on_id":"bd-pf63","type":"discovered-from","created_at":"2026-05-13T21:11:28.867999Z","created_by":"cscheid"}}} +{"id":"bd-msp0","title":"Hub-client preview resource resolution via service worker (epic)","description":"Long-term direction: replace the iframe post-processor's resource-rewriting passes (CSS data-URIs, image data-URIs, the disabled <script> inlining block) with a service worker scoped to /.quarto/project-artifacts/ and project-relative paths. The SW intercepts fetch events and serves from the VFS, giving us:\n\n- Single resolution path shared between top-frame and iframe.\n- No data-URI churn on every render (iframes routinely carry hundreds of KB of inline base64 stylesheets today).\n- Clean answer for the in-project image redirection bug.\n- Plausible path for executing real JS bundles in preview iframes (Bootstrap collapse, search, copy-button, etc.) once SW + sandbox + COEP/COOP are set up correctly.\n\nNOT in scope: cross-doc link click → editor navigation (bd-lnd3). That's a DOM-event concern, not a fetch concern; about:srcdoc iframes drop link clicks silently regardless of network resolution. The click-interception path stays in iframePostProcessor.ts even after the SW arc lands.\n\nChildren candidates (file as separate issues when this epic gets traction):\n- SW bootstrap + scope registration in hub-client.\n- VFS → fetch handler.\n- Migration of CSS resolution (remove data-URI rewrite from iframePostProcessor).\n- Migration of image resolution (remove data-URI rewrite + fixes the in-project image redirect bug).\n- JS bundle execution in preview iframes (subsumes bd-e7b7 native+incremental constraints).\n- Sandbox / COEP / COOP setup as required.\n\nParent epic: bd-0tr6 (websites, since the immediate motivation is the website rendering pipeline, but the SW infrastructure is broadly useful).","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid","updated_at":"2026-05-01T17:18:45.016932Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid"},"bd-e7b7:related":{"depends_on_id":"bd-e7b7","type":"related","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid"},"bd-lnd3:related":{"depends_on_id":"bd-lnd3","type":"related","created_at":"2026-05-01T17:18:45.016932Z","created_by":"cscheid"}}} +{"id":"bd-mtzry","title":"D6: <body> emits quarto-light / quarto-dark class","description":"## What\n\nQ1 emits `<body class=\"fullcontent quarto-light\">` (or `quarto-dark` depending on theme). Q2 emits only `<body class=\"fullcontent\">`. Add the color-mode class based on the active theme config (default `quarto-light`).\n\n## Where\n\nTemplate body-class logic lives at `crates/quarto-core/src/template.rs:136` area (per existing comment: 'Mirrors TS Quarto's format-html-bootstrap.ts body-class logic').\n\n## Tests\n\nTemplate-render test asserting the body class for:\n- default config (no theme set) → `fullcontent quarto-light`\n- explicit dark theme → `fullcontent quarto-dark`\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md (D6 section)","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-05-20T20:55:25.035424Z","created_by":"cscheid","updated_at":"2026-05-20T21:39:26.262052Z","closed_at":"2026-05-20T21:39:26.261894Z","close_reason":"Implemented in this commit: quarto-light appended to body class for default renders.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T20:55:25.035424Z","created_by":"cscheid"}}} +{"id":"bd-mw7x","title":"[websites phase 3] Navbar/footer project integration","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 3.\n\nDeliverables:\n- Extend existing NavbarGenerateTransform and FooterGenerateTransform to read project-level config from _quarto.yml and resolve cross-doc hrefs via ProjectIndex.\n- Active-item highlighting for the current page.\n- Navbar search tool stays a stub (search is a follow-up epic).\n- Tests: navbar entries pointing at .qmd files correctly render as .html links; external URLs pass through unchanged.\n\nBlocked by Phase 1.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:42:59.202302Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.330069Z","closed_at":"2026-04-29T00:31:30.329739Z","close_reason":"Phase 3 (navbar/footer project integration) implemented — see git log Phase 3 commits. Closed as part of Phase 9 cleanup.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:59.202302Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:43.309371Z","created_by":"cscheid"}}} +{"id":"bd-mwtf","title":"Hub-client: active-page parse error renders as 'Project render produced no output for the active page'","description":"When a website document has a Pass-1 parse error AND it is the active page in hub-client, the preview overlay shows the literal string 'Project render produced no output for the active page' instead of the actual parse diagnostic.\n\nRepro: examples/websites/08-hub-preview/about.qmd has an unescaped apostrophe (line 11, 'pages\\\\'') that the strict Q2 markdown parser rejects with [Q-2-10] Closed Quote Without Matching Open Quote. The CLI shows the full ariadne-style snippet via 'warning: profile-pass skipped about.qmd: ...'. Hub-client shows only the generic message.\n\nRoot cause (located): crates/wasm-quarto-hub-client/src/lib.rs:1374-1428 — render_project_active_page_to_response() checks summary.pass2_failures but never checks summary.pass1_failures. When the active page failed Pass-1, both summary.outputs and summary.pass2_failures are empty, so the L1393 fallback fires.\n\nFix: in the L1381 'no output' branch, look up summary.pass1_failures for an entry whose input matches the active path; if found, build a RenderResponse with success: false, error from the failure summary, and diagnostics: failure.diagnostics mapped to JsonDiagnostic.\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Bug 2 section).","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T13:58:04.540272Z","created_by":"cscheid","updated_at":"2026-05-01T13:58:04.540272Z","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:04.540272Z","created_by":"cscheid"}}} +{"id":"bd-my0o5","title":"q2 preview end-to-end verification for mermaid blocks","description":"Verify the MermaidEngine survives the q2-preview round trip (capture-splice path).\n\n**This task effectively closes PR #238's bd-iq0hp** — PR #238 documented that a browser E2E of multi-engine preview was not possible at PR time because the default registry uses real engines, FixtureEngine is test-only, and knitr/jupyter don't compose cleanly (knitr claims `{python}` via reticulate). Mermaid + knitr is the first real-engine pair with disjoint cell-class ownership (`{r}` vs `{mermaid}` never overlap).\n\nTest matrix:\n\n1. Document with mermaid block only — q2 preview renders the diagram.\n2. Document with engine: [knitr, mermaidjs], knitr block + mermaid block, with recorded captures — both render in preview.\n3. Edit the mermaid block — preview updates without re-running knitr's capture (capture invariance on engine 1's input).\n4. Confirm the jsdelivr script include arrives in the preview's HTML body. If C1 (inline RawBlock in engine markdown) is the chosen approach (per plan v2), this should Just Work because capture-splice preserves result.markdown. If C2/C3 is chosen instead, bd-cp3em becomes a blocker.\n\nPlan: claude-notes/plans/2026-05-28-mermaidjs-engine-design.md","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-05-28T13:45:19.961230Z","created_by":"cscheid","updated_at":"2026-05-29T13:25:16.167177Z","dependencies":{"bd-gwfdo:blocks":{"depends_on_id":"bd-gwfdo","type":"blocks","created_at":"2026-05-28T13:45:37.473723Z","created_by":"cscheid"},"bd-je48v:parent-child":{"depends_on_id":"bd-je48v","type":"parent-child","created_at":"2026-05-28T13:45:19.961230Z","created_by":"cscheid"}}} +{"id":"bd-n4e0p","title":"Canonical device-flow URL must be a module constant, not Google's response","description":"Anti-phishing requirement from plan §Phase 1 (threat #5). authenticate_start MUST return the hard-coded constant https://www.google.com/device as canonical_url alongside Google's verification_uri — and the canonical must come from a module-level constant in auth-tools.ts, NEVER copied from the AS response.\n\nTest name: start_canonical_url_is_a_constant_not_from_google_response in ts-packages/quarto-hub-mcp/test/auth/auth-tools.test.ts. Test uses a mock AS that returns a malicious verification_uri and asserts the tool's canonical_url is unchanged.\n\nPlan §Phase 7 + threat model #5: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:27:54.874842Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:54.874842Z","dependencies":{"bd-cqkts:parent-child":{"depends_on_id":"bd-cqkts","type":"parent-child","created_at":"2026-05-20T14:27:54.874842Z","created_by":"shikokuchuo"}}} +{"id":"bd-n7x2","title":"Syntax highlighting design and implementation for Quarto 2","description":"Design and implement a syntax highlighting system for code blocks in Quarto 2. Generic span-annotation AST format + tree-sitter-driven pipeline stage + per-format writers. Plan: claude-notes/plans/2026-04-19-syntax-highlighting-design.md. Research notes under claude-notes/research/syntax-highlighting-*.md.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-19T14:50:53.168567Z","created_by":"cscheid","updated_at":"2026-04-19T14:50:53.168567Z"} +{"id":"bd-n8a4","title":"L0 — ListingItemInfo profile extension","description":"Add DocumentProfile.listing_item: ListingItemInfo with curated fields + extra: BTreeMap<String, ConfigValue>. Bump DOCUMENT_PROFILE_VERSION 2 → 3. Update document-profile-contract.md with the new row plus a new §'Scoped feature surfaces' explicitly forbidding non-listing reads of listing_item.extra. Schema update in quarto-yaml-validation. See claude-notes/plans/2026-05-05-listings-epic.md §L0.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-05T19:52:49.454592Z","created_by":"cscheid","updated_at":"2026-05-05T21:30:29.284197Z","closed_at":"2026-05-05T21:30:29.283825Z","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:52:49.454592Z","created_by":"cscheid"}}} +{"id":"bd-n9dr","title":"[websites epic] Unify nav config placement across features","description":"Nav config placement across features. Phase 3 (2026-04-24) refined the framing: rather than 'unify everything into one namespace,' the principle is now \"placement follows feature semantics.\"\n\nCurrent placement (post-Phase 3):\n- 'navbar:' — top level (feature-scoped; works in single-doc + project)\n- 'page-footer:' — top level (same; revealjs/etc. legitimately use it)\n- 'website.sidebar:' — under website. (sidebar is inherently a multi-page website feature)\n- 'site-sidebar:' (per-doc override selecting which sidebar applies) — top level\n- 'website.title:' / 'website.site-url:' / 'website.favicon:' — under website. (site-scoped)\n\nThe only remaining tension is 'site-sidebar' being a doc-level override for a website-scoped feature. Options:\n(a) rename to 'website.sidebar-id' (canonical; website.sidebar-id already accepted in Phase 2 as an alias)\n(b) keep 'site-sidebar' since it's a per-doc override like 'draft:' / 'date:' and those also live at the top level\n\nNot a blocker for MVP; land before docs-facing release. See claude-notes/plans/2026-04-24-websites-phase-3.md §Decision 1 for the framing shift.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T17:53:00.610122Z","created_by":"cscheid","updated_at":"2026-04-24T19:43:25.192319Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:53:00.610122Z","created_by":"cscheid"}}} +{"id":"bd-nb32","title":"Body-link 'data-noresolveinput' escape hatch (Q1 parity)","description":"Q1 lets users opt out of body-link rewriting via data-noresolveinput attribute on individual <a> elements. Phase 6 (bd-v30t) skipped this; file once a real workflow surfaces (e.g. literal .qmd hrefs that must NOT be rewritten).","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:47.962663Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:47.962663Z","created_by":"cscheid"}}} +{"id":"bd-nf50","title":"Page-navigation rules need user-facing docs","description":"User explicitly flagged (Phase 4 Decision 9) that the flatten + dedupe + separator-as-boundary + section-header-as-neighbor rules are non-obvious and need documentation in the Q2 docs site (bd-tr81). Tie to the docs epic.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid","updated_at":"2026-04-30T13:54:10.438123Z","closed_at":"2026-04-30T13:54:10.437973Z","close_reason":"Documented as part of bd-bsut. The new \"Page navigation (prev/next)\" → \"How prev/next are chosen\" subsection in docs/navigation.qmd covers all four non-obvious rules: depth-first flatten, duplicate-href dedupe, separator-as-hard-boundary, and section-header-with-href as neighbor.","dependencies":{"bd-nwun:discovered-from":{"depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid"},"bd-tr81:related":{"depends_on_id":"bd-tr81","type":"related","created_at":"2026-04-24T22:48:12.837109Z","created_by":"cscheid"}}} +{"id":"bd-nkx4","title":"qmd reader drops whitespace between code_span and html_element (issue #182)","description":"Reader silently drops leading/trailing whitespace on bare html_element nodes when they're converted to RawInline, so AST loses the Space between adjacent Code and RawInline siblings. Writer then collides backticks and round-trip fails to re-parse.\n\nReproduction, root cause, and recommended fix scope are documented in claude-notes/issue-reports/182/triage.md on branch issue-182 (worktree .worktrees/issue-182). Short version: the html_element visitor's anchor-shorthand branch already handles leading_ws/trailing_ws correctly by emitting adjacent Space inlines; the sibling RawInline branch in the same match arm does not. The fix mirrors that pattern.\n\nLocalized in crates/pampa/src/pandoc/treesitter.rs (html_element arm). TDD-first per crates/pampa/CLAUDE.md: add a roundtrip fixture and an AST assertion before changing code.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T13:42:55.415626Z","created_by":"cscheid","updated_at":"2026-05-12T14:07:10.065411Z","closed_at":"2026-05-12T14:07:10.065243Z","close_reason":"Fixed in f2867bb1 on branch issue-182. Reader now emits leading/trailing Space inlines around RawInline when the html_element node carries surrounding whitespace, mirroring the anchor-shorthand branch in the same match arm."} +{"id":"bd-nl5q","title":"Cargo: upgrade deno_core v0.376.0 → v0.400.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.376.0 is range-pinned in workspace; latest is 0.400.0. Type: pre-1.0 minor (semver-breaking); large jump. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.767839Z","created_by":"cscheid","updated_at":"2026-05-04T18:16:04.780626Z","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.780303Z","created_by":"cscheid"}}} +{"id":"bd-nmkmi","title":"q2 render with no args walks cwd before checking for _quarto.yml","description":"`q2 render` invoked with no arguments in a directory with no `_quarto.yml` (and no `_quarto.yml` in any ancestor) eventually emits the correct \"No input given and no `_quarto.yml` found at or above <cwd>\" error — but only AFTER recursively walking the entire cwd looking for `.qmd` files.\n\nIn an empty directory the error appears instantly. In a large tree (q2 repo root: ~64k entries in `target/`, more under `external-sources/quarto-cli/`), the command appears to hang for many seconds because the walker descends into `target/` and `external-sources/` (`is_excluded_component` excludes only `_*`, `.*`, and `node_modules`).\n\nThe walk's output is then thrown away — `classify_no_inputs` decides we have no project anyway.\n\nMeasured warm-cache cost in the q2 root: 0.3s. Cold-cache cost (or with `external-sources/quarto-cli/` fully populated): multi-second freeze.\n\n**Root cause:** `crates/quarto/src/commands/render.rs:331-346` (`classify_no_inputs`) calls `ProjectContext::discover(&cwd, ...)` before checking whether a real project exists. `ProjectContext::discover` does the upward `_quarto.yml` search (cheap), and on miss falls through to `discover_project_files` → `walk_qmd` (recursive cwd walk).\n\n**Fix:** Short-circuit `classify_no_inputs` — do the cheap upward `_quarto.yml`/`_quarto.yaml` ancestor search first, and only call `ProjectContext::discover` when a real project is known to exist. Inline the upward loop (six lines, only uses `runtime.path_exists`) rather than exporting a new helper for one caller.\n\n**Plan:** claude-notes/plans/2026-05-20-render-no-project-skip-walk.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T14:41:58.708780Z","created_by":"cscheid","updated_at":"2026-05-20T14:54:44.984036Z","closed_at":"2026-05-20T14:54:44.983847Z","close_reason":"Implemented in commit 58d2bd34.\n\nApproach: added `find_project_root_upward` (parsing-free\n`path_exists`-only ancestor walk) and made `classify_no_inputs` call\nit before delegating to `ProjectContext::discover`. The expensive\n`discover_project_files`/`walk_qmd` fall-through is now skipped\nentirely when no `_quarto.yml` ancestor exists.\n\nE2E timing (warm cache, debug build):\n q2 root: 0.318 s → 0.021 s (15×; cold-cache delta larger)\n /tmp/empty: unchanged (~6 ms)\n docs/: renders normally (unchanged)\n docs/<sub>/: renders normally (Test 3 e2e)\n\nError text byte-identical: \"No input given and no `_quarto.yml`\nfound at or above <cwd>\".\n\nRegression coverage: `classify_no_inputs_does_not_walk_cwd` asserts\n`dir_list_count == 0` via a `RecordingRuntime` wrapper around\n`NativeRuntime`. `classify_no_args_from_project_subdir_returns_full_project`\npins the cwd-inside-project case.\n\nVerification: `cargo nextest run -p quarto` 100/100 pass;\n`cargo xtask verify --skip-hub-build` all 12 steps green.\n\nOut-of-scope follow-up: bd-k4ahh tracks the symmetric `q2 render <dir>`\nwith-arguments path (lower priority, filed discovered-from).","labels":["cli","perf","render"]} +{"id":"bd-nqcv","title":"Glob support in project.nav-dependencies declarations","description":"Today `project.nav-dependencies` accepts a flat list of paths. Some users may want `project.nav-dependencies: [posts/*.qmd]` or `[chapters/**/*.qmd]`. v1 doesn't support globs (open question 5 in the Phase 8 plan). Wire glob expansion through DocumentProfileStage when populating the field. Defer until a real user need surfaces.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:51.182984Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:51.182984Z","created_by":"cscheid"}}} +{"id":"bd-ntnx","title":"Investigate tree-sitter grammar CRLF handling on Windows","description":"Cargo xtask verify step 4 (tree-sitter test) fails 5/451 pipe-table tests on Windows but passes on ubuntu-latest CI. Surfaced during PR 109 Windows verification on 2026-04-24. Root cause is ambiguous between a test-corpus CRLF issue (Scenario A, .gitattributes fix) and a grammar CRLF-handling bug (Scenario B, grammar.js fix). Must investigate before remediating — fixing the test would mask a real Windows-user bug if Scenario B applies. See design for reproducer and both scenarios. Related to bd-tjbr (sibling Windows dev-ergonomics work). Target branch feature/dev-setup-improvements or its own branch.","design":"Failure mode. cd crates/tree-sitter-qmd/tree-sitter-markdown && tree-sitter test reports 451 parses, 446 successful, 5 failed on Windows. All 5 failures are pipe-table tests: Example 201 (GFM), Pipe table can precede content (two variants), Pipe table can follow content, Pipe table with blank-line caption. file test/corpus/pipe_table.txt shows CRLF line terminators (426 CR paired with 426 LF). git ls-files --eol confirms i/lf w/crlf — stored as LF in the index, materialized as CRLF on Windows checkout via core.autocrlf=true. Same mechanism caused the quarto-doctemplate failures catalogued in q2-windows-verify-tests memory note.\n\nScenario A — test-corpus CRLF. Grammar is CRLF-agnostic. Parse trees for LF and CRLF inputs are identical. Tests fail only because the corpus .txt file embeds both the input text AND the expected S-expression AST, and the expected AST was written assuming LF parse output. Remediation is a scoped .gitattributes entry: crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/*.txt eol=lf. One line, followed by git rm --cached then git checkout to normalize existing files. Real Windows user qmd content continues to parse correctly regardless of line endings.\n\nScenario B — grammar CRLF bug. Grammar does not treat carriage-return-linefeed as a block boundary where it should. Real Windows user qmd content with CRLF endings parses incorrectly — pipe tables do not detect captions as separate blocks, block boundaries drift. This is a user-facing bug; only a Windows contributor running pampa against CRLF content catches it. Remediation is in crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js — typically adding carriage-return to newline character classes or the external scanner logic. .gitattributes would mask this bug instead of fixing it.\n\nReproducer. Two layers, both diagnostic. Layer 1 tests grammar.js directly via tree-sitter parse. Layer 2 tests the full pampa pipeline that real users hit. Fixtures are written into the tree-sitter-markdown directory so tree-sitter parse picks up the configured grammar without an init-config step.\n\nLayer 1 (grammar.js):\n\nprintf 'before\\r\\n\\r\\n| a | b |\\r\\n|---|---|\\r\\n| 1 | 2 |\\r\\n\\r\\nafter\\r\\n' > crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd\nprintf 'before\\n\\n| a | b |\\n|---|---|\\n| 1 | 2 |\\n\\nafter\\n' > crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd\ncd crates/tree-sitter-qmd/tree-sitter-markdown\ntree-sitter parse test-crlf.qmd > test-crlf.parse\ntree-sitter parse test-lf.qmd > test-lf.parse\ndiff test-crlf.parse test-lf.parse\n\nLayer 2 (pampa end-to-end):\n\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-crlf.qmd > pampa-crlf.out\ncargo run --quiet -p pampa --bin pampa -- crates/tree-sitter-qmd/tree-sitter-markdown/test-lf.qmd > pampa-lf.out\ndiff pampa-crlf.out pampa-lf.out\n\nNotes on the prior reproducer in this design field. pampa has no parse subcommand — it is cargo run -p pampa --bin pampa -- input.qmd, with default -f markdown -t native. Git Bash /tmp resolves to %TEMP% but native Windows binaries resolve /tmp to C:\\tmp\\, so the previous version would have created files Git Bash could not find later. Use repo-local paths.\n\nIf both diffs are empty then Scenario A applies. If either diff is non-empty then Scenario B applies. Layer 2 also tells us whether the bug propagates past pampa's input handling into the Pandoc AST that real users render from.\n\nBroader git cross-platform context. The 2026 consensus is that most projects do not need .gitattributes. core.autocrlf=true plus LF-tolerant tooling handles 99 percent of cross-platform cases. quarto-cli is an example — no .gitattributes and no CRLF-related failures. .gitattributes is for files that must be a specific line ending (shell scripts, batch files), binary files misdetected as text, and whitespace-sensitive test corpora where the consuming tool is itself correct. Over-restrictive patterns like * text=auto eol=lf force LF everywhere and are worse for cross-platform dev than no config. The target for this project is minimal, scoped .gitattributes only where the test harness cannot be fixed — and only in Scenario A.\n\nOut of scope. Broader .gitattributes sweep for the whole repo. Fixing the 8 quarto-doctemplate CRLF failures already catalogued in q2-windows-verify-tests (separate work). Tree-sitter CLI changes (upstream, not ours).","acceptance_criteria":"Reproducer runs and classifies failure as Scenario A or Scenario B. If Scenario A then .gitattributes entry added for test/corpus/*.txt and cargo xtask verify step 4 passes on Windows. If Scenario B then follow-up beads issue filed for grammar.js fix at higher priority and this investigation issue closes with evidence. q2-windows-verify-tests memory note updated with resolution and link to fix PR or follow-up issue. No regression in CI — tree-sitter tests continue to pass on Linux.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T16:38:18.426543400Z","created_by":"cderv","updated_at":"2026-04-27T14:29:38.899054500Z","closed_at":"2026-04-27T14:29:38.898439400Z","close_reason":"Scenario B classified. Follow-up bd-0gsj filed at P1 for the grammar.js fix; full evidence in that issue's design and in the closing comment here.","labels":["tree-sitter","windows"],"dependencies":{"bd-tjbr:related":{"depends_on_id":"bd-tjbr","type":"related","created_at":"2026-04-24T16:39:17.513779500Z","created_by":"cderv"}},"comments":{"c-d152rz75":{"id":"c-d152rz75","author":"cderv","created_at":"2026-04-27T14:28:37Z","text":"Investigation complete. Result: Scenario B (real grammar CRLF bug). Layer 1 (tree-sitter parse on grammar.js) showed pipe_table extents diverge between CRLF and LF inputs — CRLF case absorbs the trailing paragraph as a malformed table row. Layer 2 (cargo run -p pampa) confirmed pampa does not normalize line endings before parsing, so the bug propagates to the Pandoc AST that drives every output format. Real Windows users with default core.autocrlf=true and the common pattern of a pipe table followed by content render structurally wrong documents. .gitattributes alone would have masked this.\n\nFollow-up filed at higher priority: bd-0gsj — Fix CRLF handling in tree-sitter-qmd grammar.js for pipe tables (P1, bug). Full evidence and reproducer carried over to bd-0gsj design field."}}} +{"id":"bd-nv5c","title":"Opt-in Pass-2 cache for filter-pure projects","description":"Phase 8 deliberately skips Pass-2 caching: filters/engines may have side effects, so caching past them is unsafe by default. A future user-opt-in surface (per-project YAML key like `pass2-cache: trusted`) could enable Pass-2 output caching for users who assert filter purity. Out of website-epic scope; lives in its own design discussion. See claude-notes/plans/2026-04-27-websites-phase-8.md §'Why no Pass-2 cache'.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:35.786086Z","dependencies":{"bd-0tr6:related":{"depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:35.786086Z","created_by":"cscheid"}}} +{"id":"bd-nvlxn","title":"Error-docs foundation: directory, front-matter, template, index","description":"Set up the docs/errors/ section so subsequent content + tooling work has a stable target.\n\nIncludes:\n- Directory layout (docs/errors/Q-X-Y.qmd, flat) and rationale doc\n- Front-matter schema: code, subsystem, title, description, status (draft|stub|complete|deprecated), since\n- Page template (sections: What this means / Why this happens / How to fix / Example / Related)\n- docs/errors/index.qmd as a Quarto listing page grouped by subsystem\n- _quarto.yml navbar + sidebar wiring\n- A README.md under docs/errors/ documenting the conventions\n- One worked example page (e.g. Q-1-1) at status=complete to anchor the template\n\nPlan: claude-notes/plans/2026-05-22-error-docs-foundation.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-22T17:09:28.478856Z","created_by":"cscheid","updated_at":"2026-05-22T19:25:25.908365Z","closed_at":"2026-05-22T19:25:25.908241Z","close_reason":"Foundation scaffold landed via merge into main: docs/errors/ directory with subsystem subdirs, README + front-matter schema + status enum + page template + cross-reference convention, listing index, Q-1-10 seed page at status: complete (chosen over the planned Q-1-1 because Q-1-1 has no production emit site), navbar/sidebar wiring, and the docs_url subsystem-segment rewrite across all 133 catalog entries. Verified end-to-end via 'cargo run --bin q2 -- render docs/' and full 'cargo xtask verify'. Tooling (bd-8otua) and content (bd-an6z4) now unblocked.","labels":["documentation","error-reporting","website"],"dependencies":{"bd-94x8a:parent-child":{"depends_on_id":"bd-94x8a","type":"parent-child","created_at":"2026-05-22T17:09:28.478856Z","created_by":"cscheid"}}} +{"id":"bd-nwun","title":"Phase 4 — Page navigation (prev/next)","description":"Implement bottom-of-page prev/next navigation strip for website projects. Mirrors Q1 nextAndPrevious algorithm. See claude-notes/plans/2026-04-24-websites-phase-4.md. Decisions 1-9 confirmed 2026-04-24. Implementation committed as 4a59a9dd on feature/websites.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-24T22:47:44.938470Z","created_by":"cscheid","updated_at":"2026-04-24T22:48:18.483814Z","closed_at":"2026-04-24T22:48:18.483357Z","close_reason":"Implemented and shipped on feature/websites in commit 4a59a9dd. 48 new tests pass; cargo xtask verify --skip-hub-tests clean. Five follow-ups filed: bd-q1pe, bd-xwq8, bd-q6ky, bd-bobp, bd-nf50.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-24T22:47:48.386065Z","created_by":"cscheid"}}} +{"id":"bd-nwyp","title":"Audit listing config parsing for PandocInlines / yaml-markdown-syntax-error fallthrough","description":"Discovered while writing L5 (bd-5vsr) snapshot test #33. Quarto YAML often parses bare frontmatter strings as PandocInlines (e.g. when a glob like 'posts/*.qmd' confuses the markdown sublexer and lands as a Span carrying the 'yaml-markdown-syntax-error' class). 'parse_contents' (config.rs:572) was matching only Scalar/Glob/Array variants, so 'contents: \"posts/*.qmd\"' silently parsed as an empty Vec, and apply_type_defaults then injected the default '*.qmd' glob — making cross-directory listing globs invisible at runtime even though the unit tests passed.\n\nFix in L5: route 'parse_contents' through 'as_plain_text' first, mirroring 'parse_listings' top-level shorthand handling. Two new unit tests lock the behavior (contents_pandoc_inlines_string_parses_as_glob, contents_array_with_pandoc_inlines_items_parses).\n\nAudit asks: what other listing-config parser branches in config.rs are still vulnerable to the same trap? Likely candidates from a quick read: parse_filter_list, parse_string_list, parse_sort, parse_field_types — any branch that matches on ConfigValueKind::Scalar(Yaml::String(_)) directly without a PandocInlines fallthrough should be reviewed and either rewritten to use as_plain_text first or have explicit PandocInlines handling added. Add unit-test coverage for each PandocInlines path discovered.\n\nOut of scope but related: this is also a signal that the YAML parser's 'PandocInlines wrapping for any string with markdown-special chars' choice imposes a hidden tax on every config consumer in the tree. A broader design pass on whether such strings should be unwrapped before reaching consumers (or whether consumers should always use as_plain_text by convention) would be worth doing.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-07T15:26:48.683892Z","created_by":"cscheid","updated_at":"2026-05-07T15:26:48.683892Z","dependencies":{"bd-5vsr:discovered-from":{"depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T15:26:48.683892Z","created_by":"cscheid"}}} +{"id":"bd-nxe8","title":"Hub-client: refactor color scheme to auto/dark/light with browser detection","description":"Replace the binary light/dark toggle in ProjectSelector with a three-way color scheme preference (auto/dark/light). Auto mode follows prefers-color-scheme. Persisted via preferences service. Monaco editor follows the setting. Preview documents are out of scope. Plan: claude-notes/plans/2026-04-02-hub-client-color-scheme.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-02T21:21:58.194813Z","created_by":"cscheid","updated_at":"2026-04-02T21:21:58.194813Z"} +{"id":"bd-nxslt","title":"q2 preview: code cells render unhighlighted; include CodeHighlightStage + teach React CodeBlock to read data-hl-spans","description":"q2 render produces <span class=\"hl-function\">cat</span><span class=\"hl-string\">"Hello, world"</span>... for the example R cell; q2 preview shows the same cell as plain <pre><code class=\"r cell-code\">cat(\"Hello, world\")</code></pre>. Root cause: CodeHighlightStage was excluded from the q2-preview pipeline (Q2_PREVIEW_STAGE_EXCLUDED) even though it's AST-level (annotates data-hl-spans on the CodeBlock node — does not emit HTML). Two-part fix: (1) remove from the exclusion list so the AST nodes get annotated; (2) update React CodeBlock component (ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx) to read data-hl-spans, decode via the JSON triple-array format, and emit nested <span class=\"hl-CAP\">tokens</span> mirroring the HTML writer's behavior in crates/pampa/src/writers/html.rs:write_highlighted_body. Wire format: data-hl-spans=\"[[start_byte, end_byte, capture_name], ...]\". Capture-to-class: replace '.' with '-' (function.builtin → hl-function-builtin). WASM safety: quarto_highlight::annotate_pandoc and built-in grammars (including r) are WASM-safe; only user-grammars are native-only and they're not in scope here.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-18T16:43:57.892743Z","created_by":"cscheid","updated_at":"2026-05-18T16:51:36.354837Z","closed_at":"2026-05-18T16:51:36.354701Z","close_reason":"Implementation complete: code-highlight now runs in the q2-preview pipeline and the React CodeBlock component reads data-hl-spans + emits the same nested hl-* span markup as q2 render. Verified end-to-end on fixture website: R cell shows <span class='hl-function'>cat</span><span class='hl-punctuation-bracket'>(</span><span class='hl-string'>\"Hello, world\"</span>...</span>. 4 new SPA integration tests; 1 new Rust pipeline-inclusion test; cargo xtask verify 12/12 green.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T16:43:57.892743Z","created_by":"cscheid"}}} +{"id":"bd-o505","title":"Wire nav-config-hash file write at end of project render","description":"Sub-phase 8.1 deferred writing the `<project>/.quarto/cache/nav-config-hash` file: 'nav_config_hash deferred — Phase 8 does not act on it per Decision 8; will land if a future refinement needs it.' The file is created when --clean-cache writes any state expectation, but no run actually produces it. Land alongside bd-par3 (smart nav-config-change detection) which is the consumer. See claude-notes/plans/2026-04-27-websites-phase-8.md §Decision 8 + Sub-phase 8.1.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid","updated_at":"2026-04-28T00:43:00.254499Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid"},"bd-par3:related":{"depends_on_id":"bd-par3","type":"related","created_at":"2026-04-28T00:43:00.254499Z","created_by":"cscheid"}}} +{"id":"bd-o5wd","title":"Phase A.3: Fill in q2-preview-spa/src/main.tsx","description":"Replace the bd-hfjj Phase 6 placeholder with a real preview host: samod connect, initWasm, read indexDocId from window.location.hash, drive <Q2PreviewIframe> off automerge state. <PreviewApp> stays local to q2-preview-spa. Engine-less. Blocked by A.0 (bridge package). See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.3.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-13T16:53:28.085848Z","created_by":"cscheid","updated_at":"2026-05-13T18:02:48.368546Z","closed_at":"2026-05-13T18:02:48.368403Z","close_reason":"Phase A.3 (q2-preview-spa main.tsx fill-in) landed on branch beads/bd-o5wd-phase-a3-fill-q2 (commit c9923868). PreviewApp boots through @quarto/preview-runtime + renders via Q2PreviewIframe; 3/3 integration tests green; SPA prod build green; bundle audit clean (zero editor symbols). cargo xtask verify 11/11.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:28.085848Z","created_by":"cscheid"}}} +{"id":"bd-o8pr","title":"Project resources: user- and engine-declared additional files","description":"Phase 0: complete (failing E2E tests written).\nPhase 1: complete -- ProjectConfig.resources, DocumentProfile v3 with resources, glob expansion, out-of-project guard, post-render copy in orchestrator. E2E verified with q2 render CLI.\n\nRemaining:\nPhase 2: engine channel + ResourceReportStage\nPhase 3: quarto.doc.add_resource Lua API\nPhase 4: render manifest + publish integration\nPhase 5: docs\n\nPlan: claude-notes/plans/2026-05-03-project-resources.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-03T18:52:39.439143Z","created_by":"cscheid","updated_at":"2026-05-03T20:04:42.900682Z","closed_at":"2026-05-03T20:04:42.900542Z","close_reason":"All 5 phases complete; feature verified end-to-end","dependencies":{"bd-k9i1:related":{"depends_on_id":"bd-k9i1","type":"related","created_at":"2026-05-03T18:52:50.754880Z","created_by":"cscheid"},"bd-t3ny:related":{"depends_on_id":"bd-t3ny","type":"related","created_at":"2026-05-03T18:52:50.851218Z","created_by":"cscheid"}}} +{"id":"bd-o90m","title":"L9 — RSS feeds","description":"New write_rss_feeds step in WebsiteProjectType::post_render. One feed per listing host opting in via feed: true|{...}. Output: <output_dir>/<host-stem>.xml plus link rel=alternate in host's <head>. Three Q1 type modes: full, partial (reuse L7's readRenderedContents), metadata (profile only). Per-category sub-feeds. Templates as embedded doctemplate (feed/preamble, feed/item, feed/postamble) using L4's escape_xml pipe. Gated on website.site-url. See claude-notes/plans/2026-05-05-listings-epic.md §L9.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:26.344489Z","closed_at":"2026-05-08T17:34:26.344345Z","close_reason":"L9 implementation complete on branch beads/bd-o90m-listings-rss-feeds. Phase 1: diagnostics + imagesize dep (8b7a9286). Phase 2: feed binding (16ece34c). Phase 3: ListingFeedStageTransform (f4c241cf). Phase 4: ListingFeedLinkTransform (d2f79ccd). Phase 5: reader extension (33abdb8a). Phase 6: complete_staged_feeds post-render (4cdef213). Phase 7: end-to-end CLI verification (0bdd219e). 60 new tests across binding (32) + stage (10) + link_inject (6) + reader_ext (18) + complete (9) + catalog (1) = 76 tests added (workspace 1820 → 1896 in quarto-core). cargo xtask verify (full incl WASM hub-client) clean. Awaiting user merge approval. Follow-ups filed: bd-yd4q (math), bd-ir8n (highlight class maps), bd-4ho9 (W3C validator), bd-eips (format.metadata.description fallback), bd-udlt (title placeholder), bd-2vl0 (Q-12-15 dedup), bd-i4wv (generator version), bd-mae2 (custom feed templates), bd-sh4h (Atom 1.0), bd-d8go (date_format pipe), bd-varx (hoist append_to_rendered_header), bd-3sa5 (HTML-aware truncation), bd-xhvs (CDATA ]]> escape).","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid"},"bd-qf7r:blocks":{"depends_on_id":"bd-qf7r","type":"blocks","created_at":"2026-05-05T19:53:59.725810Z","created_by":"cscheid"}}} +{"id":"bd-obcw","title":"Add publish.<provider>.* keys to YAML validation schema","description":"Once Quarto 2 has YAML validation infrastructure for _quarto.yml, add the publish.<provider>.* schema introduced by bd-t3ny.\n\nInitial keys (from bd-t3ny Phase 1):\n- publish.gh-pages.wait: boolean (default true) — whether to wait for the deployment to be live before declaring success.\n\nFuture keys (as providers land):\n- publish.<provider>.<provider-specific-config> — per-provider deployment configuration (custom domains, env, etc.).\n\nUntil this lands, quarto-publish does best-effort parsing with explicit error messages on malformed shapes — no schema validation, no IDE autocomplete.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md (see '_quarto.yml schema: publish.<provider>.*' section)","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-03T14:26:11.088052Z","created_by":"cscheid","updated_at":"2026-05-03T14:26:11.088052Z","dependencies":{"bd-t3ny:discovered-from":{"depends_on_id":"bd-t3ny","type":"discovered-from","created_at":"2026-05-03T14:26:11.088052Z","created_by":"cscheid"}}} +{"id":"bd-ochm","title":"Multi-format favicon variants (apple-touch-icon, sizes)","description":"Phase 7 emits a single <link rel=\"icon\"> tag. Some sites want apple-touch-icon, multiple sizes. Treat as enrichment of WebsiteFaviconTransform once a real consumer surfaces. Originating phase: bd-b9mz.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.359523Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.359523Z","created_by":"cscheid"}}} +{"id":"bd-ojtq","title":"xtask create-worktree: auto-detect integration branch (or warn) instead of defaulting to main","description":"Today `cargo xtask create-worktree <bd-id>` defaults `--base main`. For sub-task work inside an active epic (the dominant use case for create-worktree per .claude/rules/worktrees.md), main is almost always the wrong base — the convention is to branch off `feature/<epic-name>`. Silent default leads to a worktree at the wrong base that must be `git reset --hard`ed after creation, which is what happened during bd-kw93.1 setup on 2026-05-14.\n\nOptions:\n1. Auto-detect: if the beads issue has a parent-child to an epic whose branch can be inferred (e.g. the epic title or labels record it), use that branch as the base.\n2. Warn-on-default: when `--base` is not passed and the issue has a parent epic, print 'Using default base `main`; sub-tasks of <epic-id> typically branch off feature/<name>. Re-run with --base if needed.' and prompt or exit.\n3. Make `--base` required when the issue is a sub-task (has parent-child to a non-closed epic).\n\nOption 2 is the lowest-friction nudge. Option 1 needs a way to recover the integration branch name from the epic (could be a beads label, an external_ref, or just a convention scan).\n\nRelated friction: `switch-task` already does the right thing for sequential sub-task work but is under-discoverable when you've reached for create-worktree first. Cross-reference in the rules file or in xtask help text might help.\n\nAcceptance: pick one option, ship, no longer silently defaults to main when context says otherwise.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-14T14:40:07.105617Z","created_by":"cscheid","updated_at":"2026-05-14T20:03:15.368560Z","closed_at":"2026-05-14T20:03:15.368432Z","close_reason":"fetch_beads_metadata now reports parent_epic from the dependencies array; create-worktree warns when --base is at its default and the issue has an open parent epic. 5 new unit tests + 3-case binary smoke (warning fires; --base main silences; no parent = no warning). Workspace nextest 8864/8864. Merged to main as commit 28f1a18b.","dependencies":{"bd-kw93.1:discovered-from":{"depends_on_id":"bd-kw93.1","type":"discovered-from","created_at":"2026-05-14T14:40:07.105617Z","created_by":"cscheid"}}} +{"id":"bd-ooleh","title":"Print a one-line errors/warnings summary at the end of q2 render","description":"After a q2 render (especially a large project render with lots of scrolled-past output), print a single, formatted line summarizing the TOTAL number of errors and warnings the process generated. Counting logic lives in quarto-core (ProjectRenderSummary), formatting in crates/quarto/src/commands/render.rs near the existing render_summary_line. Plan: claude-notes/plans/2026-06-02-render-error-warning-summary.md. Design open for iteration before implementation.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-06-02T13:23:24.374653Z","created_by":"cscheid","updated_at":"2026-06-02T14:21:29.621260Z","closed_at":"2026-06-02T14:21:29.621109Z","close_reason":"Implemented + verified: one-line error/warning summary after q2 render. quarto-core DiagnosticCounts/diagnostic_counts (7 tests), quarto render formatting+wiring (8 tests), e2e through the binary, clean cargo xtask verify 9515/9515."} +{"id":"bd-oqbpi","title":"Author error-docs pages for listing subsystem (16 codes)","description":"Author stub-quality pages for all 16 Q-*-* listing subsystem error codes under docs/errors/listing/. Follow the template established in docs/errors/yaml/Q-1-10.qmd and docs/errors/README.md. Stub quality minimum: What this means / Why this happens / How to fix sections. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T20:35:51.314678Z","created_by":"cscheid","updated_at":"2026-05-24T20:41:36.047554Z","closed_at":"2026-05-24T20:41:36.047098Z"} +{"id":"bd-otmqu","title":"Listing sort: allow sorting by arbitrary front-matter fields, not just built-ins","description":"Q2's listing sort (crates/quarto-core/src/project/listing/sort.rs:117) only accepts a fixed set of built-in fields: title, subtitle, description, author, date, date-modified, image, image-alt, filename, path, output-href, reading-time, word-count.\n\nQ1 supports sorting by arbitrary front-matter field names. Without this, a listing of pages with custom front-matter (e.g. error-doc pages with 'code', 'subsystem', 'status' fields) can only sort by the built-ins — losing the natural sort axes the document author defined.\n\nRepro: any qmd with 'sort: code' (where 'code' is a front-matter field) emits 'Warning [Q-12-3]: Unknown sort field code; values will compare as equal.'\n\nWorkaround: sort by 'filename' if the filename encodes the sort key. Brittle but works for our error-doc pages where filenames are e.g. Q-1-10.qmd (sorts ~mostly correctly, though alphanumeric not numeric: Q-1-10 comes before Q-1-2).\n\nDiscovered while authoring docs/errors/index.qmd as part of bd-nvlxn (error-docs foundation).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-22T19:16:29.253170Z","created_by":"cscheid","updated_at":"2026-05-22T19:16:29.253170Z","labels":["listing"],"dependencies":{"bd-nvlxn:discovered-from":{"depends_on_id":"bd-nvlxn","type":"discovered-from","created_at":"2026-05-22T19:16:29.253170Z","created_by":"cscheid"}}} +{"id":"bd-p2tx","title":"Support <#foo> anchor shorthand notation in qmd","description":"Add support for <#foo> as shorthand for [foo](#foo){.anchor} in qmd reader and writer. Reader: intercept html_element nodes matching <#id> pattern and convert to Link with .anchor class. Writer: detect matching Link nodes and emit <#id> shorthand. Plan: claude-notes/plans/2026-02-10-anchor-shorthand.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-10T21:35:30.243155Z","created_by":"cscheid","updated_at":"2026-02-10T22:10:45.943407Z","closed_at":"2026-02-10T22:10:45.943379Z","close_reason":"Implemented anchor shorthand <#foo> in reader and writer. All 6394 workspace tests pass."} +{"id":"bd-p4sc","title":"Body-link rewriting: draft-mode visibility","description":"When DocumentProfile.draft && draft-mode != 'visible', replace the <a> with its inner content rather than just rewriting the href. Q1 parity. Requires draft-mode YAML config first (no Q2 surface today). Originally deferred from Phase 6 (bd-v30t).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid","updated_at":"2026-04-27T13:36:31.432468Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:36:31.432468Z","created_by":"cscheid"}}} +{"id":"bd-par3","title":"Mode B: smart nav-config-change detection","description":"Today Mode B (`quarto render foo.qmd`) renders exactly the user-named subset, regardless of whether _quarto.yml's navbar/sidebar/footer config changed since the last run. Decision 8 stores a nav-config-hash sentinel for this exact use case but Phase 8 doesn't act on it. Follow-up: when nav-config-hash differs from the cached value, also include any sidebar members of the targets in the augmented render set (their rendered HTML embeds nav HTML that may now be stale). See claude-notes/plans/2026-04-27-websites-phase-8.md §Decision 8.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:31.505676Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:31.505676Z","created_by":"cscheid"}}} +{"id":"bd-pdwr","title":"Parallel per-file rendering in ProjectPipeline (rayon + pollster)","description":"Phase 1 ships ProjectPipeline as sequential. The plan §Parallelism readiness outlines the intended path: rayon + per-worker pollster::block_on, leaving the async stage trait as ?Send. Each thread drives one file's pipeline on a single-threaded executor local to it; the main thread builds ProjectIndex between passes. Requires confirming NativeRuntime: Send + Sync and adding a where-bound to the orchestrator. Benchmark before + after on a >=10-file fixture to validate speedup.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T01:05:40.090481Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:40.090481Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:40.090481Z","created_by":"cscheid"}}} +{"id":"bd-pf63","title":"Phase B.3: Verify cross-doc + include-shortcode edits propagate to preview","description":"After B.1 lands, verify the existing onFileContent → contentTick → render path covers cross-doc edges and include shortcodes correctly. Likely zero code changes; the work is empirical: build a fixture with an {{< include x.qmd >}} relationship, edit x.qmd, assert index re-renders.\n\nAdd a Playwright case to q2-preview-spa/e2e/. Re-render filtering against the dep graph (only re-render on edges) is an optimisation deferred to Phase D.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.3.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T19:34:52.827802Z","created_by":"cscheid","updated_at":"2026-05-13T20:59:06.765257Z","closed_at":"2026-05-13T20:59:06.765059Z","close_reason":"Phase B.3 complete; zero production-code changes — new Playwright spec at q2-preview-spa/e2e/include-shortcode.spec.ts pins the cross-doc include propagation. See commit ec72abc8 on beads/bd-pf63-phase-b3-verify-cross.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T19:34:52.827802Z","created_by":"cscheid"},"bd-z529:blocks":{"depends_on_id":"bd-z529","type":"blocks","created_at":"2026-05-13T19:34:58.241393Z","created_by":"cscheid"}}} +{"id":"bd-pgczr","title":"Migrate theme-config error to structured DiagnosticMessage","description":"Convert SassError::InvalidThemeConfig flow so it reaches the CLI as a DiagnosticMessage with code (Q-14-1 in proposed new 'theme' subsystem), SourceInfo pointing at the offending YAML in _quarto.yml, and ariadne-rendered output — instead of the current plain 'error: <path>: Invalid theme configuration: …' line.\n\nToday the source_info on the offending ConfigValue is discarded by .to_string() at CompileThemeCssStage's map_err (crates/quarto-core/src/stage/stages/compile_theme_css.rs:272-273), and file_failure_from_error only extracts diagnostics for QuartoError::Parse.\n\nThis is one of two children of the theme-diagnostic overhaul epic. Sibling issue handles cross-page coalescing.\n\nPlan: claude-notes/plans/2026-05-22-theme-diagnostic-structured.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T13:43:03.443230Z","created_by":"cscheid","updated_at":"2026-05-22T14:54:55.630083Z","closed_at":"2026-05-22T14:54:55.629887Z","close_reason":"Implemented in branch beads/bd-pgczr-migrate-theme-config-error. Theme errors now render as [Q-14-1] ariadne diagnostics with source spans pointing into _quarto.yml. Verified end-to-end against external-sources/quarto-web (345 structured emissions, 0 legacy plain-text). Repetition is bd-9hlja's domain.","labels":["diagnostics","sass","theme"],"dependencies":{"bd-l26u6:parent-child":{"depends_on_id":"bd-l26u6","type":"parent-child","created_at":"2026-05-22T13:43:03.443230Z","created_by":"cscheid"}}} +{"id":"bd-picv","title":"Fix Windows path-separator assumptions in pampa quarto_api path tests","description":"On Windows, ~10 tests in crates/pampa/src/lua/quarto_api.rs (test_normalize_path_simple, test_normalize_path_with_dots, test_normalize_path_with_dotdot, test_normalize_path_with_dotdot_at_root, test_normalize_path_relative, test_normalize_path_relative_with_dotdot, test_quarto_utils_resolve_path_relative, test_quarto_utils_resolve_path_relative_with_subdir, test_quarto_utils_resolve_path_with_dotdot, test_script_dir_stack_resolve_path_uses_top) fail because expected paths are hardcoded with forward slashes ('/some/extension/dir/data.json') while the Windows implementation joins with backslashes via Path::join. Different category from bd-3pe8 (PR #95) which fixed Lua source-string path interpolation; these are output-comparison failures. Need to decide: (a) normalize quarto.utils.resolve_path output to forward slashes in production (matches quarto-cli pathWithForwardSlashes convention), or (b) write tests with platform-correct expectations using PathBuf::join. Surfaced 2026-04-28 while running cargo nextest -p pampa on Windows. Same set of tests run twice (library + bin/pampa integration), so 18-20 visible failures from one root cause.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-28T13:07:09.316426300Z","created_by":"cderv","updated_at":"2026-04-28T13:07:56.882989800Z","labels":["lua","pampa","windows"],"dependencies":{"bd-3pe8:related":{"depends_on_id":"bd-3pe8","type":"related","created_at":"2026-04-28T13:07:56.882332200Z","created_by":"cderv"}}} +{"id":"bd-povv","title":"Per-project capture cache for cross-session reuse","description":"Phase C.7 (bd-kw93.7) shipped the per-doc capture filesystem cache in <data_dir>/captures/ — the same tempdir that gets deleted when q2 preview exits. So closing and re-opening preview against the same project always misses the cache, even though the inputs are bit-for-bit identical.\n\nA per-project cache location (e.g. <project_root>/.q2/captures/, ignored by .gitignore convention) would unlock cross-session reuse. The cache key derivation (sha256 of canonical input_qmd) is already content-addressed and survives across sessions — only the directory choice changes.\n\nConsiderations:\n- Where: <project_root>/.q2/captures/? Some equivalent under XDG_CACHE_HOME keyed on project root? Discuss before implementing.\n- Cleanup: with content-hashed keys, old entries pile up across edits. A simple LRU sweep, or just letting the OS / git ignore handle it.\n- Gitignore: cache should not be committed. Either add a .q2/.gitignore on first write or document.\n- Concurrency: two q2 preview instances against the same project would race on the cache. Write atomicity is already last-writer-wins (atomic rename); concurrent readers handle a missing file gracefully.\n- Sandboxing: the existing loopback-only posture still applies.\n\nSee plan §C.7 'Open follow-up'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-14T17:35:41.522863Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:41.522863Z","dependencies":{"bd-kw93.7:discovered-from":{"depends_on_id":"bd-kw93.7","type":"discovered-from","created_at":"2026-05-14T17:35:41.522863Z","created_by":"cscheid"}}} +{"id":"bd-pp89","title":"Native glob expansion for CLI render args","description":"Phase 8.4 ships with shell-only glob expansion: `quarto render *.qmd` works on Unix shells; on Windows or with quoted args it doesn't. Phase 1's discovery.rs already has expand_patterns helper for project.render globs. Extend commands::render::classify_inputs to recognize unexpanded glob patterns and route through that helper. Cross-platform parity, matches Q1 behavior.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid","updated_at":"2026-04-28T00:42:39.215996Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid"},"bd-fegm:discovered-from":{"depends_on_id":"bd-fegm","type":"discovered-from","created_at":"2026-04-28T00:42:39.215996Z","created_by":"cscheid"}}} +{"id":"bd-pphv","title":"Sitemap incremental merge (read-existing/update/write)","description":"Phase 7 ships fresh-write sitemap only. Phase 8's incremental rebuild needs to merge: read existing sitemap.xml, patch entries for re-rendered files, preserve others. Q1 reference: external-sources/quarto-cli/src/project/types/website/website-sitemap.ts lines 113-134 (readSitemap + merge logic). Originating phase: bd-b9mz.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid","updated_at":"2026-04-27T23:37:18.998907Z","closed_at":"2026-04-27T23:37:18.998535Z","close_reason":"Sitemap incremental merge implemented in Phase 8 sub-phase 8.3. write_sitemap reads existing _site/sitemap.xml, parses out loc→lastmod, refreshes entries for pages rendered this run, preserves entries for skipped pages. Falls through to fresh-write on parse failure. 6 unit tests + 1 integration test (mode_b_sitemap_preserves_untouched_entries_lastmod) verify the merge contract.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:21.850028Z","created_by":"cscheid"}}} +{"id":"bd-q1fyw","title":"Wire _brand.yml into the comprehensive YAML validator (once it exists)","description":"Phase 5 of the brand plan deferred schema validation in favor of serde deny_unknown_fields. When quarto-yaml-validation grows a comprehensive schema framework, port the brand-* schemas from external-sources/quarto-cli/src/resources/schema/definitions.yml and wire them in.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-21T02:31:31.142079Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.142079Z"} +{"id":"bd-q1pe","title":"Emit <link rel=\"prev/next\"> meta tags for page-navigation","description":"Q1 emits <link rel='prev'> / <link rel='next'> in <head> when page-navigation is active, for SEO and browser preload. Phase 4 deferred this (Decision 7) because it touches the HTML render config + template <head> slot, tangential to the page-nav feature itself. Add when convenient.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:54.468085Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:54.468085Z","dependencies":{"bd-nwun:discovered-from":{"depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:54.468085Z","created_by":"cscheid"}}} +{"id":"bd-q30j","title":"Port automerge-inspector into hub-client as a debugging view","description":"Port external-sources/automerge-inspector into hub-client as a second Vite entry point (debug.html). Must work with the auth-enabled sync server by sharing hub-client's HttpOnly cookie over same-origin /ws proxy. Read-only document inspection + protocol traffic log. 'Out of general sight' — no link from main UI. See plan at claude-notes/plans/2026-04-16-hub-client-automerge-debugger.md for full design, open questions, and phased work items.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-16T15:54:33.232032Z","created_by":"cscheid","updated_at":"2026-04-16T15:54:33.232032Z","labels":["automerge","debugging","hub-client"]} +{"id":"bd-q6ed","title":"Display math inside a blockquote retains '> ' continuation prefix in content (issue #181)","description":"Tree-sitter grammar rule `pandoc_display_math` (crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js:367) matches its body as a single regex `/([^$]|[$][^$]|\\\\$)+/` between the two `$$` delimiters. When the math block is inside a blockquote, the interior `> ` block-continuation markers are never consumed by the grammar's `block_continuation` machinery; they end up verbatim inside the captured node text and then inside `Math.text` (see crates/pampa/src/pandoc/treesitter.rs:502-513). The qmd writer then correctly re-prefixes every line of the math body with `> ` when emitting it inside a blockquote, producing `> > p = q` and adding one more `> ` level on each round trip.\n\nFix is at the grammar level: make `pandoc_display_math` line-structured (loop over `$._newline | _math_line`) the way `pandoc_code_block` already is (grammar.js:828, with `_newline` consuming `block_continuation` at grammar.js:886). The writer is already correct; do not change it.\n\nTriage doc and minimal repros live at claude-notes/issue-reports/181/ on branch issue-181. See triage.md there for full evidence including CST output and a contrasting fenced-code-in-blockquote case that parses cleanly.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-12T17:34:18.793641Z","created_by":"cscheid","updated_at":"2026-05-12T17:34:18.793641Z"} +{"id":"bd-q6ky","title":"Plain-text aria-label projection for rich page-nav titles","description":"When DocumentProfile.title gains inline-markup support, project to plain text for aria-label and title attributes on the prev/next anchors. Phase 4 currently uses the title verbatim, which is fine while titles are plain String.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:59.865423Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:59.865423Z","dependencies":{"bd-nwun:discovered-from":{"depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:59.865423Z","created_by":"cscheid"}}} +{"id":"bd-qabnx","title":"Phase 1 — Design lock-in (hub-mcp device flow)","description":"Record-only phase. Captures the immutable v1 design decisions from empirical verification of Google's device-flow endpoints on 2026-05-19.\n\nNo code; closing condition is the plan's Phase 1 section being merged and the epic + sub-issues being filed.\n\nPlan §Phase 1: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-20T14:26:51.454050Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:18.060790Z","closed_at":"2026-05-20T21:22:18.060745Z","close_reason":"Design lock-in is recorded in plan §Phase 1 and replayed in the Phase 2 implementation. No further work.","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:26:51.454050Z","created_by":"shikokuchuo"}}} +{"id":"bd-qawx","title":"cargo xtask create-worktree DWIMs remote-tracking branch as base, doesn't create requested branch","description":"Symptom: 'cargo xtask create-worktree --issue 152 --base bugfix/issue-184' printed 'Branch: issue-152' but the worktree was actually checked out on a freshly-created local 'bugfix/issue-184' branch (tracking origin/bugfix/issue-184). No 'issue-152' branch was ever created; 'git rev-parse refs/heads/issue-152' returns exit 1 immediately after the xtask reports success. Reflog confirms.\n\nReproduction (best-effort, from this session):\n- main worktree at .worktrees/issue-184/ already exists on a local 'issue-184' branch\n- remote bugfix/issue-184 exists; no local bugfix/issue-184 yet\n- cargo xtask create-worktree --issue 152 --base bugfix/issue-184\n- Result: .git/worktrees/issue-152/HEAD reads 'ref: refs/heads/bugfix/issue-184'\n- Expected: HEAD reads 'ref: refs/heads/issue-152'\n\nLikely cause: the underlying 'git worktree add -b issue-152 .worktrees/issue-152 bugfix/issue-184' invocation may interact poorly with git's DWIM when the start-point is a remote-tracking branch. Worth a small repro test in crates/xtask/.\n\nRecovered in-place via 'git checkout -b issue-152' inside the worktree (user-approved during triage). The xtask still claimed success in stdout, so the bug is silent — that's the most user-hostile part.\n\nDiscovered during: triage of issue #152 / bd-j4fe.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-14T19:08:20.229932Z","created_by":"cscheid","updated_at":"2026-05-14T19:08:20.229932Z","dependencies":{"bd-j4fe:discovered-from":{"depends_on_id":"bd-j4fe","type":"discovered-from","created_at":"2026-05-14T19:08:20.229932Z","created_by":"cscheid"}}} +{"id":"bd-qb4o","title":"L11 — Listings epic close-out","description":"Compile per-phase follow-up bd log into single epic report. Confirm cargo xtask verify on a fresh checkout. Update document-profile-contract.md change log. Confirm hub-client renders listings end-to-end via WASM (real browser smoke test): multi-page project with listings, edit a content page, see listing host preview update with L1 fallbacks. See claude-notes/plans/2026-05-05-listings-epic.md §L11.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid","updated_at":"2026-05-05T19:54:06.937522Z","dependencies":{"bd-5vsr:blocks":{"depends_on_id":"bd-5vsr","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"},"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"},"bd-hzsi:blocks":{"depends_on_id":"bd-hzsi","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"},"bd-o90m:blocks":{"depends_on_id":"bd-o90m","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"},"bd-qf7r:blocks":{"depends_on_id":"bd-qf7r","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"},"bd-xbnf:blocks":{"depends_on_id":"bd-xbnf","type":"blocks","created_at":"2026-05-05T19:54:06.937522Z","created_by":"cscheid"}}} +{"id":"bd-qf7r","title":"L7 — Post-render placeholder upgrade (engine-rendered previews; BRACKETED)","description":"BRACKETED FEATURE — read epic §L7 'Bracketing rules' before extending. Upgrades L1-fallback description+image to engine-rendered firstPara+previewImage by reading sibling output files in WebsiteProjectType::post_render. Single module home, mandatory file-header discipline, CLI-only by construction (hub-client and quarto preview show L1 fallbacks), no cross-feature reuse, mandatory L1-fallback contract. See claude-notes/plans/2026-05-05-listings-epic.md §L7.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid","updated_at":"2026-05-07T21:11:33.486906Z","closed_at":"2026-05-07T21:11:33.486767Z","close_reason":"L7 (bd-qf7r) implemented + merged: post-render placeholder upgrade. impl d4877142, merge dc3a0f7b. CLI render now substitutes engine-rendered first paragraphs and preview images into listing entries via the bracketed post_render step. Hub-client preview retains L1 fallbacks per the bracketing rules. +50 tests over 8647 baseline → 8697 total. Follow-ups: bd-rvpd (span threading), bd-bpdz (L9 reader extension), bd-399t (docs callout), bd-fx23 (defensive id encoding).","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid"},"bd-ml8z:blocks":{"depends_on_id":"bd-ml8z","type":"blocks","created_at":"2026-05-05T19:53:43.884886Z","created_by":"cscheid"}}} +{"id":"bd-qhb2o","title":"Parse error on `***` inline code content (regression from bd-ilv8p)","description":"Inline code content of exactly three asterisks (e.g. ```***```) fails to parse with 'unexpected character or token here'. Pandoc accepts it as Code \"***\" and pampa accepted it before commit 38e889ad (bd-ilv8p, 2026-05-24). Trigger is narrow: a run of exactly 3 consecutive asterisks at the start of inline-code content (```***```, ```***x```, ```***x***```). Four+ asterisks or asterisks after other content (```x***```, ```*x***```) parse fine. Likely cause: the new third alternative in the pandoc_code_span content rule (`alias($._soft_line_break, $.pandoc_soft_break)`) shifted parser-state precedence so the inline emphasis tokenizer's Q-2-32 'triple star' token beats the content regex inside code spans. See claude-notes/plans/2026-05-24-inline-code-triple-asterisk-regression.md for repro, characterization table, root cause hypothesis, and TDD work plan.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-24T22:49:19.359947Z","created_by":"cscheid","updated_at":"2026-05-24T23:22:59.128065Z","closed_at":"2026-05-24T23:22:59.127882Z","close_reason":"Fixed: gate TRIPLE_STAR emission on valid_symbols[EMPHASIS_OPEN_STAR] in scanner.c. Inline code spans containing literal *** now parse as Code, while paragraph-level Q-2-32 diagnostic still fires correctly. See claude-notes/plans/2026-05-24-inline-code-triple-asterisk-regression.md.","dependencies":{"bd-ilv8p:discovered-from":{"depends_on_id":"bd-ilv8p","type":"discovered-from","created_at":"2026-05-24T22:49:19.359947Z","created_by":"cscheid"}}} +{"id":"bd-qhkp","title":"New projects not added to Automerge project set (stale closure in App.tsx)","description":"handleProjectCreated and share link handler in App.tsx capture stale projectSetState/projectSetActions due to missing useCallback/useEffect dependencies. The status check always sees 'loading' instead of 'connected', so addProject is never called on the synced set. Plan: claude-notes/plans/2026-04-06-fix-project-set-stale-closure.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-04-06T20:27:45.091230Z","created_by":"cscheid","updated_at":"2026-04-06T20:27:45.091230Z"} +{"id":"bd-ql55q","title":"Preview navbar brand link points to artifacts VFS root and dead-ends iframe","description":"In hub-client / q2 preview, the navbar brand anchor (the title 'Quarto 2' in docs/) renders as <a class=\"navbar-brand\" href=\"/.quarto/project-artifacts/\">.\n\nLive repro 2026-05-20 (chrome-devtools MCP against q2 preview docs/):\nclicking it fires beforeunload on the iframe, iframe location moves to\n/.quarto/project-artifacts/, and NO NAVIGATE_TO_DOCUMENT postMessage fires —\nstranding the SPA on a URL the preview server doesn't serve.\n\nBoth TS link handlers reject the trailing-slash form:\n- iframeLinkHandlers.ts::parseArtifactHref (used by q2-preview SPA, this is the path that runs in q2 preview docs/)\n- iframePostProcessor.ts::reverseMapArtifactHref (used by hub-client HTML iframe)\nBoth require .html suffix on the stem.\n\nNative q2 render is correct (href=\"./\"). Bug is preview-only.\n\nFix in both TS link handlers — recognize the bare-directory artifact-root form as the project home (index.qmd). Resolver semantics unchanged.\n\nSee plan: claude-notes/plans/2026-05-20-preview-navbar-brand-artifacts-link.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T14:07:30.497517Z","created_by":"cscheid","updated_at":"2026-05-20T14:24:11.997050Z","closed_at":"2026-05-20T14:24:11.996869Z","close_reason":"Fixed in commit ebcc7f3e. Two-surface fix in TS:\n\n- iframeLinkHandlers.ts::parseArtifactHref (q2-preview SPA path,\n always-intercept) — empty-stem branch returns\n { qmdCandidate: 'index.qmd', anchor }.\n\n- iframePostProcessor.ts::reverseMapArtifactHref (hub-client HTML\n path, strict projectFilePaths lookup) — empty/null-stem branch\n tries each RENDERABLE_EXTS as 'index'+ext against projectFilePaths;\n returns first match or null per surface policy.\n\nResolver semantics in quarto-core unchanged — the trailing-slash\ndirectory URL is correct for static-served sites; the adaptation\nbelongs at the SPA-specific interception layer.\n\nE2E verified against docs/ via chrome-devtools MCP (post-fix\nsignature exactly inverts the 2026-05-20 repro): default prevented,\nno beforeunload, iframe stays at /q2-preview.html,\nNAVIGATE_TO_DOCUMENT fires with path=index.qmd, SPA route updates,\nheading after click is \"Quarto 2\".\n\nPlan: claude-notes/plans/2026-05-20-preview-navbar-brand-artifacts-link.md","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-20T14:07:30.497517Z","created_by":"cscheid"}}} +{"id":"bd-qod9s","title":"Phase 10 — operational hardening + documentation","description":"Operator runbook for Google OAuth client (Limited-Input-Devices type) registration. End-user .mcp.json example with QUARTO_HUB_MCP_CLIENT_ID/_SECRET. README: credential-sourcing rationale + threat-model #10 cross-ref. Per-platform credential-store clear commands. Revocation runbook (myaccount.google.com). Token-leak regression sweep.\n\nFuture-work list (not in v1) captured in plan: authenticate_status/clear tools, --login CLI flag, hub-side sub_denylist, per-scope auth, GitHub OIDC, refresh-expiry monitoring, PKCE on device-auth grant.\n\nPlan §Phase 10: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-20T14:27:35.458795Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:35.458795Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:35.458795Z","created_by":"shikokuchuo"}}} +{"id":"bd-qor9a","title":"Resolve metadata paths relative to the file they were declared in (source-location-driven)","description":"Reproducer: `docs/guide/index.qmd` defines a sidebar in its frontmatter:\n\n```yaml\nsidebar:\n contents:\n - text: \"Introduction\"\n href: introduction.qmd\n - text: \"Markdown\"\n href: ../authoring/markdown/index.qmd\n```\n\nBoth targets exist relative to `docs/guide/index.qmd` (`docs/guide/introduction.qmd` and `docs/authoring/markdown/index.qmd`). Today `q2 render` warns:\n\n Sidebar references missing document information for 'introduction.qmd'\n Sidebar references missing document information for '../authoring/markdown/index.qmd'\n\nbecause `SidebarGenerateTransform` treats sidebar hrefs as project-root-relative regardless of where the YAML was written.\n\nRoot cause: `SidebarEntry::from_plain_string` (`crates/quarto-navigation/src/sidebar.rs`) and the bare-string code path in `SidebarEntry::from_config_value` strip `ConfigValue.source_info`, then `SidebarGenerateTransform` calls `index.lookup_by_source(Path::new(h))` on the bare string. There is no way at lookup time to know whether the href was written in `_quarto.yml` (project-root-relative) or in a doc's frontmatter (doc-relative).\n\nFix direction (chosen): hybrid 'known path-shaped keys' — the sidebar/navbar parser treats strings in href/file/contents/section-href positions as if they were `!path`, retaining the `ConfigValue.source_info` long enough to resolve them against `dirname(source_info.file)` at Generate time. Authors don't have to write `!path` tags. Mirrors the existing `adjust_paths_to_document_dir` machinery for directory metadata, extended to per-document frontmatter.\n\nScope: sidebar, navbar, page-footer entries (hrefs + contents items). Project-config / `_quarto.yml`-rooted values resolve to project-root-relative (unchanged behaviour). Per-doc / `_metadata.yml`-rooted values resolve to dirname-of-that-file, then normalized via `resolve_to_project_root`.\n\nThis issue also lands the SourceInfo plumbing through to the navigation diagnostics that bd-8d6rk migrates to the structured form — once the parser retains source_info, the diagnostic gets a real location and `--json` consumers can show the offending YAML line.\n\nPlan: claude-notes/plans/2026-05-20-bd-PLACEHOLDER-metadata-path-resolution.md (to be created)\n\nBlocks-on bd-8d6rk: the structured-diagnostic surface should exist before we wire SourceInfo into it.","notes":"Plan outline written: claude-notes/plans/2026-05-20-bd-qor9a-metadata-path-resolution.md (draft, awaiting iteration. Will be fleshed out in detail after bd-8d6rk lands)","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T14:56:32.967393Z","created_by":"cscheid","updated_at":"2026-05-20T17:26:26.218423Z","closed_at":"2026-05-20T17:26:26.218267Z","close_reason":"Implementation complete. RenderContext now carries source_context; NavigationItem / SidebarEntry::Section / Navbar carry href_source paired fields; resolve_metadata_path resolves hrefs against the YAML file they were authored in; sidebar/navbar/footer/page-nav generate+render pass href_source through to Q-13-* diagnostics. End-to-end verified on docs/guide/index.qmd (zero warnings; sidebar links resolve correctly). cargo xtask verify --skip-hub-build clean. Plan: claude-notes/plans/2026-05-20-bd-qor9a-metadata-path-resolution.md (all phases checked). Follow-up bd-hjv5o tracks broader generalization. Changes uncommitted pending user review.","dependencies":{"bd-8d6rk:blocks":{"depends_on_id":"bd-8d6rk","type":"blocks","created_at":"2026-05-20T14:56:32.967393Z","created_by":"cscheid"}}} +{"id":"bd-qpa2","title":"Display math column-strip uses wrong column source, mishandles inline-wrapped and labeled math (issue #181 follow-up)","description":"Follow-up to bd-q6ed / issue #181, with revised diagnosis after a second-pass investigation (see `claude-notes/issue-reports/181/triage.md` § \"Second-pass investigation\").\n\n## Symptom\n\nTwo reporter-supplied edge cases (rundel, 2026-05-12):\n\n1. **Labeled display math inside a blockquote** — `> $$\\n> p(x)\\n> $$ {#eq-p}` round-trips with a literal `> ` left in `Math.text` after the second pass.\n2. **Labeled display math at top level** — `$$\\na\\n b\\n$$ {#eq-x}` loses one column of leading whitespace from interior lines on each round trip.\n\nSubsequent probing revealed both are instances of a broader brittleness in the column-strip introduced by bd-q6ed:\n\n3. `_$$\\na\\n b\\n$$_` (emph wrapping multi-line displaymath) loses one space on **first** parse — no round trip needed.\n4. `> _$$\\n> a\\n> b\\n> $$_` (same inside a blockquote) leaks `> ` AND loses interior whitespace on first parse.\n\n## Root cause\n\n`strip_continuation_prefix` in `crates/pampa/src/pandoc/treesitter.rs` uses `node.start_position().column` (the column of `$$`) as the strip width. That column equals the cumulative block-continuation prefix width **only when `$$` is the leftmost non-prefix character on its line**. Anything that precedes `$$` on the same line (`_`, `**`, `[`, the writer's own `[` for `quarto-math-with-attribute` Spans, etc.) shifts the column while the body bytes' source layout does not change. The strip then either eats real content (when the prefix is all whitespace/`>`) or refuses to strip real prefix (when the column overshoots into real content).\n\n## Constraint\n\n`DisplayMath` must remain an inline AST node — there are large existing corpora with display math nested inside paragraphs, and the grammar restructure proposed in the original triage would break those documents.\n\n## Fix shape (reader-side, no grammar change, no AST shape change)\n\nChange the strip-width source from `math_node.start_position().column` to the start column of the **enclosing block-leaf ancestor** (`pandoc_paragraph` / `pandoc_plain`). The cumulative block-continuation prefix width equals the paragraph's start column, which is constant across all interior lines of the paragraph regardless of what precedes `$$` on the opening line.\n\nPandoc's markdown reader uses this exact strategy (verified empirically). The fix matches Pandoc's behaviour on all probed cases — including lazy-continuation, nested blockquotes, list-item indent, and inline-wrapped multi-line math. The existing conservative `bytes ∈ {>, space, tab}` guard in the helper continues to handle lazy continuation correctly.\n\nThis single-input change subsumes:\n- bd-q6ed canonical case (paragraph col = math col, identical result)\n- bd-qpa2 edges A and B (paragraph col reflects true bq/top-level width)\n- Inline-wrapped multi-line math at any block context\n\n## Regression coverage to add\n\nFixtures under `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/`:\n\n- `labeled_display_math_in_blockquote.qmd` (bd-qpa2 edge A)\n- `labeled_display_math_top_level_indented.qmd` (bd-qpa2 edge B)\n- `emph_around_multiline_display_math.qmd`\n- `emph_around_multiline_display_math_in_blockquote.qmd`\n\nReference inputs preserved at `claude-notes/issue-reports/181/exp-labeled-math-in-bq.qmd` and `exp-labeled-math-toplevel.qmd`.\n\n## Worktree / branch\n\nImplementation on its own branch with plan file at `claude-notes/plans/2026-05-12-displaymath-column-strip-fix.md`. Upstream: https://github.com/quarto-dev/q2/issues/181.\n\n## Out of scope (separate issue if desired)\n\nThe writer's `[$$…$$]{attr}` emission for `quarto-math-with-attribute` Spans is suboptimal — Pandoc emits the natural form `$$\\n…\\n$$ {attr}` for the same AST. Switching to that form would improve readability and Pandoc compatibility, but with the reader fix above it is no longer required for round-trip correctness.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-12T19:32:00.197200Z","created_by":"cscheid","updated_at":"2026-05-12T19:55:56.757118Z","dependencies":{"bd-q6ed:related":{"depends_on_id":"bd-q6ed","type":"related","created_at":"2026-05-12T19:32:00.197200Z","created_by":"cscheid"}}} +{"id":"bd-r7v2","title":"Browser smoke: confirm MathJax/KaTeX typeset in real browser","description":"Phase 4.3 of bd-w5ov could not be completed in-session because chrome-devtools-mcp disconnected after a stale browser process was killed. Implementation is complete and Phase 4.2 (CLI exercise) verified the rendered HTML markup is correct. What remains: load the rendered fixtures in a real Chromium session and confirm the math is actually typeset, not just present as raw \\(x^2\\) text.\n\nAcceptance:\n- Render /tmp/q2-math-cli/inline_math.html, display_math.html, labelled_eq.html via http.server.\n- chrome-devtools-mcp: navigate, evaluate document.querySelectorAll('mjx-container').length > 0 (MathJax fixtures).\n- Render katex.html, evaluate document.querySelectorAll('.katex, .katex-display').length > 0.\n- Confirm zero console errors from the math runtime (404s on jsDelivr would fail this).\n- Record observations in claude-notes/plans/2026-05-04-math-mode.md.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-05-04T23:58:12.775314Z","created_by":"cscheid","updated_at":"2026-05-05T00:04:57.347714Z","closed_at":"2026-05-05T00:04:57.347571Z","close_reason":"Browser smoke completed in same session as bd-w5ov implementation: 5 fixtures verified live in Chromium via chrome-devtools-mcp. MathJax 3.2.2 typesets inline + display + labelled equations from jsDelivr; KaTeX typesets via auto-render; math-free pages stay clean; user URL override honored. Recorded in plan §Browser smoke log.","dependencies":{"bd-w5ov:discovered-from":{"depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:12.775314Z","created_by":"cscheid"}}} +{"id":"bd-r82e","title":"DocumentProfile: add includes: Vec<PathBuf> for incremental-rebuild invalidation","description":"Surfaced during the main -> feature/websites merge (bd-xfwx) that threaded IncludeExpansionStage before the DocumentProfile checkpoint.\n\nProblem: after the merge, DocumentProfile.outline (and any other AST-derived fields) can be populated from headings / code / crossref targets spliced in via {{< include child.qmd >}}. The profile therefore depends on the contents of every included file, but the profile struct itself records no trail back to those files.\n\nFor incremental rebuilds (Phase 8 of the websites epic, bd-*) and for the future 'freeze' feature, the cache-key computation needs to invalidate a parent document's cached profile when ANY of its (transitive) includes change. Without tracking the include set on the profile, that is impossible.\n\nProposal: add a field roughly of the form\n\n includes: Vec<PathBuf> // or Vec<IncludeEntry { path, hash }>\n\nto DocumentProfile. Populated by IncludeExpansionStage (or by DocumentProfileStage reading a side-channel set that IncludeExpansionStage populated on the DocumentAst). Bump profile_version on the serialized shape.\n\nScope:\n- Decide on the shape (bare PathBuf list vs. (path, content-hash) pairs). For Phase 8 we'll likely want the hash too so nav-state invalidation can compare without re-reading the files.\n- Populate from IncludeExpansionStage.\n- Extend contract doc (claude-notes/designs/document-profile-contract.md).\n- Tests: profile records every included file (direct + transitive); round-trip serialization.\n\nNon-blocking for the website-epic MVP; becomes a hard prerequisite for Phase 8.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid","updated_at":"2026-04-28T00:43:08.078191Z","closed_at":"2026-04-28T00:43:08.077941Z","close_reason":"Closed as part of Phase 8.0 — DocumentProfile.includes added (v2). Verified by editing_include_invalidates_parent_profile (incremental_rebuild.rs).","labels":["websites"],"dependencies":{"bd-0tr6:related":{"depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid"},"bd-fegm:blocks":{"depends_on_id":"bd-fegm","type":"blocks","created_at":"2026-04-27T22:21:01.025552Z","created_by":"cscheid"},"bd-xfwx:related":{"depends_on_id":"bd-xfwx","type":"related","created_at":"2026-04-24T20:05:53.778909Z","created_by":"cscheid"}}} +{"id":"bd-r8n4r","title":"CaptureSplice fold: handle engine-handoff cells nested in cell wrappers","description":"apply_capture_splices folds capture splices for a multi-engine preview, but splice_cells walks TOP-LEVEL blocks only. If engine A emits engine B's cell inside a Div.cell wrapper, engine B's splice won't reach it and that cell renders as raw source. The common case (each engine's cells at top level) works. v1 limitation documented in capture_splice.rs and the plan.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-27T16:24:40.170895Z","created_by":"cscheid","updated_at":"2026-05-27T16:24:40.170895Z","dependencies":{"bd-5yff4:discovered-from":{"depends_on_id":"bd-5yff4","type":"discovered-from","created_at":"2026-05-27T16:24:40.170895Z","created_by":"cscheid"}}} +{"id":"bd-r9hs","title":"Cargo: upgrade ureq v2.12.1 → v3.3.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 2.12.1 is range-pinned in workspace; latest is 3.3.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.424872Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.584646Z","closed_at":"2026-05-04T20:30:45.584505Z","close_reason":"merged: b0ee0f18","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.861885Z","created_by":"cscheid"}}} +{"id":"bd-ra5j","title":"L5 hub-client browser smoke for categories sidebar","description":"L5 (bd-5vsr) shipped per-item category chips and the right-margin categories sidebar. Native CLI e2e was verified directly (see plan §'End-to-end CLI verification record'). Hub-client browser smoke was deferred — same call as L3.\n\nTest plan: build hub-client (cd hub-client && npm run build:all && npm run dev), open dev server, load a multi-listing fixture project (or hand-author one in the editor), confirm:\n- Each post block shows clickable category chips.\n- The right margin shows the categories sidebar with the expected pills + counts.\n- Clicking a chip or a sidebar pill filters the listing via list.js.\n\nNote: until bd-57y4 (vendor + integrate quarto-listing.scss) lands, the visuals will look bare (vertical stack of plain divs, no hover states, no cloud sizing). The functionality should still be correct — clicks fire window.quartoListingCategory(...) and list.js filters items. Visual parity is bd-57y4's job; this issue is just the functional smoke that markup + JS still glue correctly in a real browser.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T14:20:13.761736Z","created_by":"cscheid","updated_at":"2026-05-07T14:20:13.761736Z","dependencies":{"bd-5vsr:discovered-from":{"depends_on_id":"bd-5vsr","type":"discovered-from","created_at":"2026-05-07T14:20:13.761736Z","created_by":"cscheid"}}} +{"id":"bd-rcdo","title":"InlineSplice silently drops header attribute changes","description":"When changing a Header's attributes (classes, key-value pairs) without changing its inline content, the incremental writer's InlineSplice path preserves the original block text verbatim — including the old attribute suffix. The new attributes are silently lost. Discovered while testing the kanban demo's setCardStatus mutation.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-11T14:11:27.114610Z","created_by":"cscheid","updated_at":"2026-02-11T14:17:36.513428Z","closed_at":"2026-02-11T14:17:36.513409Z","close_reason":"Fixed: block_attrs_eq checks classes, kvs, and explicit IDs. 9 tests, all 6402 workspace tests pass."} +{"id":"bd-rhs6","title":"Cargo: upgrade serde_v8 v0.285.0 → v0.309.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.285.0 is range-pinned in workspace; latest is 0.309.0. Type: pre-1.0 minor (semver-breaking); large jump. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.119274Z","created_by":"cscheid","updated_at":"2026-05-04T18:16:05.361580Z","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.361239Z","created_by":"cscheid"}}} +{"id":"bd-rmx3","title":"Tree-sitter scanner rejects Unicode whitespace (U+202F repro from Claude UI paste)","description":"pampa fails to parse `You (Apr 16, 2026, 10:18\\u202FAM)` with 'unexpected character or token here' at column 25. The byte sequence at that column is e2 80 af = U+202F NARROW NO-BREAK SPACE. Repro file: ~/Desktop/daily-log/2026/04/30/whitespace-bug.qmd. Origin: pasting a Claude web UI transcript into a qmd document (Claude.ai uses U+202F before AM/PM in timestamps). Plan: claude-notes/plans/2026-04-30-unicode-whitespace-handling.md. Likely broader exposure for other Unicode whitespace classes (U+00A0, U+2007, U+2009, U+2028, U+2029, etc.) — plan includes an audit phase.","status":"closed","priority":1,"issue_type":"bug","assignee":"cscheid","created_at":"2026-04-30T21:39:28.911409Z","created_by":"cscheid","updated_at":"2026-04-30T22:22:14.789643Z","closed_at":"2026-04-30T22:22:14.789493Z","close_reason":"Fixed: PANDOC_NON_ASCII_WHITESPACE added to grammar.js regex. Plan claude-notes/plans/2026-04-30-unicode-whitespace-handling.md. All tests pass; repro round-trips byte-for-byte through pampa."} +{"id":"bd-rqba","title":"Hub-client: parse error in another file is misattributed as 'Sidebar/Body link references unknown document'","description":"When a sibling page (e.g. about.qmd) fails Pass-1, opening a *different* page (e.g. index.qmd) shows two confusing warnings:\n- 'Sidebar references unknown document about.qmd'\n- 'Body link references unknown document about.qmd'\n\nThe file *exists*; it just failed to parse. The CLI also emits these warnings, but it additionally prints the underlying 'profile-pass skipped about.qmd: <diagnostic>' so a user can connect cause and effect. Hub-client never surfaces the Pass-1 failures at all — the diagnostics live on summary.pass1_failures[i].diagnostics and never cross the WASM boundary.\n\nRoot cause (located): crates/wasm-quarto-hub-client/src/lib.rs:1374-1428 ignores summary.pass1_failures entirely. The 'unknown document' warning itself is emitted at crates/quarto-core/src/transforms/navigation_href.rs:88-96 whenever ProjectIndex.get_profile(target) returns None.\n\nResolved fix shape (decisions D1, D2 in plan):\n1. Add a dedicated 'pass1_failures' field to RenderResponse (per-entry { source_file, error, diagnostics }). Do NOT fold them into 'warnings'. Engine stays policy-free; consumers choose strict-vs-lenient (CLI: bd-creo; preview: this issue).\n2. Add JsonDiagnostic.source_file: Option<String> so project-scoped warnings can be attributed.\n3. PreviewErrorOverlay grows a section listing Pass-1 failures with source attribution and ariadne-style formatting.\n4. navigation_href.rs wording change: 'references unknown document' → 'missing document information for' (proximal improvement; richer pass1-aware rewrite is a future task, not under this plan).\n\nPlan: claude-notes/plans/2026-05-01-hub-client-website-render-ux.md (Bug 1 + decisions D1/D2).\n\nNote: bd-mwtf (active-page case) is the narrower routing fix; bd-creo is the CLI-strictness sibling sharing the same wire-shape change.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid","updated_at":"2026-05-01T14:16:58.323704Z","dependencies":{"bd-lk66:parent-child":{"depends_on_id":"bd-lk66","type":"parent-child","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid"},"bd-mwtf:related":{"depends_on_id":"bd-mwtf","type":"related","created_at":"2026-05-01T13:58:17.280207Z","created_by":"cscheid"}}} +{"id":"bd-rqgx","title":"L8 — Custom listing templates","description":"Wire template: config path through to ListingResolveTransform's resolver. Custom templates use FileSystemResolver rooted at host-page directory with MemoryResolver fallback for built-in partials. Custom templates receive the same data binding as built-ins, including listing_item.extra. template-params: exposed as listing.template_params. Missing-file diagnostic with YAML source span. Deprecation diagnostic for .ejs.md extension. See claude-notes/plans/2026-05-05-listings-epic.md §L8.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid","updated_at":"2026-05-08T14:59:38.124448Z","closed_at":"2026-05-08T14:59:38.124292Z","close_reason":"L8 implemented in 92ca4c52 on branch beads/bd-rqgx-listings-custom-templates. Custom listing templates load from host-dir-relative path with FileSystemResolver→MemoryResolver chain, allow shadowing built-in partials, and fall back gracefully via Q-12-14/Q-12-8/Q-12-10. End-to-end CLI verification recorded in the sub-plan; 8712 tests pass; cargo xtask verify green. WASM falls back to default with Q-12-8 (D1) — runtime/VFS plumbing tracked at bd-tmka. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md.","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid"},"bd-b5jm:blocks":{"depends_on_id":"bd-b5jm","type":"blocks","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid"},"bd-ml8z:blocks":{"depends_on_id":"bd-ml8z","type":"blocks","created_at":"2026-05-05T19:53:43.985311Z","created_by":"cscheid"}}} +{"id":"bd-rvpd","title":"Source-span threading for L7's Q-12-13 (and future L9 diagnostics)","description":"L7's Q-12-13 (\"Listing item from {href} produced no preview content\") fires from `post_render`, which operates on rendered HTML rather than source qmd. There's no source span available, so the diagnostic message cites the output href but not a position the user can navigate to.\n\nThreading a span through the L3-emitted placeholder comment is feasible: include the source-info offset of the listing item declaration in the begin marker, decode in L7, and attach to Q-12-13. L9 (RSS feeds) will hit the same problem; solving once is cleaner than twice.\n\nFiled at L7 close-out per the L7 plan §\"Filing reminder\" follow-up #1.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-07T19:51:07.917929Z","created_by":"cscheid","updated_at":"2026-05-07T19:51:07.917929Z","dependencies":{"bd-qf7r:discovered-from":{"depends_on_id":"bd-qf7r","type":"discovered-from","created_at":"2026-05-07T19:51:07.917929Z","created_by":"cscheid"}}} +{"id":"bd-rwxa0","title":"Inline brand block in document frontmatter not wired through single-file render path","description":"from_config_value extracts brand: from a document's flattened metadata correctly, but single-file render mode (no _quarto.yml) appears to skip CompileThemeCssStage entirely and emit only the default styles.css. Project-level brand: works fine. Either route the inline brand through the single-file path or document the limitation. Discovered during Phase 7 e2e verification on 2026-05-20. Plan ref: claude-notes/plans/2026-05-20-brand-yml-support.md.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-21T02:31:10.966556Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:10.966556Z"} +{"id":"bd-rz2we","title":"Plan 3: q2-preview website-links fixture surfaces non-idempotent link rewriting (block 0 hash differs across runs with different project roots)","description":"Surfaced by Plan 3's idempotence gate (`crates/quarto-core/tests/idempotence.rs::website_links`). Reproduce:\n\n cargo nextest run -p quarto-core --test idempotence website_links\n\nPanic message:\n fixture website-links (ProjectOrchestrator): non-idempotent\n blocks: 58bea67d61ea7d0a vs 5b51945d38f146e1\n meta: 94dc6be205c977cb vs 94dc6be205c977cb\n first divergence: Block { index: 0, hash_a: 18150854589991019955, hash_b: 8368855784726903601 }\n\nMeta is stable across runs (hashes match). Blocks diverge at index 0, which is the paragraph containing `See [the other page](other.qmd) for more.`.\n\nHypothesis: the link-rewrite or link-resolution stage captures something path-dependent into the AST when it should produce a path-independent relative URL. Each `run_q2_preview` call creates a fresh `TempDir`, so the two runs see *different* project roots but identical fixture contents. For Plan 3's pipeline-determinism contract, structural AST should not depend on the absolute project root — only on its contents and relative layout. If the link's resolved target captures an absolute path or canonicalized tempdir form, two runs disagree.\n\nLikely surfaces in:\n- `LinkRewriteTransform` (crates/quarto-core/src/transforms/link_rewrite.rs)\n- `LinkResolutionStage`\n- whatever populates Link.target after these run.\n\nNote: SingleFile mode is not exercised here because website-links is orchestrator-only (chrome / link-resolution transforms need ProjectIndex). If the same bug bites SingleFile through a different fixture later, the fix should cover both.\n\nInvestigation starting points:\n1. `find_first_divergence` already names the block index — dump the actual `Inlines` of `doc_1.ast.blocks[0]` vs `doc_2.ast.blocks[0]` and diff. The plan's panic message tells you where to start.\n2. Inspect what the Link.target string looks like after `LinkRewriteTransform`. If it differs across runs, that's the immediate cause; trace back.\n3. The fix should canonicalize at the source: emit a path-independent relative URL (or a path-relative-to-project URL) into the AST, with the absolute-path machinery confined to source_info.\n\nThis blocks closing `website_links` in the Plan 3 gate. Failing fixtures are the triage backlog per the plan's long-lived-integration-branch policy.\n\nRefs:\n- claude-notes/plans/2026-05-04-q2-preview-plan-3-builtin-filter-idempotence.md\n- branch: feature/provenance","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-21T21:20:26.675413Z","created_by":"gordon","updated_at":"2026-05-21T22:36:57.023678Z","closed_at":"2026-05-21T22:36:57.023660Z","close_reason":"fixed: split vfs_root into write-root + url-root in ResourceResolverContext + per-renderer override (with_url_root). Native test helpers now pass /.quarto/project-artifacts as the URL prefix, decoupling rendered AST URLs from the host tempdir path. See claude-notes/plans/2026-05-21-vfs-url-write-root-split.md."} +{"id":"bd-rz6yb","title":"Hub: contain index-sourced paths to project root (path-traversal write)","description":"A connecting client can write the project index CRDT directly over the sync protocol. sync_all_documents (crates/quarto-hub/src/sync.rs:505) does project_root.join() on the untrusted index key with no containment, then std::fs::write — giving an arbitrary existing-file overwrite primitive (gated only by .exists()). Authoritative gate must be at the consumption site, not add_file (which the wire attack bypasses). Plan: claude-notes/plans/2026-05-30-hub-path-traversal-containment.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-30T15:43:44.767372Z","created_by":"shikokuchuo","updated_at":"2026-05-31T03:46:51.252768Z","closed_at":"2026-05-31T03:46:51.252713Z","close_reason":"Contained index-sourced paths in sync_all_documents: lexical contained_join + canonicalize symlink-escape check"} +{"id":"bd-s0ln","title":"hub-react-todo demo app (AST sync proof of concept)","description":"Standalone Vite React app in q2-demos/hub-react-todo that connects to a sync server, subscribes to a QMD file, and renders a live-updating todo list from the Pandoc AST. Demonstrates onASTChanged callback from Phase 1 of AST sync client API. Plan: claude-notes/plans/2026-02-06-hub-react-todo-demo.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-02-06T20:15:06.711433Z","created_by":"cscheid","updated_at":"2026-02-06T20:15:06.711433Z","dependencies":{"bd-3lsb:discovered-from":{"depends_on_id":"bd-3lsb","type":"discovered-from","created_at":"2026-02-06T20:15:06.711433Z","created_by":"cscheid"}}} +{"id":"bd-s3z1g","title":"React CodeBlock parity with native div.sourceCode wrapper","description":"Q2 has two HTML output paths: the Rust HTML writer in crates/pampa/src/writers/html.rs (used by 'q2 render') and the React renderer in ts-packages/preview-renderer/src/q2-preview/blocks/CodeBlock.tsx (used by 'q2 preview' / hub-client).\n\nCommit c81b6001 ('match Pandoc's codeblock styling output') updated the native writer to emit Pandoc's nested structure for highlighted code blocks:\n\n <div class=\"sourceCode [non-language classes]\" id=\"...\"><pre class=\"sourceCode lang\"><code class=\"sourceCode lang\">…</code></pre></div>\n\nThe React component still emits the pre-fix shape (`<pre class=\"sourceCode lang\"><code>…</code></pre>`), so the styling now drifts between 'q2 render' and 'q2 preview'. The component comments at CodeBlock.tsx:170-173 explicitly call out the parity invariant.\n\n## Scope\n\n- Mirror write_highlighted_codeblock in CodeBlock.tsx: when highlight spans are present, emit the div.sourceCode wrapper; move id + non-language classes to the div; emit class='sourceCode <lang>' on both <pre> and <code>.\n- Un-highlighted code blocks stay as bare <pre><code> — already in parity.\n- Update q2-preview.integration.test.tsx (two tests around lines 263 and 297) to assert the new shape.\n\n## Acceptance\n\n- Vitest passes for the integration test file.\n- 'npm run build:all' from hub-client succeeds.\n- Visual diff of rendered fixture (test.qmd from earlier session) between 'q2 render' and 'q2 preview' shows identical rounded-background styling.\n\n## Why this is the right first slice of bd-1tl09\n\nIt stress-tests the native/React parity invariant before any of the new decoration features (filename, copy, fold, etc.) introduce more parity surface. If maintaining parity by hand turns out to be sustainable here (one shape, two tests), the rest of the plan can proceed with confidence. If not, we add a shared contract before Phase 0.\n\nDiscovered-from: bd-1tl09 epic.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-19T19:36:31.804213Z","created_by":"cscheid","updated_at":"2026-05-19T19:49:42.966821Z","closed_at":"2026-05-19T19:49:42.966645Z","close_reason":"React CodeBlock now emits Pandoc's nested <div class=\"sourceCode\">…<pre class=\"sourceCode lang\">…<code class=\"sourceCode lang\">…</code></pre></div> structure for highlighted blocks; un-highlighted blocks unchanged. Verified end-to-end with q2 preview (project mode): DOM and visual rendering identical to q2 render. Found a separate bug along the way (bd-tnm3k, single-file preview mode broken).","dependencies":{"bd-1tl09:parent-child":{"depends_on_id":"bd-1tl09","type":"parent-child","created_at":"2026-05-19T19:36:31.804213Z","created_by":"cscheid"}}} +{"id":"bd-s58v1","title":"hub-mcp device-flow RFC 8628 §5.4 + RFC 7009 hardening","description":"Harden the existing device flow before/independent of the loopback+PKCE migration: (1) RFC 8628 §5.4 anti-phishing warning in the authenticate_start user-facing text + drop the redundant 'also valid' verification_uri line; (2) RFC 7009 best-effort refresh-token revocation in authenticate_clear (read->revoke->delete). Branch: device-flow-rfc8628-hardening. See plan 2026-05-28-hub-mcp-loopback-pkce.md for the migration these align with.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T19:56:07.930288Z","created_by":"shikokuchuo","updated_at":"2026-05-28T20:03:51.274682Z","closed_at":"2026-05-28T20:03:51.274638Z","close_reason":"Implemented on branch device-flow-rfc8628-hardening (commit ac7550af): §5.4 warning + dropped redundant URL line; RFC 7009 best-effort revoke-on-clear with 4 test cases. 147 package tests + typecheck green."} +{"id":"bd-s8llm","title":"No internal API for pipeline producers to publish files into the VFS","description":"VirtualFileSystem (crates/quarto-system-runtime/src/wasm.rs:227-261) exposes write entry points only as wasm-bindgen exports — JS -> WASM. There is no internal Rust API a pipeline stage, engine, or extension can call to publish a file for downstream consumption.\n\nThis blocks any design that wants engines to ship Lua filter source as a virtual file (the natural extension of bd-execresult-filters-unused-once-fixed). It also limits what extensions can do at WASM runtime — they can't materialize generated resources for the renderer.\n\nDiscovered during mermaid engine design — see claude-notes/plans/2026-05-28-mermaidjs-engine-design.md gap G2.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-28T13:45:50.567084Z","created_by":"cscheid","updated_at":"2026-05-28T13:45:50.567084Z","dependencies":{"bd-c6h96:discovered-from":{"depends_on_id":"bd-c6h96","type":"discovered-from","created_at":"2026-05-28T13:45:50.567084Z","created_by":"cscheid"}}} +{"id":"bd-s9emf","title":"Author error-docs pages for navigation subsystem (7 codes)","description":"Author stub-quality pages for all 7 navigation subsystem error codes under docs/errors/navigation/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:56.756080Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.550067Z","closed_at":"2026-05-24T21:15:22.549714Z"} +{"id":"bd-sfr5l","title":"Phase 5 — hub-mcp credential storage (OS-native keyring)","description":"New module ts-packages/quarto-hub-mcp/src/auth/credential-store.ts using @napi-rs/keyring. Single opaque JSON blob per Entry(service, account). Per-platform service/account identifiers locked in Phase 1.\n\nTDD: cross-platform unit suite + headless-failure suite + platform-conditional suites (KEYRING_INTEGRATION=1 gate). Sibling bug bd-XXXX tracks the keyring-error blob-leak regression test specifically.\n\nAsymmetric error mapping: read returns null on backend-unavailable; write/clear throw typed KeyringUnavailableError. No silent plaintext fallback anywhere.\n\nPlan §Phase 5: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2026-05-20T14:27:10.359115Z","created_by":"shikokuchuo","updated_at":"2026-05-20T14:27:10.359115Z","dependencies":{"bd-cmp48:parent-child":{"depends_on_id":"bd-cmp48","type":"parent-child","created_at":"2026-05-20T14:27:10.359115Z","created_by":"shikokuchuo"}}} +{"id":"bd-sgm7","title":"Share link single-click: auto-connect without requiring manual project setup","description":"Make share links work in a single click regardless of whether the receiving user already has the project in their settings. Currently, new recipients must manually click 'Connect' in the ProjectSelector. The new flow should auto-create the project entry and connect immediately. Also add project name to the share URL for better UX. Plan: claude-notes/plans/2026-03-30-share-link-single-click.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-03-30T16:47:27.895709Z","created_by":"cscheid","updated_at":"2026-03-30T16:56:38.302807Z","closed_at":"2026-03-30T16:56:38.302195Z","close_reason":"Implemented: share links now auto-create project entries and connect immediately. Added project name to share URL. Removed pendingShareData plumbing. All tests pass."} +{"id":"bd-sh4h","title":"L9 follow-up: Atom 1.0 emission","description":"L9 emits RSS 2.0 only (with the atom:link rel=self extension element, matching Q1). A pure Atom 1.0 alternative would be a forward feature for users who prefer it. Likely shape: feed.format: rss|atom on the listing config; new templates under feed/templates/atom/.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-08T17:33:49.689660Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:49.689660Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:49.689660Z","created_by":"cscheid"}}} +{"id":"bd-si8b","title":"Evaluate Temml as a third math engine for HTML output","description":"MathJax (default) and KaTeX shipped in bd-w5ov. Temml is a KaTeX fork that emits MathML directly (~80 KB bundle, native browser rendering, best a11y story). MathML support is now near-universal (Chromium since 2023, WebKit + Firefox always).\n\nInvestigate whether to add Temml as a third 'html-math-method' option:\n- Output contract differs from MathJax/KaTeX (MathML in markup vs TeX delimiters).\n- Could be added as a parallel arm in MathEngine / from_meta() / render_math_slot().\n- Decide: does q2 ship TeX-source delimiters and let Temml convert client-side, or do server-side TeX→MathML conversion at render time?\n\nOut of scope: making Temml the default. Default stays MathJax for parity with Quarto 1.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-04T23:58:18.920001Z","created_by":"cscheid","updated_at":"2026-05-04T23:58:18.920001Z","dependencies":{"bd-w5ov:discovered-from":{"depends_on_id":"bd-w5ov","type":"discovered-from","created_at":"2026-05-04T23:58:18.920001Z","created_by":"cscheid"}}} +{"id":"bd-sizl","title":"q2-debug placeholder loses CustomNode type_name","description":"q2-debug's Block/Inline dispatchers (`hub-client/src/components/render/q2-debug/dispatchers.tsx`) currently render the miss path as `<span>Not registered: CustomBlock</span>` (or `<div>...</div>` for blocks) — using only `args.node.t`, which discards the CustomNode `type_name` discriminator.\n\nFor CustomBlock / CustomInline AST nodes, the rendered debug placeholder should include the type_name so developers can see *which* CustomNode hit the fallback path. Example: `Not registered: CustomBlock(Callout)` instead of `Not registered: CustomBlock`.\n\n~5 LOC change. Pattern: in the dispatcher, when `args.node.t === 'CustomBlock' || args.node.t === 'CustomInline'`, append the type_name to the displayed text.\n\n**Why**: q2-preview's parallel placeholder (`q2-preview/dispatchers.tsx` post-Plan-2C) already includes the tag name; q2-debug's debug-mode visualization should be at least as informative.\n\n**Discovered**: while reviewing Plan 2C (q2-preview customnode rendering, `claude-notes/plans/2026-05-09-q2-preview-plan-2c-customnode-rendering.md`). Not in 2C scope — q2-debug is a separate format. Filing as a follow-up.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-10T09:43:10.869153Z","created_by":"gordon","updated_at":"2026-05-10T09:43:10.869153Z"} +{"id":"bd-sjk4t","title":"braid 0.3.0 prerequisite features for q2 migration","description":"EXTERNAL/BLOCKING: four braid-side features must merge in the braid repo (~/rooms/room-1/braid) and ship as braid 0.3.0 before q2 cutover (Phase 2). Owned by a separate braid-repo agent; tracked here only as the q2 epic's blocker.\n\nFeatures: (1) recursive 'braid dep tree'; (2) 'braid create --deps <type>:<id>' one-shot create+link; (3) 'braid import' skip beads tombstones (q2 has 2: bd-1xf5, bd-298oe); (4) braid agents-info skill installer.\n\nFull spec: claude-notes/plans/2026-06-08-braid-0.3.0-features-for-migration.md\nParent: claude-notes/plans/2026-06-08-braid-migration.md (Phase 0)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-06-08T14:16:40.990334Z","created_by":"cscheid","updated_at":"2026-06-08T15:33:46.986727Z","closed_at":"2026-06-08T15:33:46.986490Z","close_reason":"braid 0.3.0 implemented + installed; all four features verified in-session 2026-06-08. Force-closed: beads treats the parent-child edge as a block (a beads quirk); the meaningful 'blocks' edge to the epic remains.","labels":["braid","migration"],"dependencies":{"bd-a1qb3:parent-child":{"depends_on_id":"bd-a1qb3","type":"parent-child","created_at":"2026-06-08T14:16:41.075549Z","created_by":"cscheid"}}} +{"id":"bd-spsv","title":"Add cargo xtask create-worktree command with CLAUDE.local.md stub","description":"Add cargo xtask create-worktree subcommand that automates full worktree setup: git worktree add, beads redirect, and CLAUDE.local.md context stub prepended with markers. Three modes: beads ID (reads br show), --issue N (reads gh issue view), --upgrade (date-based). CLAUDE.local.md holds context only (worktree location, beads pointer, GitHub URL, plan placeholder) — beads tracks status. Plan at claude-notes/plans/2026-05-07-create-worktree-xtask.md. 8 files: .gitignore, xtask/src/main.rs, xtask/src/create_worktree.rs (new), .claude/rules/xtask.md, .claude/rules/worktrees.md, investigate-beads skill, triage skill, upgrade-cargo-deps skill.","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-05-07T14:23:51.141793100Z","created_by":"cderv","updated_at":"2026-05-11T16:49:51.239535200Z","comments":{"c-jh2p5zhi":{"id":"c-jh2p5zhi","author":"chris","created_at":"2026-05-11T16:49:51Z","text":"2026-05-11 session 3 — IMPLEMENTATION COMPLETE on branch beads/bd-spsv-create-worktree-xtask. HEAD 09eead55. 24 commits ahead of main. 55 xtask tests passing.\n\nNEXT SESSION (in priority order):\n\n1) Phase E end-to-end smoke (Chris-driven, from worktree .worktrees/bd-spsv-create-worktree-xtask). Full recipe in claude-notes/plans/2026-05-11-implement-create-worktree-xtask.md § Phase E. Quick form:\n cargo build -p xtask\n cargo xtask create-worktree --help\n cargo xtask create-worktree bd-spsv --slug e2e-beads\n ISSUE=$(gh issue list --repo quarto-dev/q2 --state open --limit 1 --json number --jq '.[0].number')\n cargo xtask create-worktree --issue \"$ISSUE\" --slug e2e-issue\n cargo xtask create-worktree --upgrade --slug e2e-upgrade\n mkdir -p .worktrees/bd-spsv-collision-test ; cargo xtask create-worktree bd-spsv --slug collision-test ; rmdir .worktrees/bd-spsv-collision-test\n cargo xtask create-worktree bd-spsv --slug \"foo/bar\" # rejected\n cargo xtask create-worktree bd-spsv --slug e2e-beads # rerun-fails by design\n Q2_CREATE_WORKTREE_INJECT_FAIL=after_worktree_add cargo xtask create-worktree bd-spsv --slug rollback-test\n test ! -d .worktrees/bd-spsv-rollback-test && git branch | grep -v 'beads/bd-spsv-rollback-test' && echo OK\n # cleanup: git worktree remove on each e2e dir + git branch -d on each e2e branch\n\n2) Capture smoke transcript for PR body (per CLAUDE.md \"end-to-end verification before declaring success\").\n\n3) Push: git push -u origin beads/bd-spsv-create-worktree-xtask:feature/bd-spsv-create-worktree-xtask\n\n4) gh pr create against main. PR body should reference: 24 commits, 55 tests, smoke transcript, optional follow-ups list (below).\n\nOPTIONAL FOLLOW-UPS (non-blocking, file separately if desired):\n- clippy cleanup in create_worktree.rs: ~5 findings (map_unwrap_or at :176/:448, collapsible_if at :570, print_literal at :160, naive_bytecount in tests at :759).\n- plan_beads ordering: move validate_slug ahead of fetch_beads_metadata to fail-fast on bad --slug overrides without burning a `br show` subprocess call.\n\nSELF-BOOTSTRAP CAVEAT: this worktree itself was set up with the manual git+echo commands the new xtask replaces. The first real end-to-end use of the new command happens after this PR lands on main, on whatever worktree the next developer creates."},"c-ofo60aur":{"id":"c-ofo60aur","author":"cderv","created_at":"2026-05-11T15:43:29Z","text":"Implementation complete on branch beads/bd-spsv-create-worktree-xtask (19 commits, 0a2def90..1672540a). 54 xtask tests passing. Final whole-branch review verdict: Ready to merge. Phase E smoke tests (Chris-driven) and Phase G push remain. Two optional follow-ups noted in review: clippy cleanup of new code (~5 lints), and reordering validate_slug ahead of fetch_beads_metadata in plan_beads to fail-fast on bad slug."},"c-rjj6r8sj":{"id":"c-rjj6r8sj","author":"cderv","created_at":"2026-05-07T17:10:40Z","text":"2026-05-07 design phase complete. Worktree: .worktrees/bd-spsv-create-worktree-xtask on branch beads/bd-spsv-create-worktree-xtask (commit 0a2def90).\n\nPlan committed at claude-notes/plans/2026-05-07-create-worktree-xtask.md (~480 lines). Two sub-agent design reviews passed: pass 1 (1 blocking + 12 required → all resolved), pass 2 (3 required → all resolved).\n\nKey design decisions locked:\n- clap struct-style variant `CreateWorktree { #[command(flatten)] args }` matching existing main.rs idiom\n- ArgGroup(required, single) for mode validation\n- Slug derive: split on whitespace+hyphen, ASCII-alphanumeric, drop stop-words, take 4, error on empty\n- CLAUDE.local.md idempotent prepend with BEGIN/END markers; full failure-case table + line-ending decision rules + atomic .tmp+rename\n- time = { version = \"0.3\", features = [\"macros\", \"formatting\"] }\n- xtask is filesystem-only (never touches beads state)\n- worktrees.md gets new sections: § CLAUDE.local.md, § Manual bootstrap (fallback)\n- --slug semantics: override in beads mode, suffix in issue/upgrade\n\nNEXT SESSION: from worktree .worktrees/bd-spsv-create-worktree-xtask, invoke /superpowers:writing-plans against the design plan to produce phased implementation plan with TDD task structure. Then implement.\n\nTouched files (8): .gitignore, crates/xtask/Cargo.toml, crates/xtask/src/main.rs, crates/xtask/src/create_worktree.rs (new), .claude/rules/xtask.md, .claude/rules/worktrees.md, .claude/skills/{investigate-beads,triage,upgrade-cargo-deps}/SKILL.md.\n\nSelf-bootstrap caveat: this worktree was set up with the manual git+echo commands the new xtask replaces (chicken-and-egg). E2E test of new command happens after merge, on next worktree any dev creates."}}} +{"id":"bd-sr73","title":"Re-measure trace size on a fixture that exercises a real engine (jupyter/knitr supporting_files)","description":"bd-5qnj's provisional size budgets (≤100 KB compressed for CI fixtures, ≤1 MB for user-attached bug reports) were measured on markdown-engine fixtures where `engine_capture` is `None`. After merging bd-45yw (replay engine recording), traces from real engine runs additionally carry `engine_capture.result.supporting_files` — for jupyter/knitr documents this can include base64-encoded PNG plots, data-frame snapshots, etc.\n\nInvestigate:\n- Capture a representative jupyter trace from a real notebook (a plot + a small dataset).\n- Measure: total `latest.json.gz` size, `engine_capture.result` share, supporting_files byte share.\n- Decide whether the 100 KB CI-fixture budget still holds, or whether engine_capture needs its own size accommodation (separate file? on-disk gzip-of-gzip is unhelpful for already-compressed PNGs).\n\nReferences:\n- claude-notes/plans/2026-05-03-trace-size-for-replay.md (Phase 3 outstanding follow-up)\n- claude-notes/plans/5qnj-trace-size-investigation/measurements.md (current measurements; markdown engine only)\n- crates/quarto-trace/src/lib.rs::EngineCapture (where supporting_files content lives)","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-03T23:28:59.411296Z","created_by":"cscheid","updated_at":"2026-05-03T23:28:59.411296Z","dependencies":{"bd-5qnj:discovered-from":{"depends_on_id":"bd-5qnj","type":"discovered-from","created_at":"2026-05-03T23:28:59.411296Z","created_by":"cscheid"}}} +{"id":"bd-swpy","title":"Sidebar/navbar/footer hrefs not relativized to current page in nested directories","description":"Surfaced building examples/websites/03-nested-sidebar (bd-2jwk). resolve_href_for_html in crates/quarto-core/src/transforms/navigation_href.rs returns profile.output_href verbatim, which is project-root-relative. Body links go through resolve_doc_relative_href + ResourceResolverContext::page_url_for, so they get relativized correctly (e.g. inside _site/guide/installation.html the body link to index.qmd renders as 'index.html', not 'guide/index.html'). But sidebar / navbar / page-footer / page-nav hrefs use resolve_href_for_html and skip the resolver, producing absolute-looking project-relative paths like 'guide/index.html' from within a page at depth 1, which a browser resolves as 'guide/guide/index.html'. Reproduces in examples/websites/03-nested-sidebar/_site/guide/installation.html and reference/api.html. Fix plan: claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md (thread ResourceResolverContext through resolve_href_for_html + four Render transforms, route hits through page_url_for matching the body-link path).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid","updated_at":"2026-04-29T15:10:53.397840Z","closed_at":"2026-04-29T15:10:53.397537Z","close_reason":"Threaded ResourceResolverContext through resolve_href_for_html in commit aa50d29e. All four Render transforms (sidebar, navbar, footer, page-nav) now route hits through page_url_for, mirroring the body-link path. Native renders produce page-relative URLs (deployment-portable); hub-client vfs_root mode produces absolute /{vfs_root}/... URLs (intended). 8081 workspace tests + cargo xtask verify pass. Closes bd-swpy.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid"},"bd-2jwk:discovered-from":{"depends_on_id":"bd-2jwk","type":"discovered-from","created_at":"2026-04-29T14:07:50.403220Z","created_by":"cscheid"}}} +{"id":"bd-t3ny","title":"Publish command scaffolding + gh-pages provider","description":"Build the scaffolding for Quarto 2's `publish` command (mirroring Quarto 1's organization in src/publish/) and ship the `gh-pages` endpoint end-to-end. All other providers (quarto-pub, netlify, posit-connect, posit-connect-cloud, confluence, huggingface) and single-document publishing are explicitly deferred.\n\nPlan: claude-notes/plans/2026-05-03-publish-command-and-gh-pages.md\n\nStatus: design draft — pending user review before implementation.","status":"closed","priority":1,"issue_type":"epic","created_at":"2026-05-03T13:47:55.362968Z","created_by":"cscheid","updated_at":"2026-05-03T15:18:38.758969Z"} +{"id":"bd-t9zb","title":"Share crossref label formatting between CrossrefRenderTransform and the LSP outline","description":"CrossrefRenderTransform formats labels like 'Figure 1: <caption>' / 'Theorem 1: <title>' (hardcoded English, see crates/quarto-core/src/transforms/crossref_render.rs). The LSP outline walker (crates/quarto-lsp-core/src/analysis.rs::format_crossref_detail) now builds the same strings independently. When localization lands (crossref.fig-prefix, title-delim, etc.) the two call sites must stay consistent. Extract a shared label helper in quarto-core::crossref that both consumers call.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:35.378079Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:35.378079Z","dependencies":{"bd-ascs:discovered-from":{"depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:35.378079Z","created_by":"cscheid"}}} +{"id":"bd-tanz","title":"Cargo: upgrade runtimelib v1.6.0 → v2.0.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 1.6.0 is range-pinned in workspace; latest is 2.0.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.020523Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.678359Z","closed_at":"2026-05-04T20:30:45.678215Z","close_reason":"merged: b7b843fe","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.189033Z","created_by":"cscheid"}}} +{"id":"bd-td2a","title":"Footer text-region project-link rewriting (replaces bd-jfyl)","description":"Phase 5's bd-jfyl follow-up was deferred precisely because Phase 6's helper is its natural home: now that resolve_doc_relative_href exists, the footer renderer's text walker can call it for any .qmd hrefs in user-supplied footer text. This is the planned consumer for the helper, surfaced during Phase 6 close-out (bd-v30t). Probably also depends on the same walking infrastructure as the body-link transform.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid","updated_at":"2026-04-27T13:37:07.174383Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid"},"bd-jfyl:related":{"depends_on_id":"bd-jfyl","type":"related","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid"},"bd-v30t:discovered-from":{"depends_on_id":"bd-v30t","type":"discovered-from","created_at":"2026-04-27T13:37:07.174383Z","created_by":"cscheid"}}} +{"id":"bd-telo","title":"Support nested website.navbar in addition to top-level navbar","description":"Today q2 only reads navbar config from a top-level `navbar:` key in `_quarto.yml` (alongside `project:`). Quarto 1 and the more natural project-level shape places it under `website:` (`website.navbar:`). Both forms should work:\n\n- Top-level `navbar:` is useful for non-website projects that want a navbar (e.g. a single-doc with custom navigation).\n- Nested `website.navbar:` is the natural project-level config home (matches Q1, matches `website.sidebar`).\n\nDiscovered while smoke-testing the bd-4eyf Bootstrap JS work — a fixture written with the natural `website.navbar:` shape silently produced no navbar markup (no error, no warning), which is a usability cliff. See claude-notes/plans/2026-05-04-bootstrap-js-injection.md (\"Browser smoke log\" section, navbar follow-up note).\n\nScope:\n- Reader/parser: accept `website.navbar:` as an alias for the existing top-level `navbar:`. If both are present, decide precedence (top-level wins? merge? error?) and document.\n- Same treatment for `website.page-footer` if not already supported.\n- Tests: extend navbar_footer_pipeline.rs with the nested shape; ensure existing top-level shape still works.\n- Possibly a deprecation/migration nudge for the top-level shape if we end up preferring nested.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-04T22:14:09.515305Z","created_by":"cscheid","updated_at":"2026-05-19T15:13:02.957324Z","closed_at":"2026-05-19T15:13:02.957195Z","close_reason":"Implemented in d66ff31c (alongside bd-jjep). website.navbar / website.page-footer / website.sidebar now all accepted as aliases for the top-level forms, via quarto_config::resolve_website_value(). Precedence: top-level wins, !prefer escapes the default field-wise merge. Same treatment also applied to website.sidebar's two other readers (SidebarGenerateTransform and derive_doc_scss_layer) for consistency."} +{"id":"bd-tep4x","title":"Author error-docs pages for writer subsystem (21 codes)","description":"Author stub-quality pages for all 21 Q-3-* writer subsystem error codes under docs/errors/writer/. Codes cover writer-side failures: IO errors, format-specific unsupported features (notes, attributes, ANSI), unresolved/unprocessed markup. Follow the template established in docs/errors/yaml/Q-1-10.qmd and docs/errors/README.md. Stub quality minimum: What this means / Why this happens / How to fix sections. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T20:24:35.322406Z","created_by":"cscheid","updated_at":"2026-05-24T20:32:20.610038Z","closed_at":"2026-05-24T20:32:20.609665Z"} +{"id":"bd-tfy0","title":"[websites] Deep-directory auto-sidebar grouping","description":"Phase 2's auto expansion groups at one level only: top-level files flat, subdir files grouped into a Section with that subdir's index-page title. Q1 produces recursively nested sections for 'docs/api/v1/reference.qmd' (Docs > Api > V1 > Reference). Design an intuitive N-level grouping; the current 1-level emits 'docs/api/v1.qmd' as one Link under the 'docs' section, which is not terrible but loses structure in deep hierarchies.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T17:52:45.561606Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:45.561606Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:45.561606Z","created_by":"cscheid"}}} +{"id":"bd-tjbr","title":"Improve cargo xtask dev-setup: cmake detection and xtask self-build lock","description":"Two cross-platform dev-ergonomics improvements surfaced while verifying PR 109 on Windows after rebasing on main. Both are orthogonal to the WASM work and belong in their own PR. Target branch feature/dev-setup-improvements, worktree at .worktrees/dev-setup-improvements. Base branch origin/main. See design and acceptance fields for details.","design":"Background. Main added quarto-highlight (commit 1fa33da0, bd-n7x2 epic) which enables the `wasm` feature on tree-sitter for native builds. That pulls in wasmtime-c-api-impl as a transitive dependency, whose build.rs shells out to cmake. Result: cmake is now a hard prerequisite for `cargo build --workspace` on every platform. GitHub Actions runners have it pre-installed. Local dev boxes frequently do not (confirmed on Chris's Windows setup).\n\nFix 1 — check_cmake() in crates/xtask/src/dev_setup.rs. Follow the existing check_pandoc() pattern at line 155. Detection via `cmake --version`. If missing, print a warning with platform-specific install commands (scoop/winget on Windows, brew on macOS, apt/dnf on Linux). Unlike pandoc the warning should be stronger because cmake missing means `cargo build --workspace` fails, not just specific tests. No version constraint — any modern cmake works for wasmtime-c-api. Single function, no NativeTool struct abstraction (YAGNI).\n\nFix 2 — `--exclude xtask` in crates/xtask/src/verify.rs step 3. The current code at line 112 runs `cargo build --workspace`, which re-links target/debug/xtask.exe while the currently-running xtask.exe holds a file lock on Windows. Error: `failed to remove file ... Accès refusé (os error 5)`. Linux/macOS tolerate overwriting a running exe, so this was latent. Change to `[\"build\", \"--workspace\", \"--exclude\", \"xtask\"]`. Step 5 (nextest) is unaffected — it compiles xtask as a test binary at a different path, no conflict. Cross-platform safe.\n\nFix 3 — CONTRIBUTING.md cmake subsection. Add after the existing \"macOS: Homebrew LLVM (for WASM builds)\" section. Same shape: one paragraph explaining why, then per-platform install commands. Covers Windows (scoop/winget), macOS (brew — note it bundles with Homebrew LLVM if already installed for WASM), Linux (apt/dnf).\n\nOut of scope. Generic NativeTool struct for future deps. Version floor for cmake. Windows MSVC Build Tools check (Microsoft's canonical Rust-on-Windows guide already covers this).\n\nRelated. bd-jakt investigates a different cargo xtask dev-setup issue (--locked causing externref mismatch) — same file, different concern.","acceptance_criteria":"check_cmake() runs in cargo xtask dev-setup and reports suitable version when cmake is on PATH. When cmake is absent, dev-setup prints a clear warning with platform-specific install commands but does not fail. cargo xtask verify succeeds on Windows without hitting the xtask.exe file lock. CONTRIBUTING.md lists cmake as a prereq with install commands for all three platforms. No regression in CI (xtask tests still run via step 5 nextest --workspace).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-04-24T16:03:48.543157300Z","created_by":"cderv","updated_at":"2026-04-27T14:30:22.022558600Z","closed_at":"2026-04-27T12:40:44.509969100Z","close_reason":"Merged via PR #136","labels":["xtask"],"dependencies":{"bd-jakt:related":{"depends_on_id":"bd-jakt","type":"related","created_at":"2026-04-24T16:07:14.210865500Z","created_by":"cderv"}},"comments":{"c-50ggz951":{"id":"c-50ggz951","author":"cderv","created_at":"2026-04-24T19:10:48Z","text":"PR opened: https://github.com/quarto-dev/q2/pull/136 (commits 32667694, d34da980). Leaving issue open until merge."},"c-ghwltbvd":{"id":"c-ghwltbvd","author":"cderv","created_at":"2026-04-24T16:39:08Z","text":"All three fixes implemented and committed at 32667694 on feature/dev-setup-improvements. check_cmake() added to dev_setup.rs (platform-specific install hints via cfg; no version floor). --exclude xtask applied only on Windows (cfg-gated) in verify.rs step 3. CONTRIBUTING.md updated with cmake section. Local verification: dev-setup reports cmake 4.3.2 detected; verify steps 1-3 pass on Windows without the xtask.exe file lock; xtask unit tests 9/9 pass. Full workspace nextest run not yet performed — pending Chris to run and confirm before PR."},"c-situh2oo":{"id":"c-situh2oo","author":"cderv","created_at":"2026-04-27T14:30:22Z","text":"Design rationale not captured above. The `wasm` feature on tree-sitter exists for runtime loading of user-defined tree-sitter grammars compiled to WASM, on the native side, via wasmtime-c-api. The 12 statically-linked grammars in quarto-highlight (python, R, JS, etc.) do not need it. Browser side uses a different mechanism (web-tree-sitter via wasm-bindgen, Phase 4). Source: crates/quarto-highlight/Cargo.toml:39-45. Already scoped to non-wasm32 targets, so the WASM build itself does not pay the cmake cost.\n\nCan we avoid cmake entirely while keeping native runtime user-grammar loading via WASM? Not today. Tree-sitter 0.25 exposes one WASM-runtime feature: `wasm` -> `wasmtime-c-api` -> `wasmtime-c-api-impl` (the cmake-shelling-out crate). No alternative for wasmer, wasmi, or pure-Rust wasmtime. The choice is hard-wired into tree-sitter's C layer (lib/src/wasm_store.c), not just the Rust bindings, so a Cargo-feature-only fix is impossible. Upstream issue tree-sitter/tree-sitter#4715 (\"Consider supporting wasm-c-api\") was closed without action; no upstream issue or PR for pure-Rust wasmtime. No third-party fork solves this for the WASM-loading path.\n\nOptions.\n\n(1) Contribute upstream pluggable WASM-runtime support or a pure-Rust wasmtime switch. Long path, depends on maintainers.\n\n(2) Feature-gate the `wasm` activation in quarto-highlight (e.g. default-on `user-grammars` feature) so devs without cmake can opt out via `--no-default-features` and lose only runtime custom-grammar loading. Does not avoid cmake for the default build.\n\n(3) Switch native runtime grammar loading from WASM to native shared libraries (.so / .dylib / .dll) using upstream's own `tree-sitter-loader` crate (crates/loader/ in tree-sitter/tree-sitter, published on crates.io). It uses `libloading` for dlopen / LoadLibrary and the `cc` crate to compile grammars to dylibs — only a C compiler, no cmake. This is the same path the `tree-sitter` CLI uses for `tree-sitter parse`. Trade-off: users distribute native dylibs per-platform instead of one portable .wasm.\n\nPR 136 documented and detected cmake without exploring (1)-(3). The trade-off belongs with the lead dev who introduced quarto-highlight in bd-n7x2."}}} +{"id":"bd-tkamn","title":"D6 react: preview shell appends quarto-light to body class","description":"## What\n\nD6 in the Rust template (closed as bd-mtzry, commit 21c8ec04) appends `quarto-light` to the body class for parity with Quarto 1. The preview iframe doesn't go through that template — its body class is set imperatively in `ts-packages/preview-renderer/src/q2-preview/PreviewDocument.tsx`. Before this fix, the preview body was `fullcontent` only; render output was `fullcontent quarto-light`.\n\n## Fix\n\nMirror Rust `append_color_mode_class` in PreviewDocument.tsx as a small TS helper. Same shape (idempotent, handles empty string, suppresses append when `quarto-light` or `quarto-dark` already present).\n\n## Tests\n\nUpdated 4 existing PreviewDocument body-class tests + added 2 new tests (idempotent quarto-light, quarto-dark suppresses light).\n\n## Plan\n\nclaude-notes/plans/2026-05-20-table-default-rendering-parity.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2026-05-20T22:46:44.717252Z","created_by":"cscheid","updated_at":"2026-05-20T22:47:30.899117Z","closed_at":"2026-05-20T22:47:30.898943Z","close_reason":"Implemented in this commit: appendColorModeClass mirrors Rust helper.","dependencies":{"bd-hir7j:parent-child":{"depends_on_id":"bd-hir7j","type":"parent-child","created_at":"2026-05-20T22:46:44.717252Z","created_by":"cscheid"}}} +{"id":"bd-tky36","title":"StageContext eagerly creates+leaks a temp dir per document (lazy-init fix)","description":"StageContext::new (crates/quarto-core/src/stage/context.rs:215) eagerly calls runtime.temp_dir(\"quarto-pipeline\").into_path() for every document. The dir is created (per-page mkdir, ~2.9% of serial render CPU in the qmd-plans profile) AND leaked (into_path sets cleanup=false). The only production reader is engine_execution.rs:265, gated behind the to_run.is_empty() fast path (line 219) — so pure-markdown docs create+leak it but never read it.\n\nFix: make temp_dir lazily created on first access via std::sync::OnceLock<PathBuf> + a temp_dir(&self) -> Result<&Path> accessor. Preserves Send+Sync (no new dep). Discovered during bd-3gj56 post-fix profiling; see claude-notes/plans/2026-06-01-render-perf-profiling.md (filesystem bucket).","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-06-01T20:29:02.890587Z","created_by":"cscheid","updated_at":"2026-06-01T20:41:36.111739Z","closed_at":"2026-06-01T20:41:36.111601Z","close_reason":"StageContext temp dir now lazy (OnceLock + accessor). mkdir 3.01%->0%, serial 3650->3560ms, 0 leaked dirs (was +565). TDD + deliberate-break; full xtask verify green.","labels":["perf"],"dependencies":{"bd-3gj56:discovered-from":{"depends_on_id":"bd-3gj56","type":"discovered-from","created_at":"2026-06-01T20:29:02.890587Z","created_by":"cscheid"}}} +{"id":"bd-tmka","title":"L8 follow-up: WASM/VFS-aware custom listing template loading","description":"L8 D1 deferred this.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-08T14:56:54.353393Z","created_by":"cscheid","updated_at":"2026-05-08T14:56:54.353393Z","dependencies":{"bd-rqgx:discovered-from":{"depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:56:54.353393Z","created_by":"cscheid"}}} +{"id":"bd-tnm3k","title":"q2 preview --single-file fails when no _quarto.yml ancestor exists","description":"When invoked on a single .qmd file with no _quarto.yml ancestor, q2 preview's single-file fallback sets project_root to the file path itself (a file, not a directory). The chain then fails:\n\n1. crates/quarto/src/commands/preview.rs:270-276 — 'No _quarto.yml ancestor → single-file mode (Phase A semantics). project_root is the file path itself.'\n2. crates/quarto-hub/src/discovery.rs::ProjectFiles::discover() walks via WalkDir, which on a single-file root yields exactly one entry: the file itself.\n3. path.strip_prefix(project_root) for the same file path returns an empty PathBuf, which is pushed into qmd_files.\n4. crates/quarto-hub/src/context.rs:431 reconcile_files_with_index does project_root.join(file_path). With file_path empty, the result is project_root + '/' (a trailing-slash variant of the file path).\n5. std::fs::read_to_string fails with ENOTDIR (os error 20) because the OS treats the trailing slash as 'I want a directory here'.\n\nSymptom: the warning 'quarto_hub::context: Failed to read text file, skipping path= error=Not a directory (os error 20)' with an empty path= field fires on every iteration. The preview SPA stays stuck at 'Initializing q2-preview…' indefinitely (no document content ever reaches it).\n\nReproduction:\n\n cp /any/file.qmd /tmp/\n q2 preview --no-browser --port 0 /tmp/file.qmd\n\n(must use a directory with no _quarto.yml anywhere above it).\n\nWorkaround: place a minimal _quarto.yml ('project: type: default') alongside the file, then q2 preview works correctly.\n\nLikely fix candidates:\n- preview.rs:270-276 should set project_root to canonical.parent() (the directory containing the file), and initial_page to the file name. This matches what happens when a _quarto.yml ancestor IS found, modulo where the project root sits.\n- Alternatively: detect single-file mode earlier and special-case ProjectFiles to contain exactly that one file with a non-empty relative path.\n\nThe cleaner fix is probably the former — there's no real benefit to having project_root be a file rather than its containing directory.\n\nDiscovered during bd-s3z1g (React CodeBlock parity verification): noticed the empty path= warning while trying to e2e-test the React change. Pre-existing, not caused by anything in bd-s3z1g.\n\nRelated: bd-1tl09 (code-block decorations epic) — many of those features will require working single-file preview.","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2026-05-19T19:49:10.011815Z","created_by":"cscheid","updated_at":"2026-05-19T20:50:41.316998Z","dependencies":{"bd-s3z1g:discovered-from":{"depends_on_id":"bd-s3z1g","type":"discovered-from","created_at":"2026-05-19T19:49:35.470732Z","created_by":"cscheid"}}} +{"id":"bd-tpve","title":"qmd parser/writer: round-trip `Str \"@{some-key}\"` (inline brace forms unsupported)","description":"Discovered while implementing bd-21gu. The qmd parser rejects bare `{...}` and `\\\\@{...}` in inline contexts:\n\n printf 'foo {some-key} bar\\n' | cargo run --bin pampa -- -t native\n → Parse error (column 6, '{')\n printf '\\\\@{some-key}\\n' | cargo run --bin pampa -- -t native\n → Parse error\n\nThis means a `Str` whose body contains `@{some-key}` (e.g. coming in via JSON) cannot be round-tripped, even though the writer-side `@` escape (bd-21gu) lookahead does include `{` so it would emit `\\\\@{some-key}` — the resulting qmd then fails to re-parse.\n\nTwo possible fixes (require investigation):\n 1. Parser: accept bare `{...}` as a literal (inline-brace context disambiguation).\n 2. Writer: escape `{` and `}` defensively for `Str` inlines (parallel to the @ fix).\n\nDefer until needed by a real-world case.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-01T00:19:41.166839Z","created_by":"cscheid","updated_at":"2026-05-01T00:19:41.166839Z","dependencies":{"bd-21gu:discovered-from":{"depends_on_id":"bd-21gu","type":"discovered-from","created_at":"2026-05-01T00:19:41.166839Z","created_by":"cscheid"}}} +{"id":"bd-tr81","title":"Documentation epic: bootstrap Quarto 2 docs using Quarto 2 itself","description":"Quarto 2 is now big enough to need standalone documentation. To avoid bootstrapping gaps, we want Quarto 2 to be documented using Quarto 2. This epic tracks the documentation work that the website-projects epic (bd-0tr6) enables.\n\nScope:\n- Build the Quarto 2 docs site with Quarto 2's own website project support.\n- Document the currently-existing Quarto 2 feature surface (pipeline, transforms, filters, navigation, config schemas, hub-client basics, etc.).\n- Document the new website-projects feature set introduced by bd-0tr6 (project.type, website.* schema, DocumentProfile contract, sidebars, shared resources, etc.).\n- Migration notes: differences from Quarto 1, what is deferred, what is gone.\n\nDepends on bd-0tr6 (website epic) reaching a minimum functional state (at least phases 0-2 + 5-7 user-visible output). Sub-plans to follow in a separate design session.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-04-23T18:43:32.089404Z","created_by":"cscheid","updated_at":"2026-04-23T18:55:41.200673Z"} +{"id":"bd-ts8j","title":"Phase 9 follow-up: browser smoke recipe + GIF capture","description":"Phase 9 sub-phase 9.5 deferred the browser smoke recipe + GIF capture to a follow-up session. The native integration test (crates/quarto-core/tests/render_page_in_project.rs) exercises the same Rust code path, but a real browser session against the hub-smoke fixture (crates/quarto-core/tests/fixtures/websites/hub-smoke/) is the canonical CLAUDE.md §End-to-end-verification check.\n\nThe manual recipe is documented in claude-notes/plans/2026-04-27-websites-phase-9.md §Sub-phase 9.5. Run it via claude-in-chrome to capture a GIF, save under claude-notes/research/, and link from the close-out commit.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:47.365912Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:31:47.365912Z","created_by":"cscheid"}}} +{"id":"bd-tv2s","title":"Cargo: upgrade automerge v0.8.0 → v0.9.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.8.0 is range-pinned in workspace; latest is 0.9.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.659246Z","created_by":"cscheid","updated_at":"2026-05-04T19:06:15.794106Z","labels":["cargo","deps"],"dependencies":{"bd-0a3b:blocks":{"depends_on_id":"bd-0a3b","type":"blocks","created_at":"2026-05-04T19:06:15.793870Z","created_by":"cscheid"},"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:04.613332Z","created_by":"cscheid"}}} +{"id":"bd-tyvt","title":"Open Graph / Twitter card / social meta tags","description":"Q1 has metadataHtmlPostProcessor for og:* and twitter:* meta tags. Out of Phase 7 MVP. Q1 reference: external-sources/quarto-cli/src/project/types/website/website-meta.ts. Filed as a separate transform alongside Phase 7's metadata transforms. Originating phase: bd-b9mz.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid","updated_at":"2026-04-27T15:03:22.023239Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid"},"bd-b9mz:discovered-from":{"depends_on_id":"bd-b9mz","type":"discovered-from","created_at":"2026-04-27T15:03:22.023239Z","created_by":"cscheid"}}} +{"id":"bd-u3ze","title":"Phase C.2 follow-up: in-process Rust integration test for watcher → staleness path","description":"Drafted in tests/staleness.rs during C.2 (bd-kw93.4) but dropped from the merge because the test is flaky under `cargo nextest run` on macOS. Symptoms:\n\n- Passes standalone (`cargo nextest run --test staleness`) in <1 second.\n- Passes under `cargo test -p quarto-preview --tests` (single-process multi-test).\n- Passes under `cargo nextest run --no-capture` (all 17 tests).\n- Fails (30 s timeout) under `cargo nextest run` (default capture, all tests) — staleness flag never flips even though the file watcher demonstrably works (binary smoke confirms).\n\nSuspected interaction between notify-rs's FSEvents backend and nextest's stdout capture across multiple test processes. The watcher arms, the file edit happens, but the change event never reaches `run_file_watcher` in this configuration.\n\nWhat's covered without this test:\n- 5 unit tests for `recompute_staleness` in capture_driver::tests.\n- 4 unit tests for `compute_input_qmd` in preview_record::tests.\n- Binary smoke confirming the watcher → sync_file → on_file_changed path on macOS.\n\nWhat this test would add: end-to-end coverage of the full file-watcher + on_file_changed + recompute_staleness + sidecar-update loop in a single Rust integration test.\n\nPath forward: file again once the Playwright e2e harness lands (Phase D / E) — Playwright drives the binary directly and doesn't have the nextest capture-pipe in the loop. Alternatively, dig into notify-rs's macOS quirks and find a workaround.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-c.md §C.2 (acceptance gap).","status":"closed","priority":3,"issue_type":"task","created_at":"2026-05-14T16:25:55.539226Z","created_by":"cscheid","updated_at":"2026-05-14T20:18:16.791913Z","closed_at":"2026-05-14T20:18:16.791776Z","close_reason":"In-process staleness integration test landed in crates/quarto-preview/tests/staleness.rs. Original flake reproduced + traced: parallel nextest processes each arming an FSEvents watcher under default I/O capture causes silent event loss on macOS. Worked around with .config/nextest.toml — puts the three watcher-using integration test binaries (staleness, eager_capture, boot) in a max-threads=1 test group. 5/5 stable reruns; workspace nextest 8952/8952. Merged to feature/q2-preview-command as commit cc180477.","dependencies":{"bd-kw93.4:discovered-from":{"depends_on_id":"bd-kw93.4","type":"discovered-from","created_at":"2026-05-14T16:25:55.539226Z","created_by":"cscheid"}}} +{"id":"bd-u4ow","title":"L8 follow-up: docs/ page for custom listing templates","description":"L8 D11 deferred. When the user-facing Quarto-website tree under docs/ becomes a real public site, add a custom-listing-templates reference covering: the binding surface (listing.*, items[*].*, project.*, item.extra.*), the partial-resolver chain (FileSystemResolver primary, MemoryResolver fallback), the diagnostic meanings (Q-12-7/8/9/10/14), and the v1 limitations: no WASM custom-template loading; no extension-catalog lookup; no template cache. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §Decisions log D11.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-08T14:57:53.676341Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:53.676341Z","dependencies":{"bd-rqgx:discovered-from":{"depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:57:53.676341Z","created_by":"cscheid"}}} +{"id":"bd-u50w","title":"qmd writer drops empty bullet-list items / mutates empty list-table cells (issue #195)","description":"Two round-trip bugs in crates/pampa/src/writers/qmd.rs, both reported in https://github.com/quarto-dev/q2/issues/195 by @rundel.\n\n(1) write_bulletlist (L461) drops truly-empty items (Vec<Block> of length 0): the is_empty_item check at L480 requires item.len() == 1, so length-0 items fall through to the else branch and write nothing. No bare marker is ever emitted. Round-trip: `[..., []]` becomes `[...]`.\n\n(2) write_list_table (L986) writes literal '- []' for cells whose content is empty (L1129-1133). The reader parses that '[]' as inline text inside a Plain block, mutating the AST from cell content `[]` to `[Plain []]`.\n\nFix shape (per reporter): emit a bare marker line (e.g. '*\\n' or '-\\n') for truly-empty items / cells. The reader already accepts bare markers — input '- - X\\n -\\n' parses the trailing item as the empty Vec.\n\nIn scope:\n- write_bulletlist empty-item branch\n- write_list_table empty-cell branch\n- write_orderedlist (no is_empty_item check at all — same root cause; bundle the fix)\n- Round-trip fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ for both AST shapes\n\nTriage record: claude-notes/issue-reports/195/triage.md on branch issue-195. Existing fixture empty_list_item.qmd (covers [Plain []], not []) should keep round-tripping unchanged.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-14T21:52:44.921887Z","created_by":"cscheid","updated_at":"2026-05-14T22:11:08.972713Z","closed_at":"2026-05-14T22:11:08.972564Z","close_reason":"Fixed in commit bea39f57 on branch issue-195. write_bulletlist + write_orderedlist now emit bare marker for length-0 items; write_list_table drops literal '[]' for empty cells without attrs. Six new round-trip fixtures under crates/pampa/tests/roundtrip_tests/qmd-json-qmd/. cargo xtask verify --skip-hub-build --skip-hub-tests passes; end-to-end against reporter's exact repros confirms AST round-trips and writer is idempotent. PR pending."} +{"id":"bd-u5pr","title":"Phase 5 — Scoped artifact store + site_libs/","description":"Add ArtifactScope { Page, Project } to artifacts. Theme CSS keyed by content fingerprint. Project-scoped artifacts drained per-doc, merged sequentially into ProjectContext.project_artifacts, flushed once in WebsiteProjectType::post_render to _site/site_libs/. Single-doc behavior byte-identical (regression-tested). See claude-notes/plans/2026-04-24-websites-phase-5.md.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-25T00:21:23.689378Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:43.689396Z","closed_at":"2026-04-25T01:31:43.689146Z","close_reason":"Implemented on feature/websites: ArtifactScope { Page, Project }, ResourceResolverContext (single_doc / website / vfs_root flavors), fingerprinted theme CSS (sha256 16-hex truncation), Project-scoped artifacts drained per-doc and merged sequentially into ProjectPipeline.project_artifacts, WebsiteProjectType::post_render flushes _site/site_libs/, single-doc behavior byte-identical (regression-tested against pre-Phase-5 baseline). 7827 workspace tests pass; cargo xtask verify (full, incl. WASM) green. Follow-ups: bd-b9za, bd-78ud, bd-apvo, bd-vdl8.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-25T00:21:23.689378Z","created_by":"cscheid"}}} +{"id":"bd-u67gw","title":"Add quarto-scss-analysis-annotation markers to brand SCSS output","description":"Q1 emits // quarto-scss-analysis-annotation { ... } push/pop comments around each brand-derived SCSS block (color/typography/bootstrap-defaults). Q2's brand_layer.rs omits them — we have no analyzer that consumes them. Add when an analyzer materializes. Plan ref: claude-notes/plans/2026-05-20-brand-yml-support.md.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-21T02:31:31.204709Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.204709Z"} +{"id":"bd-u6ef","title":"hub-client e2e fails: @quarto/quarto-sync-client/dist/index.js not resolvable","description":"Running cargo xtask verify --e2e (or npm run test:all from hub-client) breaks Playwright with: 'Cannot find module .../node_modules/@quarto/quarto-sync-client/dist/index.js imported from hub-client/e2e/helpers/projectFactory.ts'.\n\nquarto-sync-client's package.json declares main: dist/index.js, but dist/ is not built as part of npm install — only the source/import/types entries (pointing at src/) get used by Vitest. Playwright runs the helper in a plain Node process that uses the default resolver, which falls back to main.\n\nReproduces on:\n- this branch (feature/q2-preview-command @ 63e27e8c)\n- main @ d0d5d39e (i.e. pre-existing, not introduced by the q2-preview work)\n\nLikely fix shapes:\n1. Add a workspace-wide pre-step that builds quarto-sync-client's dist/ (mirror of how WASM is built via 'npm run build:wasm').\n2. Switch hub-client's e2e helpers to import via a path that hits the source condition (loader / tsx / different resolver).\n3. Set 'imports' / 'exports' on quarto-sync-client so the default Node resolver finds .ts via source.\n\nDiscovered while wiring q2-preview-spa's own Playwright suite into 'cargo xtask verify --e2e' (bd-vpsy / Phase A.7); the q2-preview-spa suite is unaffected because it doesn't import quarto-sync-client at all.","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-13T19:32:52.820888Z","created_by":"cscheid","updated_at":"2026-05-13T19:32:52.820888Z","labels":["bug","e2e","hub-client"],"dependencies":{"bd-vpsy:discovered-from":{"depends_on_id":"bd-vpsy","type":"discovered-from","created_at":"2026-05-13T19:32:52.820888Z","created_by":"cscheid"}}} +{"id":"bd-ubjo","title":"L8 follow-up: broader path resolution for YAML-declared paths","description":"L8 D2 deferred. The planned !path YAML tag + Q2 metadata-merging design should unify path resolution across _quarto.yml, per-page frontmatter, and listing templates. Listing template paths would resolve relative to the YAML they were defined in. L8 ships host-page-only resolution; this issue records the linkage so when the broader design lands, listing template paths fold in cleanly. See claude-notes/plans/2026-05-07-listings-L8-custom-templates.md §Decisions log D2.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T14:57:39.790641Z","created_by":"cscheid","updated_at":"2026-05-08T14:57:39.790641Z","dependencies":{"bd-rqgx:discovered-from":{"depends_on_id":"bd-rqgx","type":"discovered-from","created_at":"2026-05-08T14:57:39.790641Z","created_by":"cscheid"}}} +{"id":"bd-udlt","title":"L9 follow-up: title placeholder substitution from rendered HTML","description":"Q1 substitutes the rendered post title (post-engine) into RSS items, because engine output may contain math etc. that the metadata title doesn't. v1 uses item.title from the profile directly. Subscribers see the metadata title; if a feed item has math in its title, it'll show up as source markup, not the rendered form. File if a user reports this.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-05-08T17:33:32.947255Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:32.947255Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:32.947255Z","created_by":"cscheid"}}} +{"id":"bd-uhmzq","title":"Author error-docs pages for cli subsystem (8 codes)","description":"Author stub-quality pages for all 8 cli subsystem error codes under docs/errors/cli/. Follow template in docs/errors/yaml/Q-1-10.qmd. See claude-notes/plans/2026-05-22-error-docs-content.md.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-24T21:07:56.482252Z","created_by":"cscheid","updated_at":"2026-05-24T21:15:22.438176Z","closed_at":"2026-05-24T21:15:22.437806Z"} +{"id":"bd-ulgr","title":"Design JS dependency handling for Quarto 2 HTML output (Bootstrap JS and beyond)","description":"Quarto 2 HTML output currently emits correct DOM for Bootstrap-based features (navbars with dropdowns, collapsible navigation, future tabset panels, callout collapse, crossref popovers, dark-mode toggle, search) but ships no JavaScript dependencies, so interactive features do not function. Decide and implement a strategy for declaring, collecting, and emitting JS dependencies through the render pipeline.\n\nScope includes: vendor vs CDN choice; who declares dependencies (theme? feature transform? template?); how deps are collected into the final HTML; interaction with the resource-collector stage; how WASM / hub-client renders get these deps; version pinning aligned with the bundled Bootstrap SCSS in quarto-sass.\n\nOutline document: claude-notes/plans/2026-04-18-html-js-deps-design.md\n\nBlocks full UX of bd-imiw (navbar dropdowns, collapse) once implemented.","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-18T19:33:38.359516Z","created_by":"cscheid","updated_at":"2026-04-18T19:33:38.359516Z"} +{"id":"bd-uy3z","title":"pampa: wire Meta and Pandoc filter callbacks in typewise dispatch","description":"Discovered while testing bd-o8pr Phase 3 (Lua filter resource channel).\n\npampa::lua::filter::filter_names lists 'Pandoc', 'Doc', 'Meta', 'Block', 'Blocks', 'Inline', 'Inlines' as recognized filter handler names — they get copied from globals into the filter table. But the typewise traversal in apply_typewise_filter does not actually invoke them.\n\nThis means a Lua filter that does:\n function Meta(meta) ... end\nor:\n function Pandoc(doc) ... end\n\nis silently ignored. Para/Str/Header/etc. all work.\n\nThis blocks:\n- Lua-filter tests for the bd-o8pr 'additivity defense' (filter mutates meta.resources): the unit test in resource_report.rs covers the logic, but an E2E test through q2 render needs Meta callback support.\n- General pandoc filter compatibility: many real filters do all their work in Pandoc(doc) or Meta(meta).\n\nReferences:\n- crates/pampa/src/lua/filter.rs:308 (filter_names list)\n- crates/pampa/src/lua/filter.rs:1730 (apply_typewise_filter)\n- crates/quarto-core/tests/project_resources.rs (filter_removing_meta_resources_does_not_drop_author_declaration test note)","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-03T19:54:04.819189Z","created_by":"cscheid","updated_at":"2026-05-03T19:54:04.819189Z","dependencies":{"bd-o8pr:discovered-from":{"depends_on_id":"bd-o8pr","type":"discovered-from","created_at":"2026-05-03T19:54:04.819189Z","created_by":"cscheid"}}} +{"id":"bd-v0zm","title":"Cargo: upgrade reqwest v0.12.28 → v0.13.3","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.12.28 is range-pinned in workspace; latest is 0.13.3. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:54.971306Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.491686Z","closed_at":"2026-05-04T20:30:45.491526Z","close_reason":"merged: d5d9b5d1","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.108448Z","created_by":"cscheid"}}} +{"id":"bd-v1qc","title":"qmd writer drops trailing newline inside code blocks (issue #173)","description":"The qmd writer in crates/pampa/src/writers/qmd.rs:628-634 emits the closing fence directly after the content text when the text already ends with '\\n', collapsing one content-line boundary. As a result, a CodeBlock whose AST text ends in '\\n' round-trips with the trailing newline removed.\n\nTriage doc: claude-notes/issue-reports/173/triage.md (on branch issue-173).\nRepro: claude-notes/issue-reports/173/repro.sh.\n\nThe pampa reader matches Pandoc exactly on this — verified across seven cases including CommonMark spec example 100. So the AST contract is correct; only the writer is wrong. Fix scope is in the triage doc.\n\nReporter: @rundel. GH issue: https://github.com/quarto-dev/q2/issues/173.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-11T20:52:28.394443Z","created_by":"cscheid","updated_at":"2026-05-11T20:52:28.394443Z"} +{"id":"bd-v30t","title":"Phase 6 — Cross-document link rewriting","description":"Rewrite body-content [link](other.qmd) references in the AST to relative output URLs. Sub-plan: claude-notes/plans/2026-04-24-websites-phase-6.md. Adds LinkRewriteTransform, resolve_doc_relative_href helper, page_url_for resolver method, and RenderContext.resource_resolver field.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-27T12:53:10.861557Z","created_by":"cscheid","updated_at":"2026-04-27T13:42:23.653492Z","closed_at":"2026-04-27T13:42:23.653203Z","close_reason":"Phase 6 complete on feature/websites: LinkRewriteTransform + resolve_doc_relative_href helper + page_url_for on ResourceResolverContext + resource_resolver field on RenderContext/StageContext. 49 new tests, full xtask verify green. Sub-plan: claude-notes/plans/2026-04-24-websites-phase-6.md. Follow-ups: bd-p4sc, bd-fo1r, bd-nb32, bd-j3a0, bd-gdrv, bd-td2a.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-27T12:53:10.861557Z","created_by":"cscheid"}}} +{"id":"bd-v5z8w","title":"Wire light/dark brand variants (brand: {light, dark}) once Q2 has light/dark SCSS seam","description":"Parsing accepts the {light, dark} shape today but uses only the light half; emits no warning. Once Q2 grows a light/dark seam in the SCSS pipeline (currently no such seam exists — bundle.rs::assemble_themes only produces a single light variant), wire the dark half through. Reference: claude-notes/plans/2026-05-20-brand-yml-support.md Phase 8. Q1 source: external-sources/quarto-cli/src/core/sass/brand.ts brandSassLayers light/dark branches.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-21T02:31:01.035107Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:01.035107Z"} +{"id":"bd-v8gx","title":"Rename flush_site_libs to flush_project_artifacts","description":"`flush_site_libs` in `crates/quarto-core/src/project/website_post_render.rs` is now called from both `WebsiteProjectType.post_render` (where the name is accurate) and `RenderToHtmlRenderer.render` (where 'site_libs' is misleading — default projects have no site_libs dir). The function body has always been general (it just iterates project_artifacts and calls `resolver.on_disk_path_for(Project, ...)`). Rename + update one error message for clarity. Pure naming hygiene.","status":"open","priority":4,"issue_type":"chore","created_at":"2026-05-01T22:49:10.919652Z","created_by":"cscheid","updated_at":"2026-05-01T22:49:10.919652Z","dependencies":{"bd-87fu:discovered-from":{"depends_on_id":"bd-87fu","type":"discovered-from","created_at":"2026-05-01T22:49:10.919652Z","created_by":"cscheid"}}} +{"id":"bd-varx","title":"L9 follow-up: hoist append_to_rendered_header + escape_html_attr to a shared util","description":"L9's link_inject.rs duplicates two small helpers from website_favicon.rs (append_to_rendered_header to write into rendered.includes.header, and escape_html_attr for double-quoted attribute values). Both are now used by ≥2 transforms (favicon + listing-feed-link). Hoist to a shared module under crates/quarto-core/src/transforms/ or website_config.rs and have both call sites use the shared form.","status":"open","priority":4,"issue_type":"task","created_at":"2026-05-08T17:34:04.030827Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:04.030827Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:04.030827Z","created_by":"cscheid"}}} +{"id":"bd-vdl8","title":"Retire DEFAULT_CSS_ARTIFACT_PATH constant once hub-client moves off synthetic VFS paths","description":"Phase 5 introduced ResourceResolverContext::vfs_root('/.quarto/project-artifacts') as the resolver flavor for the WASM hub-client, mapping artifact paths to absolute VFS URLs. The legacy DEFAULT_CSS_ARTIFACT_PATH constant is still re-exported from quarto-core::lib so it can serve as the canonical synthetic root. When Phase 9 (hub-client project rendering) migrates the hub-client off the synthetic VFS path convention (e.g. to per-page output paths), this constant can be removed. Tracked from Phase 5 task #13.","status":"open","priority":4,"issue_type":"chore","created_at":"2026-04-25T01:31:35.851331Z","created_by":"cscheid","updated_at":"2026-04-25T01:31:35.851331Z","dependencies":{"bd-u5pr:discovered-from":{"depends_on_id":"bd-u5pr","type":"discovered-from","created_at":"2026-04-25T01:31:35.851331Z","created_by":"cscheid"}}} +{"id":"bd-ve2j","title":"Project selector: show connecting state inline instead of blank page","description":"When connecting to the project set sync server, show the ProjectSelector UI with an inline connecting message in the projects list area, instead of a blank white page with centered text. Plan: claude-notes/plans/2026-04-07-project-selector-loading-ux.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-04-07T15:29:53.350342Z","created_by":"cscheid","updated_at":"2026-04-07T15:33:38.542454Z"} +{"id":"bd-vet6","title":"tree-sitter qmd: multi-line block quote inside list item fails to parse","description":"Minimal repro:\n```\n- > a\n > b\n```\n\nPandoc parses this as BulletList[[BlockQuote[Para[Str \"a\", SoftBreak, Str \"b\"]]]]. Our parser fails with a parse error at line 2 col 6.\n\nRoot cause: in crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c, the LIST_ITEM match() function has a newline branch (line 537-540) that returns 2, causing match_line case 2 (line 1991-1996) to advance past the trailing \\n of a content line. When STATE_MATCHING is left set after a SOFT_LINE_ENDING and the next scan() runs at end-of-line-2, this consumes the \\n that the line-ending gate (line 2233) needs, breaking the parse.\n\nBLOCK_QUOTE match() has no newline branch and does not advance, which is why bq-in-bq (`> > a\\n> > b\\n`) works but bq-in-list-item does not.\n\nAffects all list markers: -, *, +, 1., 1), (1), (#).\n\nPlan: claude-notes/plans/2026-05-11-bq-multiline-in-list-item.md\n\nApproach (option 2 from the analysis): guard STATE_MATCHING re-entry so that when STATE_WAS_SOFT_LINE_BREAK is set and lookahead is \\n/\\r/EOF, we skip the match_line pass and let the line-ending gate handle it.\n\nTDD: failing corpus tests first.","status":"open","priority":1,"issue_type":"bug","created_at":"2026-05-11T15:49:45.706143Z","created_by":"cscheid","updated_at":"2026-05-11T15:49:45.706143Z","labels":["bug","parser","tree-sitter"]} +{"id":"bd-vpsy","title":"Phase A.7: Playwright smoke test for q2 preview","description":"q2-preview-spa/e2e/basic-preview.spec.ts spawns quarto preview against a fixture and drives a chromium session. Asserts initial render contains expected content, editing the .qmd on disk produces a visible change within 2s, force-refresh button works, and the DOM-stability invariant holds (a data-stable-id element keeps the same DOM node identity across an edit, by === reference equality). See claude-notes/plans/2026-05-13-q2-preview-phase-a.md section A.7.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T16:54:16.784229Z","created_by":"cscheid","updated_at":"2026-05-13T19:29:52.233453Z","closed_at":"2026-05-13T19:29:52.233317Z","close_reason":"Phase A.7 complete: Playwright suite at q2-preview-spa/e2e/basic-preview.spec.ts (4 cases) pinning initial render, on-disk-edit re-render, force-refresh button, and DOM-node-identity stability. Wired into cargo xtask verify --e2e.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:54:16.784229Z","created_by":"cscheid"}}} +{"id":"bd-vtm7","title":"Investigate Windows WASM build support","description":"Check if scoop LLVM (22.1.1) supports wasm32 target on Windows. If so, build-wasm.js needs a Windows code path in findLlvmClang() and WASM tests could run locally on Windows too. Currently both WASM build and tests are Linux/macOS only.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-03T19:20:28.383217400Z","created_by":"cderv","updated_at":"2026-04-03T19:20:28.383217400Z","dependencies":{"bd-itj9:related":{"depends_on_id":"bd-itj9","type":"related","created_at":"2026-04-03T19:20:28.383217400Z","created_by":"cderv"}}} +{"id":"bd-vxl8","title":"Fix Windows Lua path escaping in pampa io_wasm tests","description":"On Windows, 9 tests in crates/pampa/src/lua/io_wasm.rs (test_io_open_append, test_io_open_read_all, test_io_open_read_bytes, test_io_open_read_line, test_io_open_read_number, test_io_open_write_and_close, test_io_open_write_flush_incremental, test_io_type, test_io_write_returns_handle_for_chaining) panic with SyntaxError: invalid escape sequence near '\"C:\\U'. Tests interpolate file_path.display() into a Lua source string via lua.load(format!(...)), and Windows backslashes are parsed as Lua escape sequences (\\U, \\t, etc.). Same root cause and same fix as PR #95 (bd-3pe8) which used quarto_util::to_forward_slashes for filter_tests.rs / mediabag.rs / system.rs. io_wasm.rs was either added after that PR or missed. Surfaced 2026-04-28 while running cargo nextest -p pampa on Windows. Documented pattern: memory note Windows Path Escaping in Lua String Contexts. The same pattern must also be applied to crates/pampa/src/lua/io_wasm.rs test code (replace file_path.display() with to_forward_slashes(&file_path) in every lua.load(format!(...)) call).","status":"open","priority":2,"issue_type":"bug","created_at":"2026-04-28T12:57:58.712055900Z","created_by":"cderv","updated_at":"2026-04-28T13:07:56.609333600Z","labels":["lua","pampa","windows"],"dependencies":{"bd-3pe8:related":{"depends_on_id":"bd-3pe8","type":"related","created_at":"2026-04-28T13:07:56.607383400Z","created_by":"cderv"}}} +{"id":"bd-w0o9","title":"[websites] draft-mode include/visible/exclude option","description":"Phase 2 always excludes drafts from auto sidebars and any containment check. Q1 supports 'draft-mode: visible|unlinked|none' — visible keeps them in the sidebar (for local preview), unlinked lists but without links, none omits entirely. Wire this through DocumentProfile.draft filtering in sidebar_auto.rs::expand_spec and similar call sites.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T17:52:35.142347Z","created_by":"cscheid","updated_at":"2026-04-24T17:52:35.142347Z","dependencies":{"bd-9svl:discovered-from":{"depends_on_id":"bd-9svl","type":"discovered-from","created_at":"2026-04-24T17:52:35.142347Z","created_by":"cscheid"}}} +{"id":"bd-w5os","title":"[websites phase 1] ProjectType trait and two-pass orchestration","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 1.\n\nDeliverables:\n- ProjectType trait (pre_render / per-file contributions / post_render).\n- DefaultProjectType (single-doc + loose directory, no-op hooks).\n- ProjectPipeline driver: discover files, pass 1 (sweep to checkpoint), build ProjectIndex, pass 2 (resume per file).\n- Wire into quarto binary: quarto render in a directory with _quarto.yml runs ProjectPipeline.\n- Regression coverage: single-doc renders still pass existing tests (now via DefaultProjectType).\n\nBlocked by Phase 0 (needs snapshot + checkpoint).","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-23T18:42:42.317267Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:47.976528Z","closed_at":"2026-04-24T01:05:47.975735Z","close_reason":"Phase 1 shipped: ProjectType trait + two-pass ProjectPipeline driver, DefaultProjectType/WebsiteProjectType placeholders, ProjectIndex, multi-file discovery, StageContext.project_index slot. All single-file and multi-file renders now flow through the driver. 7674/7674 workspace tests pass; WASM build clean. End-to-end verified on both single-file and multi-file website fixtures. Follow-ups filed as bd-ee4z, bd-d3ol, bd-2mo9, bd-p3vi, bd-5mpv, bd-9za7.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:42:42.317267Z","created_by":"cscheid"},"bd-f3jc:blocks":{"depends_on_id":"bd-f3jc","type":"blocks","created_at":"2026-04-23T18:43:41.255438Z","created_by":"cscheid"}}} +{"id":"bd-w5ov","title":"Math-mode rendering for HTML output (MathJax + KaTeX)","description":"Implement math equation rendering for HTML output via MathJax (default) and KaTeX, matching Quarto 1's user-facing surface (html-math-method:) but routed through q2's own pipeline (q2 does not invoke Pandoc).\n\nPlan: claude-notes/plans/2026-05-04-math-mode.md\nPredecessor handoff: claude-notes/plans/2026-05-04-math-mode-handoff.md (notes from bd-4eyf session)\nPredecessor work: bd-4eyf (Bootstrap JS injection — established the predicate→js:* artifact pattern this builds on)\n\nScope (v1):\n- New MathJsStage in crates/quarto-core/src/stage/stages/math_js.rs.\n- Trigger: AST walk over Inline::Math + CustomNode(\"Equation\") slots.\n- Engines: mathjax (default) + katex; html-math-method: bare-string and {method, url} object forms; user URL override skips vendoring.\n- New $math$ template slot in MINIMAL/FULL HTML templates, positioned before $for(scripts)$ so inline config block renders before the loader (matches Pandoc's slot order).\n- Loader emitted via Project-scoped js:mathjax / js:katex artifact when vendored; via direct $math$-slot injection when user supplies url:.\n- Vendor under resources/js/mathjax/ and resources/js/katex/. Bundle size strategy still TBD — see plan Q2 (recommendation: tex-chtml core ~150KB, not full ~10-15MB).\n- Hub-client (WASM): include the stage (math is stateless, no iframe-reinit problem like Bootstrap had).\n- Filter-extensibility: stage operates on publicly-described AST (Inline::Math, CustomNode(\"Equation\")) so a Lua filter could in principle implement custom math handling — same property as our navbar rendering.\n\nOut of scope (defer to follow-up issues):\n- webtex/gladtex/mathml/plain math methods.\n- Temml as a third engine (file separate evaluation issue).\n- User-supplied MathJax config object merge (v1.1).\n- 'quarto check' warning when custom templates lack $math$ slot.\n\nTDD per CLAUDE.md: tests first (unit predicate matrix in math_js.rs + integration in tests/math_mode_pipeline.rs + WASM-pipeline inclusion test); confirm red phase against noop stub; then implement; then full cargo xtask verify + CLI exercise + chrome-devtools-mcp browser smoke before closing.\n\nAwaiting decisions Q1-Q7 in plan §8 before starting.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-04T22:41:41.975994Z","created_by":"cscheid","updated_at":"2026-05-05T00:05:10.346568Z","closed_at":"2026-05-05T00:05:10.346419Z","close_reason":"Math-mode v1 shipped: MathJax (default) + KaTeX with html-math-method: bare-string and {method, url} object forms. New MathJsStage (post-AstTransforms, pre-RenderHtmlBody) walks AST for Inline::Math + CustomNode('Equation') slots and populates meta.math with engine config + CDN loader. New $math$ template slot lands the markup before $for(scripts)$ for correct MathJax config-before-loader ordering. CDN-default (parity with Pandoc/Quarto 1, zero binary growth). Hub-client/WASM gets the stage too. Tests: 11 unit + 7 integration + 3 pipeline-structure assertions, full workspace 8403/8403, full cargo xtask verify all 9 steps green. Live Chromium smoke confirmed MathJax 3.2.2 typesetting + crossref \\\\tag{N} numbering + KaTeX rendering + custom URL override + math-free clean. Plan: claude-notes/plans/2026-05-04-math-mode.md. Follow-ups filed: bd-si8b (Temml), bd-7sib (other methods), bd-hva0 (local-vendor opt-in).","dependencies":{"bd-4eyf:discovered-from":{"depends_on_id":"bd-4eyf","type":"discovered-from","created_at":"2026-05-04T22:41:41.975994Z","created_by":"cscheid"},"bd-r7v2:blocks":{"depends_on_id":"bd-r7v2","type":"blocks","created_at":"2026-05-04T23:58:34.028538Z","created_by":"cscheid"}}} +{"id":"bd-w66j","title":"Add SymbolKind icon for crossref targets in OutlinePanel","description":"hub-client/src/components/OutlinePanel.tsx::getSymbolIcon currently maps SymbolKind.Class to '◇' / 'code' styling. After bd-ascs, crossref targets (fig-x, thm-y, eq-z) use SymbolKind.Class and render with the generic code-glyph. Consider a dedicated icon or tooltip that hints at the ref type so users can tell figures / theorems / equations apart at a glance in the sidebar.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:52.493231Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:52.493231Z","dependencies":{"bd-ascs:discovered-from":{"depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:52.493231Z","created_by":"cscheid"}}} +{"id":"bd-w7x3","title":"[websites phase 4] Page navigation (prev/next)","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 4.\n\nDeliverables:\n- PageNavGenerateTransform and PageNavRenderTransform, pattern identical to other nav transforms.\n- Compute prev/next from flattened sidebar entries.\n- Opt in/out via page-navigation: true|false at project or page level.\n- Template slot: $rendered.navigation.page_navigation$.\n- Integration tests.\n\nBlocked by Phase 2 (needs Sidebar).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-23T18:43:02.852700Z","created_by":"cscheid","updated_at":"2026-04-23T18:43:47.440710Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:02.852700Z","created_by":"cscheid"},"bd-mre3:blocks":{"depends_on_id":"bd-mre3","type":"blocks","created_at":"2026-04-23T18:43:47.439797Z","created_by":"cscheid"}}} +{"id":"bd-wgup","title":"Eliminate serde_json::Value intermediate in pampa JSON writer","description":"Native profile of parse_qmd_to_ast (the hub-client's entry) on scaled lorem-ipsum fixtures shows ~50-55% of runtime in memory movement (_platform_memmove) + allocator work, and ~5-7% in indexmap::Core::insert_full. Root cause: pampa::writers::json builds a full serde_json::Value tree (each node a Value::Object backed by IndexMap<String, Value> with fresh String keys for 'c'/'s'/'t'/etc.) and then serializes it to bytes via serde_json::to_writer. Two full passes, enormous intermediate allocation. At 8x the canonical doc, _platform_memmove alone is 41% of wall time. Plan: claude-notes/plans/2026-04-22-serde-json-value-intermediate.md. Hypothesis is 'replace the Value tree with direct Serialize impls that stream JSON to the output Writer,' to be validated with the perf-harness driver introduced in the same plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-04-22T22:47:51.778056Z","created_by":"cscheid","updated_at":"2026-04-23T00:11:51.390207Z","closed_at":"2026-04-23T00:11:51.389491Z","close_reason":"Streaming JSON writer landed on perf/2026-04-22-json-sourcemap in commits 4e7a43ec (Phase 1 scaffold) and b3e15a47 (Phase 2 cutover). 1.65x-2.3x speedup across 1x-8x fixtures; IndexMap/allocator hotspots eliminated. Browser-verified by Carlos. Remaining memmove cost is the output buffer's amortized doubling — a separate optimization, documented as follow-up in the plan."} +{"id":"bd-wjg4h","title":"Browser-verify _brand.yml support in hub-client q2 preview","description":"Phase 7 of the brand plan covered native render verification but not browser. Run the WASM rebuild chain (npm run build:wasm; cargo xtask build-q2-preview-spa; cargo build --bin q2) then open a project with _brand.yml under q2 preview and confirm the iframe applies brand colors/typography. The WASM code path is identical to native; just needs ground-truthing.","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-21T02:31:31.264736Z","created_by":"cscheid","updated_at":"2026-05-21T02:31:31.264736Z"} +{"id":"bd-wjpd","title":"Cargo: upgrade tree-sitter-highlight v0.25.10 → v0.26.8","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.25.10 is range-pinned in workspace; latest is 0.26.8. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.372492Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.850328Z","closed_at":"2026-05-04T20:30:44.850181Z","close_reason":"merged: 61b01cd4","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.776730Z","created_by":"cscheid"}}} +{"id":"bd-wlza2","title":"Treat leading-/ resource paths as project-root-relative","description":"YAML 'resources:' patterns starting with '/' are interpreted as filesystem-absolute and rejected by the project-containment check. They should be project-root-relative (TS Quarto convention). Blocks rendering quarto-web under q2.\n\nPlan: claude-notes/plans/2026-05-21-resource-path-leading-slash.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-21T21:12:32.927216Z","created_by":"cscheid","updated_at":"2026-05-21T21:39:51.267265Z","closed_at":"2026-05-21T21:39:51.267102Z","close_reason":"Leading-/ YAML resource patterns now strip-prefix to project_root in expand_one. 5 new tests added (3 of which failed pre-fix). e2e on quarto-web: original error gone, four leading-/ file resources resolve correctly. Follow-up bd-47w7o tracks directory-resource handling."} +{"id":"bd-wo59","title":"Per-project capture cache for cross-session reuse","description":"Phase C.7 (bd-kw93.7) shipped the per-doc capture filesystem cache in <data_dir>/captures/ — the same tempdir that gets deleted when q2 preview exits. So closing and re-opening preview against the same project always misses the cache, even though the inputs are bit-for-bit identical.\n\nA per-project cache location (e.g. <project_root>/.q2/captures/, ignored by .gitignore convention) would unlock cross-session reuse. The cache key derivation (sha256 of canonical input_qmd) is already content-addressed and survives across sessions — only the directory choice changes.\n\nSee plan §C.7 'Open follow-up'.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-14T17:35:46.618486Z","created_by":"cscheid","updated_at":"2026-05-14T17:35:46.618486Z","dependencies":{"bd-kw93.7:discovered-from":{"depends_on_id":"bd-kw93.7","type":"discovered-from","created_at":"2026-05-14T17:35:46.618486Z","created_by":"cscheid"}}} +{"id":"bd-wv4e","title":"Tree-sitter scanner over-eagerly excludes *, -, +, #, digits from soft-break","description":"The same class of bug as bd-af1e affects 5 more characters. The scanner's line-break handler at scanner.c:2286-2291 and 2371-2376 excludes these from soft-line-break candidates whenever they appear at the start of a continuation line:\n- '*' (could be emphasis, list, thematic break)\n- '-' (could be list, thematic break, setext header)\n- '+' (could be list)\n- '#' (could be ATX header)\n- digits 0-9 (could be ordered list)\n\nBut each of these only opens a block in specific contexts (most need a trailing space, '#' needs space, '*'/'-'/'+' need space for list, '***'/'---' need 3+ for thematic break, digits need '.' or ')' followed by space). A bare 'X' followed by content is just inline text and should soft-break.\n\nVerified pampa vs pandoc divergence on:\n foo bar\n *emph* baz → pampa splits, pandoc soft-breaks\n -text more → pampa splits, pandoc soft-breaks\n +text more → pampa splits, pandoc soft-breaks\n #hashtag more → pampa splits, pandoc soft-breaks\n 123abc more → pampa splits, pandoc soft-breaks\n\nCorrect exclusions (pampa already matches pandoc for):\n * list item → BulletList opens (correct)\n - list item → BulletList opens (correct)\n # heading → Header opens (correct)\n 1. item → OrderedList opens (correct)\n\nFix approach: same as bd-af1e (peek-count). For each char, peek the trailing context to decide if it actually opens a block:\n- '*', '-': count run; if >=3 with all whitespace/eol after, thematic break (interrupt). If '* ' or '*\\t', list (interrupt). Otherwise inline.\n- '+': only list if followed by whitespace.\n- '#': only ATX if followed by whitespace or eol.\n- digits: only ordered list if followed by '.' or ')' AND space.\n\n':' (fenced div / definition list) was excluded from this issue because its semantics are more entangled with qmd-specific features and pandoc-mode-specific rules — file separately if regression observed.\n\nSibling of bd-af1e. See claude-notes/plans/2026-04-30-tree-sitter-backtick-paragraph-split.md for the bd-af1e implementation pattern.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T18:40:17.998897Z","created_by":"cscheid","updated_at":"2026-04-30T18:45:29.625753Z","closed_at":"2026-04-30T18:45:29.625599Z","close_reason":"Re-scoped: see bd-wv4e replacement for asterisks-only fix. The other characters (-, +, #, digits, :) have a backslash-escape workaround (\\-text, \\#hashtag, etc.) so are not severe enough to fix in this pass.","dependencies":{"bd-af1e:related":{"depends_on_id":"bd-af1e","type":"related","created_at":"2026-04-30T18:40:25.341409Z","created_by":"cscheid"}}} +{"id":"bd-wzhsf","title":"CVE-prevention: cookie+Bearer dual-credential MUST return 400","description":"Highest-impact item flagged in plan §Phase 2. A request carrying BOTH a session cookie AND an Authorization: Bearer header MUST be rejected with HTTP 400 and body {\"error\":\"conflicting_credentials\"} BEFORE any auth-decision logic runs.\n\nTest name: cookie_and_bearer_returns_400 in crates/quarto-hub/tests/auth_bearer.rs.\n\nThe dual-credential 400 rule must win over CSRF, WS-Origin, and per-credential auth checks (covered by sibling test dual_credential_400_wins_over_csrf_and_origin).\n\nPlan §Phase 2 — Cross-cutting security requirements: claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2026-05-20T14:27:46.526825Z","created_by":"shikokuchuo","updated_at":"2026-05-20T21:22:18.258188Z","closed_at":"2026-05-20T21:22:18.258155Z","close_reason":"Dual-credential 400 enforced. cookie_and_bearer_returns_400 (REST), ws_upgrade_rejects_dual_credentials (WS), and dual_credential_400_wins_over_csrf_and_origin all pass. Body shape locked as {\"error\":\"conflicting_credentials\"} in extract_credential and the WS handler; auth_refresh re-runs the same check before CSRF. See plan §Phase 2 — completion notes (2026-05-20).","dependencies":{"bd-0ufq5:parent-child":{"depends_on_id":"bd-0ufq5","type":"parent-child","created_at":"2026-05-20T14:27:46.526825Z","created_by":"shikokuchuo"}}} +{"id":"bd-x5r4","title":"Optional-variable syntax: $variable?$ shorthand for $if(variable)$$variable$$endif$","description":"When users see Q-10-2 warnings on a variable they intend to be optional, today they have to wrap each reference in $if(variable)$$variable$$endif$. A short $variable?$ form would be cleaner and let authors silence the warning at the use site.\n\nFeasibility (recorded in bd-xdnk plan §Follow-up):\n- `?` is unused as a sigil in the current grammar.\n- Doesn't collide with any pipe name (`pairs|first|last|rest|allbutlast|uppercase|lowercase|length|reverse|chomp|nowrap|alpha|roman|left|center|right`).\n- Pipes already use `/` as separator (`tree-sitter-doctemplate/grammar/grammar.js:84-86`), so `?` doesn't conflict.\n- Implementation cost: one grammar token, one `bool optional` field on `VariableRef`, one branch in `render_variable` that returns `Doc::Empty` silently when `optional` is set and the lookup fails.\n\nOpen question: should `?` propagate to applied partials (`$var?:partial()$`)? Probably yes — same intent. Not applicable to `$if$` itself.\n\nDiscovered while wiring template diagnostics through quarto render (bd-xdnk). Now that template warnings are user-visible, having a clean opt-out becomes more valuable.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-05T16:36:00.814658Z","created_by":"cscheid","updated_at":"2026-05-05T16:36:00.814658Z","dependencies":{"bd-xdnk:discovered-from":{"depends_on_id":"bd-xdnk","type":"discovered-from","created_at":"2026-05-05T16:36:00.814658Z","created_by":"cscheid"}}} +{"id":"bd-x5tx2","title":"Audit HashMap/HashSet iteration in user-visible output paths","description":"Follow-up from bd-hwdlq (triage of issue #222). The bd-hwdlq fix addresses one specific instance of non-deterministic diagnostic output caused by HashMap iteration in crates/quarto-parse-errors. There may be others.\n\nScope: grep across the codebase for HashMap/HashSet whose iteration order is observable in user-facing output (diagnostics, writers, snapshots, JSON emission, source maps, anywhere a Vec/String/file is built from iteration). For each instance, decide whether the iteration order is actually deterministic-by-construction (e.g. all entries are equal under the user-visible projection), or whether it needs to migrate to hashlink::LinkedHashMap / BTreeMap / sorted Vec.\n\nOut of scope: HashMap/HashSet used only for membership tests (contains/insert) where iteration is not observed.\n\nSuggested approach:\n1. ripgrep 'HashMap<\\|HashSet<' across crates/, filter to non-test code paths\n2. For each hit, trace the variable to see if it's iterated (.iter(), .values(), .keys(), for loop, .collect::<Vec>())\n3. Of the iterated ones, check whether the iteration result reaches user-visible output\n4. File sub-issues or fix directly depending on volume\n\nConsider also adding a CLAUDE.md or .claude/rules/ note codifying 'containers iterated to produce user-visible output must have deterministic iteration order.'","status":"open","priority":2,"issue_type":"task","created_at":"2026-05-21T13:14:58.809507Z","created_by":"cscheid","updated_at":"2026-05-21T13:14:58.809507Z","dependencies":{"bd-hwdlq:discovered-from":{"depends_on_id":"bd-hwdlq","type":"discovered-from","created_at":"2026-05-21T13:14:58.809507Z","created_by":"cscheid"}}} +{"id":"bd-xbnf","title":"L6 — Dependency-graph integration (listing_content_targets)","description":"Add DocumentProfile.listing_content_targets: Vec<PathBuf> (additive, no version bump). Populate during dep-graph build by expanding host's listing.contents globs against project source paths. New automatic edge source in dependency_graph.rs. Mode B picks up listing hosts when their content files are touched. See claude-notes/plans/2026-05-05-listings-epic.md §L6.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid","updated_at":"2026-05-07T17:50:28.654543Z","closed_at":"2026-05-07T17:50:28.654365Z","close_reason":"L6 implemented and merged on feature/listings as 8b5efb91 (impl ffa4d227). +26 tests over 8621 baseline → 8647. cargo xtask verify all green incl. WASM. End-to-end CLI Mode-B verification in plan.","dependencies":{"bd-61cd:parent-child":{"depends_on_id":"bd-61cd","type":"parent-child","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid"},"bd-j60g:blocks":{"depends_on_id":"bd-j60g","type":"blocks","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid"},"bd-n8a4:blocks":{"depends_on_id":"bd-n8a4","type":"blocks","created_at":"2026-05-05T19:53:32.423637Z","created_by":"cscheid"}}} +{"id":"bd-xdier","title":"q2 preview: per-doc sidebar lands at bottom of page (extra <div> wrapper breaks grid)","description":"Symptom: in docs/ website, q2 render places the per-document YAML sidebar (Quarto 2 / Introduction / Markdown) on the left as expected, but q2 preview renders the same sidebar elements at the bottom of the page (below <main>).\n\nReproduced with /Users/cscheid/rooms/room-1/q2/docs/. Render: nav#quarto-sidebar at x=310 width=250 left of main. Preview: same nav inside <div> wrapper at x=585 width=749 below main.\n\nRoot cause: ts-packages/preview-renderer/src/q2-preview/chromeSlots.tsx:53-56 (SidebarSlot, and sibling NavbarSlot/PageNavSlot/FooterSlot) wrap the injected chrome HTML in <div dangerouslySetInnerHTML=...>. The native template at crates/quarto-core/src/template.rs:185-188 emits $rendered.navigation.sidebar$ as a *direct* child of <div id=\"quarto-content\">, no wrapper. The Quarto theme CSS grid on #quarto-content assigns nav#quarto-sidebar to grid-area 'content-top / page-start / page-bottom / body-start' — but only when nav#quarto-sidebar is a grid child. With the extra wrapper <div>, the wrapper becomes the grid item with default placement 'body-content-start / body-content-end' + 'grid-row: auto', stacking below <main>.\n\nVerified by patching `display: contents` on the wrapper at runtime in the preview iframe — sidebar snapped to correct position (x=310, on left).\n\nExisting test PreviewDocument.integration.test.tsx:252 checks `quartoContent.querySelector('nav#quarto-sidebar')` (descendant), not direct-child relationship — missed the bug.\n\nFix: add `style={{display: 'contents'}}` to the wrapping <div> in SidebarSlot (and apply same fix to sibling slots NavbarSlot, PageNavSlot, FooterSlot for parity — they share the same root cause even if the symptoms are less severe today). Add tests that assert direct-child relationship via `Array.from(parent.children).includes(node)` rather than `parent.querySelector(...)`.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-20T18:31:14.064173Z","created_by":"cscheid","updated_at":"2026-05-20T18:36:14.362832Z","closed_at":"2026-05-20T18:36:14.362650Z","close_reason":"Wrapper <div> in chrome slots now display:contents — sidebar/navbar/footer/page-nav are transparent to parent CSS grid/flex layout, matching native template byte-for-byte. Fix verified via failing-first tests (4 new in PreviewDocument.integration.test.tsx) and end-to-end browser check on docs/: sidebar at x=310 width=250 (left), main at x=585.5 — identical to q2 render. cargo xtask verify: all 12 steps green.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-20T18:31:14.064173Z","created_by":"cscheid"}}} +{"id":"bd-xdnk","title":"Doctemplate diagnostics dropped on quarto render path","description":"The doctemplate engine produces ariadne-formatted warnings (e.g. Q-10-2 'Undefined variable') with accurate source locations. These surface correctly via the pampa CLI (crates/pampa/src/main.rs:449 calls template.render_with_diagnostics and prints them with ariadne), but the quarto render orchestrator path drops them: crates/quarto-core/src/template.rs:412 (render_with_compiled_template, used by crates/quarto-core/src/stage/stages/apply_template.rs) calls template.render(&ctx), the non-diagnostic API. As a result, undefined variables and similar template warnings are silently swallowed under 'quarto render'. Plan: claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-05T13:31:01.034589Z","created_by":"cscheid","updated_at":"2026-05-05T17:28:59.548543Z","closed_at":"2026-05-05T17:28:59.548414Z","close_reason":"Implemented and merged to main (commits acf589a2 sync, 6544ff1b feat, 3422b636 docs). Doctemplate diagnostics now flow through quarto render with ariadne-rendered source-located warnings; pre-existing template: YAML lookup bug also fixed. Plan: claude-notes/plans/2026-05-05-doctemplate-diagnostics-quarto-render.md. Follow-ups: bd-x5r4 ($variable?$ syntax → q2#158), bd-khuj (hub-client UI smoke)."} +{"id":"bd-xee1","title":"[websites phase 6] Cross-document link rewriting","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 6.\n\nDeliverables:\n- HTML post-render transform that rewrites href attributes pointing at project-relative .qmd paths to corresponding output hrefs using ProjectIndex.\n- Correctly handle query strings, hash fragments (#anchor), and subdirectory paths.\n- Diagnostic warning for broken .qmd links (target not in index).\n- Tests: fixtures with inter-page links, including anchor and query suffixes.\n\nBlocked by Phase 1 (needs ProjectIndex).","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-23T18:43:12.763310Z","created_by":"cscheid","updated_at":"2026-04-29T00:31:30.633024Z","closed_at":"2026-04-29T00:31:30.632656Z","close_reason":"Phase 6 (cross-document link rewriting) implemented (commit 070412c0). Closed as part of Phase 9 cleanup.","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:12.763310Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:45.378785Z","created_by":"cscheid"}}} +{"id":"bd-xfwx","title":"Merge main → feature/websites: IncludeExpansion before DocumentProfile checkpoint","description":"Merge main into feature/websites such that the include-shortcode expansion pipeline stage (main, 215482fb) is wired into the pipeline BEFORE the DocumentProfile checkpoint (feature/websites, e8674612).\n\nPost-merge pipeline order (HTML / WASM / analysis):\n Parse -> MetadataMerge -> IncludeExpansion -> DocumentProfile -> UnwrapProfile -> PreEngineSugaring -> ...\n\nRationale: statically-knowable information a document declares via {{< include ... >}} (headings, code blocks, crossref targets) must be visible to DocumentProfile so downstream project-level features (sidebars, nav, cross-doc links, incremental rebuilds, future freeze) see a consistent AST.\n\nGates start of Phase 4 of the website epic (bd-0tr6).\n\nPlan: claude-notes/plans/2026-04-24-include-expansion-merge.md\n\nMain conflicts expected in:\n- crates/quarto-core/src/pipeline.rs (imports, three builders, tests)\n- crates/quarto-core/src/stage/mod.rs (re-exports)\n- crates/quarto-core/src/stage/stages/mod.rs (module declarations)\n- .beads/issues.jsonl\n\nTDD: A regression test (profile sees heading from included file) is added BEFORE the merge and must fail on feature/websites HEAD for the right reason (no IncludeExpansionStage), then pass after the merge resolution.\n\nNo push without explicit user approval.","status":"in_progress","priority":1,"issue_type":"task","created_at":"2026-04-24T20:02:12.975940Z","created_by":"cscheid","updated_at":"2026-04-24T20:06:26.895630Z","labels":["websites"],"dependencies":{"bd-0tr6:related":{"depends_on_id":"bd-0tr6","type":"related","created_at":"2026-04-24T20:02:12.975940Z","created_by":"cscheid"}}} +{"id":"bd-xgb4","title":"Share link project never joins synced project set","description":"Visiting #/share/<indexDocId> opens the project but never adds it to the user's synced project set (profile doc). Later trying to add the same docId via the Connect form fails with a misleading 'may already exist' error.\n\nRoot cause is three separate bugs:\n1. App.tsx share route gates projectSetActions.addProject on status === 'connected', which is racy against useProjectSet's async init. On initial share-link load the guard almost always fails, the add is skipped, and there is no retry.\n2. ProjectSelector renders the list from projectSetEntries when useProjectSet is true, so the share-flow's IDB-only entry is invisible.\n3. ProjectSelector.handleConnectProject skips the getProjectByIndexDocId dedupe check that the share route has, and projectStorage.addProject then collides with the IDB unique index on indexDocId. The form also never calls projectSetActions.addProject, so even a successful add wouldn't reach the synced set.\n\nFull analysis and TDD fix plan in claude-notes/plans/2026-04-16-share-link-project-not-added.md.\n\nRepro: https://quarto-hub.com/#/share/SNHcgVzUkWpGFmcxkCkpCDfFtmu?server=wss%3A%2F%2Fquarto-hub.com%2Fws&file=%2Felliot%2Findex.qmd&name=Demo+Playground — opens fine but SNHcgVzUkWpGFmcxkCkpCDfFtmu is absent from the reporting user's profile projects map, and manual add via Connect form fails with 'Failed to add project. The document ID may already exist.'","notes":"Reconciler implemented and verified. See phase 3 checklist in claude-notes/plans/2026-04-16-share-link-project-not-added.md. Awaiting user approval before committing/pushing.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-04-16T19:26:55.995937Z","created_by":"cscheid","updated_at":"2026-04-16T20:09:56.136603Z","labels":["hub-client","project-set","share"]} +{"id":"bd-xhvs","title":"L9 follow-up: escape ]]> in CDATA-wrapped feed bodies","description":"feed/complete.rs wraps the substituted body in <![CDATA[…]]>. If the rendered HTML contains the literal sequence ]]>, the CDATA terminates prematurely and the XML is malformed. The fix is to split such bodies at every ]]> and emit two CDATA sections: ]]><![CDATA[. v1 doesn't handle this because the typical Quarto-rendered output never contains ]]>; file a real-world report would force the issue.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-08T17:34:13.045704Z","created_by":"cscheid","updated_at":"2026-05-08T17:34:13.045704Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:34:13.045704Z","created_by":"cscheid"}}} +{"id":"bd-xly8b","title":"Catalog/corpus drift: markdown Q-2-X assignments diverge between error_catalog.json, pampa/resources/error-corpus/, and production-emit sites","description":"While authoring docs/errors/markdown/ pages (bd-lgxdr), found multiple drift cases between the three sources of truth:\n\n1. **Q-2-5**: catalog title 'Unclosed Emphasis' (generic), but corpus Q-2-5.json and production code (json.rs:328) use 'Unclosed Underscore Emphasis'. Catalog says Q-2-14 is the underscore-specific one. Production behavior collapses to Q-2-5; Q-2-14 is never actually emitted with the *with_code* API.\n\n2. **Q-2-35**: catalog says 'Invalid List-Table Structure' (matches production emits at treesitter_utils/postprocess.rs:785,976), but corpus Q-2-35.json claims 'Indented code blocks are not supported'. The corpus appears stale.\n\n3. **Q-2-36, Q-2-37, Q-2-38**: present in pampa/resources/error-corpus/ as Q-2-36.json (Old-style knitr chunk options), Q-2-37.json (Line break in link destination), Q-2-38.json (Unclosed Attribute Specifier) — and Q-2-36 is emitted in production (treesitter.rs:1244) — but NONE are in error_catalog.json. The catalog jumps Q-2-35 → Q-2-39.\n\n4. **Q-2-6, Q-2-8**: in catalog but never emitted in production. Reserved for future strict-mode (Q-2-6) and upgraded-to-error-and-renumbered (Q-2-8 → Q-2-36).\n\nPlan: the catalog is authoritative for docs_url; the corpus needs to be reconciled to match. Add missing Q-2-36/37/38 to the catalog (or remove from corpus if they should not exist). Fix Q-2-5 and Q-2-35 corpus titles to match catalog. Decide whether Q-2-14 should be deprecated or whether production should be updated to emit it for the underscore variant specifically.\n\nDiscovered from: bd-lgxdr (markdown subsystem error-docs pages).","status":"open","priority":3,"issue_type":"bug","created_at":"2026-05-22T20:38:32.703765Z","created_by":"cscheid","updated_at":"2026-05-22T20:38:32.703765Z","labels":["documentation","error-reporting","markdown"],"dependencies":{"bd-lgxdr:discovered-from":{"depends_on_id":"bd-lgxdr","type":"discovered-from","created_at":"2026-05-22T20:38:32.703765Z","created_by":"cscheid"}}} +{"id":"bd-xm7l","title":"Audit non-cargo / vendored dependencies and expand upgrade skill","description":"Expand the upgrade-cargo-deps skill (or add a sibling audit-vendored-deps skill) so the bi-weekly dependency audit also covers non-Cargo vendored assets — Bootstrap SCSS/Icons, chicago-author-date CSL, tree-sitter highlight queries, quarto-cli built-in extensions, knitr R scripts, Pandoc HTML template, quarto-system-runtime JS bundles, reveal.js-menu CSS, etc. Discovery strategies and a per-asset inventory live at claude-notes/research/vendored-dependencies-inventory.md. Plan + phased work items at claude-notes/plans/2026-05-04-vendored-deps-audit.md.","status":"open","priority":2,"issue_type":"epic","created_at":"2026-05-04T21:14:02.442855Z","created_by":"cscheid","updated_at":"2026-05-04T21:14:02.442855Z","labels":["deps","vendored"]} +{"id":"bd-xoaic","title":"q2 get-config: emit merged document config as JSON","description":"GH #256. New CLI subcommand `q2 get-config <file> [yaml-path]` that returns the fully-merged document configuration (after _quarto.yml / _metadata.yml / frontmatter merge + format flattening) as JSON, so external tools don't have to reimplement Quarto 2 metadata-resolution semantics.\n\nEmpty path => entire merged metadata. Option to choose prose representation: plain/markdown string vs Pandoc AST JSON.\n\nReuses the parse+MetadataMerge (profile-checkpoint) pipeline; no engines/filters/render. Plan: claude-notes/plans/2026-06-02-get-config-command.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2026-06-02T22:40:37.283762Z","created_by":"cscheid","updated_at":"2026-06-03T02:14:39.874945Z"} +{"id":"bd-xs2u","title":"Em-dash / en-dash in document titles breaks something in hub-client","description":"User reported during L3 testing (2026-05-06): when uploading a project containing em-dash characters (U+2014, '—') in document titles, hub-client exhibits some bug. The user worked around it by replacing em-dashes with regular dashes in the Automerge documents.\n\nI (Claude) did not reproduce the bug myself; I only observed that the workaround (replace em-dash with single dash) made hub-client behave correctly afterwards. The bug could be in any of:\n- pampa parser handling of unicode dashes in YAML strings\n- hub-client / Monaco display of titles with non-ASCII characters\n- The Automerge text sync round-trip (less likely; bytes round-tripped identically in my test)\n\nReproduction (potentially):\n1. Create a Q2 .qmd with 'title: \"Some — text\"' (em-dash) in the frontmatter.\n2. Upload via scripts/upload-project.mjs to wss://sync.automerge.org.\n3. Open in hub-client and observe whatever the user observed.\n\nTo investigate: have the user describe the exact symptom (render error? blank title? wrong rendering?), then bisect against the affected component.\n\nDiscovered while testing L3 (bd-ml8z) listings via hub-client; see claude-notes/plans/2026-05-06-listings-L3-resolve-transform.md §\"Hand-off summary\".","status":"open","priority":2,"issue_type":"bug","created_at":"2026-05-06T22:08:24.119375Z","created_by":"cscheid","updated_at":"2026-05-06T22:08:24.119375Z","dependencies":{"bd-ml8z:discovered-from":{"depends_on_id":"bd-ml8z","type":"discovered-from","created_at":"2026-05-06T22:08:24.119375Z","created_by":"cscheid"}}} +{"id":"bd-xvdop","title":"Experiment: consolidate integration tests to reduce target/ size","description":"Rust defaults give each tests/*.rs file its own test binary, fully linked against the crate + all transitive deps. We have 164 integration test files across 20 crates; target/debug is currently 251 GB while target/release is 2.7 GB, suggesting per-file debug binaries are the dominant bloat. The ark project applied matklad's tests/integration/ consolidation pattern (posit-dev/ark#1240) and saw a ~57% drop in fresh cargo clean size and a ~3x drop in CI runner footprint. This issue tracks an experiment to measure the same change on Q2 from a macOS dev machine, piloting pampa (57 files) first before deciding on a full rollout. Plan: claude-notes/plans/2026-05-28-integration-test-consolidation.md","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-28T16:16:18.200610Z","created_by":"cscheid","updated_at":"2026-05-28T16:16:18.200610Z"} +{"id":"bd-xwq8","title":"Suppress page-nav for custom-layout pages","description":"Q1 hides the prev/next strip when a page sets page-layout: custom. Phase 4 ships without this; defer until a real page hits the edge case. See Phase 4 plan non-goals.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-24T22:47:57.195184Z","created_by":"cscheid","updated_at":"2026-04-24T22:47:57.195184Z","dependencies":{"bd-nwun:discovered-from":{"depends_on_id":"bd-nwun","type":"discovered-from","created_at":"2026-04-24T22:47:57.195184Z","created_by":"cscheid"}}} +{"id":"bd-xxul","title":"Non-.qmd input extensions in project discovery (.md, .ipynb, .Rmd)","description":"Phase 1 of the website epic explicitly discovers only .qmd files. The plan §File-list expansion defers the decision about which non-.qmd extensions are renderable documents (to include in project.files) vs. source artifacts (to treat like resources). Needs a user conversation about semantics for .md (literal markdown — render? copy?), .ipynb (converted at render time in Q1), .Rmd. Once settled, extend discovery and the pipeline's SourceType handling.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-24T01:05:32.255233Z","created_by":"cscheid","updated_at":"2026-04-24T01:05:32.255233Z","dependencies":{"bd-w5os:discovered-from":{"depends_on_id":"bd-w5os","type":"discovered-from","created_at":"2026-04-24T01:05:32.255233Z","created_by":"cscheid"}}} +{"id":"bd-y1fs3","title":"q2 preview: CodeBlock DOM mismatches q2 render — classes go on <code> instead of <pre>, sourceCode class missing","description":"q2 render emits '<pre class=\"sourceCode r cell-code\"><code><span class=\"hl-…\">…</span></code></pre>'; q2 preview emits '<pre><code class=\"r cell-code\"><span class=\"hl-…\">…</span></code></pre>'. Two divergences: (1) language/role classes are on <code> in preview, but on <pre> in render (native writer's behavior, see crates/pampa/src/writers/html.rs:963-975); (2) the 'sourceCode' class — prepended to <pre>'s class list whenever data-hl-spans is present (write_code_container_attr at line 487-495) — is entirely missing from preview. Both differences break Quarto theme rules that key off .sourceCode and pre.sourceCode, causing the visible spacing/indentation drift the user reported. Fix in React CodeBlock: move classes + data-* kvs to <pre>; bare <code>; prepend 'sourceCode' to <pre>'s class list when data-hl-spans is non-empty.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid","updated_at":"2026-05-18T17:44:55.722896Z","closed_at":"2026-05-18T17:44:55.722758Z","close_reason":"Implementation complete: React CodeBlock now mirrors the native HTML writer's DOM shape — classes + data-* kvs on <pre>, bare <code>, sourceCode prepended when data-hl-spans is present. Verified end-to-end: pre.className matches between q2 render and q2 preview ('sourceCode r cell-code' on both), code.className empty on both. 2 tests rewritten, 0 new added; 150/150 SPA integration tests green; cargo xtask verify 12/12 green.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid"},"bd-nxslt:related":{"depends_on_id":"bd-nxslt","type":"related","created_at":"2026-05-18T17:39:17.866285Z","created_by":"cscheid"}}} +{"id":"bd-y9zl","title":"Add pandoc.List metatable to all list-like tables in Lua API","description":"Tables returned from element field access (classes, BulletList/OrderedList/LineBlock/DefinitionList content, etc.) are created as plain Lua tables without the pandoc.List metatable. This means List methods like :includes(), :map(), :filter() are not available on these tables, breaking compatibility with the Pandoc Lua API and Quarto 1 filters. The fix is to set the List metatable on every table that represents a sequence.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-04-10T20:31:24.710801Z","created_by":"cscheid","updated_at":"2026-04-10T20:52:46.525642Z","closed_at":"2026-04-10T20:52:46.524965Z","close_reason":"Implemented: all classes and container content fields now carry the pandoc.List metatable"} +{"id":"bd-yd4q","title":"L9 follow-up: math handling in full feeds","description":"Port Q1's KaTeX/MathJax preservation pathways from readRenderedContents. Currently L9 v1 emits math notation as it appears in the rendered HTML (typically <span class=\"math\">$…$</span> or rendered KaTeX HTML). RSS readers without Quarto's CSS may not render this; subscribers can click through to the linked HTML page in the meantime. Reader extension lives in feed/reader_ext.rs; gated behind an RssReaderOptions flag (math handling is currently noted as forward-compat in the L7 reader). See claude-notes/plans/2026-05-08-listings-L9-rss-feeds.md §\"Out of scope for L9 (deferred)\".","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-08T17:33:09.979615Z","created_by":"cscheid","updated_at":"2026-05-08T17:33:09.979615Z","dependencies":{"bd-o90m:discovered-from":{"depends_on_id":"bd-o90m","type":"discovered-from","created_at":"2026-05-08T17:33:09.979615Z","created_by":"cscheid"}}} +{"id":"bd-ylig","title":"QMD writer drops shortcode arguments and delimiters","description":"User-reported round-trip failure: `printf '{{< video https://youtu.be/abc width=\"800\" height=\"450\" >}}\\n' | pampa -t qmd` produces `{{video}}` — losing the `{{<` / `>}}` delimiters, the URL positional arg, and named keyword args.\n\nRoot cause: `crates/pampa/src/writers/qmd.rs:1716` `write_shortcode` emits only `{{ + name + }}`, ignoring `is_escaped`, `positional_args`, and `keyword_args`. Even the no-arg form is wrong (qmd syntax requires `{{< name >}}`, not `{{name}}`).\n\nThe parser populates the `Shortcode` struct correctly; the JSON / native writers preserve all data via `shortcode_to_span`. Only the qmd writer is broken.\n\nThe existing roundtrip suite in `tests/roundtrip_tests/qmd-json-qmd/` does NOT catch this: it goes qmd → JSON → qmd, and the JSON writer converts `Inline::Shortcode` to `Inline::Span`, so `write_shortcode` is never exercised.\n\nPlan: claude-notes/plans/2026-04-30-shortcode-qmd-roundtrip.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-30T20:37:29.647311Z","created_by":"cscheid","updated_at":"2026-04-30T21:05:09.860926Z","closed_at":"2026-04-30T21:05:09.860702Z","close_reason":"Implemented qmd writer round-trip for shortcodes; switched keyword_args to LinkedHashMap for source-order preservation. End-to-end verified, full xtask verify green."} +{"id":"bd-yttl","title":"Expose CrossrefIndex from LSP analyze_document for future features","description":"The LSP analysis pipeline now builds a full CrossrefIndex (via CrossrefIndexTransform running inside AstTransformsStage). We currently extract symbols out of the post-pipeline AST and discard the StageContext.crossref_index. Future analysis features — unresolved-ref diagnostics (a dangling @fig-xyz), hover previews that show the target's rendered label, go-to-definition for @references — all want that index. Surface it on the DocumentAnalysis return value so callers can use it without re-running the pipeline.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-17T22:16:46.157105Z","created_by":"cscheid","updated_at":"2026-04-17T22:16:46.157105Z","dependencies":{"bd-ascs:discovered-from":{"depends_on_id":"bd-ascs","type":"discovered-from","created_at":"2026-04-17T22:16:46.157105Z","created_by":"cscheid"}}} +{"id":"bd-yu16","title":"[websites phase 7] Post-render: sitemap, favicon, site-url, title prefix","description":"Plan: claude-notes/plans/2026-04-23-website-project-epic.md § Phase 7.\n\nDeliverables:\n- WebsiteProjectType::post_render orchestration.\n- Sitemap generation at _site/sitemap.xml, gated on website.site-url. Incremental-aware: read existing, update entries, write.\n- robots.txt referencing sitemap if not already present.\n- Favicon: copy to output dir, inject <link rel=icon> in page head.\n- Title prefix: rendered <title> becomes '<page-title> — <website-title>'.\n- Tests against fixtures.\n\nBlocked by Phase 1.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-23T18:43:17.733419Z","created_by":"cscheid","updated_at":"2026-04-23T18:43:46.410213Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-23T18:43:17.733419Z","created_by":"cscheid"},"bd-w5os:blocks":{"depends_on_id":"bd-w5os","type":"blocks","created_at":"2026-04-23T18:43:46.409250Z","created_by":"cscheid"}}} +{"id":"bd-yxlh","title":"Full Q1 sidebar rollup parity (Decision B from bd-f5yi breakpoint plan)","description":"Port Q1's mid-range sidebar UX from external-sources/quarto-cli/.../navigation/quarto-nav.scss:558-590. Below the lg (992 px) breakpoint, take the floating sidebar out of the grid (position: static), stack it horizontally below the navbar with a border-bottom, and make it Bootstrap-collapsible — visible only when a hamburger toggle adds the .show class.\n\nCurrently we ship the smaller fix (Decision A, c8dcbcf6): hide the sidebar entirely below lg. That makes the layout honest but leaves no in-pane way to navigate to siblings at half-pane previews. Q1 parity restores that affordance.\n\nRequires:\n1. Bootstrap's collapse JS bundle to be loaded — blocked on bd-e7b7 (JS library loading).\n2. Markup emission: nav.quarto-secondary-nav strip with the hamburger toggle (data-bs-toggle / data-bs-target wired to the sidebar's id).\n3. SCSS: port the rules under media-breakpoint-down(lg) from quarto-nav.scss:558-590 (sidebar position:static, .collapsing/.show z-index 1000, etc.).\n\nWhen this lands, the bd-f5yi-followup commit's display:none rule should be replaced with the rollup pattern — keep that in mind to avoid drift.\n\nPlan: claude-notes/plans/2026-05-01-website-sidebar-breakpoints.md (Decision B + future deferred work).\n\nParent epic: bd-0tr6 (websites).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid","updated_at":"2026-05-01T17:00:47.128592Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid"},"bd-e7b7:blocks":{"depends_on_id":"bd-e7b7","type":"blocks","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid"},"bd-f5yi:related":{"depends_on_id":"bd-f5yi","type":"related","created_at":"2026-05-01T17:00:47.128592Z","created_by":"cscheid"}}} +{"id":"bd-yxqt","title":"Phase A.1+A.2: quarto preview CLI shim + crates/quarto-preview shell crate","description":"Add 'quarto preview' clap subcommand (mirror commands/hub.rs) + new crates/quarto-preview/ that owns CLI logic, embedded SPA serving (include_dir!), and the build.rs placeholder pattern (mirrors quarto-trace-server). Engine-less for Phase A. See claude-notes/plans/2026-05-13-q2-preview-phase-a.md §A.1, §A.2.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-05-13T16:53:27.986192Z","created_by":"cscheid","updated_at":"2026-05-13T17:43:16.279448Z","closed_at":"2026-05-13T17:43:16.279315Z","close_reason":"Phase A.1 (CLI shape) + A.2 (quarto-preview crate + SPA-serving + smoke tests) landed on branch beads/bd-yxqt-phase-a1a2-quarto-preview (commit e085ad75). Rust-side verify green (cargo xtask verify --skip-hub-build et al). A.5 will replace the NotImplemented stub with real boot.","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T16:53:27.986192Z","created_by":"cscheid"}}} +{"id":"bd-z2j7o","title":"Audit codebase for String→{String, SourceInfo} refactors; consider WithSourceInfo<T> wrapper","description":"As we add source-info to more data types (e.g. RawResourcePattern in bd-c1et2), we keep introducing ad-hoc wrappers of the shape:\n\n struct RawFoo { payload: String, source_info: SourceInfo }\n\nA parametric wrapper\n\n pub struct WithSourceInfo<T> {\n pub payload: T,\n pub source_info: SourceInfo,\n }\n impl<T> WithSourceInfo<T> { /* into_payload, as_ref, as_mut, map, ... */ }\n\nwould (a) eliminate boilerplate, (b) compose with iterators/traits, (c) make it easy to thread source info through generic code without writing a new struct each time.\n\nScope of the audit:\n1. Find existing ad-hoc wrappers of this shape across crates (likely candidates: quarto-core, quarto-yaml-validation, quarto-csl, quarto-pandoc-types, quarto-error-reporting). Grep for 'source_info:' adjacent to a payload field; check ConfigValue/ConfigMapEntry shape; check whether RawResourcePattern (bd-c1et2) qualifies.\n2. Decide whether unifying them on a common WithSourceInfo<T> is worth the churn — would all sites actually fit, or are some shaped enough differently (e.g. multiple spans per record) that a uniform wrapper would be procrustean?\n3. If yes: design the API (which methods, Deref or no, serde behavior, source-info-merging for derived values), prototype on one crate, fan out a small refactor in follow-up issues.\n4. If no: document the decision so the next person doesn't re-litigate it.\n\nNot urgent. Pick up when there's slack between user-facing features.","status":"open","priority":3,"issue_type":"task","created_at":"2026-05-21T21:58:55.016623Z","created_by":"cscheid","updated_at":"2026-05-21T21:58:55.016623Z","dependencies":{"bd-c1et2:discovered-from":{"depends_on_id":"bd-c1et2","type":"discovered-from","created_at":"2026-05-21T21:58:55.016623Z","created_by":"cscheid"}}} +{"id":"bd-z529","title":"Phase B.1: Broaden FileWatcher allow-list for q2 preview","description":"Replace is_qmd_file with a richer predicate that admits .qmd, _quarto.yml, _metadata.yml, .png/.jpg/.jpeg/.gif/.svg/.webp, and .tsx (defer _extensions/** per plan Q-B1).\n\nPlumb through HubConfig as a WatchFilter enum so the hub binary keeps .qmd-only and quarto-preview opts into broad. Tests first: unit tests in crates/quarto-hub/src/watch.rs plus an integration test that edits _quarto.yml and asserts the event surfaces.\n\nPlan: claude-notes/plans/2026-05-13-q2-preview-phase-b.md §B.1.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-13T19:34:52.716556Z","created_by":"cscheid","updated_at":"2026-05-13T19:56:05.279002Z","closed_at":"2026-05-13T19:56:05.278869Z","close_reason":"WatchFilter enum landed on feature/q2-preview-command (merge a528da4c). New PreviewBroad accepts _quarto.{yml,yaml}, _metadata.{yml,yaml}, image extensions, .tsx; hub keeps default QmdOnly. 5 unit + 2 integration tests in crates/quarto-hub/src/watch.rs. cargo xtask verify --skip-hub-build clean. End-to-end smoke verified through q2 preview binary (boot log shows filter=PreviewBroad; _quarto.yml edit produces File change detected + samod sync).","dependencies":{"bd-kw93:parent-child":{"depends_on_id":"bd-kw93","type":"parent-child","created_at":"2026-05-13T19:34:52.716556Z","created_by":"cscheid"}}} +{"id":"bd-z6we","title":"Kanban: Move status dropdown left of title","description":"Move the status dropdown in CardComponent.tsx from the bottom of the card to inline with the title, on the left side. Status and title should be on a single line. Plan: claude-notes/plans/2026-02-11-kanban-ui-enhancements.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-11T18:32:27.405581Z","created_by":"cscheid","updated_at":"2026-02-11T18:33:35.835738Z","closed_at":"2026-02-11T18:33:35.835721Z","close_reason":"Implemented - status dropdown moved to left of title"} +{"id":"bd-zb5k","title":"Suppress noisy 'lua error' panic stack traces in WASM (cosmetic — caught control flow)","description":"rust_lua_throw at crates/wasm-quarto-hub-client/src/c_shim.rs:452 panics with 'lua error' as a replacement for Lua's longjmp-based LUAI_THROW. The panics are caught by rust_lua_protected_call (catch_unwind) — this is expected control flow, not a bug. However, console_error_panic_hook prints the full stack trace for every panic, spamming both 'cargo xtask verify' output and hub-client production console (visible to users in browser).\n\nFix: install a custom panic hook that suppresses panics matching the Lua throw sentinel, while preserving full stack traces for genuine panics.\n\nThe hub-client e2e test helper already explicitly tolerates these as transient (hub-client/e2e/helpers/previewExtraction.ts:38-45).\n\nPlan: claude-notes/plans/2026-04-16-suppress-lua-panic-noise.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-16T18:20:50.553012Z","created_by":"cscheid","updated_at":"2026-04-16T19:08:52.428405Z","closed_at":"2026-04-16T19:08:52.427623Z","close_reason":"Implemented: LuaThrow sentinel + filter hook. cargo xtask verify clean (0 lua error mentions). Plan: claude-notes/plans/2026-04-16-suppress-lua-panic-noise.md"} +{"id":"bd-zerg","title":"Phase 9 follow-up: parallel Pass-1 over project files","description":"On a _quarto.yml edit, the Phase-8 cache-key invalidation propagates to every profile entry simultaneously. The orchestrator's pass_one loop (crates/quarto-core/src/project/orchestrator.rs) is sequential: it runs N head pipelines back-to-back. Trivially parallelizable since per-file work is independent.\n\nNative: rayon + pollster-per-worker (matches the rest of the pipeline's Send-free trait shape). WASM: futures::future::join_all over the WasmRuntime calls.\n\nPhase 9 plan §Risks calls this out — order-of-seconds latency on a 100-file project after a _quarto.yml edit. Active page render still feels snappy on warm-cache edits; this is the genuine cold-path.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid","updated_at":"2026-04-29T00:32:22.622408Z","dependencies":{"bd-0tr6:parent-child":{"depends_on_id":"bd-0tr6","type":"parent-child","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid"},"bd-ayj6:discovered-from":{"depends_on_id":"bd-ayj6","type":"discovered-from","created_at":"2026-04-29T00:32:22.622408Z","created_by":"cscheid"}}} +{"id":"bd-zh24","title":"Cargo: upgrade similar v2.7.0 → v3.1.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 2.7.0 is range-pinned in workspace; latest is 3.1.0. Type: major. Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.269126Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:44.640911Z","closed_at":"2026-05-04T20:30:44.640764Z","close_reason":"merged: 4c337eb6","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.611150Z","created_by":"cscheid"}}} +{"id":"bd-znva","title":"Cargo: upgrade sha2 v0.10.9 → v0.11.0","description":"Major upgrade surfaced by cargo-upgrade survey 2026-05-04. Current 0.10.9 is range-pinned in workspace; latest is 0.11.0. Type: pre-1.0 minor (semver-breaking). Review changelog and bump deliberately. See claude-notes/plans/2026-05-04-cargo-upgrade-survey.md and bd-hb8h.","status":"closed","priority":3,"issue_type":"chore","created_at":"2026-05-04T18:15:55.219569Z","created_by":"cscheid","updated_at":"2026-05-04T20:30:45.031277Z","closed_at":"2026-05-04T20:30:45.031138Z","close_reason":"merged: 0812812e","labels":["cargo","deps"],"dependencies":{"bd-hb8h:discovered-from":{"depends_on_id":"bd-hb8h","type":"discovered-from","created_at":"2026-05-04T18:16:05.527354Z","created_by":"cscheid"}}} +{"id":"bd-zpl4u","title":"Heading inside list item is silently dropped by AST converter","description":"Minimal repro: `* # Section 1` produces an empty BulletList in pampa, while Pandoc produces a BulletList containing a Header.\n\n```bash\necho '* # Section 1' | cargo run --bin pampa -- --to json | jq '.blocks'\n# → [{\"c\":[[]],\"s\":0,\"t\":\"BulletList\"}] (one empty item)\n\necho '* # Section 1' | pandoc -f markdown -t json | jq '.blocks'\n# → BulletList containing one Header block\n```\n\nRoot cause: tree-sitter correctly produces `list_item → section → atx_heading`, but `process_list_item` in crates/pampa/src/pandoc/treesitter.rs (lines 262–317) has no `filter_map` arm for `PandocNativeIntermediate::IntermediateSection`. The catch-all `_ => None` (line 306) silently discards the section and all the blocks it contains.\n\n`process_section` in crates/pampa/src/pandoc/treesitter_utils/section.rs (lines 27–29) already handles this case correctly by extending the block vector. The fix to `process_list_item` should mirror that pattern (the current shape — `filter_map` returning `Option<Block>` — can't flat-map a multi-block section, so it'll need a small refactor to a `Vec<Block>` builder loop).\n\nThis is a data-loss bug. Any list item that contains a heading (or anything else wrapped in a `section` intermediate) loses that content entirely.\n\nPlan: claude-notes/plans/2026-05-20-heading-in-list-item-dropped.md\n\nTDD: write the failing parser test first, then implement.\n\nRelated but distinct: bd-vet6 (multi-line block quote inside list item is a tree-sitter scanner bug, not a converter bug).","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-20T20:10:34.991088Z","created_by":"cscheid","updated_at":"2026-05-20T20:23:31.045315Z","closed_at":"2026-05-20T20:23:31.045143Z","close_reason":"Fixed: process_list_item now handles IntermediateSection by extending the block list (mirroring process_section). Refactored from filter_map to an explicit Vec<Block> builder so multi-block sections can be flattened. Also turned the previously-silent catch-all _ => None into a loud panic for unknown variants; added explicit no-op arms for IntermediateUnknown (ERROR nodes, marker delimiters) and bullet-marker node-name filters that preserve the existing tolerant behavior. Plan: claude-notes/plans/2026-05-20-heading-in-list-item-dropped.md","labels":["bug","pampa","parser"]} +{"id":"bd-zvh2p","title":"q2-preview: thread attribution through render_page_for_preview","description":"The hub-client's q2-preview surface has attribution-ready consumer wiring (`useAttributionHover`, `<AttributionWrap>` on the q2-preview dispatchers, `{attr.stylesheet}` / `{...attr.hostProps}` / `{attr.overlay}` interpolated in `PreviewDocument.tsx`). All of this is inert today because `render_page_for_preview` (in `crates/wasm-quarto-hub-client/src/lib.rs`) doesn't accept an `attribution_json` argument, so the active-page ctx never gets a `PreBuiltAttributionProvider` and the resulting AST JSON's `astContext.attribution*` fields are empty. With an empty `AttributionLookupContext`, `useAttributionHover` returns its inert form and the consumer wiring renders nothing — DOM stays byte-identical to pre-attribution.\n\nExtending `render_page_for_preview` to accept `attribution_json: Option<String>` and forward it through the same machinery `parse_qmd_to_ast_with_attribution` and `render_page_in_project_with_attribution` already use is the missing piece. Once it lands, the React side lights up automatically — no further hub-client changes required.\n\nProducer-side reference points:\n- `crates/wasm-quarto-hub-client/src/lib.rs` — `render_page_for_preview` and the shared `render_project_active_page_to_response` it delegates to. After the May 2026 merge of origin/main, the latter already takes `attribution_json: Option<String>`; the preview entry just needs to accept and forward it.\n- `crates/quarto-core/src/transforms/attribution_generate.rs` + `attribution_render.rs` — the transforms that read `ctx.attribution_provider` and populate `astContext.attribution*`.\n\nDiscovered while merging origin/main into feature/q2-preview-command (PR #190 attribution pipeline). See:\n- claude-notes/research/2026-05-19-attribution-merge-briefing.md (overall merge context)\n- claude-notes/research/2026-05-19-PreviewDocument-merge-resolution.md (the consumer-side analysis that surfaced this gap)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-19T16:15:43.566932Z","created_by":"cscheid","updated_at":"2026-05-19T16:15:43.566932Z","labels":["attribution","q2-preview"]} +{"id":"bd-zzke","title":"Consolidate six divergent inlines_to_(plain_)text helpers","description":"Six functions in tree share names but disagree on semantics: code/math contribution, Quoted wrapping characters, Note recursion, LineBreak handling, trimming. Sites: quarto-pandoc-types/src/config_value.rs:22, quarto-core/src/transforms/title_block.rs:144, quarto-core/src/transforms/metadata_normalize.rs:110, quarto-core/src/template.rs:626, quarto-config/src/format.rs:129, quarto-lsp-core/src/analysis.rs:713. Each call site has subtly different requirements. A clean consolidation likely needs an options-driven helper (PlainTextOptions { wrap_quoted, line_break_as, include_code, include_notes, ... }) plus per-site audit and tests so existing snapshots don't churn. Surfaced during L1 (bd-izqh) sub-plan review on 2026-05-06; deliberately deferred — L1 picks metadata_normalize's helper to reuse without consolidating. P3 hygiene; not a listings-epic blocker. Comparison table and reasoning in claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md when updated.","status":"open","priority":3,"issue_type":"chore","created_at":"2026-05-06T13:21:05.130039Z","created_by":"cscheid","updated_at":"2026-05-06T13:21:05.130039Z"} +{"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","created_by":"unknown","updated_at":"2025-12-21T21:40:02.851880Z"} +{"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","created_by":"unknown","updated_at":"2025-12-23T01:10:58.943494Z","closed_at":"2025-12-23T01:10:58.943494Z"} +{"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","created_by":"unknown","updated_at":"2025-12-06T00:23:28.822793Z","closed_at":"2025-12-06T00:23:28.822793Z"} +{"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","created_by":"unknown","updated_at":"2025-12-17T14:39:08.442844Z","closed_at":"2025-12-17T14:39:08.442844Z"} +{"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","created_by":"unknown","updated_at":"2025-12-22T22:24:39.178837Z"} +{"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","created_by":"unknown","updated_at":"2025-10-28T17:43:01.067279Z","closed_at":"2025-10-28T17:43:01.067279Z","dependencies":{"k-5:blocks":{"depends_on_id":"k-5","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-18T20:29:07.029816Z","created_by":"unknown","updated_at":"2025-10-18T20:33:05.814566Z","closed_at":"2025-10-18T20:33:05.814566Z","dependencies":{"k-9:blocks":{"depends_on_id":"k-9","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-21T14:25:31.725350Z","created_by":"unknown","updated_at":"2025-10-21T15:29:21.892234Z","closed_at":"2025-10-21T15:29:21.892234Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T15:29:21.905483Z","closed_at":"2025-10-21T15:29:21.905483Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T15:38:21.880567Z","closed_at":"2025-10-21T15:38:21.880567Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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 <anonymous> or <unknown> 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","created_by":"unknown","updated_at":"2025-10-21T17:50:22.100652Z","closed_at":"2025-10-21T17:50:22.100652Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T18:51:17.142583Z","closed_at":"2025-10-21T18:51:17.142583Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T19:25:31.639143Z","closed_at":"2025-10-21T19:25:31.639143Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T19:03:11.811461Z","closed_at":"2025-10-21T19:03:11.811461Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T19:06:33.632747Z","closed_at":"2025-10-21T19:06:33.632747Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T19:08:31.949797Z","closed_at":"2025-10-21T19:08:31.949797Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T20:10:55.413016Z","closed_at":"2025-10-21T20:10:55.413016Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-11","title":"Change treesitter_to_pandoc return type to Vec<DiagnosticMessage>","description":"Update function signature from Result<Pandoc, Vec<String>> to Result<Pandoc, Vec<DiagnosticMessage>> so caller decides output format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:38:24.598967Z","created_by":"unknown","updated_at":"2025-10-18T20:40:03.746055Z","closed_at":"2025-10-18T20:40:03.746055Z","dependencies":{"k-10:blocks":{"depends_on_id":"k-10","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:55:08.741639Z","closed_at":"2025-10-26T23:55:08.741639Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:49:18.075259Z","closed_at":"2025-10-26T23:49:18.075259Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:46:15.930561Z","closed_at":"2025-10-26T23:46:15.930561Z","dependencies":{"k-105:parent-child":{"depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:35:00.653765Z","closed_at":"2025-10-21T21:35:00.653765Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:35:18.025299Z","closed_at":"2025-10-21T21:35:18.025299Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:35:42.091665Z","closed_at":"2025-10-21T21:35:42.091665Z"} +{"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<DiagnosticMessage>, (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","created_by":"unknown","updated_at":"2025-10-21T21:36:44.314650Z","closed_at":"2025-10-21T21:36:44.314650Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:37:44.061757Z","closed_at":"2025-10-21T21:37:44.061757Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:45:38.861845Z","closed_at":"2025-10-21T21:45:38.861845Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:46:14.190057Z","closed_at":"2025-10-21T21:46:14.190057Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:58:49.265615Z","closed_at":"2025-10-18T20:58:49.265615Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:46:47.566335Z","closed_at":"2025-10-21T21:46:47.566335Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T21:59:53.715645Z","closed_at":"2025-10-21T21:59:53.715645Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T23:41:35.889473Z","closed_at":"2025-10-21T23:41:35.889473Z"} +{"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","created_by":"unknown","updated_at":"2025-10-21T23:59:07.392181Z","closed_at":"2025-10-21T23:59:07.392181Z"} +{"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","created_by":"unknown","updated_at":"2025-10-22T00:10:10.754049Z","closed_at":"2025-10-22T00:10:10.754049Z"} +{"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","created_by":"unknown","updated_at":"2025-10-22T00:19:24.518246Z","closed_at":"2025-10-22T00:19:24.518246Z"} +{"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","created_by":"unknown","updated_at":"2025-10-22T00:24:17.995116Z","closed_at":"2025-10-22T00:24:17.995116Z"} +{"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","created_by":"unknown","updated_at":"2025-10-22T01:26:37.015408Z","closed_at":"2025-10-22T01:26:37.015408Z"} +{"id":"k-128","title":"Optimize TreeSitterLogObserver::log() by eliminating HashMap","description":"Replace expensive HashMap<String, String> 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","created_by":"unknown","updated_at":"2025-10-22T11:39:14.817675Z","closed_at":"2025-10-22T11:39:14.817675Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:42:03.011089Z","closed_at":"2025-10-26T23:42:03.011089Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:59:41.186788Z","closed_at":"2025-10-18T20:59:41.186788Z","dependencies":{"k-12:blocks":{"depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-22T23:05:13.094318Z","closed_at":"2025-10-22T23:05:13.094318Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-22T23:08:33.467759Z","closed_at":"2025-10-22T23:08:34.467759Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:42:00.744388Z","closed_at":"2025-10-26T23:42:00.744388Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:42:01.495515Z","closed_at":"2025-10-26T23:42:01.495515Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:42:02.312977Z","closed_at":"2025-10-26T23:42:02.312977Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T20:08:57.586887Z","closed_at":"2025-10-24T20:08:57.586887Z","dependencies":{"k-129:discovered-from":{"depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:31:45.414849Z","closed_at":"2025-10-26T23:31:45.414849Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T02:59:40.261766Z","closed_at":"2025-10-23T02:59:40.261766Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T02:15:27.352089Z","closed_at":"2025-10-23T02:15:27.352089Z","dependencies":{"k-137:discovered-from":{"depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T02:19:09.658039Z","closed_at":"2025-10-23T02:19:09.658039Z","dependencies":{"k-137:discovered-from":{"depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:00:10.563035Z","closed_at":"2025-10-18T21:00:10.563035Z","dependencies":{"k-13:blocks":{"depends_on_id":"k-13","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-23T02:12:00.460817Z","created_by":"unknown","updated_at":"2025-10-23T02:19:09.671979Z","closed_at":"2025-10-23T02:19:09.671979Z","dependencies":{"k-137:discovered-from":{"depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T02:27:28.482932Z","closed_at":"2025-10-23T02:27:28.482932Z","dependencies":{"k-137:discovered-from":{"depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T02:57:13.812166Z","closed_at":"2025-10-23T02:57:13.812166Z","dependencies":{"k-137:discovered-from":{"depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T12:34:44.712870Z","closed_at":"2025-10-23T12:34:44.712870Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T12:34:44.727911Z","closed_at":"2025-10-23T12:34:44.727911Z","dependencies":{"k-143:discovered-from":{"depends_on_id":"k-143","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T12:34:44.741261Z","closed_at":"2025-10-23T12:34:44.741261Z","dependencies":{"k-143:discovered-from":{"depends_on_id":"k-143","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T13:20:40.231680Z","closed_at":"2025-10-23T13:20:40.231680Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T13:32:42.732198Z","closed_at":"2025-10-23T13:32:42.732198Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T13:45:31.672631Z","closed_at":"2025-10-23T13:45:31.672631Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T17:45:20.485265Z","closed_at":"2025-10-23T17:45:20.485265Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:01:41.486977Z","closed_at":"2025-10-18T21:01:41.486977Z"} +{"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","created_by":"unknown","updated_at":"2025-10-23T17:47:04.698524Z","closed_at":"2025-10-23T17:47:04.698524Z","dependencies":{"k-149:blocks":{"depends_on_id":"k-149","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T17:48:48.740615Z","closed_at":"2025-10-23T17:48:48.740615Z","dependencies":{"k-150:blocks":{"depends_on_id":"k-150","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-23T18:35:50.557744Z","closed_at":"2025-10-23T18:35:50.557744Z"} +{"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","created_by":"unknown","updated_at":"2025-10-24T13:36:00.404196Z","closed_at":"2025-10-24T13:36:00.404196Z"} +{"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","created_by":"unknown","updated_at":"2025-10-25T21:07:52.581349Z","closed_at":"2025-10-25T21:07:52.581349Z","dependencies":{"k-153:blocks":{"depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T21:14:20.529174Z","closed_at":"2025-10-25T21:14:20.529174Z","dependencies":{"k-153:blocks":{"depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-154:blocks":{"depends_on_id":"k-154","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T21:14:24.618835Z","closed_at":"2025-10-25T21:14:24.618835Z","dependencies":{"k-155:blocks":{"depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T21:14:28.790889Z","closed_at":"2025-10-25T21:14:28.790889Z","dependencies":{"k-155:blocks":{"depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T21:16:37.445561Z","closed_at":"2025-10-25T21:16:37.445561Z","dependencies":{"k-153:blocks":{"depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-154:blocks":{"depends_on_id":"k-154","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-155:blocks":{"depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-156:blocks":{"depends_on_id":"k-156","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-157:blocks":{"depends_on_id":"k-157","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:29:52.156094Z","closed_at":"2025-10-26T23:29:52.156094Z","dependencies":{"k-158:blocks":{"depends_on_id":"k-158","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:02:22.538397Z","closed_at":"2025-10-18T21:02:22.538397Z","dependencies":{"k-14:discovered-from":{"depends_on_id":"k-14","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","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-24T13:19:32.846057Z","created_by":"unknown","updated_at":"2025-10-24T13:19:32.846057Z","dependencies":{"k-159:blocks":{"depends_on_id":"k-159","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:27:04.140204Z","closed_at":"2025-10-24T15:27:04.140204Z","dependencies":{"k-153:blocks":{"depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T20:48:31.557376Z","closed_at":"2025-10-24T20:48:31.557376Z"} +{"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","created_by":"unknown","updated_at":"2025-11-23T13:21:55.528209Z","closed_at":"2025-11-23T13:21:56.528209Z","dependencies":{"k-162:blocks":{"depends_on_id":"k-162","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:54:27.543970Z","closed_at":"2025-10-24T15:54:27.543970Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:55:13.953795Z","closed_at":"2025-10-24T15:55:13.953795Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:56:24.260185Z","closed_at":"2025-10-24T15:56:24.260185Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:57:52.681088Z","closed_at":"2025-10-24T15:57:52.681088Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:46:36.162552Z","closed_at":"2025-10-24T15:46:36.162552Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T15:47:34.756365Z","closed_at":"2025-10-24T15:47:34.756365Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:02:50.910791Z","closed_at":"2025-10-18T21:02:50.910791Z","dependencies":{"k-14:discovered-from":{"depends_on_id":"k-14","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:06:00.607724Z","closed_at":"2025-10-24T16:06:00.607724Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:06:59.864233Z","closed_at":"2025-10-24T16:06:59.864233Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:07:40.188106Z","closed_at":"2025-10-24T16:07:40.188106Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:08:25.332487Z","closed_at":"2025-10-24T16:08:25.332487Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:09:22.376036Z","closed_at":"2025-10-24T16:09:22.376036Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:09:25.967312Z","closed_at":"2025-10-24T16:09:25.967312Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:12:39.359469Z","closed_at":"2025-10-24T16:12:39.359469Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T21:21:20.650903Z","closed_at":"2025-11-21T21:21:20.650903Z"} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:46:42.758620Z","closed_at":"2025-10-24T16:46:42.758620Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T16:54:23.889669Z","closed_at":"2025-10-24T16:54:23.889669Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-23T20:42:33.122903Z","closed_at":"2025-11-23T20:42:33.122903Z"} +{"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","created_by":"unknown","updated_at":"2025-10-24T17:15:46.089637Z","closed_at":"2025-10-24T17:15:46.089637Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T17:49:29.713001Z","closed_at":"2025-10-24T17:49:29.713001Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T17:57:51.624207Z","closed_at":"2025-10-24T17:57:51.624207Z","dependencies":{"k-162:discovered-from":{"depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T18:36:18.082815Z","closed_at":"2025-10-24T18:36:18.082815Z"} +{"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","created_by":"unknown","updated_at":"2025-10-24T18:55:21.564143Z","closed_at":"2025-10-24T18:55:21.564143Z","dependencies":{"k-183:discovered-from":{"depends_on_id":"k-183","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T17:39:58.876960Z","closed_at":"2025-10-27T17:39:58.876960Z","dependencies":{"k-184:discovered-from":{"depends_on_id":"k-184","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T20:53:20.459575Z","closed_at":"2025-10-24T20:53:20.459575Z","dependencies":{"k-163:blocks":{"depends_on_id":"k-163","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T20:59:11.937345Z","closed_at":"2025-10-24T20:59:11.937345Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T21:01:25.654773Z","closed_at":"2025-10-24T21:01:25.654773Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-24T21:02:20.215088Z","closed_at":"2025-10-24T21:02:20.215088Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:19:18.951040Z","closed_at":"2025-10-18T21:19:18.951040Z"} +{"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","created_by":"unknown","updated_at":"2025-10-24T23:55:37.165020Z","closed_at":"2025-10-24T23:55:37.165020Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T00:02:11.691055Z","closed_at":"2025-10-25T00:02:11.691055Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T20:09:44.542169Z","closed_at":"2025-11-22T20:09:44.542169Z","dependencies":{"k-186:blocks":{"depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-199:parent-child":{"depends_on_id":"k-199","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-226:parent-child":{"depends_on_id":"k-226","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-227:parent-child":{"depends_on_id":"k-227","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-228:parent-child":{"depends_on_id":"k-228","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-229:parent-child":{"depends_on_id":"k-229","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-230:parent-child":{"depends_on_id":"k-230","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:57:47.434955Z","closed_at":"2025-11-22T17:57:47.434955Z","dependencies":{"k-215:parent-child":{"depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T21:27:19.855441Z","closed_at":"2025-11-21T21:27:19.855441Z"} +{"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","created_by":"unknown","updated_at":"2025-11-21T22:43:30.621215Z","closed_at":"2025-11-21T22:43:30.621215Z","dependencies":{"k-194:blocks":{"depends_on_id":"k-194","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<Blocks> (items are just Vec<Block>)\n- OrderedList: content: Vec<Blocks>\n- DefinitionList: content: Vec<(Inlines, Vec<Blocks>)>\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","created_by":"unknown","updated_at":"2025-11-22T17:16:20.114640Z","dependencies":{"k-194:related":{"depends_on_id":"k-194","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:04:34.595797Z","closed_at":"2025-10-25T22:04:34.595797Z","dependencies":{"k-192:blocks":{"depends_on_id":"k-192","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T13:29:10.499327Z","closed_at":"2025-10-26T13:29:10.499327Z","dependencies":{"k-192:blocks":{"depends_on_id":"k-192","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T20:10:34.761200Z","closed_at":"2025-10-26T20:10:34.761200Z"} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:52:57.650458Z","closed_at":"2025-12-05T17:52:57.650458Z","dependencies":{"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:44:34.098318Z","dependencies":{"k-5u7d:blocks":{"depends_on_id":"k-5u7d","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-07T20:04:03.803304Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:03:54.064275Z","closed_at":"2025-10-18T20:03:54.064275Z","dependencies":{"k-1:parent-child":{"depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:19:23.558381Z","closed_at":"2025-10-18T21:19:23.558381Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:16:20.097895Z"} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:04:25.755776Z","closed_at":"2025-10-25T22:04:25.755776Z","dependencies":{"k-197:blocks":{"depends_on_id":"k-197","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:05:48.090250Z","closed_at":"2025-10-25T22:05:48.090250Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:12:44.094540Z","closed_at":"2025-10-25T22:12:44.094540Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-202:blocks":{"depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:19:35.159696Z","closed_at":"2025-10-25T22:19:35.159696Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-202:blocks":{"depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:23:17.567920Z","closed_at":"2025-10-25T22:23:17.567920Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-202:blocks":{"depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:32:59.817754Z","closed_at":"2025-10-25T22:32:59.817754Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-202:blocks":{"depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-25T22:36:04.510263Z","closed_at":"2025-10-25T22:36:04.510263Z","dependencies":{"k-201:discovered-from":{"depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-202:blocks":{"depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T13:19:08.044421Z","closed_at":"2025-10-26T13:19:08.044421Z","dependencies":{"k-198:blocks":{"depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T13:28:59.968188Z","closed_at":"2025-10-26T13:28:59.968188Z","dependencies":{"k-198:blocks":{"depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:05:55.916257Z","closed_at":"2025-10-18T22:05:55.916257Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T13:21:47.518356Z","closed_at":"2025-10-26T13:21:47.518356Z","dependencies":{"k-198:blocks":{"depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T16:01:13.072053Z","closed_at":"2025-10-26T16:01:13.072053Z","dependencies":{"k-215:parent-child":{"depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T19:11:24.255824Z","closed_at":"2025-10-26T19:11:24.255824Z","dependencies":{"k-215:parent-child":{"depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T16:58:31.135004Z","closed_at":"2025-10-26T16:58:31.135004Z","dependencies":{"k-215:parent-child":{"depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-23T13:23:08.030986Z","dependencies":{"k-215:parent-child":{"depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T18:41:12.897767Z","closed_at":"2025-10-26T18:41:12.897767Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:51:28.968013Z","closed_at":"2025-10-26T15:51:28.968013Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:52:07.126355Z","closed_at":"2025-10-26T15:52:07.126355Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-216:blocks":{"depends_on_id":"k-216","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:52:48.294202Z","closed_at":"2025-10-26T15:52:48.294202Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-217:blocks":{"depends_on_id":"k-217","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:55:17.061504Z","closed_at":"2025-10-26T15:55:17.061504Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-218:blocks":{"depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-22","title":"Create FileInformation struct in quarto-source-map","description":"Create new FileInformation struct with line_breaks: Vec<usize>, total_length: usize. Implement new(content: &str) to build line breaks, and offset_to_location(offset: usize) -> Option<Location> using binary search.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:02:56.232581Z","created_by":"unknown","updated_at":"2025-10-18T22:05:45.641994Z","closed_at":"2025-10-18T22:05:45.641994Z","dependencies":{"k-21:blocks":{"depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:56:38.514039Z","closed_at":"2025-10-26T15:56:38.514039Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-218:blocks":{"depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:59:03.606461Z","closed_at":"2025-10-26T15:59:03.606461Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-218:blocks":{"depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T15:59:39.285131Z","closed_at":"2025-10-26T15:59:39.285131Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-219:blocks":{"depends_on_id":"k-219","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-220:blocks":{"depends_on_id":"k-220","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-221:blocks":{"depends_on_id":"k-221","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T16:00:37.293217Z","closed_at":"2025-10-26T16:00:37.293217Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-222:blocks":{"depends_on_id":"k-222","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T16:01:03.217626Z","closed_at":"2025-10-26T16:01:03.217626Z","dependencies":{"k-211:parent-child":{"depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-223:blocks":{"depends_on_id":"k-223","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T16:58:22.696385Z","closed_at":"2025-10-26T16:58:22.696385Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T19:53:02.425030Z","closed_at":"2025-10-26T19:53:02.425030Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T19:59:08.815485Z","closed_at":"2025-10-26T19:59:08.815485Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:02:19.102887Z","closed_at":"2025-10-26T23:02:19.102887Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T19:42:44.401741Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:05:50.600484Z","closed_at":"2025-10-18T22:05:50.600484Z","dependencies":{"k-21:blocks":{"depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-22:blocks":{"depends_on_id":"k-22","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T20:09:34.747691Z","closed_at":"2025-11-22T20:09:34.747691Z"} +{"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","created_by":"unknown","updated_at":"2025-10-26T21:07:37.710896Z","closed_at":"2025-10-26T21:07:37.710896Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T20:37:15.192830Z","closed_at":"2025-10-26T20:37:15.192830Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T20:54:16.503510Z","closed_at":"2025-10-26T20:54:16.503510Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T21:10:41.080365Z","closed_at":"2025-10-26T21:10:41.080365Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T21:28:19.311741Z","closed_at":"2025-10-26T21:28:19.311741Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T21:47:18.290867Z","closed_at":"2025-10-26T21:47:18.290867Z","dependencies":{"k-228:discovered-from":{"depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:01:47.435407Z","closed_at":"2025-10-26T23:01:47.435407Z","dependencies":{"k-236:discovered-from":{"depends_on_id":"k-236","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-26T23:01:49.334469Z","closed_at":"2025-10-26T23:01:49.334469Z","dependencies":{"k-237:discovered-from":{"depends_on_id":"k-237","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T18:08:16.912137Z","closed_at":"2025-10-27T18:08:16.912137Z","dependencies":{"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-24","title":"Update SourceFile to use FileInformation","description":"Replace content: Option<String> with file_info: Option<FileInformation> 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","created_by":"unknown","updated_at":"2025-10-18T22:05:50.601812Z","closed_at":"2025-10-18T22:05:50.601812Z","dependencies":{"k-21:blocks":{"depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-23:blocks":{"depends_on_id":"k-23","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:08:07.071665Z","closed_at":"2025-10-27T19:08:07.071665Z","dependencies":{"k-239:blocks":{"depends_on_id":"k-239","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:12:40.073286Z","closed_at":"2025-10-27T19:12:40.073286Z","dependencies":{"k-240:blocks":{"depends_on_id":"k-240","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:23:12.685582Z","closed_at":"2025-10-27T19:23:12.685582Z","dependencies":{"k-241:blocks":{"depends_on_id":"k-241","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T18:26:27.793481Z","closed_at":"2025-10-27T18:26:27.793481Z","dependencies":{"k-240:blocks":{"depends_on_id":"k-240","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T20:44:24.504843Z","closed_at":"2025-10-27T20:44:24.504843Z"} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:38:17.309306Z","closed_at":"2025-10-27T19:38:17.309306Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T20:44:06.294854Z","closed_at":"2025-10-27T20:44:06.294854Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:46:02.772603Z","closed_at":"2025-10-27T19:46:02.772603Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:49:55.414023Z","closed_at":"2025-10-27T19:49:55.414023Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T19:58:22.784063Z","closed_at":"2025-10-27T19:58:22.784063Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:05:50.602620Z","closed_at":"2025-10-18T22:05:50.602620Z","dependencies":{"k-21:blocks":{"depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-24:blocks":{"depends_on_id":"k-24","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T20:06:09.812703Z","closed_at":"2025-10-27T20:06:09.812703Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-23T21:31:46.507675Z","dependencies":{"k-244:parent-child":{"depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T20:49:23.303020Z","closed_at":"2025-10-27T20:49:23.303020Z","dependencies":{"k-246:blocks":{"depends_on_id":"k-246","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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 <unknown> 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","created_by":"unknown","updated_at":"2025-10-28T00:00:17.403934Z","closed_at":"2025-10-28T00:00:17.403934Z"} +{"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 '<unknown>' 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","created_by":"unknown","updated_at":"2025-10-27T21:16:13.911919Z","closed_at":"2025-10-27T21:16:13.911919Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T23:42:53.114542Z","closed_at":"2025-10-27T23:42:53.114542Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-254:blocks":{"depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:16:20.080536Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-254:blocks":{"depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T21:17:17.713815Z","closed_at":"2025-10-27T21:17:17.713815Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:16:20.060665Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-254:blocks":{"depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-23T22:33:25.614765Z","closed_at":"2025-11-23T22:33:25.614765Z","dependencies":{"k-253:parent-child":{"depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:05:50.603342Z","closed_at":"2025-10-18T22:05:50.603342Z","dependencies":{"k-21:blocks":{"depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-25:blocks":{"depends_on_id":"k-25","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T21:49:11.657292Z","closed_at":"2025-10-27T21:49:11.657292Z","dependencies":{"k-259:parent-child":{"depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T22:32:26.093957Z","closed_at":"2025-10-27T22:32:26.093957Z","dependencies":{"k-259:parent-child":{"depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-260:blocks":{"depends_on_id":"k-260","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-263:blocks":{"depends_on_id":"k-263","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T23:47:22.612432Z","closed_at":"2025-10-27T23:47:22.612432Z","dependencies":{"k-259:parent-child":{"depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-261:blocks":{"depends_on_id":"k-261","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T22:18:56.921501Z","closed_at":"2025-10-27T22:18:56.921501Z","dependencies":{"k-259:parent-child":{"depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-27T22:53:08.602927Z","closed_at":"2025-10-27T22:53:08.602927Z"} +{"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<W: Write> 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","created_by":"unknown","updated_at":"2025-10-28T17:41:33.456561Z","closed_at":"2025-10-28T17:41:33.456561Z"} +{"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","created_by":"unknown","updated_at":"2025-10-28T17:41:10.099815Z","closed_at":"2025-10-28T17:41:10.099815Z","dependencies":{"k-265:parent-child":{"depends_on_id":"k-265","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-28T17:41:16.899192Z","closed_at":"2025-10-28T17:41:16.899192Z","dependencies":{"k-265:parent-child":{"depends_on_id":"k-265","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-266:blocks":{"depends_on_id":"k-266","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-28T16:15:27.884278Z","closed_at":"2025-10-28T16:15:27.884278Z"} +{"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","created_by":"unknown","updated_at":"2025-11-23T20:12:12.904383Z"} +{"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","created_by":"unknown","updated_at":"2025-10-20T20:01:48.597932Z","closed_at":"2025-10-20T20:01:48.597932Z","dependencies":{"k-26:blocks":{"depends_on_id":"k-26","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-28T17:46:03.678537Z","created_by":"unknown","updated_at":"2025-10-28T17:47:48.299992Z","closed_at":"2025-10-28T17:47:48.299992Z"} +{"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","created_by":"unknown","updated_at":"2025-10-28T21:32:43.820599Z","closed_at":"2025-10-28T21:32:43.820599Z"} +{"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","created_by":"unknown","updated_at":"2025-10-28T21:38:04.698925Z","closed_at":"2025-10-28T21:38:04.698925Z","dependencies":{"k-271:blocks":{"depends_on_id":"k-271","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-28T21:40:59.039113Z","closed_at":"2025-10-28T21:40:59.039113Z","dependencies":{"k-271:blocks":{"depends_on_id":"k-271","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-272:blocks":{"depends_on_id":"k-272","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T01:43:36.133317Z","closed_at":"2025-11-03T01:43:36.133317Z"} +{"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","created_by":"unknown","updated_at":"2025-10-31T14:48:36.628598Z","closed_at":"2025-10-31T14:48:36.628598Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T20:18:54.857654Z","closed_at":"2025-10-31T20:18:54.857654Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T17:24:44.809925Z","closed_at":"2025-10-31T17:24:44.809925Z","dependencies":{"k-276:blocks":{"depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T17:26:10.708652Z","closed_at":"2025-10-31T17:26:10.708652Z","dependencies":{"k-276:blocks":{"depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T17:26:10.724745Z","closed_at":"2025-10-31T17:26:10.724745Z","dependencies":{"k-276:blocks":{"depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:22:04.031733Z","closed_at":"2025-10-18T22:22:04.031733Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T17:26:10.740469Z","closed_at":"2025-10-31T17:26:10.740469Z","dependencies":{"k-276:blocks":{"depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T18:09:46.765Z","closed_at":"2025-10-31T18:09:46.765Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T21:26:24.646709Z","closed_at":"2025-10-31T21:26:24.646709Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T20:27:18.613533Z","closed_at":"2025-10-31T20:27:18.613533Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T20:34:08.012522Z","closed_at":"2025-10-31T20:34:08.012522Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T20:34:25.418640Z","closed_at":"2025-10-31T20:34:25.418640Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T21:06:03.468672Z","closed_at":"2025-10-31T21:06:03.468672Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T21:56:50.024368Z","closed_at":"2025-10-31T21:56:50.024368Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T22:31:33.507566Z","closed_at":"2025-10-31T22:31:33.507566Z"} +{"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","created_by":"unknown","updated_at":"2025-10-31T22:45:27.917951Z","closed_at":"2025-10-31T22:45:27.917951Z"} +{"id":"k-29","title":"Phase 1: Add parent source tracking to YamlBuilder","description":"Add parent_source_info: Option<SourceInfo> 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","created_by":"unknown","updated_at":"2025-10-18T22:38:35.985808Z","closed_at":"2025-10-18T22:38:35.985808Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-31T23:25:35.363177Z","closed_at":"2025-10-31T23:25:35.363177Z"} +{"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","created_by":"unknown","updated_at":"2025-10-31T23:43:51.661380Z","closed_at":"2025-10-31T23:43:51.661380Z"} +{"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","created_by":"unknown","updated_at":"2025-11-01T00:27:43.842428Z","closed_at":"2025-11-01T00:18:04.049524Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T00:33:23.693705Z","closed_at":"2025-11-01T00:33:23.693705Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T00:55:15.367334Z","closed_at":"2025-11-01T00:55:15.367334Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T00:01:04.973064Z","closed_at":"2025-11-01T00:01:04.973064Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T01:48:55.678220Z","closed_at":"2025-11-01T01:48:55.678220Z"} +{"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","created_by":"unknown","updated_at":"2025-11-01T02:14:33.743053Z","closed_at":"2025-11-01T02:14:33.743053Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T02:26:25.684869Z","closed_at":"2025-11-01T02:26:25.684869Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T02:32:27.301036Z","closed_at":"2025-11-01T02:32:27.301036Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T16:13:09.415728Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-03T19:55:59.905970Z","closed_at":"2026-01-03T19:55:59.905970Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-27T20:03:00.911330Z","closed_at":"2025-12-27T20:03:00.911330Z"} +{"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","created_by":"unknown","updated_at":"2025-12-30T03:55:24.256186Z","closed_at":"2025-12-30T03:55:24.256186Z","dependencies":{"k-ic1o:blocks":{"depends_on_id":"k-ic1o","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:14:40.405072Z","closed_at":"2025-10-18T20:14:40.405072Z","dependencies":{"k-1:parent-child":{"depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-2:blocks":{"depends_on_id":"k-2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-7:blocks":{"depends_on_id":"k-7","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:39:34.512581Z","closed_at":"2025-10-18T22:39:34.512581Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T03:01:51.434711Z","closed_at":"2025-11-01T03:01:51.434711Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T02:38:59.095103Z","closed_at":"2025-11-01T02:38:59.095103Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T02:42:05.008450Z","closed_at":"2025-11-01T02:42:05.008450Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T04:14:26.674066Z","closed_at":"2025-11-01T04:14:26.674066Z","dependencies":{"k-274:parent-child":{"depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T12:28:54.434190Z","closed_at":"2025-11-01T12:28:54.434190Z"} +{"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","created_by":"unknown","updated_at":"2025-11-01T12:28:42.208115Z","closed_at":"2025-11-01T12:28:42.208115Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T02:04:50.201748Z","closed_at":"2025-11-03T02:04:50.201748Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T01:50:25.625159Z","closed_at":"2025-11-03T01:50:25.625159Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T02:33:34.131856Z","closed_at":"2025-11-03T02:33:34.131856Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T13:59:13.885450Z","closed_at":"2025-11-03T13:59:14.885450Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:41:22.376621Z","closed_at":"2025-10-18T22:41:22.376621Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T14:06:29.115490Z","closed_at":"2025-11-03T14:06:29.115490Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T14:12:51.300456Z","closed_at":"2025-11-03T14:12:51.300456Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-01T20:00:04.740233Z","closed_at":"2025-11-01T20:00:04.740233Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T14:18:53.658811Z","closed_at":"2025-11-03T14:18:53.658811Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T14:41:02.451758Z","closed_at":"2025-11-03T14:41:02.451758Z","dependencies":{"k-274:discovered-from":{"depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-03T15:05:33.123244Z","closed_at":"2025-11-03T15:05:33.123244Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T15:54:03.088546Z","closed_at":"2025-11-03T15:54:03.088546Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T17:45:28.627632Z","closed_at":"2025-11-03T17:45:28.627632Z"} +{"id":"k-318","title":"Replace HashMap with LinkedHashMap in Attr type for deterministic ordering","description":"The Attr type uses HashMap<String, String> 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","created_by":"unknown","updated_at":"2025-11-03T20:04:22.926055Z","closed_at":"2025-11-03T20:04:22.926055Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T20:29:15.855063Z","closed_at":"2025-11-03T20:29:15.855063Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T22:43:13.262464Z","closed_at":"2025-10-18T22:43:13.262464Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-5:discovered-from":{"depends_on_id":"k-5","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T14:41:19.757841Z","closed_at":"2025-11-14T14:41:19.757841Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T21:13:26.130344Z","closed_at":"2025-11-03T21:13:26.130344Z"} +{"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","created_by":"unknown","updated_at":"2025-11-03T21:37:04.679866Z","closed_at":"2025-11-03T21:37:04.679866Z"} +{"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","created_by":"unknown","updated_at":"2025-11-04T00:14:19.103121Z","closed_at":"2025-11-04T00:14:19.103121Z"} +{"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","created_by":"unknown","updated_at":"2025-11-21T22:34:00.180804Z","closed_at":"2025-11-21T22:34:00.180804Z"} +{"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 ' <https://example.com>' instead of '<https://example.com>'. 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","created_by":"unknown","updated_at":"2025-11-04T15:49:05.993299Z","closed_at":"2025-11-04T15:49:05.993299Z","dependencies":{"k-324:parent-child":{"depends_on_id":"k-324","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-04T16:43:01.190870Z","closed_at":"2025-11-04T16:43:01.190870Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T00:21:50.917881Z","closed_at":"2025-11-22T00:21:50.917881Z","dependencies":{"k-326:blocks":{"depends_on_id":"k-326","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-05T01:29:16.200370Z","closed_at":"2025-11-05T01:29:16.200370Z"} +{"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","created_by":"unknown","updated_at":"2025-11-05T13:02:51.864538Z","closed_at":"2025-11-05T13:02:51.864538Z"} +{"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<FileId>. Embed SourceContext inside ASTContext per Option B design.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:36.662455Z","created_by":"unknown","updated_at":"2025-10-18T23:27:15.657617Z","closed_at":"2025-10-18T23:27:15.657617Z","dependencies":{"k-27:blocks":{"depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-05T19:46:40.465850Z","closed_at":"2025-11-05T19:46:40.465850Z"} +{"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","created_by":"unknown","updated_at":"2025-11-05T20:01:28.613813Z","closed_at":"2025-11-05T20:01:28.613813Z","dependencies":{"k-330:discovered-from":{"depends_on_id":"k-330","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-05T20:01:36.295285Z","closed_at":"2025-11-05T20:01:36.295285Z","dependencies":{"k-330:discovered-from":{"depends_on_id":"k-330","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-06T22:35:30.578778Z"} +{"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 <b>, <div> 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","created_by":"unknown","updated_at":"2025-11-12T14:36:00.378413Z","closed_at":"2025-11-12T14:36:00.378413Z"} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:40:55.718065Z","closed_at":"2025-11-12T19:40:55.718065Z"} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:32:36.891887Z","closed_at":"2025-11-12T19:32:36.891887Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:33:41.519292Z","closed_at":"2025-11-12T19:33:41.519292Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:36:15.751848Z","closed_at":"2025-11-12T19:36:15.751848Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:36:15.771082Z","closed_at":"2025-11-12T19:36:15.771082Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:48:16.603529Z","closed_at":"2025-11-22T17:48:16.603529Z"} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:37:36.301652Z","closed_at":"2025-11-12T19:37:36.301652Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-12T19:40:55.699049Z","closed_at":"2025-11-12T19:40:55.699049Z","dependencies":{"k-335:discovered-from":{"depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-13T20:39:11.144489Z","closed_at":"2025-11-13T20:39:11.144489Z"} +{"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","created_by":"unknown","updated_at":"2025-11-14T16:15:41.543373Z","closed_at":"2025-11-14T16:15:41.543373Z"} +{"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","created_by":"unknown","updated_at":"2025-11-14T17:10:24.027024Z","closed_at":"2025-11-14T17:10:24.027024Z"} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:29:05.396509Z","closed_at":"2025-11-14T19:29:05.396509Z"} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:05:14.240363Z","closed_at":"2025-11-14T19:05:14.240363Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:08:00.189647Z","closed_at":"2025-11-14T19:08:00.189647Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:10:12.751588Z","closed_at":"2025-11-14T19:10:12.751588Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:11:35.251671Z","closed_at":"2025-11-14T19:11:35.251671Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T00:04:48.900860Z","closed_at":"2025-11-22T00:04:48.900860Z","dependencies":{"k-34:parent-child":{"depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:17:10.408383Z","closed_at":"2025-11-14T19:17:10.408383Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:17:10.410164Z","closed_at":"2025-11-14T19:17:10.410164Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:17:10.410723Z","closed_at":"2025-11-14T19:17:10.410723Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:23:39.416458Z","closed_at":"2025-11-14T19:23:39.416458Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:23:39.418322Z","closed_at":"2025-11-14T19:23:39.418322Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:23:39.418988Z","closed_at":"2025-11-14T19:23:39.418988Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:23:39.419721Z","closed_at":"2025-11-14T19:23:39.419721Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:28:54.946892Z","closed_at":"2025-11-14T19:28:54.946892Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:28:54.948769Z","closed_at":"2025-11-14T19:28:54.948769Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:28:54.949325Z","closed_at":"2025-11-14T19:28:54.949325Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T00:04:49.822970Z","closed_at":"2025-11-22T00:04:49.822970Z","dependencies":{"k-34:parent-child":{"depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-14T19:28:54.949855Z","closed_at":"2025-11-14T19:28:54.949855Z","dependencies":{"k-345:parent-child":{"depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-15T01:04:00.707457Z","closed_at":"2025-11-15T01:04:00.707457Z"} +{"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","created_by":"unknown","updated_at":"2025-11-19T22:18:08.690160Z","closed_at":"2025-11-19T22:18:08.690160Z"} +{"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 '<metadata>' 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","created_by":"unknown","updated_at":"2025-11-20T20:27:40.567512Z","closed_at":"2025-11-20T20:27:40.567512Z"} +{"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","created_by":"unknown","updated_at":"2025-11-20T20:26:22.926768Z","closed_at":"2025-11-20T20:26:22.926768Z","dependencies":{"k-363:discovered-from":{"depends_on_id":"k-363","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-20T16:10:30.541919Z","closed_at":"2025-11-20T16:10:30.541919Z"} +{"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","created_by":"unknown","updated_at":"2025-11-20T16:28:28.684132Z","closed_at":"2025-11-20T16:28:28.684132Z","dependencies":{"k-365:blocks":{"depends_on_id":"k-365","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-20T19:59:11.904645Z","closed_at":"2025-11-20T19:59:11.904645Z"} +{"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","created_by":"unknown","updated_at":"2025-11-20T19:25:44.888949Z","closed_at":"2025-11-20T19:25:44.888949Z"} +{"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","created_by":"unknown","updated_at":"2025-11-20T20:52:07.524457Z","closed_at":"2025-11-20T20:52:07.524457Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:48:04.808557Z","closed_at":"2025-11-22T17:48:04.808557Z","dependencies":{"k-34:parent-child":{"depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-36:blocks":{"depends_on_id":"k-36","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T16:52:18.540504Z","closed_at":"2025-11-21T16:52:18.540504Z"} +{"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","created_by":"unknown","updated_at":"2025-11-21T16:52:19.237997Z","closed_at":"2025-11-21T16:52:19.237997Z"} +{"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","created_by":"unknown","updated_at":"2025-11-21T22:17:43.181211Z","closed_at":"2025-11-21T22:17:43.181211Z","dependencies":{"k-373:blocks":{"depends_on_id":"k-373","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T22:08:41.290257Z","closed_at":"2025-11-21T22:08:41.290257Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T00:25:25.520456Z","closed_at":"2025-11-22T00:25:25.520456Z","dependencies":{"k-327:discovered-from":{"depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-23T13:22:18.115493Z","closed_at":"2025-11-23T13:22:19.115493Z","dependencies":{"k-327:discovered-from":{"depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T01:24:47.758567Z","closed_at":"2025-11-22T01:24:47.758567Z","dependencies":{"k-327:discovered-from":{"depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-22T01:54:03.547745Z","closed_at":"2025-11-22T01:54:03.547745Z","dependencies":{"k-327:discovered-from":{"depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<DiagnosticMessage>>\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","created_by":"unknown","updated_at":"2025-11-22T00:39:09.781466Z","closed_at":"2025-11-22T00:39:09.781466Z","dependencies":{"k-375:discovered-from":{"depends_on_id":"k-375","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:42:04.043711Z","closed_at":"2025-11-25T19:42:04.043711Z"} +{"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","created_by":"unknown","updated_at":"2025-11-22T17:48:05.641805Z","closed_at":"2025-11-22T17:48:05.641805Z","dependencies":{"k-34:parent-child":{"depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-37:blocks":{"depends_on_id":"k-37","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-24T21:49:58.895960Z","closed_at":"2025-11-24T21:49:58.895960Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-24T17:54:04.183731Z","closed_at":"2025-11-24T17:54:04.183731Z"} +{"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","created_by":"unknown","updated_at":"2025-11-24T21:54:34.349376Z","closed_at":"2025-11-24T21:54:34.349376Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<String> (e.g., [\"employee\", \"salary\"])\n - pipes: Vec<Pipe>\n\n- Pipe struct with:\n - name: String\n - args: Vec<PipeArg>\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","created_by":"unknown","updated_at":"2025-11-24T22:05:32.336525Z","closed_at":"2025-11-24T22:05:32.336525Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-382:blocks":{"depends_on_id":"k-382","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<TemplateValue>)\n- Map(HashMap<String, TemplateValue>)\n- Null\n\nTemplateContext struct:\n- variables: HashMap<String, TemplateValue>\n- parent: Option<Box<TemplateContext>> 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","created_by":"unknown","updated_at":"2025-11-24T22:05:33.710566Z","closed_at":"2025-11-24T22:05:33.710566Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-382:blocks":{"depends_on_id":"k-382","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<TemplateNode>\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","created_by":"unknown","updated_at":"2025-11-24T22:56:27.881729Z","closed_at":"2025-11-24T22:56:27.881729Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-383:blocks":{"depends_on_id":"k-383","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T23:02:12.497544Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-385:blocks":{"depends_on_id":"k-385","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<String>\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","created_by":"unknown","updated_at":"2025-11-25T15:38:14.035683Z","closed_at":"2025-11-25T15:38:14.035683Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-384:blocks":{"depends_on_id":"k-384","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-385:blocks":{"depends_on_id":"k-385","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:41:49.942200Z","closed_at":"2025-11-25T19:41:49.942200Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-387:blocks":{"depends_on_id":"k-387","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T15:26:36.889681Z","closed_at":"2025-11-25T15:26:36.889681Z","dependencies":{"k-387:discovered-from":{"depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T00:31:09.547380Z","closed_at":"2025-10-19T00:31:09.547380Z","dependencies":{"k-27:parent-child":{"depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T15:26:38.203878Z","closed_at":"2025-11-25T15:26:38.203878Z","dependencies":{"k-387:discovered-from":{"depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T15:26:39.100972Z","closed_at":"2025-11-25T15:26:39.100972Z","dependencies":{"k-387:discovered-from":{"depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T16:17:19.603977Z","dependencies":{"k-387:discovered-from":{"depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-395:parent-child":{"depends_on_id":"k-395","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T15:26:40.878582Z","closed_at":"2025-11-25T15:26:40.878582Z","dependencies":{"k-387:discovered-from":{"depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T16:38:24.233547Z","closed_at":"2025-11-25T16:38:24.233547Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-387:blocks":{"depends_on_id":"k-387","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-396:blocks":{"depends_on_id":"k-396","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T16:17:37.633828Z"} +{"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","created_by":"unknown","updated_at":"2025-11-25T16:03:30.508450Z","closed_at":"2025-11-25T16:03:30.508450Z","dependencies":{"k-379:parent-child":{"depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.200536Z","closed_at":"2025-11-25T19:11:51.200536Z"} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.074435Z","closed_at":"2025-11-25T19:11:51.074435Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.094042Z","closed_at":"2025-11-25T19:11:51.094042Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T16:37:59.220906Z","closed_at":"2026-01-02T16:37:59.220906Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-06T20:11:18.440069Z","closed_at":"2025-12-06T20:11:18.440069Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T21:20:01.983787Z","closed_at":"2025-10-18T21:20:01.983787Z","dependencies":{"k-1:parent-child":{"depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-3:blocks":{"depends_on_id":"k-3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<quarto_source_map::SourceInfo>' 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","created_by":"unknown","updated_at":"2025-10-19T00:38:50.085409Z","closed_at":"2025-10-19T00:38:50.085409Z","dependencies":{"k-27:parent-child":{"depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-39:blocks":{"depends_on_id":"k-39","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.113212Z","closed_at":"2025-11-25T19:11:51.113212Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.130469Z","closed_at":"2025-11-25T19:11:51.130469Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.147737Z","closed_at":"2025-11-25T19:11:51.147737Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.165301Z","closed_at":"2025-11-25T19:11:51.165301Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:15:37.665909Z","closed_at":"2025-11-25T19:15:37.665909Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<DiagnosticMessage>)\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","created_by":"unknown","updated_at":"2025-11-25T18:08:35.769022Z","closed_at":"2025-11-25T18:08:35.769022Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-25T19:11:51.183021Z","closed_at":"2025-11-25T19:11:51.183021Z","dependencies":{"k-397:blocks":{"depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-26T15:21:24.129138Z"} +{"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","created_by":"unknown","updated_at":"2025-12-02T14:11:40.923141Z","closed_at":"2025-12-02T14:11:40.923141Z","dependencies":{"k-407:parent-child":{"depends_on_id":"k-407","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T19:35:48.602062Z","dependencies":{"k-407:parent-child":{"depends_on_id":"k-407","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T00:39:10.753194Z","closed_at":"2025-10-19T00:39:10.753194Z","dependencies":{"k-27:parent-child":{"depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-40:blocks":{"depends_on_id":"k-40","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:39:55.842344Z"} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:04:55.611804Z","closed_at":"2025-11-27T17:04:55.611804Z","dependencies":{"k-410:parent-child":{"depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T19:21:10.731725Z","closed_at":"2025-11-27T19:21:10.731725Z","dependencies":{"k-410:parent-child":{"depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-411:blocks":{"depends_on_id":"k-411","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:01:45.534141Z","closed_at":"2025-11-27T17:01:45.534141Z","dependencies":{"k-411:parent-child":{"depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:02:06.043105Z","closed_at":"2025-11-27T17:02:06.043105Z","dependencies":{"k-411:parent-child":{"depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-413:blocks":{"depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:04:15.346252Z","closed_at":"2025-11-27T17:04:15.346252Z","dependencies":{"k-411:parent-child":{"depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-413:blocks":{"depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:02:20.701548Z","closed_at":"2025-11-27T17:02:20.701548Z","dependencies":{"k-411:parent-child":{"depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-413:blocks":{"depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:04:37.326057Z","closed_at":"2025-11-27T17:04:37.326057Z","dependencies":{"k-411:parent-child":{"depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-413:blocks":{"depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:31:41.294011Z","closed_at":"2025-11-27T17:31:41.294011Z","dependencies":{"k-411:discovered-from":{"depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:33:26.358626Z","closed_at":"2025-11-27T17:33:26.358626Z","dependencies":{"k-411:discovered-from":{"depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<SourceInfo> 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","created_by":"unknown","updated_at":"2025-11-23T21:31:08.197492Z","dependencies":{"k-27:related":{"depends_on_id":"k-27","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-49:blocks":{"depends_on_id":"k-49","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-50:blocks":{"depends_on_id":"k-50","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:35:50.881377Z","closed_at":"2025-11-27T17:35:50.881377Z","dependencies":{"k-411:discovered-from":{"depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-419:blocks":{"depends_on_id":"k-419","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T17:36:41.069830Z","closed_at":"2025-11-27T17:36:41.069830Z","dependencies":{"k-411:discovered-from":{"depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-420:blocks":{"depends_on_id":"k-420","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:39:26.789258Z","dependencies":{"k-412:blocks":{"depends_on_id":"k-412","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T21:09:46.829119Z","closed_at":"2025-11-27T21:09:46.829119Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-27T21:42:22.993502Z","closed_at":"2025-11-27T21:42:22.993502Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:49.665867Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-424:blocks":{"depends_on_id":"k-424","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:39:05.064799Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-425:blocks":{"depends_on_id":"k-425","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:56.733561Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-426:blocks":{"depends_on_id":"k-426","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:43.145568Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T01:08:34.290502Z","closed_at":"2025-11-28T01:08:34.290502Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-43","title":"Performance: Optimize SourceMapping to use Rc/Arc instead of Box","description":"SourceMapping currently uses Box<SourceInfo> 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<SourceInfo> or Arc<SourceInfo> to make cloning cheap (reference counting). Need to study: serialization implications, thread-safety requirements, and performance benchmarks.","notes":"RECOMMENDATION: Use Rc<SourceInfo> instead of Box<SourceInfo>.\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<SourceInfo> → Rc<SourceInfo>\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","created_by":"unknown","updated_at":"2025-10-19T13:37:10.883135Z","closed_at":"2025-10-19T13:37:10.883135Z","dependencies":{"k-27:related":{"depends_on_id":"k-27","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T01:41:14.539423Z","closed_at":"2025-11-28T01:41:14.539423Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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: '<i>Title</i>' 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","created_by":"unknown","updated_at":"2025-11-28T01:48:43.349730Z","closed_at":"2025-11-28T01:48:43.349730Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-432","title":"Implement flip-flop formatting","description":"When italic is applied to content already containing <i>, nested italics should flip to normal using <span style='font-style:normal;'>. 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","created_by":"unknown","updated_at":"2025-11-28T02:09:50.056754Z","closed_at":"2025-11-28T02:09:50.056754Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T01:59:06.682741Z","closed_at":"2025-11-28T01:59:06.682741Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T02:27:32.265412Z","closed_at":"2025-11-28T02:27:32.265412Z","dependencies":{"k-422:discovered-from":{"depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T20:03:36.943769Z","closed_at":"2025-11-29T20:03:36.943769Z","dependencies":{"k-433:discovered-from":{"depends_on_id":"k-433","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T20:03:41.974135Z","closed_at":"2025-11-29T20:03:41.974135Z","dependencies":{"k-433:discovered-from":{"depends_on_id":"k-433","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T18:07:43.402073Z","closed_at":"2025-11-28T18:07:43.402073Z"} +{"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","created_by":"unknown","updated_at":"2025-11-28T16:03:39.592859Z","closed_at":"2025-11-28T16:03:39.592859Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T16:09:07.167129Z","closed_at":"2025-11-28T16:09:07.167129Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-438:blocks":{"depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T20:09:12.027921Z","closed_at":"2025-10-20T20:09:12.027921Z","dependencies":{"k-34:related":{"depends_on_id":"k-34","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-43:related":{"depends_on_id":"k-43","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T16:09:07.187101Z","closed_at":"2025-11-28T16:09:07.187101Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-438:blocks":{"depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T16:15:26.022830Z","closed_at":"2025-11-28T16:15:26.022830Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-438:blocks":{"depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T17:56:18.167906Z","closed_at":"2025-11-28T17:56:18.167906Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-438:blocks":{"depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T18:07:32.662010Z","closed_at":"2025-11-28T18:07:32.662010Z","dependencies":{"k-437:parent-child":{"depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-438:blocks":{"depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:32.516951Z"} +{"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","created_by":"unknown","updated_at":"2025-11-28T20:12:59.745492Z","closed_at":"2025-11-28T20:12:59.745492Z"} +{"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","created_by":"unknown","updated_at":"2025-11-28T20:15:43.161183Z","closed_at":"2025-11-28T20:15:43.161183Z","dependencies":{"k-445:blocks":{"depends_on_id":"k-445","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-28T20:31:25.900914Z","closed_at":"2025-11-28T20:31:25.900914Z"} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:22.468703Z"} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:38:15.598805Z"} +{"id":"k-45","title":"Phase 4: Design and implement MetaWithSourceInfo structure","description":"Replace Meta (LinkedHashMap<String, MetaValue>) 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","created_by":"unknown","updated_at":"2025-10-20T20:04:31.593778Z","closed_at":"2025-10-20T20:04:31.593778Z","dependencies":{"k-27:parent-child":{"depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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 `<name-part>` 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","created_by":"unknown","updated_at":"2025-11-29T20:08:00.894711Z","closed_at":"2025-11-29T20:08:00.894711Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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: `<i>Givenname</i> <i>al</i>`\nActual: `<i>Givenname al</i>`\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","created_by":"unknown","updated_at":"2025-11-29T19:39:53.245554Z","closed_at":"2025-11-29T19:39:53.245554Z","dependencies":{"k-450:discovered-from":{"depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T18:46:32.542137Z","closed_at":"2025-11-29T18:46:32.542137Z","dependencies":{"k-450:discovered-from":{"depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T18:46:31.396474Z","closed_at":"2025-11-29T18:46:31.396474Z","dependencies":{"k-450:discovered-from":{"depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T18:18:00.913473Z","closed_at":"2025-11-29T18:18:00.913473Z"} +{"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","created_by":"unknown","updated_at":"2025-11-29T20:12:02.663648Z","closed_at":"2025-11-29T20:12:02.663648Z","dependencies":{"k-436:discovered-from":{"depends_on_id":"k-436","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T20:12:03.427389Z","closed_at":"2025-11-29T20:12:03.427389Z","dependencies":{"k-436:discovered-from":{"depends_on_id":"k-436","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T21:11:31.817796Z","closed_at":"2025-11-29T21:11:31.817796Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T21:27:52.875388Z","closed_at":"2025-11-29T21:27:52.875388Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-29T23:22:58.185735Z","closed_at":"2025-11-29T23:22:58.185735Z","dependencies":{"k-422:parent-child":{"depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T14:13:21.642330Z","closed_at":"2025-10-19T14:13:21.642330Z","dependencies":{"k-45:parent-child":{"depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T00:24:58.065969Z","closed_at":"2025-11-30T00:24:58.065969Z","dependencies":{"k-459:related":{"depends_on_id":"k-459","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:39:48.849997Z","dependencies":{"k-410:discovered-from":{"depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T00:39:39.256509Z","dependencies":{"k-410:discovered-from":{"depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T15:28:19.259304Z","closed_at":"2025-11-30T15:28:19.259304Z","dependencies":{"k-410:discovered-from":{"depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T17:30:20.907173Z","closed_at":"2025-11-30T17:30:20.907173Z","dependencies":{"k-410:parent-child":{"depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T19:05:57.671644Z","closed_at":"2025-11-30T19:05:57.671644Z","dependencies":{"k-432:discovered-from":{"depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-466","title":"CSL: Parse HTML entities as markup in text values","description":"HTML entities in <text value=\"...\"/> should be unescaped and interpreted as markup. Currently <b> is output literally instead of being parsed as <b>. 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","created_by":"unknown","updated_at":"2025-11-30T18:37:17.862362Z","closed_at":"2025-11-30T18:37:17.862362Z","dependencies":{"k-432:discovered-from":{"depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T18:50:15.848404Z","closed_at":"2025-11-30T18:50:15.848404Z","dependencies":{"k-432:discovered-from":{"depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-30T19:45:15.789582Z","closed_at":"2025-11-30T19:45:15.789582Z","dependencies":{"k-465:discovered-from":{"depends_on_id":"k-465","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T18:12:17.896290Z","closed_at":"2025-12-02T18:12:17.896290Z","dependencies":{"k-409:blocks":{"depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T14:17:44.723311Z","closed_at":"2025-10-19T14:17:44.723311Z","dependencies":{"k-45:parent-child":{"depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-46:blocks":{"depends_on_id":"k-46","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T18:32:20.722738Z","closed_at":"2025-12-02T18:32:20.722738Z","dependencies":{"k-469:blocks":{"depends_on_id":"k-469","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T18:56:21.923872Z","closed_at":"2025-12-02T18:56:21.923872Z","dependencies":{"k-470:blocks":{"depends_on_id":"k-470","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T21:05:14.135869Z","closed_at":"2025-12-02T21:05:14.135869Z","dependencies":{"k-471:blocks":{"depends_on_id":"k-471","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T22:14:30.672190Z","dependencies":{"k-409:related":{"depends_on_id":"k-409","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T22:53:10.573147Z","closed_at":"2025-12-02T22:53:10.573147Z","dependencies":{"k-409:blocks":{"depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-04T14:29:40.472449Z","dependencies":{"k-409:blocks":{"depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-02T22:33:30.243699Z","dependencies":{"k-409:blocks":{"depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-490:related":{"depends_on_id":"k-490","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T15:18:30.243945Z","closed_at":"2025-12-03T15:18:30.243945Z","dependencies":{"k-409:discovered-from":{"depends_on_id":"k-409","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T01:48:57.671782Z","closed_at":"2025-12-03T01:48:57.671782Z","dependencies":{"k-477:discovered-from":{"depends_on_id":"k-477","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T15:18:31.006010Z","closed_at":"2025-12-03T15:18:31.006010Z","dependencies":{"k-477:discovered-from":{"depends_on_id":"k-477","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-478:blocks":{"depends_on_id":"k-478","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T14:24:09.733868Z","closed_at":"2025-10-19T14:24:09.733868Z","dependencies":{"k-45:parent-child":{"depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-47:blocks":{"depends_on_id":"k-47","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T15:53:30.532131Z","closed_at":"2025-12-03T15:53:30.532131Z","dependencies":{"k-409:discovered-from":{"depends_on_id":"k-409","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T16:57:39.450950Z","closed_at":"2025-12-03T16:57:39.450950Z","dependencies":{"k-480:discovered-from":{"depends_on_id":"k-480","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T19:25:57.044049Z","closed_at":"2025-12-03T19:25:57.044049Z","dependencies":{"k-475:blocks":{"depends_on_id":"k-475","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T19:25:58.186288Z","closed_at":"2025-12-03T19:25:58.186288Z","dependencies":{"k-482:blocks":{"depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-04T14:29:23.938869Z","dependencies":{"k-482:blocks":{"depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-04T14:29:29.166127Z","dependencies":{"k-482:blocks":{"depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T20:04:08.541192Z","closed_at":"2025-12-03T20:04:08.541192Z","dependencies":{"k-473:blocks":{"depends_on_id":"k-473","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T22:19:54.038912Z","closed_at":"2025-12-03T22:19:54.038912Z","dependencies":{"k-486:blocks":{"depends_on_id":"k-486","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T22:36:56.224766Z","closed_at":"2025-12-03T22:36:56.224766Z","dependencies":{"k-487:blocks":{"depends_on_id":"k-487","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T22:52:45.423477Z","closed_at":"2025-12-03T22:52:45.423477Z","dependencies":{"k-488:blocks":{"depends_on_id":"k-488","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T16:04:06.866105Z","closed_at":"2025-10-19T16:04:06.866105Z","dependencies":{"k-45:parent-child":{"depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-48:blocks":{"depends_on_id":"k-48","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T19:48:36.751574Z","dependencies":{"k-489:blocks":{"depends_on_id":"k-489","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T23:07:51.384615Z","dependencies":{"k-490:blocks":{"depends_on_id":"k-490","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-03T22:59:12.611465Z","dependencies":{"k-491:blocks":{"depends_on_id":"k-491","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T20:33:29.866817Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-08T20:02:35.709646Z"} +{"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","created_by":"unknown","updated_at":"2025-12-20T18:10:00.065583Z","dependencies":{"k-b1x1:blocks":{"depends_on_id":"k-b1x1","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:29:40.921902Z","closed_at":"2025-10-18T20:29:40.921902Z"} +{"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","created_by":"unknown","updated_at":"2025-10-19T18:35:07.223867Z","closed_at":"2025-10-19T18:35:07.223867Z","dependencies":{"k-45:parent-child":{"depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-49:blocks":{"depends_on_id":"k-49","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-51:blocks":{"depends_on_id":"k-51","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T14:30:13.120375Z","closed_at":"2025-10-19T14:30:13.120375Z"} +{"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<YamlWithSourceInfo>, SourceInfo)>\n- into_hash() -> Option<(Vec<YamlHashEntry>, 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","created_by":"unknown","updated_at":"2025-10-19T15:27:03.395761Z","closed_at":"2025-10-19T15:27:03.395761Z"} +{"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","created_by":"unknown","updated_at":"2025-10-19T15:28:28.405622Z","closed_at":"2025-10-19T15:28:28.405622Z","dependencies":{"k-52:blocks":{"depends_on_id":"k-52","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T20:32:57.307896Z","closed_at":"2025-10-20T20:32:57.307896Z","dependencies":{"k-35:blocks":{"depends_on_id":"k-35","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-49:discovered-from":{"depends_on_id":"k-49","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T16:11:33.697790Z","closed_at":"2025-10-19T16:11:33.697790Z","dependencies":{"k-49:discovered-from":{"depends_on_id":"k-49","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-19T17:53:13.554596Z","closed_at":"2025-10-19T17:53:13.554596Z"} +{"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","created_by":"unknown","updated_at":"2025-10-19T19:15:45.496951Z","closed_at":"2025-10-19T19:15:45.496951Z","dependencies":{"k-44:blocks":{"depends_on_id":"k-44","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T21:18:15.209080Z","closed_at":"2025-11-21T21:18:15.209080Z","dependencies":{"k-57:blocks":{"depends_on_id":"k-57","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T22:50:54.809108Z","closed_at":"2025-11-21T22:50:54.809108Z","dependencies":{"k-58:blocks":{"depends_on_id":"k-58","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-07T20:25:57.601925Z","closed_at":"2025-12-07T20:25:57.601925Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T23:25:12.290518Z"} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:54:10.567791Z","closed_at":"2025-12-05T17:54:10.567791Z","dependencies":{"k-u1iy:blocks":{"depends_on_id":"k-u1iy","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-05T22:12:23.959817Z","closed_at":"2025-12-05T22:12:23.959817Z"} +{"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","created_by":"unknown","updated_at":"2025-12-06T17:31:05.489645Z","closed_at":"2025-12-06T17:31:05.489645Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:30:15.033025Z","closed_at":"2025-10-18T20:30:15.033025Z","dependencies":{"k-12:blocks":{"depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-2:blocks":{"depends_on_id":"k-2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-3:blocks":{"depends_on_id":"k-3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-4:blocks":{"depends_on_id":"k-4","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-19T19:08:19.728117Z","created_by":"unknown","updated_at":"2025-11-21T22:58:27.168763Z","closed_at":"2025-11-21T22:58:27.168763Z","dependencies":{"k-59:blocks":{"depends_on_id":"k-59","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T23:30:14.960862Z","closed_at":"2025-11-21T23:30:14.960862Z","dependencies":{"k-60:blocks":{"depends_on_id":"k-60","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T14:35:15.084731Z","closed_at":"2025-10-20T14:35:15.084731Z"} +{"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<quarto_source_map::SourceInfo> 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","created_by":"unknown","updated_at":"2025-10-20T18:08:15.349955Z","closed_at":"2025-10-20T18:08:15.349955Z","dependencies":{"k-27:parent-child":{"depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T15:15:58.737432Z","closed_at":"2025-10-20T15:15:58.737432Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-65","title":"Add source_info_qsm to all Inline types in inline.rs","description":"Add 'pub source_info_qsm: Option<quarto_source_map::SourceInfo>' 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","created_by":"unknown","updated_at":"2025-10-20T15:33:20.994543Z","closed_at":"2025-10-20T15:33:20.994543Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-64:blocks":{"depends_on_id":"k-64","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-66","title":"Add source_info_qsm to all Block types in block.rs","description":"Add 'pub source_info_qsm: Option<quarto_source_map::SourceInfo>' 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","created_by":"unknown","updated_at":"2025-10-20T15:33:21.009695Z","closed_at":"2025-10-20T15:33:21.009695Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-64:blocks":{"depends_on_id":"k-64","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:21:55.811406Z","closed_at":"2025-10-20T16:21:55.811406Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-65:blocks":{"depends_on_id":"k-65","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-66:blocks":{"depends_on_id":"k-66","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:26:25.717196Z","closed_at":"2025-10-20T16:26:25.717196Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-67:blocks":{"depends_on_id":"k-67","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","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-20T15:04:18.157380Z","created_by":"unknown","updated_at":"2025-10-20T17:52:21.024388Z","closed_at":"2025-10-20T17:52:21.024388Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-68:blocks":{"depends_on_id":"k-68","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-05T23:34:49.291138Z","closed_at":"2026-01-05T23:34:49.291138Z"} +{"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","created_by":"unknown","updated_at":"2025-12-15T21:54:35.598252Z"} +{"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","created_by":"unknown","updated_at":"2025-12-21T16:30:54.707146Z","dependencies":{"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T17:57:18.729364Z","closed_at":"2025-12-31T17:57:18.729364Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-23T00:52:26.137510Z","closed_at":"2025-12-23T00:52:26.137510Z","dependencies":{"k-nkhl:discovered-from":{"depends_on_id":"k-nkhl","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:30:37.920982Z","closed_at":"2025-10-18T20:30:37.920982Z","dependencies":{"k-12:blocks":{"depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-20T15:04:26.832490Z","created_by":"unknown","updated_at":"2025-10-20T18:25:36.442096Z","closed_at":"2025-10-20T18:25:36.442096Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-69:blocks":{"depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T20:01:18.681793Z","closed_at":"2025-10-20T20:01:18.681793Z","dependencies":{"k-63:parent-child":{"depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-70:blocks":{"depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T15:43:44.018029Z","closed_at":"2025-10-20T15:43:44.018029Z","dependencies":{"k-65:blocks":{"depends_on_id":"k-65","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-66:blocks":{"depends_on_id":"k-66","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T15:45:41.347372Z","closed_at":"2025-10-20T15:45:41.347372Z","dependencies":{"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-72:blocks":{"depends_on_id":"k-72","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:21:57.363200Z","closed_at":"2025-10-20T16:21:57.363200Z","dependencies":{"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-72:blocks":{"depends_on_id":"k-72","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:21:58.983699Z","closed_at":"2025-10-20T16:21:58.983699Z","dependencies":{"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-74:blocks":{"depends_on_id":"k-74","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:22:00.516003Z","closed_at":"2025-10-20T16:22:00.516003Z","dependencies":{"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-73:blocks":{"depends_on_id":"k-73","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T16:22:02.172140Z","closed_at":"2025-10-20T16:22:02.172140Z","dependencies":{"k-67:parent-child":{"depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-75:blocks":{"depends_on_id":"k-75","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-76:blocks":{"depends_on_id":"k-76","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T19:32:35.332457Z","closed_at":"2025-10-20T19:32:35.332457Z","dependencies":{"k-69:discovered-from":{"depends_on_id":"k-69","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T17:44:48.351038Z","closed_at":"2025-10-20T17:44:48.351038Z","dependencies":{"k-69:blocks":{"depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-18T00:09:59.702600Z","dependencies":{"k-xvte:discovered-from":{"depends_on_id":"k-xvte","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T17:15:32.791569Z","closed_at":"2026-01-02T17:15:32.791569Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T15:35:57.964195Z","closed_at":"2026-01-02T15:35:57.964195Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T18:04:56.711244Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:31:12.689417Z","closed_at":"2025-10-18T20:31:12.689417Z"} +{"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","created_by":"unknown","updated_at":"2025-10-20T17:44:56.135319Z","closed_at":"2025-10-20T17:44:56.135319Z","dependencies":{"k-69:blocks":{"depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T17:51:06.884202Z","closed_at":"2025-10-20T17:51:06.884202Z","dependencies":{"k-69:blocks":{"depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T19:40:01.368890Z","closed_at":"2025-10-20T19:40:01.368890Z","dependencies":{"k-69:discovered-from":{"depends_on_id":"k-69","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T18:13:23.311889Z","closed_at":"2025-10-20T18:13:23.311889Z","dependencies":{"k-70:blocks":{"depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T18:21:48.289778Z","closed_at":"2025-10-20T18:21:48.289778Z","dependencies":{"k-70:blocks":{"depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T18:25:31.169093Z","closed_at":"2025-10-20T18:25:31.169093Z","dependencies":{"k-70:blocks":{"depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-83:discovered-from":{"depends_on_id":"k-83","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-84:discovered-from":{"depends_on_id":"k-84","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T18:36:27.383592Z","closed_at":"2025-10-20T18:36:27.383592Z","dependencies":{"k-84:discovered-from":{"depends_on_id":"k-84","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-11-21T21:40:17.413701Z","closed_at":"2025-11-21T21:40:17.413701Z"} +{"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","created_by":"unknown","updated_at":"2025-10-20T19:26:24.079640Z","closed_at":"2025-10-20T19:26:24.079640Z","dependencies":{"k-87:discovered-from":{"depends_on_id":"k-87","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-20T19:44:18.877845Z","closed_at":"2025-10-20T19:44:18.877845Z"} +{"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","created_by":"unknown","updated_at":"2025-10-18T20:31:40.941416Z","closed_at":"2025-10-18T20:31:40.941416Z","dependencies":{"k-8:blocks":{"depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","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-21T13:40:49.635916Z","created_by":"unknown","updated_at":"2025-10-21T18:46:14.689557Z","closed_at":"2025-10-21T18:46:14.689557Z","dependencies":{"k-8:related":{"depends_on_id":"k-8","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T13:45:34.411580Z","closed_at":"2025-10-21T13:45:34.411580Z","dependencies":{"k-90:discovered-from":{"depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T13:46:54.514894Z","closed_at":"2025-10-21T13:46:54.514894Z","dependencies":{"k-90:discovered-from":{"depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T13:48:43.584432Z","closed_at":"2025-10-21T13:48:43.584432Z","dependencies":{"k-90:discovered-from":{"depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T13:48:43.599576Z","closed_at":"2025-10-21T13:48:43.599576Z","dependencies":{"k-90:discovered-from":{"depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T18:46:17.688561Z","closed_at":"2025-10-21T18:46:17.688561Z","dependencies":{"k-90:discovered-from":{"depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"id":"k-96","title":"Consolidate qmd::read error reporting to DiagnosticMessage","description":"Refactor qmd::read to return Result<ParseResult, Vec<DiagnosticMessage>> instead of Result<(Pandoc, ASTContext), Vec<String>>. 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","created_by":"unknown","updated_at":"2025-11-23T13:22:48.147789Z","closed_at":"2025-11-23T13:22:49.147789Z"} +{"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<DiagnosticMessage> instead of Vec<String>","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:08.296798Z","created_by":"unknown","updated_at":"2025-10-21T15:38:21.894018Z","closed_at":"2025-10-21T15:38:21.894018Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<ParseResult, Vec<DiagnosticMessage>>","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:16.000177Z","created_by":"unknown","updated_at":"2025-10-21T15:29:13.893568Z","closed_at":"2025-10-21T15:29:13.893568Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-10-21T15:29:21.878964Z","closed_at":"2025-10-21T15:29:21.878964Z","dependencies":{"k-96:discovered-from":{"depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-20T18:09:56.561644Z","dependencies":{"k-bk15:blocks":{"depends_on_id":"k-bk15","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T17:53:25.290075Z","closed_at":"2026-01-02T17:53:25.290075Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-07T19:24:55.234213344Z","closed_at":"2026-01-07T19:24:55.234213344Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<DiagnosticMessage>` 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<DiagnosticMessage>` + 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","created_by":"unknown","updated_at":"2025-12-28T21:59:15.646353Z","closed_at":"2025-12-28T21:59:15.646353Z","dependencies":{"k-i5nw:blocks":{"depends_on_id":"k-i5nw","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-20T18:09:58.811967Z","dependencies":{"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-yd14:blocks":{"depends_on_id":"k-yd14","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-01T17:41:53.887269Z","closed_at":"2026-01-01T17:41:53.887269Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-20T18:09:54.697347Z","dependencies":{"k-6qau:blocks":{"depends_on_id":"k-6qau","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-01T18:12:22.787341Z","closed_at":"2026-01-01T18:12:22.787341Z"} +{"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","created_by":"unknown","updated_at":"2026-01-01T17:49:51.261619Z","closed_at":"2026-01-01T17:49:51.261619Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-07T18:15:30.555039724Z","closed_at":"2026-01-07T18:15:30.555039724Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T19:12:09.524301Z","closed_at":"2026-01-02T19:12:09.524301Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-29T18:53:14.549566Z","dependencies":{"k-2tu9:discovered-from":{"depends_on_id":"k-2tu9","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-27T17:43:49.771037Z","closed_at":"2025-12-27T17:43:49.771037Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T18:38:51.272709Z","closed_at":"2026-01-02T18:38:51.272709Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:54:27.284787Z","dependencies":{"k-5u7d:blocks":{"depends_on_id":"k-5u7d","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-07T19:25:00.147917236Z","closed_at":"2026-01-07T19:25:00.147917236Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-28T18:12:25.636523Z"} +{"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","created_by":"unknown","updated_at":"2025-12-06T18:52:28.741554Z"} +{"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","created_by":"unknown","updated_at":"2025-12-16T22:59:48.737986Z","dependencies":{"k-333:parent-child":{"depends_on_id":"k-333","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-27T18:32:51.150423Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T23:35:41.415120Z"} +{"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","created_by":"unknown","updated_at":"2026-01-07T19:25:02.064190971Z","closed_at":"2026-01-07T19:25:02.064190971Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T15:41:52.744353Z","closed_at":"2026-01-02T15:41:52.744353Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T21:05:17.263951Z","closed_at":"2026-01-02T21:05:17.263951Z"} +{"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","created_by":"unknown","updated_at":"2025-12-28T23:05:27.665775Z","closed_at":"2025-12-28T23:05:27.665775Z"} +{"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","created_by":"unknown","updated_at":"2025-12-30T04:08:59.618876Z","closed_at":"2025-12-30T04:08:59.618876Z","dependencies":{"k-suww:blocks":{"depends_on_id":"k-suww","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-28T18:01:12.646463Z","closed_at":"2025-12-28T18:01:12.646463Z","dependencies":{"k-evpj:related":{"depends_on_id":"k-evpj","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T20:06:51.694953Z","closed_at":"2026-01-02T20:06:51.694953Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-16T23:27:03.039945Z","closed_at":"2025-12-16T23:27:03.039945Z","dependencies":{"k-g9uc:discovered-from":{"depends_on_id":"k-g9uc","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-01T17:12:44.264491Z","closed_at":"2026-01-01T17:12:44.264491Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-07T19:24:57.484988440Z","closed_at":"2026-01-07T19:24:57.484988440Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-01T18:07:15.030512Z","closed_at":"2026-01-01T18:07:15.030512Z"} +{"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","created_by":"unknown","updated_at":"2026-01-03T20:40:30.304193Z","closed_at":"2026-01-03T20:40:30.304193Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-03T22:13:59.526466Z","closed_at":"2026-01-03T22:13:59.526466Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T19:31:48.152479Z","closed_at":"2026-01-02T19:31:48.152479Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-09T22:53:24.323101Z","dependencies":{"k-4wex:discovered-from":{"depends_on_id":"k-4wex","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","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-07T20:03:57.230535Z","created_by":"unknown","updated_at":"2025-12-07T20:32:45.993075Z","closed_at":"2025-12-07T20:32:45.993075Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-21T18:19:34.525509Z"} +{"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","created_by":"unknown","updated_at":"2025-12-08T19:24:44.089038Z","dependencies":{"k-4wex:related":{"depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","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-05T15:11:18.944162Z","created_by":"unknown","updated_at":"2025-12-05T15:51:02.454702Z","closed_at":"2025-12-05T15:51:02.454702Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T18:11:54.401607Z","closed_at":"2026-01-02T18:11:54.401607Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-03T19:45:19.773692Z","closed_at":"2026-01-03T19:45:19.773692Z"} +{"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","created_by":"unknown","updated_at":"2025-12-17T19:14:33.644673Z"} +{"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","created_by":"unknown","updated_at":"2025-12-23T00:58:52.580617Z","closed_at":"2025-12-23T00:58:52.580617Z","dependencies":{"k-0sdx:parent-child":{"depends_on_id":"k-0sdx","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-08T20:57:44.114865Z","closed_at":"2026-01-08T20:57:44.114865Z"} +{"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","created_by":"unknown","updated_at":"2025-12-06T18:28:32.985751Z","closed_at":"2025-12-06T18:28:32.985751Z"} +{"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","created_by":"unknown","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-07T17:06:46.867359Z","created_by":"unknown","updated_at":"2025-12-07T20:03:11.132977Z","closed_at":"2025-12-07T20:03:11.132977Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T23:28:34.047474Z","closed_at":"2025-12-31T23:28:34.047474Z"} +{"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","created_by":"unknown","updated_at":"2026-01-07T19:25:01.283740946Z","closed_at":"2026-01-07T19:25:01.283740946Z","dependencies":{"k-kh5i:blocks":{"depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-28T22:38:54.778863Z"} +{"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","created_by":"unknown","updated_at":"2025-12-23T02:12:42.733023Z"} +{"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","created_by":"unknown","updated_at":"2025-12-21T21:57:32.879272Z","dependencies":{"k-02o9:discovered-from":{"depends_on_id":"k-02o9","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-08T19:24:50.277282Z","dependencies":{"k-4wex:related":{"depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T20:20:07.712645Z","closed_at":"2026-01-02T20:20:07.712645Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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<YamlWithSourceInfo> and From<MetaValueWithSourceInfo>. 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","created_by":"unknown","updated_at":"2025-12-07T20:09:59.964477Z","closed_at":"2025-12-07T20:09:59.964477Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-28T16:05:55.349648Z","closed_at":"2025-12-28T16:05:55.349648Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T17:22:31.779870Z","closed_at":"2026-01-02T17:22:31.779870Z"} +{"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","created_by":"unknown","updated_at":"2025-12-07T20:04:10.627776Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-01T18:03:23.415423Z","closed_at":"2026-01-01T18:03:23.415423Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-30T15:04:55.815946Z","closed_at":"2025-12-30T15:04:55.815946Z"} +{"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","created_by":"unknown","updated_at":"2025-12-20T21:21:06.462048Z","dependencies":{"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T15:50:38.721023Z","closed_at":"2025-12-31T15:50:38.721023Z"} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:53:45.539905Z","closed_at":"2025-12-05T17:53:45.539905Z","dependencies":{"k-1c5v:blocks":{"depends_on_id":"k-1c5v","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:44:39.511340Z","dependencies":{"k-1c5v:blocks":{"depends_on_id":"k-1c5v","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-y2f3:blocks":{"depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T16:05:28.986193Z","closed_at":"2026-01-02T16:05:28.986193Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-31T16:01:53.804686Z"} +{"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","created_by":"unknown","updated_at":"2025-12-07T21:11:54.315717Z"} +{"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","created_by":"unknown","updated_at":"2025-12-05T22:42:14.443669Z","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","created_by":"unknown","updated_at":"2025-12-07T20:23:53.601939Z","closed_at":"2025-12-07T20:23:53.601939Z","dependencies":{"k-riq2:blocks":{"depends_on_id":"k-riq2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-07T20:03:04.849222Z","closed_at":"2025-12-07T20:03:04.849222Z","dependencies":{"k-zvzm:parent-child":{"depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-02T16:46:18.557357Z","closed_at":"2026-01-02T16:46:18.557357Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-20T17:41:46.424300Z"} +{"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","created_by":"unknown","updated_at":"2025-12-20T22:20:11.652560Z","dependencies":{"k-xlko:discovered-from":{"depends_on_id":"k-xlko","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-17T22:25:33.504802Z","dependencies":{"k-6daf:related":{"depends_on_id":"k-6daf","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-05T17:14:58.723177Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T16:51:52.729268Z","closed_at":"2026-01-02T16:51:52.729268Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-20T18:09:57.538163Z","dependencies":{"k-9aj6:blocks":{"depends_on_id":"k-9aj6","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"},"k-xlko:parent-child":{"depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2026-01-07T02:29:24.776640699Z","closed_at":"2026-01-07T02:29:24.776640699Z","dependencies":{"k-oomv:blocks":{"depends_on_id":"k-oomv","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-08T19:24:58.012901Z","dependencies":{"k-4wex:related":{"depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-06T21:01:18.104329Z","closed_at":"2025-12-06T21:01:18.104329Z"} +{"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","created_by":"unknown","updated_at":"2026-01-02T16:32:17.975741Z","closed_at":"2026-01-02T16:32:17.975741Z","dependencies":{"k-uoc5:parent-child":{"depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import"}}} +{"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","created_by":"unknown","updated_at":"2025-12-23T01:11:05.668441Z"} +{"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","created_by":"unknown","updated_at":"2025-12-15T20:13:07.621186Z"} +{"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","created_by":"unknown","updated_at":"2025-12-07T15:30:16.359027Z"} diff --git a/.cargo/config.toml b/.cargo/config.toml index 80e59fcfa..daab58d75 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -5,3 +5,4 @@ # See crates/xtask/src/main.rs for available commands xtask = "run --package xtask --" dev-setup = "xtask dev-setup" +create-worktree = "xtask create-worktree" diff --git a/.claude/rules/integration-tests.md b/.claude/rules/integration-tests.md new file mode 100644 index 000000000..03c9350b8 --- /dev/null +++ b/.claude/rules/integration-tests.md @@ -0,0 +1,94 @@ +# Integration test layout + +All integration tests in this workspace live in +`tests/integration/<name>.rs` + a `tests/integration/main.rs` that +declares each as `pub mod <name>;`. Cargo compiles **one +`integration` binary per crate** instead of one binary per file. + +**Do not add new `tests/<name>.rs` files at the top level of any +crate's `tests/` directory.** Cargo would treat each one as its +own test binary that statically links the crate's full dependency +closure — pampa's closure alone is ~130 MB. That was the bloat we +removed in bd-xvdop (commits `1b420d65` through `1592e8cd`), worth +~9 GB in `target/debug` and ~6.5 GB in `target/release` at the +workspace level. + +## Adding a new integration test + +1. Create the test file: `crates/<crate>/tests/integration/<your_test>.rs`. +2. Register it in `main.rs`: + ```rust + // crates/<crate>/tests/integration/main.rs + pub mod <your_test>; + ``` + Keep the list alphabetized. + +That's it — nextest still runs each `#[test]` in its own process, +so test isolation is preserved. Filter expressions use the new +selector form `package(<crate>) & binary(integration) & test(<file>::)`. + +## If you move test files + +Any **source-file-relative path** in the moved files needs to be +re-evaluated against the new location. The pampa pilot migration +burned several iterations on insta `set_snapshot_path` calls that +silently resolved to the wrong directory. + +Audit grep before declaring a move done — including **cross-language +references** (the bd-xvdop PR shipped without this audit and broke +a TypeScript test that hardcoded a Rust snapshot path): + +```bash +# Rust side — source-file-relative paths inside the moved files +grep -nE 'include_str!|include_bytes!|include_dir!|#\[path|set_snapshot_path|"\.\./' \ + crates/<crate>/tests/integration/*.rs + +# Cross-language side — anything in hub-client / ts-packages / +# scripts / CI config that references the old paths +grep -rn 'crates/<crate>/tests/' \ + --include='*.ts' --include='*.tsx' --include='*.js' --include='*.mjs' \ + --include='*.json' --include='*.toml' --include='*.yml' --include='*.yaml' \ + hub-client/ ts-packages/ scripts/ .github/ .config/ +``` + +Each `../` needs to be re-checked: moving from `tests/foo.rs` to +`tests/integration/foo.rs` adds one directory level, so any +relative path inside the file usually needs one more `../`. And +any hardcoded `crates/<X>/tests/<Y>` path elsewhere in the repo — +typically a TS test that reads a Rust snapshot or fixture — needs +the new `tests/integration/<Y>` location. + +Insta `.snap` files also live in a snapshot directory adjacent to +the test source by default. If you move a test that uses default +insta snapshot paths, the existing `.snap` files need to move too: + +- Directory: `tests/snapshots/` → `tests/integration/snapshots/` +- Filename: gains an `integration__` prefix because insta's + `module_path!()`-based filenames now start with the binary's + name (`integration`) + +## Why this matters (the measurements) + +From bd-xvdop's Phase 6 measurement (controlled, back-to-back +`cargo clean` + `cargo build --workspace --tests`, alternating +between baseline and full rollout): + +| | Before | After | Δ | +| -------------------------- | ------: | -------: | -----: | +| target/debug | 21 GB | 12 GB | −43 % | +| target/release | 11 GB | 4.5 GB | −59 % | +| Executables in deps/ | 220 | 76 | −65 % | +| Sum of executable bytes | 10.5 GiB | 2.5 GiB | −77 % | +| Release-mode build wall | 158 s | 120 s | −24 % | + +The two extra `../` characters in a relative path are easy to get +wrong; the disk savings are not. Prefer the convention even when it +feels redundant. + +## References + +- `claude-notes/plans/2026-05-28-integration-test-consolidation.md` +- `claude-notes/research/2026-05-28-integration-test-bloat.md` +- [matklad: "Delete Cargo Integration Tests"](https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html) +- [posit-dev/ark#1240](https://github.com/posit-dev/ark/pull/1240) — + the precedent that motivated this change diff --git a/.claude/rules/wasm.md b/.claude/rules/wasm.md index 56273e15e..85a54e125 100644 --- a/.claude/rules/wasm.md +++ b/.claude/rules/wasm.md @@ -13,3 +13,42 @@ Correct pattern: #[cfg(not(target_arch = "wasm32"))] // Native code (full Lua stdlib via Lua::new()) ``` + +## Async traits use `#[async_trait(?Send)]` + +All async traits in this project must use `#[async_trait(?Send)]`, +not the default `#[async_trait]`. + +Correct pattern: +```rust +use async_trait::async_trait; + +#[async_trait(?Send)] +impl PipelineStage for MyStage { + async fn run(&self, input: PipelineData, ctx: &mut StageContext) + -> Result<PipelineData, PipelineError> { /* ... */ } +} +``` + +**Why.** The `#[async_trait]` macro rewrites `async fn` on a trait into a +function returning a `Pin<Box<dyn Future + 'a>>`. The default form adds a +`+ Send` bound to that future, requiring everything captured across `await` +points to be `Send`. The `?Send` form drops that requirement. + +The same trait definitions are used by both: + +- **Native CLI** — could satisfy `Send`, but the codebase uses + single-task execution; `Send` would be over-restrictive. +- **WASM (hub-client)** — `wasm32-unknown-unknown` is single-threaded; + `Send` is meaningless there. Several captured types in WASM contexts + (e.g. `Rc<RefCell<…>>`, JS interop handles) are not `Send` and would + make the trait uncompilable for WASM if `Send` were required. + +`?Send` is the lowest-common-denominator that lets one trait definition +serve both targets. The cost is that you cannot `tokio::spawn` such a +future onto a multi-threaded runtime — but the pipeline doesn't do that; +stages run sequentially within a single task. + +If you find yourself wanting to drop `?Send`, that is a signal something +is wrong with the design of the calling context, not with the trait. +Stop and ask before changing it. diff --git a/.claude/rules/worktrees.md b/.claude/rules/worktrees.md index e7c8a9806..5a61b6e60 100644 --- a/.claude/rules/worktrees.md +++ b/.claude/rules/worktrees.md @@ -1,21 +1,200 @@ # Worktrees +## Two patterns, two commands + +Worktrees and sub-task branches are separate concerns. Pick based on +the *shape* of the work, not on the strand boundary. + +- **`cargo xtask create-worktree`** — spin up a *new* worktree at + `.worktrees/<id>-<slug>/`. Right for **parallel** or + **investigation** work that benefits from isolation: + - `/investigate-beads` digs into a single strand without touching + the main checkout. + - `/triage` records context on a GH issue without committing on + top of in-flight work. + - `/upgrade-cargo-deps` runs full verification on a throwaway + branch. + - A reviewer wants to check out a colleague's branch *while* you + keep working. + + These pay the fresh-worktree cost on purpose: `npm install` from + cold, `cargo build` from cold, no pollution of any other working + state. That's a feature, not a tax. + +- **`cargo xtask switch-task <bd-id>`** — *reuse* the current + worktree's checkout, swap the branch in place. Right for + **sequential** implementation work inside an epic, where each + sub-task branches off the same integration line and benefits from + keeping `node_modules/` + `target/` warm. + + Usage at sub-task hand-off: + + ```bash + # finish the previous sub-task (commit, close the braid strand, etc.) + cargo xtask switch-task bd-yxqt --from feature/q2-preview-command + ``` + + That switches the current worktree to `feature/q2-preview-command`, + fast-forward-pulls (so any sibling sub-tasks that merged in the + meantime show up), creates a fresh `beads/bd-yxqt-<slug>` topic + branch off the new tip, marks the braid strand `in_progress` (via + `braid update`), and rewrites the `CLAUDE.local.md` context block. + Omit `--from` to branch off the current HEAD. + +The two commands are siblings — `create-worktree` does *more* (it +adds a worktree); `switch-task` does *less* (it stays in place). Use +whichever matches the work. + +## Integration-line convention + +Epic work should accumulate on a long-lived **integration branch** +(commonly `feature/<short-name>` — e.g. `feature/q2-preview-command`). +Each sub-task lives on its own topic branch. When a sub-task closes: + +```bash +git switch feature/q2-preview-command +git merge --no-ff beads/<id>-<slug> +git push origin feature/q2-preview-command +``` + +The `--no-ff` preserves the sub-task as a single merge commit, so +the integration branch's history reads as one entry per sub-task. +This is what `switch-task --from <branch>` expects to find when it +fast-forward-pulls — a clean integration line with all ready work +already merged in. + ## Directory Convention All worktrees live in `.worktrees/` at the project root. This directory is git-ignored. -## Beads Redirect +## Branch naming + +- **GH issue triage worktree** → branch `issue-<N>` at `.worktrees/issue-<N>/`. Local branch stays bare; only the remote uses a prefix (see § Pushing for PR). +- **Braid strand investigation worktree** → branch `beads/<id>-<slug>` at `.worktrees/<id>-<slug>/`, where `<slug>` is a short kebab-case form of the strand title (3–5 words, lowercase). +- **In-place sub-task branch (via `switch-task`)** → branch `beads/<id>-<slug>` *without* a corresponding `.worktrees/` directory; the branch lives wherever the caller's worktree is checked out. + +The directory mirrors the leaf of the branch name. The conventions are stable so colleagues and tooling can recognize a worktree's origin from the path alone. + +> **Note on the `beads/` branch prefix.** It is a *historical* git +> namespace, kept after the braid migration because the xtask code emits +> it and tooling/muscle-memory recognize it. It does not imply beads is +> involved — the strand lives in the braid skein. Renaming the prefix to +> `braid/` is a separable future cleanup (it would touch +> `create_worktree.rs`, `switch_task.rs`, and this convention together). -This project uses `br` for issue tracking. After creating any worktree, add a redirect file so `br` uses the main project's database. The `.beads/` directory already exists in the worktree (tracked by git) — just add the `redirect` file alongside the existing files. Do NOT delete or overwrite tracked `.beads/` content. +## Fresh worktree bootstrap + +Use `cargo xtask create-worktree <bd-id>` (or `--issue N` / `--upgrade`) for new worktrees — +it handles `git worktree add` and the CLAUDE.local.md context stub in +one shot. After it finishes, run `npm install` from the new worktree if hub-client is in scope: ```bash -# .beads/ already exists from git — just add the redirect -# 3 levels up from .worktrees/<name>/.beads/ to reach project root -echo "../../../.beads" > .worktrees/<name>/.beads/redirect +cargo xtask create-worktree bd-XXXX +cd .worktrees/<id>-<slug> +npm install # only if hub-client work is in scope +cargo xtask verify --skip-hub-build # confirm green at branch HEAD ``` -The `redirect` file is already in `.beads/.gitignore`, so it won't show as a git change. Verify with `br where` from inside the worktree. +`--base` defaults to `main` when omitted. **If the strand has an +open parent epic, the command prints a warning** nudging you toward +the epic's integration branch (e.g. `feature/<name>`). Pass +`--base <branch>` to branch off the integration line, or `--base main` +explicitly to silence the warning when `main` really is what you want. +For sequential sub-task work *inside* an existing worktree, reach for +`cargo xtask switch-task` (see the two-patterns section above) — it +fast-forwards the integration branch and branches off its current tip +automatically. + +If the xtask is not yet built (fresh clone, or a branch where `cargo build -p xtask` has +not run), see § Manual bootstrap below. + +`cargo xtask dev-setup` exists for Rust dev tools (cargo-nextest, wasm-bindgen-cli) but +does not currently run `npm install`. bd-7giz tracks extending it. + +## Braid skein resolution in worktrees (no redirect needed) + +Unlike beads — which needed a per-worktree `.beads/redirect` file pointing +at the main repo's database — **braid worktrees need zero setup.** The skein +is a synced CRDT identified by the doc id, and braid resolves it via, in order: -## Committing beads changes +1. `BRAID_DOC_ID` / `BRAID_SYNC_URL` env vars (rarely used here); +2. a `.braid.toml` in the current directory **or any parent** — a worktree + under `.worktrees/<leaf>/` walks up to the repo-root `.braid.toml` (which + is gitignored, so it is present in the main checkout the worktree shares a + filesystem with); +3. `~/.config/braid/projects.toml`, selected by the committed, non-secret + `.braid-project` marker (contents: `q2`) — this is what makes *fresh + clones* and out-of-tree worktrees resolve with no per-worktree setup. + +The local braid cache is shared by all worktrees (keyed by a hash of the doc +id), so there is no database to redirect. Verify resolution from inside a +worktree with `braid list` (it should print the project's strands). + +> **The doc id is a secret.** `.braid.toml` holds a read/write bearer token; +> it is gitignored and must never be committed. The committed `.braid-project` +> marker only names the project, never the secret. + +## CLAUDE.local.md + +`cargo xtask create-worktree` prepends a worktree context section to `CLAUDE.local.md`. +Claude Code loads it automatically — no need to run `braid show` to orient at session start. + +The section contains: worktree declaration, main repo path (`../..`), the braid +strand id (or `**GitHub issue:** #N` in `--issue` mode), GitHub URL when +available, an italic-prose placeholder for the plan file path, and a +`**Skill:**` line naming the slash-command that continues the work +(`/investigate-beads`, `/triage`, or `/upgrade-cargo-deps`). Placeholders are +self-documenting — they say exactly what to replace them with. + +Status lives in the braid skein, not in this file. Run `braid show <id>` for current status + notes. + +The section is delimited by `<!-- BEGIN/END WORKTREE CONTEXT -->` markers so it can be +refreshed in place (e.g. when a worktree is recreated, or by hand-editing the file). +The `update_claude_local_md` rewrite is idempotent at the file level: re-running it on +a file that already has a managed section replaces that section without duplicating it +and preserves any user content below. + +`cargo xtask create-worktree` itself is **not** idempotent end-to-end — `git worktree add` +fails fast if the directory already exists. To refresh a worktree's CLAUDE.local.md, +either edit it by hand (the markers make this safe) or remove the worktree and recreate. + +## Committing strand changes (there are none) + +braid stores strands in the synced skein, **not** in git. Strand +create/update/close operations produce **nothing to commit** — they converge +through the CRDT on every command, from any worktree, automatically. (This is +the big simplification over beads' "edit in the worktree, but commit `.beads/` +from the main repo" rule.) The only git-tracked braid artifact is the +backup-only `.braid/snapshot.jsonl` (see the snapshot policy in `CLAUDE.md`), +which is regenerated from the skein and never hand-edited or re-imported. + +## Pushing for PR + +Local branch names stay bare (`issue-<N>`, `beads/<id>-<slug>`). The remote branch name uses a prefix that reflects the work type — `bugfix/`, `feature/`, etc.: + +```bash +# GH issue, bug fix +git push -u origin issue-<N>:bugfix/issue-<N> + +# Braid strand, feature work +git push -u origin beads/<id>-<slug>:feature/<id>-<slug> +``` + +This keeps local branches short and consistent while remote refs are self-describing in PR lists. + +## Manual bootstrap + +If `cargo xtask create-worktree` is unavailable (fresh clone before first build, or +the xtask binary is broken on the current branch), fall back to manual setup: + +```bash +git worktree add -b beads/<id>-<slug> .worktrees/<id>-<slug> main +``` -With a redirect active, all beads data lives physically in the main repo's `.beads/`. JSONL changes from worktree work are only visible in `git status` from the main repo. All beads git commits must happen from the main repo, not from a worktree branch. +No redirect step is needed (see § Braid skein resolution above). Verify with +`braid list` from inside the worktree — if it prints strands, the skein +resolved. CLAUDE.local.md is not part of the manual bootstrap — once the xtask +binary is built, re-running `cargo xtask create-worktree` is not safe on the +existing worktree (see above), but the template lives in +`crates/xtask/src/create_worktree.rs` (`build_section`) for hand-copying if +needed. diff --git a/.claude/rules/xtask.md b/.claude/rules/xtask.md index 140e32c83..05a455d5d 100644 --- a/.claude/rules/xtask.md +++ b/.claude/rules/xtask.md @@ -21,6 +21,8 @@ paths: |---------|-------|---------| | `cargo xtask dev-setup` | `cargo dev-setup` | Install required dev tools (cargo-nextest, wasm-bindgen-cli) | | `cargo xtask lint` | — | Run custom lint checks | +| `cargo xtask create-worktree` | `cargo create-worktree` | Create git worktree + CLAUDE.local.md context stub (braid needs no redirect) | +| `cargo xtask braid-snapshot` | — | Write backup-only `braid export` to `.braid/snapshot.jsonl` (one-directional; never re-import) | | `cargo xtask verify` | — | Full project verification (build + tests for Rust and hub-client) | ## Dev tool version pinning diff --git a/.claude/skills/braid/SKILL.md b/.claude/skills/braid/SKILL.md new file mode 100644 index 000000000..6f294c9ea --- /dev/null +++ b/.claude/skills/braid/SKILL.md @@ -0,0 +1,26 @@ +--- +name: braid +description: Reference for braid, this project's issue tracker (the "skein" of "strands"). Use whenever you need braid command syntax — finding ready work, creating/updating/closing strands, dependencies, ready/blocked queries — or when a user mentions braid, a strand, or a bd- issue id and you need the authoritative, version-matched usage. The body defers to `braid agents-info` for the full guide. +--- + +<!-- the lines below are managed by `braid agents-info --install`; the + frontmatter above is preserved across re-installs (it lives outside + the BEGIN/END markers). --> +<!-- BEGIN BRAID (managed by `braid agents-info --install`) --> +# braid issue tracking + +This project tracks issues ("strands") with **braid**. For the +authoritative, version-matched usage guide — every command, flag, and +convention — run: + + braid agents-info + +Core loop: `braid ready` finds workable strands; claim one with `braid +update <id> --status in_progress --assignee <you>`; leave a trail with +`braid comment <id> "..."`; finish with `braid close <id> --reason "..."`. +File discovered work as you go in one shot: + + braid create "<title>" --type <task|bug|...> --deps discovered-from:<current-id> + +Attribute your changes with `BRAID_AUTHOR=<you>`. +<!-- END BRAID --> diff --git a/.claude/skills/investigate-beads/SKILL.md b/.claude/skills/investigate-beads/SKILL.md new file mode 100644 index 000000000..8292fab75 --- /dev/null +++ b/.claude/skills/investigate-beads/SKILL.md @@ -0,0 +1,128 @@ +--- +name: investigate-beads +description: Investigate a braid strand (bd-XXXX issue) in the current checkout, gather context from its dependency graph, and produce a plan-skeleton + triage verdict (ready / needs-info / blocked). Use when the user provides a strand ID (bd-XXXX) and asks to investigate, scope, or understand the work needed. +--- + +# Investigate-Beads Skill + +> Naming note: this skill keeps the `investigate-beads` name (and `/investigate-beads` +> invocation) for stability, but the project now tracks work in **braid** — a strand +> is one issue in the braid skein. Commands below use `braid`. + +Takes a braid strand from "user pointed at it" to "a plan skeleton and a triage verdict committed to the current branch." It works in whatever checkout you invoke it in and does **not** create or switch worktrees or branches — you choose where the work lands. It is the strand counterpart to `triage` (which handles GitHub issues, where no branch exists yet and one must be created). + +Does **not** implement the fix or finalize the design. Produces enough context to start a focused design session — or to recommend that the issue isn't ready yet. + +## When to use + +User says any of: +- "investigate bd-XXXX" / "let's look at bd-XXXX" +- "what would it take to work on bd-XXXX" +- pastes a beads ID and asks for context / scoping + +**Do not** use for: +- Strands you've already scoped (just edit on `main` or an existing branch) +- GitHub-originated issues — use `triage` instead, which handles the GH side and files a braid strand if needed +- Strands you're about to implement immediately in the current session — `braid update <id> --status in_progress` and start working; this skill's overhead only earns its keep when the strand needs context-gathering before scoping + +## Outcome: two durable artifacts + +1. A plan skeleton at `claude-notes/plans/YYYY-MM-DD-<slug>.md`, committed to the current branch (along with any investigative artifacts). +2. A triage verdict in the plan, plus design questions for the user — one of: + - **Ready to design** — context clear, draft phases sketched, design questions ready for alignment. + - **Needs more info** — specific questions that have to be answered before scoping makes sense. + - **Not ready / blocked** — prerequisites missing, or `discovered-from` chain suggests the original problem was solved differently and the issue should be closed/deferred. + +Investigative artifacts (small repros, exploratory snippets, notes you took while reading the dependency graph) live alongside the plan under `claude-notes/plans/<slug>-investigation/` and are committed with it. + +## Steps + +### 1. Pre-flight: verify HEAD is green + +```bash +cargo xtask verify --skip-hub-build +``` + +Same rationale as `triage`: catches "the issue is already broken at HEAD" vs. "you introduced it" confusion later, and surfaces environment problems before the user is invested. If `verify` fails for a non-bootstrap reason, stop and tell the user. For fresh-clone bootstrap, see `.claude/rules/worktrees.md` § Fresh worktree bootstrap. + +### 2. Read the issue + +```bash +braid show <id> --json +``` + +(braid's `show --json` is a single object, not an array — read the description, status, type, priority, dates. Note who created it and when — old strands often have stale assumptions worth flagging.) + +### 3. Walk the dependency graph + +This is the step that earns the skill its keep. A strand's *meaning* is usually richer than its description; the graph carries why-it-was-filed and what-blocks-what. + +```bash +braid dep tree <id> # parent-child descendant tree (epic → subtasks) +braid dep list <id> # all edges, both directions (blocks / related / discovered-from / ...) +``` + +For each linked strand, read it the same way. In particular: + +- **`discovered-from` chain**: trace it. The originating issue (or session) usually has the context that explains *why* this one was filed — what the parent was trying to do when it surfaced this. Often the most informative single piece of context. +- **`blocks` edges (incoming)**: things that depend on this one. If the dependents are open, they pin the urgency. If they're closed, this issue may already have been addressed differently. +- **`related`**: same area of the codebase; useful for "how is this normally done here." + +### 4. Read the referenced plan + code + +If the description references a plan file (`claude-notes/plans/...`), read it. If it points at code paths (`crates/foo/src/bar.rs:line`), read those. + +Spot-check the area: does the code the strand points at still exist with the same shape? Strands age — a six-month-old strand may have been overtaken by a refactor. + +### 5. Write the plan skeleton + +This skill does **not** create or switch worktrees or branches. Write and commit in whatever checkout you were invoked in — the user controls where the work lands (a long-running worktree they pointed you at, the current branch, wherever). If you think a different branch or worktree is warranted, *say so and let the user set it up*; do not create one yourself. + +Create `claude-notes/plans/YYYY-MM-DD-<slug>.md` (where `<slug>` is a short kebab-case form of the issue title, 3–5 words) using `references/plan-skeleton-template.md`. Put any investigative scratch (small fixtures, exploratory grep output you want to preserve) under `claude-notes/plans/<slug>-investigation/`. + +The plan **is a skeleton, not a finished plan.** Phases are draft headings with rough work items; the design questions section is where the real thinking still has to happen *with the user*. + +### 6. Plan-skeleton commit + +```bash +git add -A +git commit -m "Investigate bd-XXXX: <one-line summary>" +``` + +Commits to the current branch — whichever checkout you were invoked in. Captures the plan skeleton + any investigative artifacts. Do not leave investigative files uncommitted — they are part of the record. + +### 7. Strand: update status, do NOT close + +```bash +braid update <id> --status in_progress +``` + +Even if the verdict is "not ready / blocked," leave the strand in `in_progress` — it has a plan now, which is *progress*. Closing should only happen when the plan recommends close (overtaken / not reproducible) AND the user agrees. + +If you discovered any incidental work, file each as its own strand and link with `--deps related:<this-id>` or `--deps discovered-from:<this-id>` on `braid create` (one shot), e.g. +`braid create "..." -t task -p 2 --deps discovered-from:<this-id>`. + +braid syncs the skein automatically — **there is nothing to commit** for strand +changes (no more `br sync --flush-only; git add .beads/`). The plan-skeleton +commit in step 6 covers the durable artifacts. + +### 8. Hand back to the user + +Report: +- the branch the work landed on +- the plan-skeleton path +- the verdict in one line +- the design questions verbatim (so the user can respond inline without opening the file) + +The user takes it from there: answers the questions to turn the skeleton into a real plan, says "not now," or asks for more investigation. + +## Anti-patterns + +- **Skipping the dependency graph.** Reading only the issue description loses the "why was this filed" context that `discovered-from` carries. The graph is the highest-leverage step. +- **Writing a finished plan instead of a skeleton.** Real design happens in conversation; if the skeleton already pins the answer, the user has no room to redirect. +- **Closing "not ready" issues unilaterally.** Always make the close recommendation a question for the user, never a unilateral action. +- **Skipping pre-flight verify.** Same trap as `triage`: hides bootstrap problems inside the investigation. +- **Forwarded TODOs in the open-questions section.** Each question should be specific and answerable. "Figure out the design" is not a design question. +- **Putting investigative artifacts in `/tmp`.** They are part of the durable record; commit them under `claude-notes/plans/<slug>-investigation/`. +- **Running the full skill for a 5-minute lookup.** If the user just wants to know what a strand *is*, summarize from `braid show` and stop. The skill's overhead (plan skeleton + commit) earns its keep when the investigation needs to write code (repros, fixtures), not when it's purely descriptive. +- **Creating or switching a worktree/branch on the user's behalf.** This skill works in the checkout it was invoked in. If isolation seems warranted, recommend it and let the user set up the worktree/branch — do not run `cargo xtask create-worktree` / `switch-task` / `git switch` yourself. diff --git a/.claude/skills/investigate-beads/references/plan-skeleton-template.md b/.claude/skills/investigate-beads/references/plan-skeleton-template.md new file mode 100644 index 000000000..1fcf54b6d --- /dev/null +++ b/.claude/skills/investigate-beads/references/plan-skeleton-template.md @@ -0,0 +1,67 @@ +# Plan-skeleton template + +Copy the body below into `claude-notes/plans/YYYY-MM-DD-<slug>.md` and fill it in. The plan **is a skeleton, not a finished plan** — phases are draft headings; the design questions section is where the real thinking still has to happen with the user. + +```markdown +# <Issue title> (bd-XXXX) + +**Date:** YYYY-MM-DD +**Beads:** bd-XXXX +**Worktree:** `.worktrees/<id>-<slug>` (branch `beads/<id>-<slug>`, based on `main` @ `<short-sha>`) +**Status:** Investigation — pending design alignment with user. **Do not start implementation until the user gives the go-ahead.** + +## Triage verdict + +One of: +- **Ready to design.** Context is clear; this plan sketches phases and lists design questions. Once those are settled, ready to implement. +- **Needs more info.** Specific questions (below) must be answered before this can be scoped. +- **Not ready / blocked.** Prerequisites unmet (list them), OR `discovered-from` context suggests this is overtaken / should be closed. Recommendation: <close | defer | wait on bd-YYYY>. + +State the verdict in one sentence. The rest of the plan justifies it. + +## Issue context + +Quote or paraphrase the issue description. Note status, priority, type, age. + +## Dependency graph + +What the `dep tree` looks like, and what each edge tells us: + +- **discovered-from**: <parent> — the original session was working on X when this surfaced because <Y>. +- **blocks**: <dependent issues, open or closed> — implies <urgency / no-longer-relevant / etc.> +- **related**: <neighbors> — useful as <model for how this kind of work usually looks here>. + +If the graph is empty, say so explicitly — it changes the calculus (no incoming pressure, no clear context). + +## What the code looks like today + +Spot-check report: do the file paths in the description still exist? Has the area been refactored since the issue was filed? Is the symptom the issue describes still reproducible at HEAD? + +If reproducible at HEAD, capture the smallest repro under `claude-notes/plans/<slug>-investigation/`. + +If NOT reproducible (the issue may have been incidentally fixed), say so and recommend close. + +## Proposed phases (draft) + +Skeleton only — actual phase contents wait on the design discussion. + +- Phase 0 — Test plan (TDD: failing tests written first). +- Phase 1 — <core change> +- Phase 2 — <integration> +- ... +- Phase N — Docs + +## Open design questions for the user + +Concrete, answerable questions that will let us turn the skeleton into a real plan. Examples: + +1. **Scope.** Is this change limited to <X> or should it also cover <Y>? +2. **API surface.** Should we expose <thing> publicly, or keep it internal? +3. **Behavior under <edge case>.** What's the expected behavior when ...? + +If the verdict is "not ready / blocked," replace this section with a "What's missing" list — what would have to land first. + +## Risks / tradeoffs (draft) + +If anything is already obvious from the investigation (e.g. "this touches a stage that has no tests", "this conflicts with bd-YYYY's direction"), note it. If you're not sure yet, say so. +``` diff --git a/.claude/skills/preview-render-parity/SKILL.md b/.claude/skills/preview-render-parity/SKILL.md new file mode 100644 index 000000000..5d47550e4 --- /dev/null +++ b/.claude/skills/preview-render-parity/SKILL.md @@ -0,0 +1,283 @@ +--- +name: preview-render-parity +description: Diagnose and fix DOM / style differences between `q2 preview` and `q2 render` so the two pipelines produce visually-equivalent output. Use when the user reports that the preview's appearance, spacing, classes, or DOM structure doesn't match the rendered site — phrases like "preview vs render differs", "preview shows X differently", "spacing/margin/padding off", "DOM doesn't match", "missing class in preview", or shows a specific computed-style mismatch (e.g. "17px in preview, 34px in render"). Also invoked explicitly via `/preview-parity`. +--- + +# preview-render-parity Skill + +`q2 preview`'s React renderer (`ts-packages/preview-renderer/src/q2-preview/...`) is **supposed to produce the same DOM as `q2 render`'s native HTML writer** (`crates/pampa/src/writers/html.rs`) for the same input. Every divergence — wrong tag, classes on the wrong element, missing classes, attribute leakage, missing pipeline stage — costs the user visible style drift, because the Quarto theme CSS is the same in both places and assumes the native writer's DOM shape. + +This skill turns a "preview looks slightly wrong" report into a closed braid strand with a regression test, a verified-in-browser fix, and a `--no-ff` merge into the integration branch. + +## When to use + +User says any of: +- "preview shows X differently from render" +- "spacing / margin / padding / indentation / etc. is different between preview and render" +- "DOM doesn't match" +- "this class is in render but missing in preview" (or vice versa) +- "X is on `<pre>` in render but on `<code>` in preview" (or similar tag/element placement complaint) +- describes a specific `getComputedStyle` mismatch ("17px vs 34px") +- shows a screenshot comparison of the two pipelines +- explicitly: `/preview-parity` or `/preview-render-parity` + +**Do not** use for: +- Preview-server bugs that aren't about rendered output (file watcher misses, samod sync failures, capture pipeline failures, port conflicts). +- Render-side bugs in `q2 render` (when the user wants the *render* output changed, not preview brought into line). +- Quarto theme CSS changes (changing the rules themselves, not making preview match them). +- Replay-engine / capture splice work (those have their own design space — see `claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md`). + +## Preconditions + +- A running `q2 preview` URL (the user usually provides one, or you can start it: `cargo run --bin q2 -- preview <path> --no-browser --port <p>` after `cargo build --bin q2 --release` for the latest WASM). +- A running comparison `q2 render` URL (typically `python -m http.server` over the fixture's `_site/` directory). +- Chrome via the chrome-devtools MCP (`mcp__plugin_chrome-devtools-mcp_chrome-devtools__*`). + +**The native HTML writer is the canonical contract.** Whenever the spec is unclear, read `crates/pampa/src/writers/html.rs` for the `Block::*` or `Inline::*` arm in question — that's what `q2 render` actually does, and `q2 preview` must mirror it. Discrepancies between Pandoc's convention and pampa's are common; trust the pampa code, not your memory of Pandoc. + +## The standing fixture + +`~/Desktop/daily-log/2026/05/15/q2-preview-test-website/` is a 2-page website with one R code cell that the user keeps using for these comparisons. Use it as the default fixture unless the user names another. Render it via `q2 render .`, serve `_site/` over `python -m http.server`, run `q2 preview .` against it, and compare in Chrome. + +## Diagnosis workflow + +### 1. Locate the element on both pages + +Open both URLs in Chrome via the MCP. Use `mcp__plugin_chrome-devtools-mcp_chrome-devtools__select_page` to switch between them. + +For `q2 render`, the target is in `document` directly. + +For `q2 preview`, the rendered document is **inside an iframe**: + +```js +const iframe = document.querySelector('iframe'); +const doc = iframe.contentDocument; +// ...querySelector on `doc` +``` + +When computing styles in preview, use `iframe.contentWindow.getComputedStyle(target)`, not the parent `window`'s. + +### 2. Compare DOM shape + +For the same logical element on both sides, capture: `outerHTML.slice(0, 500)`, `tagName`, `className`, `id`, attribute list, and the parent chain (up to body). The parent chain often surfaces a structural difference one level up that explains the symptom. + +### 3. Compare computed styles (when the symptom is visual) + +```js +const cs = getComputedStyle(target); // or iframe.contentWindow for preview +return {marginTop: cs.marginTop, marginBottom: cs.marginBottom, /* ... */}; +``` + +A *value* difference (17px vs 34px) is usually a *selector* difference — one side matches a more specific rule. Enumerate the matching rules: + +```js +// Scan all stylesheets for rules that match the target and have margin/padding. +const matches = []; +for (const sheet of document.styleSheets) { + try { + for (const rule of sheet.cssRules || []) { + if (!rule.selectorText) continue; + try { + if (target.matches(rule.selectorText) && /margin|padding/.test(rule.cssText)) { + matches.push({selector: rule.selectorText, css: rule.cssText.slice(0, 200), href: sheet.href}); + } + } catch {} + } + } catch {} +} +``` + +The render side will typically have a more-specific selector that doesn't match in preview because *some attribute or tag* differs (next-sibling tag, an absent class, etc.). + +### 4. Classify the divergence + +The five categories observed so far: + +| Category | Symptom | Where the fix lives | +|---|---|---| +| **Wrong tag** | `<div>` vs `<section>`, `<pre>` vs `<code>`, etc. | React component in `q2-preview/blocks/` or `q2-preview/inlines/` | +| **Wrong attribute placement** | classes on `<code>` instead of `<pre>` | Same — mirror `write_*_attr` in `crates/pampa/src/writers/html.rs` | +| **Missing classes** | `sourceCode`, `cell-output`, etc. absent in preview | React component (often a conditional add — `if highlight present, prepend sourceCode`) | +| **Stage exclusion** | Some pipeline-emitted attribute (`data-hl-spans`, `data-loc`) absent from the AST entirely | `Q2_PREVIEW_STAGE_EXCLUDED` in `crates/quarto-core/src/pipeline.rs` | +| **Attribute leakage** | A `data-*` attr the writer *consumes* leaks to the DOM in preview | React component — filter the consumed key (e.g. `data-hl-spans`) | + +If the symptom looks like more than one category at once, file separate braid sub-strands and tackle them one at a time (the bd-y1fs3 work surfaced bd-coffj this way). + +### 5. Find the canonical native behavior + +```bash +grep -n "Block::<NodeType>\|fn write_<thing>\|<tag\|class=\"<class>" crates/pampa/src/writers/html.rs +``` + +Read the matching arm. Pay attention to: + +- **Which element gets the `Attr`** (id + classes + kvs). Pampa's convention is: classes on the OUTER container (`<pre>`, `<section>`, `<figure>`), inner `<code>` / etc. bare. This is the opposite of vanilla Pandoc and a recurring gotcha. +- **Helpers that prepend / mutate the attr** before emission (e.g. `write_code_container_attr` adds `sourceCode` when `data-hl-spans` is present). +- **Tag elevation** based on classes (e.g. `Div` with `"section"` class → `<section>`). +- **Attribute filtering** (consumed keys like `data-hl-spans`). + +### 6. Find the React component handling the same AST node + +Block-level: +``` +ts-packages/preview-renderer/src/q2-preview/blocks/<NodeType>.tsx +``` + +Inline: +``` +ts-packages/preview-renderer/src/q2-preview/inlines/<NodeType>.tsx +``` + +Pipeline stages: `crates/quarto-core/src/stage/stages/<stage>.rs` + the q2-preview pipeline at `crates/quarto-core/src/pipeline.rs::build_q2_preview_pipeline_stages` (and the exclusion list `Q2_PREVIEW_STAGE_EXCLUDED`). + +## TDD workflow + +### File a braid strand + topic branch + +```bash +braid create "q2 preview: <one-line symptom>" \ + -t bug -p 2 \ + --deps "parent-child:bd-kw93" \ + -d "$(cat <<EOF +<symptom — what the user sees> + +q2 render produces: <DOM/style> +q2 preview produces: <DOM/style> + +Root cause: <where the divergence is>. Native writer: <file:line>. + +Fix: mirror the writer — <one-line plan>. +EOF +)" +# braid prints the new strand id on stdout. Capture it as <id>. +braid update <id> --status in_progress +git switch -c beads/<id>-<short-slug> +``` + +bd-kw93 is the q2-preview epic; every parity sub-strand is parent-child to it. (The git branch prefix stays `beads/` — a stable historical namespace.) + +### Write the failing test FIRST + +Three test surfaces, pick the right one: + +| Test surface | Use when | +|---|---| +| `ts-packages/preview-renderer/src/q2-preview/q2-preview.integration.test.tsx` | DOM/component shape — most common. Mount a small AST fixture via `mount(blocks)`, assert on the rendered DOM. | +| `crates/quarto-core/src/pipeline.rs` (tests module) | Pipeline stage inclusion / exclusion. Pattern: `q2_preview_pipeline_includes_<stage_name>` asserts the name appears in `build_q2_preview_pipeline_stages(None, None).iter().map(s => s.name())`. | +| `q2-preview-spa/src/PreviewApp.integration.test.tsx` | SPA-app-level behavior (boot, document.title, capture wiring) — when the symptom is about the outer SPA, not a single AST node. | + +For the SPA-app integration tests, **the existing render-error tests at lines 415/460 of `PreviewApp.integration.test.tsx` override `renderPageForPreview` with `mockImplementation`**. `vi.clearAllMocks()` only clears call history, not implementations, so later tests inherit the stale stub. **Always restore the default closure-over-state mock at the top of your test** (see the bd-iuzmk pattern with `resetRenderPageForPreviewMockToDefault`). + +Run the failing test: + +```bash +# preview-renderer (component / DOM tests) +(cd ts-packages/preview-renderer && npm run test:integration) + +# q2-preview-spa (SPA-app tests) +(cd q2-preview-spa && npm run test:integration) + +# quarto-core (pipeline / Rust tests) +cargo nextest run -p quarto-core --lib <test-name> +``` + +Confirm RED for the right reason — the assertion message should name the missing tag / class / attribute, not a generic JSON-shape error. + +### Implement the fix + +Mirror the native writer's behavior in the React component (or update the exclusion list / add a stage). Keep the diff minimal and the comment dense — link bd-id and the native-writer file:line so future maintainers see the contract. + +### Verify GREEN + +Same commands. Then full suite: + +```bash +cargo xtask verify +``` + +All 12 steps must pass. The verify rebuilds the WASM + the q2-preview SPA bundle, which is what `q2 preview` embeds in its binary. + +### E2E browser verification + +Tests passing alone is NECESSARY BUT NOT SUFFICIENT — CLAUDE.md mandates real-binary check for CLI / UI features. After verify: + +```bash +cargo build --bin q2 --release # picks up the freshly-built SPA +pkill -f "q2 preview" 2>/dev/null; sleep 1 +cd <fixture> && rm -rf .quarto +/Users/cscheid/repos/github/quarto-dev/q2/target/release/q2 preview . --port <p> --no-browser & +``` + +Then load `http://127.0.0.1:<p>/?page=<file>` in Chrome via the MCP and run the SAME assertion against the live DOM (computed style, `querySelector` match, `outerHTML` substring). Record the snippet in the commit body. + +## Ship + +```bash +# Close the strand (braid syncs the skein automatically — nothing to commit) +braid close <id> --reason "Fixed: <one-line>" + +# Commit (component fix + test in one commit when they're tightly coupled) +git add <component> <test> +git commit -m "...(bd-<id>)" + +# Merge --no-ff into the integration branch +git switch feature/q2-preview-command +git merge --no-ff beads/<id>-<slug> -m "Merge bd-<id>: <one-line>" + +# Push (only after explicit user OK, per CLAUDE.md GIT PUSH POLICY) +git push origin feature/q2-preview-command +``` + +**Commit-message style** (per repo convention — read `git log -5 --pretty=format:"%h %s%n%b%n---"` on `feature/q2-preview-command` if in doubt): + +- Title with bd-id: `<imperative one-line summary> (bd-<id>)`. +- Body: user-visible symptom → root cause (cite native-writer file:line) → fix → verification recipe (include test counts + the `cargo xtask verify N/N green` line + a DOM-snippet from the live browser). +- `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>` footer. + +## Landmines + +These caught me on previous fixes; check before assuming "it's broken": + +- **Pampa puts classes on the OUTER container.** For `CodeBlock`, classes go on `<pre>`, `<code>` is bare. This is the opposite of vanilla Pandoc. See `Block::CodeBlock` in `crates/pampa/src/writers/html.rs` and `write_code_container_attr`. bd-y1fs3. + +- **`sourceCode` class is conditional.** The native writer prepends it to a code container's class list **only when `data-hl-spans` is present** (i.e. the code-highlight stage actually annotated something). Idempotent: don't add if the author already has it. See `write_code_container_attr` lines 487-495. + +- **`data-hl-spans` is consumed, not forwarded.** The React `CodeBlock` reads it to emit `<span class="hl-...">` markup and must **not** leak the raw attr to the DOM. Other `data-*` keys (e.g. `data-loc`) still pass through. bd-nxslt. + +- **Tag elevation for Divs.** `Div.attr.classes.contains("section")` → emit `<section>`, not `<div>` (sectionize transform output). Quarto theme CSS keys off `<section>`. The constant `SECTION = 'section'` lives in `ts-packages/preview-renderer/src/q2-preview/quartoClasses.ts`. bd-coffj. + +- **`Q2_PREVIEW_STAGE_EXCLUDED` only drops HTML-emission stages.** AST-level stages (they write annotations onto existing nodes, not raw HTML) belong in q2-preview. `CodeHighlightStage` was wrongly excluded for the same wrong reason. Before adding to the exclusion list, confirm the stage actually produces an HTML string. bd-nxslt. + +- **iframe `getComputedStyle`.** Always `iframe.contentWindow.getComputedStyle(target)` — never the parent window's. Wrong window returns the parent's `<body>` styles applied to whatever `target` happens to inherit. + +- **Vitest `clearAllMocks` does NOT clear `mockImplementation`.** It clears call history only. Earlier tests in `PreviewApp.integration.test.tsx` override `renderPageForPreview`; your new tests inherit the stale impl. Top-of-test reset: + + ```ts + async function resetRenderPageForPreviewMockToDefault() { + const runtime = await import('@quarto/preview-runtime'); + (runtime.renderPageForPreview as ReturnType<typeof vi.fn>).mockImplementation( + async () => runtimeMockState.renderResult, + ); + } + ``` + + bd-iuzmk. + +- **Pampa MetaValue shape**: `{t: 'MetaString' | 'MetaInlines' | 'MetaBlocks' | 'MetaMap' | 'MetaList' | 'MetaBool', c: ...}`. Use `@quarto/preview-renderer/framework`'s `extractMetaString` / `extractMetaStringList` rather than reading raw `c`. + +- **WASM safety.** Stages live in `quarto-core` and run on both native and `wasm32-unknown-unknown`. Anything WASM-incompatible must be `cfg(not(target_arch = "wasm32"))`-gated. `quarto-highlight`'s user-grammar machinery is native-only; built-in grammars are WASM-safe. + +## Sub-strands to file when discovered + +If diagnosis surfaces a second divergence in the same area, **file a sibling braid strand** rather than expanding the current fix's scope. The repo's convention is one small focused PR per parity fix. bd-y1fs3 surfaced bd-coffj this way; both shipped as separate `--no-ff` merges. The skill optimizes for cycle time per fix, not for batched mega-PRs. + +## Cross-references + +- Parent epic: `bd-kw93` — q2 preview. +- Capture-splice design (separate scope): `claude-notes/plans/2026-05-18-q2-preview-project-replay-engine.md`. +- Phase F (chrome-rendering parity): `claude-notes/plans/2026-05-14-q2-preview-phase-f.md`. +- Native HTML writer: `crates/pampa/src/writers/html.rs`. Read this. Often. +- Q2-preview pipeline build: `crates/quarto-core/src/pipeline.rs::build_q2_preview_pipeline_stages`. +- Q2-preview React block components: `ts-packages/preview-renderer/src/q2-preview/blocks/`. +- Q2-preview React inline components: `ts-packages/preview-renderer/src/q2-preview/inlines/`. +- Class-name constants shared between Rust + React: `ts-packages/preview-renderer/src/q2-preview/quartoClasses.ts`. diff --git a/.claude/skills/reader-expectations-prose/SKILL.md b/.claude/skills/reader-expectations-prose/SKILL.md new file mode 100644 index 000000000..2b5f0017e --- /dev/null +++ b/.claude/skills/reader-expectations-prose/SKILL.md @@ -0,0 +1,115 @@ +--- +name: reader-expectations-prose +description: Improve prose clarity using the reader-expectations methodology of Gopen & Swan ("The Science of Scientific Writing", American Scientist, Nov-Dec 1990). Use when the user asks for writing improvement, prose review, revision suggestions, help making writing clearer or more readable, feedback on a draft, or mentions clarity, flow, emphasis, sentence structure, or "why this passage is hard to read". Works on any expository prose (papers, reports, memos, docs, essays), not only scientific writing. +--- + +# Reader-Expectations Prose Review + +## Source attribution + +This skill applies the rhetorical principles articulated by **George Gopen and Judith Swan** in *"The Science of Scientific Writing"*, originally published in *American Scientist*, November–December 1990 (the methodology itself draws on prior work by Joseph M. Williams and Gregory G. Colomb). When you use this skill, briefly tell the user that the recommendations come from that article, so they can read the original if they want. + +The article's core claim: readers interpret prose using structural expectations about *where* information should appear. Writing is clearer when its structure satisfies those expectations. The point is not to simplify the substance — it is to remove the structural obstacles that make substance hard to extract. + +## When to invoke this skill + +Invoke when the user asks for help improving a piece of writing — for example: + +- "Can you improve this paragraph?" +- "Why is this hard to read?" +- "How can I make this clearer?" +- "Review my draft." +- "This feels clunky — can you tighten it?" + +Apply the skill to the prose the user provides (or points to). Do not silently rewrite — show the user what is wrong, why, and what to change. + +## The seven principles + +These are **principles, not rules**. Slavish adherence will not produce good prose. Any one can be violated to good effect; skilled stylists violate them deliberately at exceptional moments. Use them as diagnostic lenses, not as a checklist to enforce. + +1. **Subject–verb proximity.** Follow a grammatical subject as soon as possible with its verb. Anything of length between them is read as interruption, and therefore as lesser importance — even when the interrupting material is in fact important. + +2. **Stress position.** Readers naturally emphasize material that arrives at the moment of *syntactic closure* — the end of a sentence, or just before a properly used colon or semicolon. Put the information you want emphasized there. A sentence is "too long" not at a fixed word count but when it contains more stress-worthy items than it has stress positions. + +3. **Topic position.** The beginning of a sentence frames it: readers assume the sentence is "a story about" whoever or whatever appears first. Put the person, thing, or concept whose story it is in the topic position. + +4. **Old information links backward; new information goes to the stress position.** The topic position is for material that connects to what came before (linkage and context). The stress position is for the new information you want the reader to take away. The common failure — *the No. 1 problem in American professional writing, per the authors* — is reversing this: writers rush new information to the front and bury linkage at the end. + +5. **Action lives in the verb.** Express the real action of each clause as its verb, not as a nominalization buried inside a noun phrase ("inhibits" rather than "produces an inhibition of"). When actions hide in nouns, readers cannot tell what is happening. + +6. **Context before novelty.** Within a sentence, paragraph, or section, give the reader orientation before asking them to absorb something new. + +7. **Structural emphasis must match substantive emphasis.** The places the structure tells the reader to emphasize must be the places the writer actually wants emphasized. Mismatch is the most reliable source of misreading. + +A corollary: when old information is *absent* (not just misplaced), the reader has to invent the logical link. This is how revision exposes conceptual gaps — once you arrange old/new properly, you often discover that a connecting sentence was never written. + +## Review procedure + +Work in this order. Each step typically uncovers issues that make later steps easier. + +### 1. Read the passage and identify what it is *trying* to do + +Before diagnosing anything, state in one sentence what story the passage seems to be telling and who/what is its main subject. If you can't, that itself is the first finding — and tells you the topic positions are not doing their job. + +### 2. Scan topic positions + +List the grammatical subject (or topic phrase) of each sentence in order. Then ask: + +- Is there a consistent thread? Does the same "character" recur where it should? +- Do the topic positions contain *old* information that links to the previous sentence — or are they introducing new material the reader has not yet been prepared for? +- Where the topic shifts, is the shift signalled and justified? + +### 3. Scan stress positions + +Identify what sits at the end of each sentence (and immediately before any colon or semicolon). Then ask: + +- Is that the information the writer most wants emphasized? +- If two or three stress-worthy items are crammed into one sentence with only one stress position, the sentence needs to be split or restructured. +- If the stress position holds something trivial (a date, a hedging clause, a parenthetical), the real emphasis-worthy material is being deprioritized. + +### 4. Check subject–verb distance + +For long sentences, locate subject and verb. If they are widely separated, decide whether the intervening material is (a) important enough to warrant its own clause/sentence, or (b) an aside that should be deleted or relocated. Either fix is acceptable; leaving the interruption in place is not. + +### 5. Check that verbs carry the action + +Underline the verbs. If they are mostly forms of *is/are/has/was*, or vague linkers (*involves, concerns, relates to, occurs*), look for the real action — usually it is trapped inside a noun. Reanimate it as a verb. + +### 6. Look for missing connectives (logical gaps) + +Where you have rearranged old/new information and the sentences still don't flow, suspect a missing sentence — a connection the writer left implicit because it was obvious to them. Name what is missing; offer to supply it only if the technical content is within reach, otherwise flag it for the writer. + +### 7. Compose specific revisions + +For each diagnosis, give the user: + +- The original sentence(s). +- The specific diagnosis (which principle is violated and how). +- A concrete revised version. +- A brief note on what the revision changed and why. + +Do not rewrite silently. The user should be able to see the principle in action and apply it themselves next time. + +## Output format + +When reviewing a passage, structure the response like this: + +1. **What this passage seems to be about** — one sentence stating the apparent subject/story. +2. **Diagnoses** — a short list of the structural issues found, each tagged with the relevant principle (e.g., "Topic position — sentence 3"). Be specific: quote the offending text. +3. **Proposed revision** — the rewritten passage in full, so the user can see how the pieces fit together. If you had to fill a logical gap with content the author did not provide, mark that addition clearly and recommend the author confirm it. +4. **What changed and why** — a short explanation pairing each substantive edit with the principle behind it. Avoid line-by-line pedantry; group related edits. +5. **Caveats** — note where you guessed at the author's intended emphasis, and invite correction. Per Gopen & Swan, "meaning requires the combined participation of text and reader" — the reviewer cannot know the author's intent with certainty. + +Briefly cite the source on first invocation in a conversation: *"Applying the reader-expectations methodology from Gopen & Swan, 'The Science of Scientific Writing' (American Scientist, 1990)."* + +## What to avoid + +- Don't pursue "plain English" or simplification as a goal. The article is explicit that the aim is clarification, not simplification; jargon and technical vocabulary are not the target. +- Don't enforce word-count limits on sentences. Length is a symptom, not the disease. +- Don't blame the passive voice reflexively. *"Pollen is dispersed by bees"* is the correct sentence when the paragraph's story is about pollen. +- Don't apply the principles as rigid rules. Note when a violation is deliberate and effective, and leave it alone. +- Don't pile on small grammatical or stylistic nits unrelated to reader expectations — that is a different review. If the user wants line edits too, ask before mixing them in. + +## A worked-example shape (for reference, not output) + +From the article: when the topic positions of a paragraph are scanned and reveal *new* information in nearly every slot — *"Large earthquakes / The rates / Therefore one / subsequent mainshocks / great plate boundary ruptures / the southern segment of the San Andreas fault / the smaller the standard deviation"* — the diagnosis is that the recurring concept ("recurrence intervals") is being denied the topic position it deserves. The fix is to rebuild each sentence so that recurrence-interval information opens it and the new, emphasis-worthy claim closes it. Use this scanning move whenever a paragraph feels disorienting on first read. diff --git a/.claude/skills/triage/SKILL.md b/.claude/skills/triage/SKILL.md new file mode 100644 index 000000000..62391793a --- /dev/null +++ b/.claude/skills/triage/SKILL.md @@ -0,0 +1,121 @@ +--- +name: triage +description: Set up an isolated worktree and triage a GitHub issue into a durable on-branch record. Use when the user says "triage issue #N", "let's look at issue #N", or pastes a github.com/quarto-dev/q2/issues/N URL to investigate. +--- + +# Triage Skill + +Takes a GitHub issue from "user pasted a link" to "isolated worktree on its own branch, with a triage record committed to it." Does **not** diagnose the bug or design the fix — that comes after, in whatever workflow the triage outcome calls for (bug fix, doc update, "wai" answer, duplicate close, etc.). + +## When to use + +User says any of: +- "triage issue #N" / "let's look at issue #N" +- pastes a `github.com/quarto-dev/q2/issues/N` URL and asks you to investigate +- "set up a worktree for issue #N" + +**Do not** use for: +- Fixes the user already has scoped (just edit on `main` or an existing branch) +- Internal braid strands without an upstream GH issue (no triage doc needed; the strand description is the record) + +## Outcome: three durable artifacts + +1. A worktree branch `issue-<N>` at `.worktrees/issue-<N>/`, with one commit containing the triage record (and any investigative fixtures). +2. A triage document at `claude-notes/issue-reports/<N>/triage.md` on that branch. +3. A braid strand (only if the triage concludes there is real work to do — see § Outcomes that don't get a braid strand). + +Investigative artifacts (minimal repros, side-by-side fixtures, comparison outputs) live alongside the triage doc under `claude-notes/issue-reports/<N>/` and are committed with it. They are part of the record, not throwaways. + +## Steps + +### 1. Pre-flight: verify HEAD is green + +```bash +cargo xtask verify --skip-hub-build +``` + +Catches "the bug is already there at HEAD" vs. "you introduced it" confusion later, and surfaces environment problems before the user is invested. If `verify` fails for a non-bootstrap reason, **stop and tell the user.** Do not start the triage on a broken HEAD. For fresh-clone bootstrap, see `.claude/rules/worktrees.md` § Fresh worktree bootstrap. + +### 2. Read the issue + +```bash +gh issue view <N> --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments +``` + +Read the body and every comment. If the issue contains multiple distinct reports (a list of unrelated bugs in one issue is common), confirm with the user which one(s) you're triaging. Capture that scope decision in the triage doc. + +### 3. Create the worktree (skip if already inside it) + +**First, check if you're already in the right worktree.** A `CLAUDE.local.md` whose `**GitHub issue:**` line matches `#<N>` means the worktree exists and you're in it — skip to step 4. Re-running `cargo xtask create-worktree --issue <N>` from there would fail (`git worktree add` errors on existing directories). + +If you're in the main checkout or a different worktree, create it now: + +```bash +cargo xtask create-worktree --issue <N> +# Creates the worktree and CLAUDE.local.md context stub. +# This step runs BEFORE the braid strand is created (step 6). The `--issue` +# template's `**Strand:**` line is a self-documenting placeholder pointing +# at `braid search <N>` / `braid create`. After step 6 creates the bd-XXXX, +# edit that line in CLAUDE.local.md manually to point at the new ID. +# Do NOT re-run the xtask with `<bd-id>` to "refresh" — that creates a +# separate worktree at `.worktrees/<bd-id>-<slug>` rather than +# updating this one. +# Fallback for fresh clones where the xtask is not yet built: +# see .claude/rules/worktrees.md § Manual bootstrap. +``` + +Branch + directory naming follows `.claude/rules/worktrees.md` § Branch naming (`issue-<N>` for triage). The worktree resolves the braid skein automatically (repo-root `.braid.toml` walk-up / committed `.braid-project` marker) — no per-worktree setup. + +### 4. Bootstrap the worktree + +See `.claude/rules/worktrees.md` § Fresh worktree bootstrap. Then re-run `cargo xtask verify --skip-hub-build` from inside the worktree to confirm green at branch HEAD. + +### 5. Reproduce, investigate, write the triage doc + +Create `claude-notes/issue-reports/<N>/` and put inside it: + +- `repro.<ext>` — the smallest input that triggers whatever the issue describes (a `.qmd`, a config snippet, a shell script, etc.). +- Any side-by-side comparison fixtures you generate while investigating. Name them descriptively (`exp-prefix.qmd`, `exp-suffix.qmd`, etc.). +- `triage.md` — see `references/triage-doc-template.md` for the template. + +For diagnosing the actual bug (root cause, code locations, fix scope), this skill defers to the per-crate `CLAUDE.md` files (e.g. `crates/pampa/CLAUDE.md` for the TDD round-trip workflow). Do whatever investigation the issue calls for and capture the conclusions in the triage doc — but the skill itself is silent on *how* to diagnose. + +### 6. Outcomes that don't get a braid strand + +A braid strand is only created when the triage concludes there is concrete work to do in this repo. Skip the strand when: + +- **Working as intended.** Triage doc explains why, and you (or the user) responds on the GH issue with the explanation. +- **Duplicate.** Triage doc points at the existing bd-XXXX. Optionally comment on the duplicate GH issue. +- **Pure documentation update** small enough to do in the same triage session — just do it and skip the strand. +- **Need more info from the reporter.** Triage doc captures what you don't yet know; you (or the user) ask the reporter on GH. Revisit when they respond. + +When you do file a braid strand: + +```bash +braid create "<headline> (issue #<N>)" -t bug|task|feature -p <0-4> -d "<description>" +``` + +braid prints the new strand id on stdout. The description should reference the triage doc path and the worktree branch. If you discovered any incidental work during triage, file each as its own strand and link with `--deps related:<main-bd-id>`. + +### 7. Commit the triage record on the worktree branch + +```bash +cd .worktrees/issue-<N> +git add -A +git commit -m "Triage issue #<N>: <one-line summary> (bd-XXXX)" +``` + +Captures the triage doc plus all investigative artifacts. Do not leave investigative files uncommitted — they are part of the record. If a fix follows in the same session, that fix is a separate commit on the same branch. + +braid syncs the skein automatically on every command — there is **nothing to commit** for the strand created in step 6 (no `.beads/` directory, no JSONL to stage). The branch commit above covers the durable code/doc artifacts. + +### 8. Pushing for PR + +See `.claude/rules/worktrees.md` § Pushing for PR. Local branch stays bare (`issue-<N>`); remote uses a prefix reflecting the work type. + +## Anti-patterns + +- **Skipping pre-flight verify.** Hides bootstrap problems and pre-existing failures inside the triage. +- **Putting investigative artifacts in `/tmp` or untracked paths.** They are part of the durable record. +- **Forcing a braid strand when the outcome is "working as intended" or "duplicate".** A triage doc is enough; a stub strand is noise. +- **Silent investigations.** If you spend more than a few minutes exploring without finding the answer, surface what you've tried in the triage doc as evidence — even unanswered. The doc is a record of effort, not just conclusions. diff --git a/.claude/skills/triage/references/triage-doc-template.md b/.claude/skills/triage/references/triage-doc-template.md new file mode 100644 index 000000000..1bea57e74 --- /dev/null +++ b/.claude/skills/triage/references/triage-doc-template.md @@ -0,0 +1,49 @@ +# Triage doc template + +Copy the body below into `claude-notes/issue-reports/<N>/triage.md` and fill it in. + +```markdown +# Issue #<N> — <one-line headline> + +- **GitHub**: https://github.com/quarto-dev/q2/issues/<N> +- **Reporter**: @<login> (<name>), <date> +- **Triage date**: <today> +- **Worktree**: `.worktrees/issue-<N>` (branch `issue-<N>`, based on `main` @ `<short-sha>`) +- **Beads issue**: bd-XXXX (or "none — see Outcome") +- **Scope**: which part(s) of the issue this triage covers, and which it explicitly excludes. + +## Summary + +One paragraph: what the user reported, whether you reproduced it, and the conclusion in one sentence ("real bug, fix is small", "working as intended, see explanation below", "duplicate of bd-XXXX", etc.). + +## Reproduction + +Exact commands. Show input and observed-vs-expected output. Reference the fixture under `claude-notes/issue-reports/<N>/`. + +## Localization (if applicable) + +`file:line` pointers to the code involved. If the bug is "X is missing", note where the analogous working code lives so the fix has a model to copy. + +## Open questions — resolved during triage + +For each open question raised during investigation, write the question, the experiment that answered it, and the conclusion. **Do not leave forwarded TODOs.** If a question can't be answered in this triage, escalate it to the user before declaring the triage done. + +## Outcome / recommended next step + +One of: +- "Filed bd-XXXX with fix scope below." +- "Working as intended; see explanation. Will respond on GH." +- "Duplicate of bd-XXXX." +- "Documentation gap; will update `docs/...`." +- "Need more info from reporter; will respond on GH with these questions: ..." + +## Verification commands used + +The exact `gh`, `cargo`, etc. commands you ran, so a future reader can re-do the investigation. + +## Cross-references + +- bd-XXXX entries +- related claude-notes/ documents +- relevant `CLAUDE.md` rules +``` diff --git a/.claude/skills/upgrade-cargo-deps/PINS.md b/.claude/skills/upgrade-cargo-deps/PINS.md new file mode 100644 index 000000000..8557e149c --- /dev/null +++ b/.claude/skills/upgrade-cargo-deps/PINS.md @@ -0,0 +1,130 @@ +# Cargo dependency pins and known transitive incompatibilities + +This document is read by the `upgrade-cargo-deps` skill on every survey +run. The goal: every pin and every known-bad version pair has a written +reason and a written removal condition, so the skill can periodically +re-check whether the pin is still load-bearing. + +When the skill runs (see `SKILL.md`, step 4: "Identify excluded / +vendored crates"), it reads this file, lists each entry under the +"Skipped" section of the survey plan, and **explicitly checks the +removal condition**. If the condition is met, the survey plan should +flag the pin as removable so the next session can land the cleanup. + +## Format + +Each entry is a level-3 heading with these required fields: + +- **Where**: file path(s) and line(s) where the pin lives. +- **Pin**: the literal cargo constraint or the affected versions. +- **Reason**: why this pin exists (one paragraph max). +- **Removal condition**: a concrete, observable trigger for un-pinning. + The skill checks this on each run. +- **Last reviewed**: YYYY-MM-DD of the most recent skill run that + re-checked this entry. + +If you discover a new pin or transitive incompatibility, add an entry +here in the same format. If a pin is removed, leave a tombstone entry +under "Resolved" (below) for one or two skill cycles, then delete. + +## Active pins + +### wasm-bindgen-futures `=0.4.58` (and transitively wasm-bindgen `=0.2.108`, js-sys `=0.3.85`) + +**Where**: +- `crates/quarto-system-runtime/Cargo.toml` (in the `cfg(target_arch = + "wasm32")` deps section). +- `crates/wasm-quarto-hub-client/Cargo.toml` (top-level `[dependencies]`). +- The `[patch.crates-io]` entry in + `crates/wasm-quarto-hub-client/Cargo.toml` redirects + `wasm-bindgen-futures` to the vendored + `crates/wasm-bindgen-futures-patch/`, which carries the + corresponding `wasm-bindgen = "=0.2.108"` and `js-sys = "=0.3.85"` + exact pins inside its own Cargo.toml. + +**Pin**: `wasm-bindgen-futures = "=0.4.58"` at both call sites. + +**Reason**: We vendor a copy of `wasm-bindgen-futures` in +`crates/wasm-bindgen-futures-patch/` to substitute upstream's +implementation via `[patch.crates-io]`. The vendored copy is at +version 0.4.58 and pins the wasm-bindgen ecosystem to `=0.2.108` / +`=0.3.85` (matching the locally-installed `wasm-bindgen-cli` tooling +the project's `npm run build:wasm` script invokes). Without the `=` +constraint at the call sites, cargo's resolver prefers the highest +matching version on crates.io (currently 0.4.70) over the patch's +0.4.58, silently dropping the patch and the transitive exact pins. +The result is a wasm-bindgen 0.2.120 in the lockfile that mismatches +the installed CLI and breaks `npm run build:wasm` with a "version +mismatch" error. + +**Removal condition**: One of: + +1. The vendored `wasm-bindgen-futures-patch` is bumped to a current + upstream version (whatever wasm-bindgen-futures is at on + crates.io). After re-vendoring: + - Update both pin sites to match the new patch version (or relax + to a caret if no exact pin is needed for the substitution). + - Run `cargo install -f wasm-bindgen-cli --version <new>` to align + the CLI. + - Verify `npm run build:wasm` still succeeds. +2. The reason for vendoring is gone — i.e., we no longer need any + custom wasm-bindgen-futures behavior. In that case delete the + `wasm-bindgen-futures-patch/` crate, drop the + `[patch.crates-io]` entry, drop both pins. (If this is true, the + patch's diff vs. upstream should be empty or trivially mergeable.) + +**Why the patch exists in the first place**: see +`claude-notes/plans/2026-04-20-wasm-shim-merge.md` and the comment in +`crates/wasm-bindgen-futures-patch/Cargo.toml`. (As of 2026-05-04 the +patch is the upstream `wasm-bindgen-futures 0.4.58` source verbatim; +if the diff vs. upstream really is empty, condition 2 above applies +and the patch can simply be deleted — confirm by re-vendoring fresh +and `diff`-ing.) + +**Last reviewed**: 2026-05-04 (added). + +## Known transitive incompatibilities + +### temporal_rs 0.1.2 ↔ icu_calendar 2.2.x (semver violation upstream) + +**Where**: dep chain `deno_core v0.376 → v8 v142 → temporal_capi +v0.1.2 → temporal_rs v0.1.2 → icu_calendar ^2.1`. We don't depend on +icu_calendar directly. + +**Symptom**: when `Cargo.lock` is regenerated from scratch (e.g. +`rm Cargo.lock && cargo build`, or `cargo update --aggressive`), +cargo picks the latest `icu_calendar 2.2.x` under the `^2.1` +constraint. `temporal_rs 0.1.2`'s source uses +`icu_calendar::cal::AnyCalendarDifferenceError`, +`icu_calendar::types::DateDurationUnit`, and several +`DateFromFieldsError::*` variants that were removed in icu_calendar +2.2. The build fails with ~9 `E0599` / `E0432` errors in `temporal_rs`. +`Cargo.lock` happens to pin icu_calendar at `2.1.1` from a prior +resolve, so day-to-day builds work — the breakage only surfaces on +regeneration. + +**Reason it's not pinned by us**: the bad version (`icu_calendar +2.2.x`) is technically a minor release on a 1.x crate (semver- +compatible with 2.1), so it should not have removed public APIs. +This is an upstream semver violation, not something we need to +defend against indefinitely. Pinning it ourselves would mean adding +icu_calendar as a direct workspace dep we don't otherwise use, which +is invasive for a bug that has a natural upstream resolution. + +**Removal condition**: bd-nl5q (deno_core 0.376 → 0.400) lands. The +newer deno_core/v8 stack pulls in newer `temporal_rs` (0.2.x at +time of writing), which is compiled against current icu_calendar +APIs. Once deno_core is bumped, run `rm Cargo.lock && cargo build +--workspace` from a fresh state — if it succeeds, this entry can be +deleted. + +**Workaround until then**: don't regenerate `Cargo.lock` from +scratch. If a merge or operation forces it, restore the pre-merge +lockfile (`git checkout HEAD -- Cargo.lock`) and let cargo update +incrementally rather than from-scratch. + +**Last reviewed**: 2026-05-04 (added). + +## Resolved + +(empty — populate with tombstones when a pin or workaround is removed) diff --git a/.claude/skills/upgrade-cargo-deps/SKILL.md b/.claude/skills/upgrade-cargo-deps/SKILL.md new file mode 100644 index 000000000..fb8ee9010 --- /dev/null +++ b/.claude/skills/upgrade-cargo-deps/SKILL.md @@ -0,0 +1,315 @@ +--- +description: Survey the workspace for available Rust dependency upgrades, apply patch/minor bumps in an isolated worktree, run full `cargo xtask verify`, and produce a plan doc + per-major braid strands so the user can review and merge. Use when the user says "upgrade cargo deps", "check for dependency upgrades", "do the bi-weekly cargo upgrade", or asks about outdated dependencies. Runs on demand only — there is no schedule. +--- + +# upgrade-cargo-deps Skill + +This skill turns the repetitive "are any of our Rust deps behind?" task into a single review-friendly artifact. It does **not** push, open PRs, or make decisions about major upgrades. It produces: + +1. A worktree branch with patch/minor upgrades applied and verified. +2. A plan doc at `claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md` summarizing what happened. +3. One braid strand per available major upgrade, linked from the plan. + +The user merges the worktree branch when satisfied, triages the strands at their own cadence, and (optionally) closes the survey plan. + +## When to use + +- User says "upgrade cargo deps", "run the cargo upgrade survey", "check our Rust dependencies", "do the bi-weekly upgrade". +- The most recent `claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md` is older than ~2 weeks and the user asks for a fresh survey. +- User pastes `cargo update --dry-run` output and asks "what should we do about this". + +**Suggested cadence:** bi-weekly. There is no scheduled trigger; the user runs it. + +**Do not** use for: +- npm / hub-client dependency upgrades (out of scope for v1). +- Rust toolchain upgrades (`rust-toolchain.toml`). +- `cargo audit` / security-advisory work. +- Single-dependency upgrades the user has already decided to do. + +## Why a worktree (not the main checkout) + +**All work happens in `.worktrees/cargo-upgrade-YYYY-MM-DD/`, never in the main checkout.** Other Claude agents (or the user) may be working on the same repo concurrently. Running `cargo update` and a full `cargo xtask verify` in the main checkout would: + +- Race with another agent's edits to `Cargo.lock` or `Cargo.toml`. +- Tie up `target/` and the test runner for ~10+ minutes during verification. +- Risk leaving the user's working copy in a half-applied state if the skill is interrupted. + +The worktree gives this skill its own checkout, its own branch, and its own `target/` — fully isolated from anything else in flight. The user merges the branch when ready; until then, nothing the skill does touches their working tree. Steps 1 (pre-flight verify) and 2 (dry-run survey) are the only read-only operations that run in the main checkout, and they don't write any files. + +## Outcome: three durable artifacts + +1. **Worktree branch** `cargo-upgrade-YYYY-MM-DD` at `.worktrees/cargo-upgrade-YYYY-MM-DD/` containing the applied `Cargo.lock` change (and any `Cargo.toml` widenings — see "Major upgrades" below; for v1 the answer is *none*) plus a verified test/build run. +2. **Plan doc** at `claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md` with three sections: Applied & verified / Needs review (majors) / Skipped (vendored or excluded). +3. **One braid strand per major upgrade**, type `chore`, priority `3`, linked from the plan. + +If verification fails, the skill stops, leaves the worktree intact, and reports the failure so the user can investigate. + +## Steps + +### 1. Pre-flight: verify HEAD is green + +Run from the main repo root (this is the only build/test command that runs outside the worktree): + +```bash +cargo xtask verify --skip-hub-build +``` + +Same rationale as the other skills: catches "broken at HEAD" vs. "this skill broke it" confusion later. If it fails for a non-bootstrap reason, **stop and tell the user.** Don't survey on a broken HEAD. + +If another agent appears to be actively editing the main checkout (e.g. `git status` shows uncommitted changes you didn't make), pause and tell the user before proceeding — the worktree will branch from `main`, but a dirty main checkout often means coordination is needed first. + +### 2. Survey: what's available? + +Run the dry-run survey from the **main repo root** (not a worktree — surveying is read-only): + +```bash +cargo update --dry-run --workspace --verbose +``` + +The output has two important shapes: + +- `Locking N packages to latest compatible versions` — patch/minor bumps available within current semver ranges. These are what `cargo update` would apply. +- `Unchanged <crate> v<current> (available: v<latest>)` — a newer version exists but is **outside** the currently-declared semver range. These are the major-bump (or sometimes minor-but-out-of-range) candidates. + +Capture the full verbose output — you'll quote it in the plan doc. + +Also capture the duplicates baseline: + +```bash +cargo tree --duplicates --workspace --depth 0 +``` + +Count the number of duplicate-version entries — each crate listed twice (or more) counts as one duplicate. You'll compare this before/after. + +### 3. Classify the "Unchanged" entries + +For each `Unchanged X v<a.b.c> (available: v<x.y.z>)` line, classify by comparing the version pair into two buckets: + +**Bucket A — Breaking (file individual braid strands in step 11):** +- **Major** (`a.b.c → x.y.z`, x > a, a ≥ 1) — semver-breaking. +- **Pre-1.0 minor** (`0.b.c → 0.y.z`, y > b) — semantically breaking in Cargo's resolver. + +**Bucket B — Non-breaking, out-of-range (list in plan, no individual strands):** +- **Patch out-of-range** (`a.b.c → a.b.z`, z > c). +- **Minor out-of-range** (`a.b.c → a.y.z`, y > b, a ≥ 1). +- **Pre-1.0 patch** (`0.b.c → 0.b.z`, z > c). +- **Pre-release transitions** (e.g. `0.6.0-pre.1 → 0.6.0-pre.2`). + +The Bucket B entries appear because either the workspace declares a narrower range than upstream is at, or a transitive constraint pins us back. They're non-breaking. Filing 20+ strands for tiny patch deltas like `libc 0.2.185 → 0.2.186` would be noise. The plan doc lists them under "Surfaced but not filed (patch/minor out-of-range)" for reference; the user can opt to widen workspace ranges in a follow-up. + +For v1 the skill **does not** edit `Cargo.toml` to widen ranges, even for Bucket B. Bucket A only gets strands; no `Cargo.toml` changes. + +### 4. Identify excluded / vendored / pinned crates + +Don't propose changes for these — they're either upstream vendored, workspace-excluded, or deliberately pinned: + +- **Read `.claude/skills/upgrade-cargo-deps/PINS.md`.** That doc is the authoritative list of every deliberate pin and every known transitive incompatibility, with a written removal condition for each. For every entry: + 1. List it under "Skipped (pinned)" in the survey plan with a one-line "why" + a pointer to PINS.md. + 2. **Re-evaluate the removal condition** against the current state of the repo and the upstream registry. If the condition has been met (e.g. the upstream crate is no longer reverse-deped on; a vendored patch can be re-vendored fresh; a transitive incompat has been fixed by another upgrade landing), call this out at the top of the survey plan as **"Pin can now be removed: <name>"** so the user can land a separate cleanup PR. Update the entry's "Last reviewed" date in PINS.md to today's date as part of the survey worktree's first commit. + +- **`crates/wasm-bindgen-futures-patch/`** — vendored upstream `wasm-bindgen-futures` crate. See PINS.md for the full pin chain (`wasm-bindgen-futures = "=0.4.58"` → transitive `wasm-bindgen = "=0.2.108"`, `js-sys = "=0.3.85"`). + +- **Workspace-excluded crates** (per root `Cargo.toml`): `wasm-quarto-hub-client`, `wasm-qmd-parser`, `tree-sitter-language-wasm-shim`, `pampa/fuzz`, `crates/experiments/*` (other than reconcile-viewer). Their `Cargo.lock` entries still come from the workspace lock, so `cargo update` covers them, but their `Cargo.toml` dep ranges aren't part of `--workspace` resolution for direct edits. + +If a major-upgrade candidate's only consumer is one of the vendored/pinned crates, list it under "Skipped" with the reason; don't file a strand. + +### 5. Create the worktree (skip if already inside it) + +**First, check if you're already in the right worktree.** A `CLAUDE.local.md` whose `**Task:**` line says `Cargo dependency upgrade — YYYY-MM-DD` for today's date means the worktree exists and you're in it — skip to step 6. Re-running `cargo xtask create-worktree --upgrade` from there would fail (`git worktree add` errors on existing directories). + +If you're in the main checkout or a different worktree, create it now: + +```bash +cargo xtask create-worktree --upgrade +# Creates a cargo-upgrade-YYYY-MM-DD worktree with CLAUDE.local.md. +# Fallback for fresh clones where the xtask is not yet built: +# see .claude/rules/worktrees.md § Manual bootstrap. +``` + +The worktree resolves the braid skein automatically — no per-worktree setup. + +### 6. Bootstrap the worktree (conditional) + +Skip this step if step 7 will be a no-op. Concretely: if step 2's dry-run output started with `Locking 0 packages`, you won't run a worktree-side verify in step 8, so `node_modules/` isn't needed. + +Otherwise — fresh worktrees have no `node_modules/`, and `cargo xtask verify` (run in step 8) needs hub-client deps: + +```bash +cd .worktrees/cargo-upgrade-$DATE +npm install +``` + +When `bd-7giz` (`cargo xtask setup`) lands, replace `npm install` with that and update this skill. + +### 7. Apply patch/minor upgrades + +From inside the worktree: + +```bash +cargo update --workspace +``` + +This rewrites `Cargo.lock` with all in-range upgrades. Stage it but don't commit yet — verification comes first. + +If `cargo update` reports "Locking 0 packages" (i.e. nothing in range to upgrade), there's nothing to apply. **Skip steps 8–10 (verify, post-state duplicates, lockfile commit)** — pre-flight in step 1 already validated `main`, and the worktree branches from `main` with an identical lockfile, so re-running `cargo xtask verify` in the worktree confirms only what step 1 already confirmed. Add a note in the plan that the lockfile was already current; still file strands for any Bucket A upgrades from step 3. + +### 8. Verify + +Run the **full** verification — slower is fine, the value is full output if anything fails: + +```bash +cargo xtask verify +``` + +This runs `cargo build --workspace`, `cargo nextest run --workspace`, the hub-client build, and hub-client tests. + +**On failure**: do not commit the lockfile change. Run `git restore Cargo.lock` to revert, leave the worktree in place for diagnosis, and report: + +- The full failing command output (or a path to a captured log). +- Which upgrades the lockfile would have applied (from step 2's "Locking" output). +- A recommendation: usually "isolate the offender by `cargo update -p <crate>` one at a time and re-run verify." + +In this state, don't file the survey plan yet — escalate to the user. The next session can either land the safe subset or open a strand per failing dep. + +### 9. Capture the post-state duplicates + +```bash +cargo tree --duplicates --workspace --depth 0 +``` + +Compare the count to the baseline from step 2. Surface any **new** duplicates introduced by the upgrade as a yellow flag in the plan doc. + +### 10. Commit the lockfile + +```bash +git add Cargo.lock +git commit -m "$(cat <<'EOF' +cargo update: apply in-range upgrades (YYYY-MM-DD survey) + +See claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md. + +Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> +EOF +)" +``` + +(Replace `YYYY-MM-DD` with the actual date.) + +### 11. File braid strands for breaking upgrades + +For each **Bucket A** (Major / pre-1.0 minor) candidate from step 3, file a `chore` strand. Bucket B (out-of-range patch/minor) entries do **not** get individual strands — they're listed in the plan doc only. Run from inside the worktree (the worktree resolves the shared skein automatically): + +```bash +braid create "Cargo: upgrade <crate> v<a.b.c> → v<x.y.z>" \ + -t chore -p 3 -l deps -l cargo \ + -d "Major upgrade surfaced by cargo-upgrade survey YYYY-MM-DD. Current version <a.b.c> is range-pinned in workspace; latest is <x.y.z>. Review changelog and bump deliberately. See claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md." +``` + +braid prints each new strand id on stdout; capture them — you'll list them in the plan. + +### 12. Write the plan doc + +Create `claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md` using the template below. Commit it to the worktree branch. + +```markdown +# Cargo dependency upgrade survey — YYYY-MM-DD + +**Worktree:** `.worktrees/cargo-upgrade-YYYY-MM-DD` (branch `cargo-upgrade-YYYY-MM-DD`, based on `main` @ `<short-sha>`) +**Skill:** `.claude/skills/upgrade-cargo-deps/SKILL.md` +**Previous survey:** `<link to prior plan, or "none">` + +## TL;DR + +- Applied: N patch/minor upgrades via `cargo update` (commit `<hash>`). +- Needs review: M major upgrades (strands: bd-XXXX, bd-YYYY, …). +- Skipped: K (vendored / excluded — see below). +- Duplicates: <before> → <after> (delta: <±N>). +- Verification: `cargo xtask verify` <PASSED | FAILED> — <one-line summary>. + +## Applied & verified + +Patch/minor upgrades applied in `cargo update`: + +| Crate | Before | After | +|---|---|---| +| <name> | <ver> | <ver> | +| … | | | + +Verification: full `cargo xtask verify` passed (or: link to log if not). + +## Needs review (major upgrades) + +| Crate | Current | Available | Strand | +|---|---|---|---| +| <name> | <a.b.c> | <x.y.z> | bd-XXXX | +| … | | | | + +Each strand carries a one-line description and labels `deps`, `cargo`. Triage at your cadence. + +## Skipped + +- **`<crate>`** — <reason: e.g. "consumed only by `crates/wasm-bindgen-futures-patch/` (vendored)"> +- … + +## Duplicate-version delta + +Before: <N> duplicates. +After: <N> duplicates. + +<If new duplicates were introduced, list them here as a yellow flag.> + +## Notes + +<Any judgment calls made during the survey: pre-release version handling, classification edge cases, things that surprised you. Keep terse.> +``` + +### 13. Final commit on the worktree + +If you wrote the plan after the lockfile commit, add it as a separate commit: + +```bash +git add claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md +git commit -m "$(cat <<'EOF' +plan: cargo dependency upgrade survey YYYY-MM-DD + +Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> +EOF +)" +``` + +### 14. Report + +braid syncs the skein automatically on every command — the strands filed in step 11 are already durable, with **nothing to commit** (no `.beads/` directory, no JSONL, no `sync` step). Report to the user: + +- The worktree path and branch name. +- The plan doc path. +- The list of strands filed. +- The verification status. +- A reminder: **do not push without explicit approval** (per CLAUDE.md GIT PUSH POLICY). + +### 15. Stop + +Hand the worktree back to the user. They review the lockfile diff, merge or discard the branch, and triage the strands at their cadence. + +## Failure modes & escalation + +- **Verification fails after `cargo update`**: revert `Cargo.lock`, leave worktree, report. Do **not** file the plan as "applied"; describe the failure in a half-survey plan if useful. +- **`cargo update` reports zero changes but majors are available**: still write the plan, still file strands. The survey's value isn't only the lockfile bump. +- **A `Locking N` lands but `cargo tree --duplicates` count *grew***: not a failure, but call it out prominently in the plan TL;DR. The user may decide to revert. +- **HEAD verification fails in step 1**: stop. Tell the user. Don't survey on a broken HEAD. + +## Conventions used by this skill + +- **Branch / worktree name**: `cargo-upgrade-YYYY-MM-DD`. +- **Plan filename**: `claude-notes/plans/YYYY-MM-DD-cargo-upgrade-survey.md`. +- **Strand type/priority/labels** for majors: `chore`, `p3`, labels `deps` + `cargo`. +- **Pinning convention**: deliberate version pins are recorded in `.claude/skills/upgrade-cargo-deps/PINS.md`, not as `# pinned:` comments in `Cargo.toml`. PINS.md gives each pin a written reason, an explicit removal condition, and a "last reviewed" date the skill updates each run. The skill reads PINS.md as part of step 4 ("Identify excluded / vendored / pinned crates") and re-evaluates removal conditions every survey. Inline `# pinned: <reason>` comments next to a `Cargo.toml` constraint are still welcome as a local pointer, but PINS.md is the source of truth. + +## See also + +- **`.claude/skills/upgrade-cargo-deps/PINS.md`** — every deliberate pin and known transitive incompatibility, with a removal condition the skill re-checks every run. Read this before listing the "Skipped" section of the survey plan. +- Design plan: `claude-notes/plans/2026-05-04-cargo-dependency-upgrade-skill.md` +- Braid epic: bd-hb8h +- `CLAUDE.md` GIT PUSH POLICY (the skill must not push) +- `CLAUDE.md` "Full Project Verification" (`cargo xtask verify` semantics) +- `.claude/rules/worktrees.md` (worktree convention) diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 000000000..86cf325fa --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,39 @@ +# Nextest configuration. +# +# Why this file exists (2026-05-14, bd-u3ze): on macOS, running multiple +# `cargo nextest` processes that each construct a `notify-rs` FSEvents +# watcher under default I/O capture causes filesystem events to silently +# fail to reach our `on_file_changed` callback. The symptom is the +# staleness test timing out at 15 s waiting for a write event that +# never propagates, while standalone runs and `--no-capture` runs both +# pass in ~1.1 s. The root cause appears to live in the interaction +# between notify-rs's CFRunLoop-based FSEvents backend and nextest's +# per-process stdout/stderr pipe setup; we couldn't fix it from the +# Rust side. +# +# Workaround: serialize the quarto-preview integration tests that boot +# the full server (and therefore arm a real FSEvents watcher). Each +# still runs in its own process; nextest just ensures only one of them +# is in flight at a time. Adds ~3-4 seconds to the workspace test suite +# at most, in exchange for deterministic results. +# +# If you're adding a new integration test under `crates/quarto-preview/ +# tests/integration/` that calls `run_with_on_ready` or otherwise +# instantiates the file watcher, add its module name to the regex +# in the override filter below. +# +# Layout note (2026-05-28, bd-xvdop): integration tests across the +# workspace now live in `tests/integration/main.rs` + sibling modules +# (matklad pattern), so each crate produces a single `integration` +# test binary instead of one binary per file. Filters that used to +# target per-file binary names now need `package(...) & test(...::)` +# selectors instead. + +[test-groups] +# Quarto-preview integration tests that arm a `notify-rs` FSEvents +# watcher. Limited to one in-flight process at a time. +quarto-preview-fs-watcher = { max-threads = 1 } + +[[profile.default.overrides]] +filter = "package(quarto-preview) & binary(integration) & test(/^(staleness|eager_capture|boot)::/)" +test-group = "quarto-preview-fs-watcher" diff --git a/.github/workflows/hub-client-e2e.yml b/.github/workflows/hub-client-e2e.yml index d8ef6103b..0a5152383 100644 --- a/.github/workflows/hub-client-e2e.yml +++ b/.github/workflows/hub-client-e2e.yml @@ -6,6 +6,10 @@ on: paths: - 'hub-client/**' - '.github/workflows/hub-client-e2e.yml' + pull_request: + paths: + - 'hub-client/**' + - '.github/workflows/hub-client-e2e.yml' workflow_dispatch: inputs: recreate-all-snapshots: @@ -15,10 +19,15 @@ on: jobs: e2e-tests: - runs-on: ubuntu-latest-8x + runs-on: ubuntu-latest name: Hub-Client E2E Tests if: github.repository == 'quarto-dev/q2' + # Needed for the "Commit new baselines" step to push back to the + # workflow branch. Default GITHUB_TOKEN is read-only. + permissions: + contents: write + steps: - name: Checkout Repo uses: actions/checkout@v6 @@ -32,11 +41,17 @@ jobs: [ "$time" != "@0" ] && touch -d "$time" "$file" 2>/dev/null || true done - # Rust toolchain for WASM build + # Rust toolchain for WASM build. Use the named `@nightly` ref + # (not `@master`, which hard-errors without an explicit `toolchain:` + # input) — it installs the nightly toolchain; cargo then reads the + # pinned dated nightly from rust-toolchain.toml (bd-at72) at build + # time. Matches the pattern Carlos established for ts-test-suite.yml + # on main. - name: Set up Rust nightly uses: dtolnay/rust-toolchain@nightly with: targets: wasm32-unknown-unknown + components: rust-src - name: Set up Clang uses: egor-tensin/setup-clang@v2 @@ -51,6 +66,14 @@ jobs: - name: Install wasm-pack run: cargo install wasm-pack + # build-wasm.js verifies wasm-bindgen CLI matches the version + # pinned in Cargo.lock; install that exact version. + - name: Install wasm-bindgen-cli + run: | + VERSION=$(awk '/^name = "wasm-bindgen"$/{getline; gsub(/version = |"/, ""); print; exit}' Cargo.lock) + echo "Installing wasm-bindgen-cli $VERSION" + cargo install -f wasm-bindgen-cli --version "$VERSION" + # tree-sitter for grammar builds - name: Set up tree-sitter CLI run: | @@ -59,25 +82,64 @@ jobs: chmod +x tree-sitter-linux-x86 sudo mv tree-sitter-linux-x86 /usr/local/bin/tree-sitter - # Node.js and dependencies + # Node.js and dependencies. + # + # PINNED to 24.15.0 — do NOT bump to a bare '24' (which floats to + # >=24.16). Node 24.16.0 introduced a yauzl stream-destruction + # regression that hangs `for await` over `openReadStream`, which + # makes `playwright install chromium` hang FOREVER right after the + # browser download hits 100% (extraction deadlocks; the job then + # burns the full 6h cap). It is fixed in Playwright >= 1.60.0, but + # we pin @playwright/test at ^1.50.0 -> 1.58.0. 24.15.0 is the last + # Node release before the regression, so it keeps Playwright 1.58 / + # Chromium 145 and leaves the visual-regression baselines unchanged. + # Refs: microsoft/playwright#40724, fixed by #40747 (PW 1.60.0). + # REMOVE this pin once @playwright/test is bumped to >= 1.60.0 (and + # regenerate the visual baselines for the newer Chromium then). - name: Set up Node.js uses: actions/setup-node@v6 with: - node-version: '24' + node-version: '24.15.0' cache: 'npm' - name: Install npm dependencies run: npm ci - - name: Build TypeScript packages - run: npm run build - - # Build WASM module + # WASM artifacts must exist before any package's `vite build` runs + # (hub-client and q2-demos/* all import the WASM module). - name: Build WASM run: | cd hub-client npm run build:wasm + # Build only the workspaces the e2e tests actually exercise. + # q2-demos/* currently fail their vite build (they import an + # absolute path "/src/wasm-js-bridge/cache.js" that only exists + # in hub-client/), and trace-viewer is not under test here. + # + # VITE_E2E=1 on the hub-client build pulls in src/test-hooks.ts so + # the Playwright suite can reach internal services via + # `window.__quartoTest` (production bundles don't expose source + # paths the way `vite dev` did). The flag is consumed only by the + # `if (import.meta.env.VITE_E2E === '1')` branch in src/main.tsx; + # production-user builds leave it unset and tree-shake the hooks out. + - name: Build TypeScript packages (ts-packages + hub-client) + env: + VITE_E2E: '1' + run: | + for pkg in ts-packages/*/; do + if [ -f "$pkg/package.json" ]; then + npm run build --workspace "$pkg" --if-present + fi + done + npm run build --workspace hub-client --if-present + + # globalSetup launches the hub via `cargo run --bin hub` with a 120s + # readiness timeout. On a cold CI runner the compile alone exceeds + # that, so pre-build it here. + - name: Pre-build hub binary + run: cargo build --bin hub + # Install Playwright browsers - name: Install Playwright run: | @@ -112,13 +174,16 @@ jobs: cd hub-client npx playwright test --config playwright.visual.config.ts --update-snapshots=missing - # If retry passed (only missing baselines), commit them back + # If retry passed (only missing baselines), commit them back. + # Use `find` instead of a `**` glob — bash globstar isn't enabled + # by default and visual specs sit directly under hub-client/e2e/, + # not one directory deeper. - name: Commit new baselines if: steps.visual.outcome == 'failure' && steps.visual-retry.outcome == 'success' run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add -f hub-client/e2e/**/*-snapshots/ + find hub-client/e2e -type d -name '*-snapshots' -exec git add -f {} + git diff --cached --quiet || git commit -m "Add missing Playwright visual regression baselines" git push diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 4184d6506..2f0763909 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -59,6 +59,13 @@ jobs: uses: Swatinem/rust-cache@v2 with: cache-on-failure: true + # cache-bin: false avoids clobbering the freshly-installed + # ~/.cargo/bin/{cargo,rustup,...} with stale proxies from a + # previous run. Intermittently broke macOS CI on 2026-05-14 + # with `cargo xtask … → rustup-init: unexpected argument`. + # cargo-nextest / cargo-insta re-install via taiki-e/install- + # action's prebuilts each run, which is cheap (~1-2s). + cache-bin: false shared-key: "rust-test-suite" # Cache cargo-nextest and insta separately to avoid reinstalling @@ -100,7 +107,9 @@ jobs: if: runner.os == 'macOS' run: brew install tree-sitter-cli - # Free disk space on Linux runners (14 GB SSD is tight for Rust monorepo) + # Free disk space on Linux runners (14 GB SSD is tight for Rust monorepo). + # `remove_tool_cache: true` is safe — no step in this job uses /opt/hostedtoolcache/ + # (no setup-node, setup-python, etc.). See claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md. - name: Free disk space if: runner.os == 'Linux' uses: endersonmenezes/free-disk-space@7901478139cff6e9d44df5972fd8ab8fcade4db1 # v3 @@ -108,28 +117,32 @@ jobs: remove_android: true remove_dotnet: true remove_haskell: true + remove_tool_cache: true + + - name: Prune Docker images + if: runner.os == 'Linux' + shell: bash + run: | + sudo docker image prune --all --force + sudo docker builder prune -a --force # Custom lint checks (before build to fail fast) - name: Run custom lints shell: bash run: cargo xtask lint - # Build and test - # Deny warnings in CI so they don't accumulate silently - - name: Build - shell: bash - run: cargo build - env: - RUSTFLAGS: "-D warnings" - - name: Test block tree-sitter grammar shell: bash run: | cd crates/tree-sitter-qmd/tree-sitter-markdown tree-sitter test + # `ci` profile + `--tests` makes a separate `cargo build` redundant. + # `--tests` (not `--all-targets`) excludes benches — `quarto-yaml` declares + # `harness = false` benches that nextest can't enumerate as tests. + # See claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md. - name: Test Rust code shell: bash - run: cargo nextest run + run: cargo nextest run --tests --cargo-profile ci env: RUSTFLAGS: "-D warnings" diff --git a/.github/workflows/ts-test-suite.yml b/.github/workflows/ts-test-suite.yml index 0acb179ab..fc5f40296 100644 --- a/.github/workflows/ts-test-suite.yml +++ b/.github/workflows/ts-test-suite.yml @@ -27,7 +27,7 @@ jobs: name: Run test suite if: github.repository == 'quarto-dev/q2' - + steps: - name: Checkout Repo uses: actions/checkout@v6 @@ -46,9 +46,16 @@ jobs: id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@main - # Consistent Rust setup for both platforms + # Consistent Rust setup for both platforms. Use the named `@nightly` + # ref (not `@master`, which hard-errors without an explicit + # `toolchain:` input) — it installs the nightly toolchain; cargo + # then reads the pinned dated nightly from rust-toolchain.toml + # (bd-at72) at build time. Matches the existing pattern on main. - name: Set up Rust nightly uses: dtolnay/rust-toolchain@nightly + with: + targets: wasm32-unknown-unknown + components: rust-src - name: Output rust version shell: bash diff --git a/.gitignore b/.gitignore index 180fc7e78..7fbb0e091 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,14 @@ crates/wasm-quarto-hub-client/pkg/ .worktrees/ /.luarc.json + +.claude/scheduled_tasks.lock + +# Per-session local context (managed by `cargo xtask create-worktree` for worktrees) +CLAUDE.local.md + +# braid issue tracker — .braid.toml holds the skein doc id, a read/write +# bearer token. NEVER commit it. The committed, non-secret `.braid-project` +# marker (which only names the project) is intentionally NOT ignored. +.braid.toml +.braid-stragglers.jsonl diff --git a/.mcp.json b/.mcp.json index 2f0633544..89278aac1 100644 --- a/.mcp.json +++ b/.mcp.json @@ -4,9 +4,7 @@ "type": "stdio", "command": "node", "args": [ - "ts-packages/quarto-hub-mcp/dist/index.js", - "--server", - "wss://sync.automerge.org" + "ts-packages/quarto-hub-mcp/dist/index.js" ] } } diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..a45fd52cc --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24 diff --git a/CLAUDE.md b/CLAUDE.md index 751a2d2ce..d5f4b130a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,10 +51,27 @@ When a commit includes updated or new snapshot files (`.snap` files under `snaps ## **WORK TRACKING** -We use br (beads_rust) for issue tracking instead of Markdown TODOs or external tools. - -**Note:** `br` is non-invasive and never executes git commands. After `br sync --flush-only`, you must manually run `git add .beads/ && git commit`. -We use plans for additional context and bookkeeping. Write plans to `claude-notes/plans/YYYY-MM-DD-<description>.md`, and reference the plan file in the issues. +We use **braid** for issue tracking instead of Markdown TODOs or external tools. +braid stores all issues for the project in a **skein** (a single +[automerge](https://automerge.org) CRDT document); a single issue is a +**strand**. The skein — synced through a sync server — is the **source of +truth**. There is no git involvement and no `.beads/`-style JSONL to commit: +edits converge through the CRDT, not through merge tooling. (We migrated off +beads_rust on 2026-06-08; see `claude-notes/plans/2026-06-08-braid-migration.md`.) + +**`braid` is non-invasive and never executes git commands.** Unlike the old +`br sync --flush-only; git add .beads/` dance, there is **nothing to commit** +after issue work — the skein syncs itself. (A `.braid/snapshot.jsonl` backup +*is* committed periodically, but it is **backup-only and one-directional** — +see the snapshot policy below. Never `braid import` it back.) + +For the authoritative, version-matched command guide, run `braid agents-info` +(or invoke the `/braid` skill). The quick reference below is a convenience +summary, not the contract. + +We use plans for additional context and bookkeeping. Write plans to +`claude-notes/plans/YYYY-MM-DD-<description>.md`, and reference the plan file +in the strands. ### File Structure Plan files should include: @@ -96,70 +113,70 @@ Complex plans can have phases, and work items are then split into multiple lists For simple tasks (single file changes, bug fixes), the TodoWrite tool is sufficient. -### Beads Quick Reference +### Braid Quick Reference ```bash -# Find ready work (no blockers) -br ready --json - -# Create new issue -br create "Issue title" -t bug|feature|task -p 0-4 -d "Description" --json +# Find ready work (active + unblocked) +braid ready --json -# Create with explicit ID (for parallel workers) -br create "Issue title" --id worker1-100 -p 1 --json +# Create new strand (prints its id; braid assigns a bd-<random> id) +braid create "Strand title" -t bug|feature|task -p 0-4 -d "Description" --json # Create with labels -br create "Issue title" -t bug -p 1 -l bug,critical --json - -# Create multiple issues from markdown file -br create -f feature-plan.md --json +braid create "Strand title" -t bug -p 1 -l bug -l critical --json -# Update issue status -br update <id> --status in_progress --json +# Create and link discovered work in one shot +braid create "Found bug in auth" -t bug -p 1 --deps discovered-from:<current-id> --json -# Link discovered work (old way) -br dep add <discovered-id> <parent-id> --type discovered-from +# Update status +braid update <id> --status in_progress --json -# Create and link in one command (new way) -br create "Issue title" -t bug -p 1 --deps discovered-from:<parent-id> --json +# Link existing strands (id depends on target) +braid dep add <discovered-id> <parent-id> --type discovered-from # Complete work -br close <id> --reason "Done" --json +braid close <id> --reason "Done" -# Show dependency tree -br dep tree <id> +# Show an epic's descendant tree / one strand's details +braid dep tree <id> +braid show <id> --json -# Get issue details -br show <id> --json - -# Import with collision detection -br import -i .beads/issues.jsonl --dry-run # Preview only -br import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve +# Backup snapshot (one-directional — see snapshot policy; NEVER import it back) +braid export > .braid/snapshot.jsonl ``` +Notes on the move from beads: +- **No explicit `--id`.** braid assigns collision-free ids; with a CRDT, + parallel workers never need to pre-agree on ids. (The migration *preserved* + every existing `bd-XXXX` id via `braid import`, so source references stay + valid.) +- **No `br create -f <file>` bulk create.** Use `braid import <jsonl>` for bulk. +- **No `br sync --flush-only` / `git add .beads/`.** The skein is the source of + truth; there is nothing to commit after issue work. + ### Workflow -1. **Check for ready work**: Run `br ready` to see what's unblocked -2. **Claim your task**: `br update <id> --status in_progress` -3. **Work on it**: Implement, test, document -4. **Discover new work**: If you find bugs or TODOs, create issues: - - Old way (two commands): `br create "Found bug in auth" -t bug -p 1 --json` then `br dep add <new-id> <current-id> --type discovered-from` - - New way (one command): `br create "Found bug in auth" -t bug -p 1 --deps discovered-from:<current-id> --json` -5. **Complete**: `br close <id> --reason "Implemented"` -6. **Sync and commit**: - ```bash - br sync --flush-only - git add .beads/ - git commit -m "sync beads" - ``` +1. **Check for ready work**: `braid ready` to see what's unblocked +2. **Claim your task**: `braid update <id> --status in_progress` +3. **Work on it**: implement, test, document; leave a trail with + `braid comment <id> "..."` +4. **Discover new work**: file it and link it in one shot: + `braid create "Found bug in auth" -t bug -p 1 --deps discovered-from:<current-id> --json` +5. **Complete**: `braid close <id> --reason "Implemented"` + +That's the whole loop — **no sync-and-commit step.** braid syncs the skein to +the server on every command. (`braid sync` forces a round trip if you want to +confirm convergence.) ### Issue Types - `bug` - Something broken that needs fixing - `feature` - New functionality - `task` - Work item (tests, docs, refactoring) -- `epic` - Large feature composed of multiple issues +- `epic` - Large feature composed of multiple strands - `chore` - Maintenance work (dependencies, tooling) +- `docs` - Documentation work (braid adds this type) +- `question` - Open question to resolve (braid adds this type) ### Priorities @@ -171,12 +188,41 @@ br import -i .beads/issues.jsonl --resolve-collisions # Auto-resolve ### Dependency Types -- `blocks` - Hard dependency (issue X blocks issue Y) -- `related` - Soft relationship (issues are connected) +- `blocks` - Hard dependency (X depends on / is blocked by Y) - `parent-child` - Epic/subtask relationship -- `discovered-from` - Track issues discovered during work - -Only `blocks` dependencies affect the ready work queue. +- `related` - Soft relationship (strands are connected) +- `discovered-from` - Track strands discovered during work +- braid also accepts `conditional-blocks`, `waits-for`, `replies-to`, + `duplicates`, `supersedes`, `caused-by`. + +**What gates `ready`:** `blocks`, `conditional-blocks`, and `waits-for` make a +strand unready while their target is active. `parent-child` does **not** block +the child (children stay workable); instead an open child blocks the *parent's* +close. `related`/`discovered-from` and the rest are informational. + +> Note: this differs subtly from beads, where `parent-child` could make a child +> read as blocked. In braid the child is always workable and the parent refuses +> to close while children are open — the intended epic semantics. + +### Snapshot backup policy (READ THIS) + +The skein (automerge CRDT) is the **single source of truth**. We additionally +commit a `.braid/snapshot.jsonl` (`braid export`) to the repo so issues stay +greppable in PRs, diffable in git history, and recoverable. This snapshot is +**backup-only and strictly one-directional**: + +- It flows **automerge → file only** (`cargo xtask braid-snapshot`, or + `braid export > .braid/snapshot.jsonl`). It is **never** an import or sync + source back into the skein. **Never run `braid import .braid/snapshot.jsonl`.** +- On any git **conflict** in `.braid/snapshot.jsonl`, do **not** hand-merge: + resolve by regenerating from the live skein (`braid export`). The CRDT is + authoritative; the file is a photograph. (Yes, this means the snapshot on one + branch may show strand state created on another — "cross-branch + contamination" is expected and fine, because the snapshot is not the truth.) +- The snapshot lives on whatever work branch you're on; it is not special. + +The only time JSONL is ever imported is the **one-time migration** (beads' +`.beads/issues.jsonl` → braid), which is already done. ## Where information lives (memory vs. repo) @@ -198,7 +244,7 @@ Where project-wide information should live instead: - **`claude-notes/plans/`** — decisions, rationale, in-progress work. - **`claude-notes/research/`** — findings, audits, reference material. - **Code comments** — invariants local to specific code. -- **Commit messages + `br`** — temporal context, who did what when. +- **Commit messages + `braid`** — temporal context, who did what when. What memory is *actually* appropriate for: @@ -234,7 +280,7 @@ When fixing ANY bug: **This is non-negotiable. Never implement a fix before verifying the test fails. Stop and ask the user if you cannot think of a way to mechanically test the bad behavior. Only deviate if writing new features.** -**Do NOT close a beads test suite item unless all tests pass. If you feel you're low on tokens, report that and open subtasks to work on new sessions.** +**Do NOT close a braid test-suite strand unless all tests pass. If you feel you're low on tokens, report that and open subtasks to work on new sessions.** ## Workspace structure @@ -266,7 +312,7 @@ When fixing ANY bug: - `quarto-citeproc`: citation processing engine using CSL styles **Tree-sitter grammars:** -- `tree-sitter-qmd`: tree-sitter grammars for block and inline parsers +- `tree-sitter-qmd`: tree-sitter grammar for qmd (a single unified grammar parsing both block structure and inline content) - `tree-sitter-doctemplate`: tree-sitter grammar for document templates - `quarto-treesitter-ast`: generic tree-sitter AST traversal utilities @@ -312,6 +358,10 @@ All VFS file paths use the `/project/` prefix. When resolving file paths in WASM - `wasm-quarto-hub-client` is the WASM client (NOT wasm-qmd-parser) - Always check `git diff` for uncommitted changes before starting work on a continuation session +### Document profile checkpoint + +The render pipeline has a **profile checkpoint** between `MetadataMergeStage` and `PreEngineSugaringStage`: `DocumentProfileStage` extracts a typed, serializable `DocumentProfile` (title, outline, authors, etc.) into a `PipelineData::AtProfile` variant, and `UnwrapProfileStage` immediately hands the AST back to downstream stages. Project-scoped features (sidebars, cross-document links, incremental rebuilds, eventual `freeze`) are meant to consume this profile without re-running engines or user filters. Profiles are **read-only** — any feature that needs state not yet in the profile should move its producer earlier in the pipeline and add a field (with a `profile_version` bump), not back-patch. See `claude-notes/designs/document-profile-contract.md` for the full contract and `claude-notes/plans/2026-04-23-website-project-epic.md` for the epic. + ## hub-client Commit Instructions **IMPORTANT**: When making commits that include changes to `hub-client/`, you MUST also update `hub-client/changelog.md`. @@ -363,6 +413,35 @@ If you cannot test a feature end-to-end (e.g. no access to a browser for a hub-c Past incidents where they diverged: - **2026-04-20**: `CodeHighlightStage` never ran under `quarto render` because the CLI path used a different branch of `render_qmd_to_html` than the tests. Every test passed; no rendered document had highlighting. See `claude-notes/plans/2026-04-19-syntax-highlighting-design.md` ("Phase 2 post-mortem") and the process-improvement plan at `claude-notes/plans/2026-04-20-end-to-end-verification-process.md`. +- **2026-05-20**: `q2 preview` silently served a stale render after Rust changes to `quarto-core`. `cargo build --bin q2` succeeded and the preview *ran*, but the iframe loaded a WASM image built before the changes — the embedded SPA's `wasm-quarto-hub-client_bg.wasm` is only refreshed when the WASM is rebuilt explicitly. See **Verifying Rust changes in `q2 preview`** below. + +## Verifying Rust changes in `q2 preview` + +`q2 preview` embeds the SPA bundle at `q2-preview-spa/dist/` into the +binary via `include_dir!`. The SPA loads the WASM at +`hub-client/wasm-quarto-hub-client/wasm_quarto_hub_client_bg.wasm`, +which is a build artifact of the `wasm-quarto-hub-client` crate (which +in turn depends on `quarto-core`, `pampa`, etc.). + +A plain `cargo build --bin q2` does NOT rebuild the WASM, and the +preview will silently run pre-change code. Tests will all pass; the +render path will look correct; the preview iframe will not. + +To pick up Rust changes in `q2 preview`, run the full chain: + +```bash +cd hub-client && npm run build:wasm # rebuild WASM from current Rust +cargo xtask build-q2-preview-spa # bundle WASM into q2-preview-spa/dist/ +cargo build --bin q2 # re-embed dist/ via include_dir! +``` + +`cargo xtask verify` (without `--skip-hub-build`) runs steps 1 and 2 +as part of the hub-build leg; after it finishes you still need step 3 +manually if you want the next `q2 preview` invocation to be fresh. + +For the deeper context (which crate produces which artifact, why the +chain doesn't auto-fire, how to diagnose stale-WASM symptoms) see +`claude-notes/instructions/preview-spa-rebuild.md`. ## Build Commands @@ -407,6 +486,7 @@ cargo xtask lint --quiet # Only show errors ### Current Lint Rules - **external-sources-in-macro**: Detects references to `external-sources/` in compile-time macros like `include_dir!`, `include_str!`, `include_bytes!`. These break builds because `external-sources/` is not version-controlled. +- **metadata-as-str**: Detects `meta.get("key")…as_str()` reads of document metadata. A bare YAML string in front-matter context is stored as `ConfigValueKind::PandocInlines`, for which `ConfigValue::as_str()` returns `None` — silently dropping the option. Use `as_plain_text()` instead (handles both `Scalar(String)` and `PandocInlines`). Only flags chains whose `.get(<string literal>)` receiver is a metadata expression (final identifier `meta`/`metadata`); internal map reads and test code are skipped. Suppress a deliberate scalar-only read with a `// lint:allow(metadata-as-str)` comment on the line or the line above. Introduced with bd-y89ihf0i. ### Adding New Lint Rules @@ -450,12 +530,13 @@ This repository has Claude Code hooks configured in `.claude/settings.json`. - When a cd command fails for you, that means you're confused about the current directory. In this situations, ALWAYS run `pwd` before doing anything else. - use `jq` instead of `python3 -m json.tool` for pretty-printing. When processing JSON in a shell pipeline, prefer `jq` when possible. - Always create a plan. Always work on the plan one item at a time. -- In the tree-sitter-markdown and tree-sitter-markdown-inline directories, you rebuild the parsers using "tree-sitter generate; tree-sitter build". Make sure the shell is in the correct directory before running those. Every time you change the tree-sitter parsers, rebuild them and run "tree-sitter test". If the tests fail, fix the code. Only change tree-sitter tests you've just added; do not touch any other tests. If you end up getting stuck there, stop and ask for my help. +- The qmd grammar is unified: there is a single grammar directory, `crates/tree-sitter-qmd/tree-sitter-markdown` (there is no longer a separate `tree-sitter-markdown-inline` directory). In that directory you rebuild the parser using "tree-sitter generate; tree-sitter build". Make sure the shell is in the correct directory before running those. Every time you change the tree-sitter parser, rebuild it and run "tree-sitter test". If the tests fail, fix the code. Only change tree-sitter tests you've just added; do not touch any other tests. If you end up getting stuck there, stop and ask for my help. - When attempting to find binary differences between files, always use `xxd` instead of other tools. - .c only works in JSON formats. Inside Lua filters, you need to use Pandoc's Lua API. Study https://raw.githubusercontent.com/jgm/pandoc/refs/heads/main/doc/lua-filters.md and make notes to yourself as necessary (use claude-notes in this directory) - Sometimes you get confused by macOS's using many different /private/tmp directories linked to /tmp. Prefer to use temporary directories local to the project you're working on (which you can later clean) - When using `echo` on Bash, be careful about escaping. `!` requires you to use single quotes. BAD, DO NOT USE: echo "![](hello)". GOOD, DO USE: '![](hello)'. - The documentation in docs/ is a user-facing Quarto website. There, you should document usage and not technical details. +- **The docs/ website is rendered with Quarto 2, NOT Quarto 1.** Always use `cargo run --bin q2 -- render docs/` (or `cargo run --bin q2 -- preview docs/`), never `quarto render` / `quarto preview`. The user's system `quarto` binary may be symlinked to a quarto-cli dev checkout and is *not* what builds this site. Verifying changes with Q1 produces misleading results: Q1 may reject Q2-specific YAML schema entries that Q2 accepts, and vice versa. - **CRITICALLY IMPORTANT**. IF YOU EVER FIND YOURSELF WANTING TO WRITE A HACKY SOLUTION (OR A "TODO" THAT UNDOES EXISTING WORK), STOP AND ASK THE USER. THAT MEANS YOUR PLAN IS NOT GOOD ENOUGH ## External Sources Policy diff --git a/Cargo.lock b/Cargo.lock index 9f5e9acfb..7fea400d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.1" @@ -100,15 +109,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "ar_archive_writer" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" -dependencies = [ - "object 0.37.3", -] - [[package]] name = "arbitrary" version = "1.4.2" @@ -143,6 +143,24 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.4", + "slab", + "windows-sys 0.61.2", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -214,6 +232,28 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "aws-lc-rs" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.8.9" @@ -241,7 +281,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sha1", + "sha1 0.10.6", "sync_wrapper", "tokio", "tokio-tungstenite 0.29.0", @@ -303,7 +343,7 @@ dependencies = [ "axum-extra", "dashmap 6.1.0", "jsonwebtoken", - "reqwest", + "reqwest 0.12.28", "serde", "thiserror 2.0.18", "tokio", @@ -555,6 +595,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -655,6 +697,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "cobs" version = "0.3.0" @@ -685,21 +742,31 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "comrak" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321d20bf105b6871a49da44c5fbb93e90a7cd6178ea5a9fe6cbc1e6d4504bc5e" +checksum = "aac0b255932a9cd52fbfd664b67957f9f2e095ae4711cb0e41b4e291edef94c2" dependencies = [ "caseless", "entities", + "finl_unicode", "jetscii", "phf 0.13.1", - "phf_codegen 0.13.1", + "phf_codegen", "rustc-hash", "smallvec", "typed-arena", - "unicode_categories", ] [[package]] @@ -773,6 +840,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -816,20 +893,38 @@ dependencies = [ "libc", ] +[[package]] +name = "cranelift-assembler-x64" +version = "0.123.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb1ffe339f197d6645b4d3037edf67c13cd3aa8871f29c2c9c046c729c1b9a17" +dependencies = [ + "cranelift-assembler-x64-meta", +] + +[[package]] +name = "cranelift-assembler-x64-meta" +version = "0.123.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81a21df73d1b12ed19eba481c08de8891e179e1870ed28d6e397f7746108f5" +dependencies = [ + "cranelift-srcgen", +] + [[package]] name = "cranelift-bforest" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e15d04a0ce86cb36ead88ad68cf693ffd6cda47052b9e0ac114bc47fd9cd23c4" +checksum = "3cf917d0180c15c945c13c8dde615d32a015769513b29158f728311d85a8f80d" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c6e3969a7ce267259ce244b7867c5d3bc9e65b0a87e81039588dfdeaede9f34" +checksum = "a6f4e1af2df00798c2895d228bb53d65c5aa09acace8525096f0b53830ffe42c" dependencies = [ "serde", "serde_derive", @@ -837,11 +932,12 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c22032c4cb42558371cf516bb47f26cdad1819d3475c133e93c49f50ebf304e" +checksum = "4e3a5d7300e4b44933dcf2947399945abe3f30f92c789b496ad72949e3ee15a6" dependencies = [ "bumpalo", + "cranelift-assembler-x64", "cranelift-bforest", "cranelift-bitset", "cranelift-codegen-meta", @@ -850,44 +946,50 @@ dependencies = [ "cranelift-entity", "cranelift-isle", "gimli", - "hashbrown 0.14.5", + "hashbrown 0.15.5", "log", + "pulley-interpreter", "regalloc2", "rustc-hash", "serde", "smallvec", "target-lexicon", + "wasmtime-internal-math", ] [[package]] name = "cranelift-codegen-meta" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904bc71c61b27fc57827f4a1379f29de64fe95653b620a3db77d59655eee0b8" +checksum = "becdb5c3111800d7f8e666fe5f35693bfc77de4401bfcaea19815caf7c482fb9" dependencies = [ + "cranelift-assembler-x64-meta", "cranelift-codegen-shared", + "cranelift-srcgen", + "heck", + "pulley-interpreter", ] [[package]] name = "cranelift-codegen-shared" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40180f5497572f644ce88c255480981ae2ec1d7bb4d8e0c0136a13b87a2f2ceb" +checksum = "d8fa77efffa12934971f757e154b16dd5e369a7f388a0f3adff74aadfd4c5a1d" [[package]] name = "cranelift-control" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d132c6d0bd8a489563472afc171759da0707804a65ece7ceb15a8c6d7dd5ef" +checksum = "62441d3aae3372381e03a121880482158ce90ca3bc2a56607cc122ee07536fe4" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d0d9618275474fbf679dd018ac6e009acbd6ae6850f6a67be33fb3b00b323" +checksum = "7bdc9832a010e0d411439aa016e1664dd23ca5c8953bf26b90fe34ad4b76822d" dependencies = [ "cranelift-bitset", "serde", @@ -896,9 +998,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fac41e16729107393174b0c9e3730fb072866100e1e64e80a1a963b2e484d57" +checksum = "9530b689b7c3accdbb32263ca318e19ab3bcf616d3a160c8456537c99b4c565b" dependencies = [ "cranelift-codegen", "log", @@ -908,21 +1010,27 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca20d576e5070044d0a72a9effc2deacf4d6aa650403189d8ea50126483944d" +checksum = "3fcd3258a4d87376f2681c72269a42009286a3d3707b2af4024ba5b3750ad477" [[package]] name = "cranelift-native" -version = "0.116.1" +version = "0.123.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dee82f3f1f2c4cba9177f1cc5e350fe98764379bcd29340caa7b01f85076c7" +checksum = "642c5703a22b58abccbf46f46c0dae65f0535bbe725beec70527a1ffcbbc1d34" dependencies = [ "cranelift-codegen", "libc", "target-lexicon", ] +[[package]] +name = "cranelift-srcgen" +version = "0.123.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d200dcd5a37de108ec1329e0ba924e2badd2c0ef2343c338310135159ae454e2" + [[package]] name = "crc32fast" version = "1.5.0" @@ -932,6 +1040,25 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -955,7 +1082,7 @@ checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ "bitflags 2.11.1", "crossterm_winapi", - "derive_more 2.1.1", + "derive_more", "document-features", "mio", "parking_lot", @@ -1007,14 +1134,14 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3" +checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.3", + "phf 0.13.1", "smallvec", ] @@ -1028,6 +1155,15 @@ dependencies = [ "syn", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1229,17 +1365,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -1289,6 +1414,7 @@ dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", "crypto-common 0.2.1", + "ctutils", ] [[package]] @@ -1379,6 +1505,18 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1419,9 +1557,9 @@ dependencies = [ [[package]] name = "ego-tree" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" +checksum = "b04dc5a38e4f151a79d9f2451ae6037fb6eaf5cba34771f44781f80e508498e3" [[package]] name = "either" @@ -1565,6 +1703,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "finl_unicode" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5" + [[package]] name = "flate2" version = "1.1.9" @@ -1627,6 +1771,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1652,16 +1802,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures" version = "0.3.32" @@ -1766,15 +1906,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "generic-array" version = "0.14.9" @@ -1837,9 +1968,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", "indexmap", @@ -1910,6 +2041,25 @@ dependencies = [ "crc32fast", ] +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -1967,7 +2117,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha1", + "sha1 0.10.6", ] [[package]] @@ -1985,6 +2135,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" @@ -2007,7 +2163,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -2019,6 +2175,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.2", +] + [[package]] name = "home" version = "0.5.12" @@ -2030,14 +2195,12 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.29.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" dependencies = [ "log", - "mac", "markup5ever", - "match_token", ] [[package]] @@ -2104,6 +2267,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -2131,6 +2295,22 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -2149,9 +2329,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2338,6 +2520,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + [[package]] name = "include_dir" version = "0.7.4" @@ -2409,7 +2597,7 @@ dependencies = [ "pest", "pest_derive", "serde", - "similar", + "similar 2.7.0", "tempfile", ] @@ -2430,20 +2618,30 @@ dependencies = [ ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.2" +name = "is-docker" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] [[package]] -name = "itertools" -version = "0.12.1" +name = "is-wsl" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" dependencies = [ - "either", + "is-docker", + "once_cell", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itertools" version = "0.13.0" @@ -2480,6 +2678,65 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.85" @@ -2499,7 +2756,7 @@ dependencies = [ "base64 0.22.1", "ed25519-dalek", "getrandom 0.2.17", - "hmac", + "hmac 0.12.1", "js-sys", "p256", "p384", @@ -2515,9 +2772,8 @@ dependencies = [ [[package]] name = "jupyter-protocol" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4649647741f9794a7a02e3be976f1b248ba28a37dbfc626d5089316fd4fbf4c8" +version = "2.0.0" +source = "git+https://github.com/cscheid/runtimed?rev=fc58eb48139a30cc559ac5973cb6debb00375b88#fc58eb48139a30cc559ac5973cb6debb00375b88" dependencies = [ "async-trait", "bytes", @@ -2685,12 +2941,6 @@ dependencies = [ "which 8.0.2", ] -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "mach2" version = "0.4.3" @@ -2702,27 +2952,13 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.14.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ "log", - "phf 0.11.3", - "phf_codegen 0.11.3", - "string_cache", - "string_cache_codegen", "tendril", -] - -[[package]] -name = "match_token" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "web_atoms", ] [[package]] @@ -2989,9 +3225,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", "hashbrown 0.15.5", @@ -2999,15 +3235,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.4" @@ -3020,6 +3247,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "open" +version = "5.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + [[package]] name = "openssl" version = "0.10.78" @@ -3145,7 +3383,7 @@ dependencies = [ "regex", "serde", "serde_json", - "sha1", + "sha1 0.11.0", "supports-hyperlinks", "tempfile", "tokio", @@ -3279,7 +3517,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "phf_macros", + "phf_macros 0.11.3", "phf_shared 0.11.3", ] @@ -3289,20 +3527,11 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ + "phf_macros 0.13.1", "phf_shared 0.13.1", "serde", ] -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", -] - [[package]] name = "phf_codegen" version = "0.13.1" @@ -3346,6 +3575,19 @@ dependencies = [ "syn", ] +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "phf_shared" version = "0.11.3" @@ -3417,6 +3659,20 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.4", + "windows-sys 0.61.2", +] + [[package]] name = "pollster" version = "0.4.0" @@ -3525,25 +3781,26 @@ dependencies = [ ] [[package]] -name = "psm" -version = "0.1.30" +name = "pulley-interpreter" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3852766467df634d74f0b2d7819bf8dc483a0eb2e3b0f50f756f9cfe8b0d18d8" +checksum = "35eaba3163b9faf1d707f0704a7370bfdbe73622c766acdaf1fa4addb87510de" dependencies = [ - "ar_archive_writer", - "cc", + "cranelift-bitset", + "log", + "pulley-macros", + "wasmtime-internal-math", ] [[package]] -name = "pulley-interpreter" -version = "29.0.1" +name = "pulley-macros" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d95f8575df49a2708398182f49a888cf9dc30210fb1fd2df87c889edcee75d" +checksum = "ac294897a29ce07919714f9f25c11a819d75759d47eb9f3273845ffea5a5760d" dependencies = [ - "cranelift-bitset", - "log", - "sptr", - "wasmtime-math", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3568,19 +3825,26 @@ name = "quarto" version = "0.1.0" dependencies = [ "anyhow", + "async-trait", "clap", + "open", "pampa", "pollster", "quarto-core", "quarto-doctemplate", + "quarto-error-reporting", "quarto-hub", "quarto-lsp", + "quarto-preview", + "quarto-publish", "quarto-sass", + "quarto-source-map", "quarto-system-runtime", "quarto-test", "quarto-trace", "quarto-trace-server", "quarto-util", + "serde", "serde_json", "serde_yaml", "tempfile", @@ -3615,6 +3879,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "quarto-brand" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "serde_yaml", + "thiserror 2.0.18", +] + [[package]] name = "quarto-citeproc" version = "0.1.0" @@ -3630,7 +3904,7 @@ dependencies = [ "rust-embed", "serde", "serde_json", - "similar", + "similar 3.1.0", "thiserror 2.0.18", ] @@ -3655,8 +3929,14 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", + "clap", + "flate2", + "glob", "hashlink", + "hex", + "imagesize", "include_dir", + "insta", "jupyter-protocol", "pampa", "pathdiff", @@ -3675,17 +3955,22 @@ dependencies = [ "quarto-trace", "quarto-util", "quarto-yaml", + "rayon", "regex", "runtimelib", + "scraper", "serde", "serde_json", - "sha2 0.10.9", + "serde_yaml", + "sha2 0.11.0", "tempfile", "thiserror 2.0.18", + "time", "tokio", "tokio-util", "tracing", "uuid", + "walkdir", "which 8.0.2", "yaml-rust2", ] @@ -3712,6 +3997,7 @@ dependencies = [ "quarto-treesitter-ast", "serde", "serde_json", + "tempfile", "thiserror 2.0.18", "tree-sitter", "tree-sitter-doctemplate", @@ -3735,6 +4021,7 @@ dependencies = [ "ariadne", "once_cell", "quarto-source-map", + "schemars", "serde", "serde_json", "thiserror 2.0.18", @@ -3786,24 +4073,29 @@ dependencies = [ "automerge", "axum", "axum-jwt-auth", + "base64 0.22.1", + "chrono", "clap", "cookie", "dirs", "fs2", "futures", "hex", - "hmac", + "hmac 0.13.0", "http", "infer", "jsonwebtoken", "notify", "notify-debouncer-mini", + "parking_lot", + "quarto-util", "rand 0.9.4", - "reqwest", + "reqwest 0.13.3", + "rsa", "samod", "serde", "serde_json", - "sha2 0.10.9", + "sha2 0.11.0", "tempfile", "thiserror 2.0.18", "time", @@ -3857,6 +4149,7 @@ dependencies = [ name = "quarto-navigation" version = "0.1.0" dependencies = [ + "quarto-config", "quarto-pandoc-types", "quarto-source-map", "yaml-rust2", @@ -3878,6 +4171,7 @@ dependencies = [ name = "quarto-parse-errors" version = "0.1.0" dependencies = [ + "hashlink", "quarto-error-message-macros", "quarto-error-reporting", "quarto-source-map", @@ -3886,6 +4180,38 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "quarto-preview" +version = "0.1.0" +dependencies = [ + "anyhow", + "automerge", + "axum", + "flate2", + "http", + "http-body-util", + "include_dir", + "pampa", + "pollster", + "quarto-core", + "quarto-error-reporting", + "quarto-hub", + "quarto-pandoc-types", + "quarto-source-map", + "quarto-system-runtime", + "quarto-trace", + "reqwest 0.12.28", + "samod", + "serde", + "serde_json", + "sha2 0.11.0", + "tempfile", + "thiserror 2.0.18", + "tokio", + "tower 0.5.3", + "tracing", +] + [[package]] name = "quarto-project-create" version = "0.1.0" @@ -3898,6 +4224,31 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "quarto-publish" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "pollster", + "quarto-config", + "quarto-core", + "quarto-error-reporting", + "quarto-pandoc-types", + "quarto-source-map", + "quarto-system-runtime", + "quarto-util", + "serde", + "serde_json", + "serde_yaml", + "tempfile", + "thiserror 2.0.18", + "tracing", + "ureq", + "url", + "uuid", +] + [[package]] name = "quarto-sass" version = "0.1.0" @@ -3906,13 +4257,16 @@ dependencies = [ "include_dir", "insta", "once_cell", + "quarto-brand", "quarto-pandoc-types", "quarto-source-map", "quarto-system-runtime", "regex", "serde", "serde_json", - "sha2 0.10.9", + "serde_yaml", + "sha2 0.11.0", + "tempfile", "thiserror 2.0.18", "yaml-rust2", ] @@ -3935,7 +4289,7 @@ dependencies = [ "grass", "js-sys", "pollster", - "reqwest", + "reqwest 0.13.3", "serde", "serde_json", "serde_v8", @@ -3967,8 +4321,10 @@ dependencies = [ name = "quarto-trace" version = "0.1.0" dependencies = [ + "flate2", "serde", "serde_json", + "sha2 0.11.0", "thiserror 2.0.18", ] @@ -4052,9 +4408,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-xml" -version = "0.37.5" +version = "0.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +checksum = "721da970c312655cde9b4ffe0547f20a8494866a4af5ff51f18b7c633d0c870b" dependencies = [ "memchr", ] @@ -4085,6 +4441,7 @@ version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", @@ -4209,6 +4566,26 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "reconcile-viewer" version = "0.1.0" @@ -4244,11 +4621,31 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regalloc2" -version = "0.11.2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc06e6b318142614e4a48bc725abbf08ff166694835c43c9dae5a9009704639a" +checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734" dependencies = [ "allocator-api2", "bumpalo", @@ -4295,17 +4692,22 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", + "hyper-tls", "hyper-util", "js-sys", "log", + "mime", + "native-tls", "percent-encoding", "pin-project-lite", "quinn", @@ -4316,6 +4718,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", + "tokio-native-tls", "tokio-rustls", "tower 0.5.3", "tower-http", @@ -4327,6 +4730,45 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "reqwest" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower 0.5.3", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures 0.4.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys", +] + [[package]] name = "resb" version = "0.1.2" @@ -4343,7 +4785,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -4383,9 +4825,8 @@ dependencies = [ [[package]] name = "runtimelib" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1c46eb84b80531e9745a859f60fd599eab9f6397d0db1bda8c99720796d3000" +version = "2.0.0" +source = "git+https://github.com/cscheid/runtimed?rev=fc58eb48139a30cc559ac5973cb6debb00375b88#fc58eb48139a30cc559ac5973cb6debb00375b88" dependencies = [ "base64 0.22.1", "bytes", @@ -4487,6 +4928,8 @@ version = "0.23.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" dependencies = [ + "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -4495,6 +4938,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.14.0" @@ -4505,12 +4960,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -4616,6 +5099,31 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -4624,9 +5132,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scraper" -version = "0.22.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3d051b884f40e309de6c149734eab57aa8cc1347992710dc80bcc1c2194c15" +checksum = "f0f5297102b8b62b4454ee8561601b2d551b4913148feb4241ca9d1a04bf4526" dependencies = [ "cssparser", "ego-tree", @@ -4667,7 +5175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.11.1", - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -4685,19 +5193,19 @@ dependencies = [ [[package]] name = "selectors" -version = "0.26.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" dependencies = [ "bitflags 2.11.1", "cssparser", - "derive_more 0.99.20", - "fxhash", + "derive_more", "log", "new_debug_unreachable", - "phf 0.11.3", - "phf_codegen 0.11.3", + "phf 0.13.1", + "phf_codegen", "precomputed-hash", + "rustc-hash", "servo_arc", "smallvec", ] @@ -4748,6 +5256,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.149" @@ -4843,6 +5362,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", +] + [[package]] name = "sha1_smol" version = "1.0.1" @@ -4942,12 +5472,37 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "similar" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "similar" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d93e861ede2e497b47833469b8ec9d5c07fa4c78ce7a00f6eb7dd8168b4b3f" +dependencies = [ + "bstr", +] + [[package]] name = "simple_asn1" version = "0.6.4" @@ -5035,12 +5590,6 @@ dependencies = [ "der", ] -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -5070,25 +5619,24 @@ checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" [[package]] name = "string_cache" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared 0.11.3", + "phf_shared 0.13.1", "precomputed-hash", - "serde", ] [[package]] name = "string_cache_codegen" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", ] @@ -5200,6 +5748,27 @@ dependencies = [ "syn", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -5260,12 +5829,11 @@ dependencies = [ [[package]] name = "tendril" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" dependencies = [ - "futf", - "mac", + "new_debug_unreachable", "utf-8", ] @@ -5643,9 +6211,9 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.25.10" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" +checksum = "887bd495d0582c5e3e0d8ece2233666169fa56a9644d172fc22ad179ab2d0538" dependencies = [ "cc", "regex", @@ -5687,9 +6255,9 @@ dependencies = [ [[package]] name = "tree-sitter-highlight" -version = "0.25.10" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc5f880ad8d8f94e88cb81c3557024cf1a8b75e3b504c50481ed4f5a6006ff3" +checksum = "ccde2b54a34b58313e69c02496a2a9ad38d59af79b196b5e1df063431752a7e0" dependencies = [ "regex", "streaming-iterator", @@ -5831,7 +6399,7 @@ dependencies = [ "log", "native-tls", "rand 0.9.4", - "sha1", + "sha1 0.10.6", "thiserror 2.0.18", "utf-8", ] @@ -5848,7 +6416,7 @@ dependencies = [ "httparse", "log", "rand 0.9.4", - "sha1", + "sha1 0.10.6", "thiserror 2.0.18", ] @@ -5921,12 +6489,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -5939,6 +6501,34 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +dependencies = [ + "base64 0.22.1", + "log", + "percent-encoding", + "rustls", + "rustls-pki-types", + "ureq-proto", + "utf8-zero", + "webpki-roots", +] + +[[package]] +name = "ureq-proto" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" +dependencies = [ + "base64 0.22.1", + "http", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.8" @@ -5958,6 +6548,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -6165,12 +6761,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.221.3" +version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc8444fe4920de80a4fe5ab564fff2ae58b6b73166b89751f8c6c93509da32e5" +checksum = "724fccfd4f3c24b7e589d333fc0429c68042897a7e8a5f8694f31792471841e7" dependencies = [ - "leb128", - "wasmparser 0.221.3", + "leb128fmt", + "wasmparser 0.236.1", ] [[package]] @@ -6211,9 +6807,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.221.3" +version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185" +checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ "bitflags 2.11.1", "hashbrown 0.15.5", @@ -6236,116 +6832,117 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.221.3" +version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7343c42a97f2926c7819ff81b64012092ae954c5d83ddd30c9fcdefd97d0b283" +checksum = "2df225df06a6df15b46e3f73ca066ff92c2e023670969f7d50ce7d5e695abbb1" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.221.3", + "wasmparser 0.236.1", ] [[package]] name = "wasmtime" -version = "29.0.1" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11976a250672556d1c4c04c6d5d7656ac9192ac9edc42a4587d6c21460010e69" +checksum = "2060d93be880840d764ab537464b916e22c07758ac5d43e5f07cc86fec6d1bec" dependencies = [ + "addr2line", "anyhow", "bitflags 2.11.1", "bumpalo", "cc", "cfg-if", - "hashbrown 0.14.5", + "hashbrown 0.15.5", "indexmap", "libc", "log", "mach2", "memfd", - "object 0.36.7", + "object", "once_cell", - "paste", "postcard", - "psm", "pulley-interpreter", - "rustix 0.38.44", + "rustix 1.1.4", "serde", "serde_derive", "smallvec", - "sptr", "target-lexicon", - "wasmparser 0.221.3", - "wasmtime-asm-macros", - "wasmtime-component-macro", - "wasmtime-cranelift", + "wasmparser 0.236.1", "wasmtime-environ", - "wasmtime-fiber", - "wasmtime-jit-icache-coherence", - "wasmtime-math", - "wasmtime-slab", - "wasmtime-versioned-export-macros", - "wasmtime-winch", - "windows-sys 0.59.0", + "wasmtime-internal-asm-macros", + "wasmtime-internal-cranelift", + "wasmtime-internal-fiber", + "wasmtime-internal-jit-debug", + "wasmtime-internal-jit-icache-coherence", + "wasmtime-internal-math", + "wasmtime-internal-slab", + "wasmtime-internal-unwinder", + "wasmtime-internal-versioned-export-macros", + "wasmtime-internal-winch", + "windows-sys 0.60.2", ] [[package]] -name = "wasmtime-asm-macros" -version = "29.0.1" +name = "wasmtime-c-api-impl" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f178b0d125201fbe9f75beaf849bd3e511891f9e45ba216a5b620802ccf64f2" +checksum = "33bd4cfa38cb2ff4eefc63853cf82f1a3fc464091f0f346e5fbb591194ce9e07" dependencies = [ - "cfg-if", + "anyhow", + "log", + "tracing", + "wasmtime", + "wasmtime-internal-c-api-macros", ] [[package]] -name = "wasmtime-c-api-impl" -version = "29.0.1" +name = "wasmtime-environ" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea30cef3608f2de5797c7bbb94c1ba4f3676d9a7f81ae86ced1b512e2766ed0c" +checksum = "902f991ca8c2e5abc03119eb5d7f7f57da1b7c2123addb8214b49c188737711e" dependencies = [ "anyhow", + "cranelift-bitset", + "cranelift-entity", + "gimli", + "indexmap", "log", - "tracing", - "wasmtime", - "wasmtime-c-api-macros", + "object", + "postcard", + "serde", + "serde_derive", + "smallvec", + "target-lexicon", + "wasm-encoder 0.236.1", + "wasmparser 0.236.1", + "wasmprinter", ] [[package]] -name = "wasmtime-c-api-macros" -version = "29.0.1" +name = "wasmtime-internal-asm-macros" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022a79ebe1124d5d384d82463d7e61c6b4dd857d81f15cb8078974eeb86db65b" +checksum = "b02cec619b54ce7652d1d7676718a42ccf5f16b2fb23c27cd6e3c307bc93907a" dependencies = [ - "proc-macro2", - "quote", + "cfg-if", ] [[package]] -name = "wasmtime-component-macro" -version = "29.0.1" +name = "wasmtime-internal-c-api-macros" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d74de6592ed945d0a602f71243982a304d5d02f1e501b638addf57f42d57dfaf" +checksum = "3541e5aa546b6fbabbcd2c80b3f0913741d3bc3bc8be8bf18019ffb381979e4f" dependencies = [ - "anyhow", "proc-macro2", "quote", - "syn", - "wasmtime-component-util", - "wasmtime-wit-bindgen", - "wit-parser 0.221.3", ] [[package]] -name = "wasmtime-component-util" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707dc7b3c112ab5a366b30cfe2fb5b2f8e6a0f682f16df96a5ec582bfe6f056e" - -[[package]] -name = "wasmtime-cranelift" -version = "29.0.1" +name = "wasmtime-internal-cranelift" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366be722674d4bf153290fbcbc4d7d16895cc82fb3e869f8d550ff768f9e9e87" +checksum = "54eb7fc20c8692dc96148365d7a00a1b79fee810833c75bdf8ec073a46e4721a" dependencies = [ "anyhow", "cfg-if", @@ -6355,87 +6952,90 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "gimli", - "itertools 0.12.1", + "itertools 0.14.0", "log", - "object 0.36.7", + "object", + "pulley-interpreter", "smallvec", "target-lexicon", - "thiserror 1.0.69", - "wasmparser 0.221.3", + "thiserror 2.0.18", + "wasmparser 0.236.1", "wasmtime-environ", - "wasmtime-versioned-export-macros", + "wasmtime-internal-math", + "wasmtime-internal-versioned-export-macros", ] [[package]] -name = "wasmtime-environ" -version = "29.0.1" +name = "wasmtime-internal-fiber" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdadc1af7097347aa276a4f008929810f726b5b46946971c660b6d421e9994ad" +checksum = "30708e122dcc1e175c66345c209c01752ca0cd20c9021721b6f56968342e9dbe" dependencies = [ "anyhow", - "cranelift-bitset", - "cranelift-entity", - "gimli", - "indexmap", - "log", - "object 0.36.7", - "postcard", - "serde", - "serde_derive", - "smallvec", - "target-lexicon", - "wasm-encoder 0.221.3", - "wasmparser 0.221.3", - "wasmprinter", + "cc", + "cfg-if", + "libc", + "rustix 1.1.4", + "wasmtime-internal-asm-macros", + "wasmtime-internal-versioned-export-macros", + "windows-sys 0.60.2", ] [[package]] -name = "wasmtime-fiber" -version = "29.0.1" +name = "wasmtime-internal-jit-debug" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccba90d4119f081bca91190485650730a617be1fff5228f8c4757ce133d21117" +checksum = "1eeaab071a646d9ae205266adf186c63fa6d077d36b0b33628dd6c3d321d3195" dependencies = [ - "anyhow", "cc", - "cfg-if", - "rustix 0.38.44", - "wasmtime-asm-macros", - "wasmtime-versioned-export-macros", - "windows-sys 0.59.0", + "wasmtime-internal-versioned-export-macros", ] [[package]] -name = "wasmtime-jit-icache-coherence" -version = "29.0.1" +name = "wasmtime-internal-jit-icache-coherence" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5e8552e01692e6c2e5293171704fed8abdec79d1a6995a0870ab190e5747d1" +checksum = "09979561e6e4a17bf55722463b066ccb968f010ac6ec5d647e4dff19eddbb19e" dependencies = [ "anyhow", "cfg-if", "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] -name = "wasmtime-math" -version = "29.0.1" +name = "wasmtime-internal-math" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29210ec2aa25e00f4d54605cedaf080f39ec01a872c5bd520ad04c67af1dde17" +checksum = "9193eb852e5c68aeb95a5ea7538c2bec503023169a0b24430224b4f1ded24988" dependencies = [ "libm", ] [[package]] -name = "wasmtime-slab" -version = "29.0.1" +name = "wasmtime-internal-slab" +version = "36.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "289bfa4fbb43f406f36166737f1f25522c215ef2ef11f98423089a6a7590a3d1" + +[[package]] +name = "wasmtime-internal-unwinder" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb5821a96fa04ac14bc7b158bb3d5cd7729a053db5a74dad396cd513a5e5ccf" +checksum = "4e748c970993865d9bf474465c3f10f96e541c472bc8f7ec0b031779f4ac29c6" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "log", + "object", +] [[package]] -name = "wasmtime-versioned-export-macros" -version = "29.0.1" +name = "wasmtime-internal-versioned-export-macros" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ff86db216dc0240462de40c8290887a613dddf9685508eb39479037ba97b5b" +checksum = "e97e07438cb8b50df3bc9659c56757830a15235c94268dbbd54186524fd4ed84" dependencies = [ "proc-macro2", "quote", @@ -6443,34 +7043,22 @@ dependencies = [ ] [[package]] -name = "wasmtime-winch" -version = "29.0.1" +name = "wasmtime-internal-winch" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbabfb8f20502d5e1d81092b9ead3682ae59988487aafcd7567387b7a43cf8f" +checksum = "107aa0c3f71cc590c786d6d6e09893558b383f4d78107b864a9fd978929d0244" dependencies = [ "anyhow", "cranelift-codegen", "gimli", - "object 0.36.7", + "object", "target-lexicon", - "wasmparser 0.221.3", - "wasmtime-cranelift", + "wasmparser 0.236.1", "wasmtime-environ", + "wasmtime-internal-cranelift", "winch-codegen", ] -[[package]] -name = "wasmtime-wit-bindgen" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8358319c2dd1e4db79e3c1c5d3a5af84956615343f9f89f4e4996a36816e06e6" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "wit-parser 0.221.3", -] - [[package]] name = "web-sys" version = "0.3.85" @@ -6491,6 +7079,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web_atoms" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7cff6eef815df1834fd250e3a2ff436044d82a9f1bc1980ca1dbdf07effc538" +dependencies = [ + "phf 0.13.1", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "1.0.7" @@ -6521,6 +7130,17 @@ dependencies = [ "libc", ] +[[package]] +name = "win_uds" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd30a1a28a3799479cbf4e17284a220ea9ff6bad098a9d0224543a5d1efe1da" +dependencies = [ + "async-io", + "futures-io", + "socket2", +] + [[package]] name = "winapi" version = "0.3.9" @@ -6554,20 +7174,22 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "29.0.1" +version = "36.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f849ef2c5f46cb0a20af4b4487aaa239846e52e2c03f13fa3c784684552859c" +checksum = "646e2d01f59d7006e24a370762abfb63d5918696ff02197e027efd15252a1f79" dependencies = [ "anyhow", + "cranelift-assembler-x64", "cranelift-codegen", "gimli", "regalloc2", "smallvec", "target-lexicon", - "thiserror 1.0.69", - "wasmparser 0.221.3", - "wasmtime-cranelift", + "thiserror 2.0.18", + "wasmparser 0.236.1", "wasmtime-environ", + "wasmtime-internal-cranelift", + "wasmtime-internal-math", ] [[package]] @@ -6611,6 +7233,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -6823,7 +7456,7 @@ checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", "heck", - "wit-parser 0.244.0", + "wit-parser", ] [[package]] @@ -6873,25 +7506,7 @@ dependencies = [ "wasm-encoder 0.244.0", "wasm-metadata", "wasmparser 0.244.0", - "wit-parser 0.244.0", -] - -[[package]] -name = "wit-parser" -version = "0.221.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896112579ed56b4a538b07a3d16e562d101ff6265c46b515ce0c701eef16b2ac" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.221.3", + "wit-parser", ] [[package]] @@ -6934,8 +7549,10 @@ dependencies = [ "anyhow", "clap", "proc-macro2", + "serde_json", "syn", "tempfile", + "time", "walkdir", ] @@ -7028,9 +7645,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zeromq" -version = "0.6.0-pre.1" +version = "0.6.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f06ccf13d2d6709a7463d175b88598c88a5dc63c8907ffb6f32a8a16baf77c1f" +checksum = "d92d9897a1fefd826fbbfc98b11ef50aba2e37a425142163f1792744c701b6d2" dependencies = [ "async-trait", "asynchronous-codec", @@ -7048,6 +7665,7 @@ dependencies = [ "tokio", "tokio-util", "uuid", + "win_uds", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f7e223eed..6e726d757 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ edition = "2024" [workspace.dependencies] anyhow = "1.0.101" -quick-xml = "0.37" +quick-xml = "0.39" ariadne = "0.6" clap = { version = "4.5", features = ["derive", "cargo", "env"] } insta = "1.46.3" @@ -53,9 +53,10 @@ async-trait = "0.1" tokio-util = "0.7" pollster = "0.4" regex = "1.12" -scraper = "0.22" +scraper = "0.26" grass = "0.13.4" include_dir = "0.7" +flate2 = "1.1" uuid = { version = "1", features = ["v4"] } base64 = "0.22" walkdir = "2" @@ -86,10 +87,10 @@ features = ["std"] default-features = false [workspace.dependencies.tree-sitter] -version = "0.25.10" +version = "0.26" [workspace.dependencies.tree-sitter-highlight] -version = "0.25.10" +version = "0.26" [workspace.dependencies.tree-sitter-qmd] path = "./crates/tree-sitter-qmd" @@ -155,6 +156,9 @@ path = "./crates/quarto-lsp-core" [workspace.dependencies.quarto-lsp] path = "./crates/quarto-lsp" +[workspace.dependencies.quarto-brand] +path = "./crates/quarto-brand" + [workspace.dependencies.quarto-sass] path = "./crates/quarto-sass" @@ -170,6 +174,9 @@ path = "./crates/quarto-hub" [workspace.dependencies.quarto-navigation] path = "./crates/quarto-navigation" +[workspace.dependencies.quarto-publish] +path = "./crates/quarto-publish" + [workspace.dependencies.quarto-test] path = "./crates/quarto-test" @@ -269,6 +276,16 @@ verbose_file_reads = "warn" [patch.crates-io] lua-src = { path = "crates/lua-src-wasm" } +# Fork of runtimelib that adds venv-aware kernelspec discovery +# (`data_dirs_with_jupyter_paths`, `find_kernelspec_with_jupyter_paths`) +# and threads `searched_paths` through `RuntimeError::KernelNotFound`. +# Pinned to a SHA on cscheid/runtimed; will be removed once the +# upstream PR (bd-875x) lands and a release ships. +runtimelib = { git = "https://github.com/cscheid/runtimed", rev = "fc58eb48139a30cc559ac5973cb6debb00375b88" } +# `runtimelib` depends on `jupyter-protocol` via the runtimed workspace, +# so we must patch jupyter-protocol from the same SHA to avoid pulling +# in two distinct `jupyter_protocol::JupyterMessage` types. +jupyter-protocol = { git = "https://github.com/cscheid/runtimed", rev = "fc58eb48139a30cc559ac5973cb6debb00375b88" } # Profiles must be set at the workspace level [profile.dev] @@ -277,6 +294,17 @@ lua-src = { path = "crates/lua-src-wasm" } # https://github.com/wasm-bindgen/wasm-bindgen/issues/3451#issuecomment-1562982835 opt-level = "s" +# CI-only profile (used by `.github/workflows/test-suite.yml`). Strips +# debuginfo to fit GHA disk. Locally, omit `--cargo-profile ci` to get +# full debuginfo via the default `dev` profile. +# See claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md. +[profile.ci] +inherits = "dev" +debug = "line-tables-only" + +[profile.ci.package."*"] +debug = false + # Release-like profile with debug info preserved for profilers (samply, etc.). # Used by perf-harness drivers; see claude-notes/instructions/performance-profiling.md. [profile.release-perf] diff --git a/README.md b/README.md index 668ca4255..b9465ebe7 100644 --- a/README.md +++ b/README.md @@ -4,105 +4,22 @@ > **Experimental** - This project is under active development. It's not yet ready for production use, and will not be for a while. -This repository is a Rust implementation of the next version of [Quarto](https://quarto.org). The goal is to replace parts of the TypeScript/Deno runtime with a unified Rust implementation, enabling: - -- Shared validation logic between CLI and Language Server Protocol (LSP) -- Improved performance, particularly for LSP operations -- Single-binary distribution - -## Why Rust? - -Posit has been investing in Rust for developer tooling: - -- [Air](https://github.com/posit-dev/air/) - An R formatter and LSP written in Rust -- [Ark](https://github.com/posit-dev/ark/) - An R kernel for Jupyter written in Rust - -Rust offers compelling advantages for Quarto's tooling: - -- **Performance** - Native compilation provides significant speedups for parsing and validation, critical for responsive LSP experiences -- **WebAssembly** - Rust compiles to WASM, enabling browser-based tooling and editor integrations without separate runtime dependencies -- **Single binary** - No runtime installation required; simpler distribution and deployment -- **Memory safety** - Eliminates entire classes of bugs without garbage collection overhead - -## Key Crates - -### pampa - -The most mature crate in this workspace. **pampa** is our Rust port of [Pandoc](https://pandoc.org), the universal document converter. While not a feature-for-feature reimplementation, pampa offers many of the same APIs and will feel familiar to Pandoc users. - -Currently, pampa focuses on parsing Quarto Markdown (QMD) and producing Pandoc AST output with full source location tracking. - -```bash -# Parse QMD to Pandoc JSON -cargo run -p pampa -- input.qmd -t json - -# Parse with verbose tree-sitter output (for debugging) -cargo run -p pampa -- input.qmd -t json -v -``` - -**Features:** -- Tree-sitter based parsing (block + inline grammars) -- Multiple output formats: JSON, HTML, ANSI, Markdown, plaintext -- Lua filter support (Pandoc-compatible) -- Source location tracking through all transformations - -### Supporting Infrastructure - -The crates in this workspace share a focus on **precise source location tracking** and **uniform error reporting**: - -| Crate | Purpose | -|-------|---------| -| `quarto-source-map` | Unified source location tracking with transformation history | -| `quarto-error-reporting` | Structured diagnostics with tidyverse-style formatting | -| `quarto-yaml` | YAML parsing with fine-grained source locations | -| `quarto-xml` | XML parsing with source tracking (for CSL files) | -| `quarto-pandoc-types` | Pandoc AST type definitions | -| `quarto-doctemplate` | Pandoc-compatible document template engine | - -## Source Location Tracking - -A core design principle: every semantic entity carries source location information through all transformations. This enables: - -- Precise error messages pointing to exact locations in source files -- Provenance tracking through string extraction, concatenation, and filtering -- Serializable source info for LSP caching - -```rust -// Source info tracks transformations -enum SourceInfo { - Original { ... }, // Direct file position - Substring { parent, ... }, // Extracted from parent - Concat { pieces, ... }, // Multiple sources combined - FilterProvenance { ... }, // Created by Lua filter -} -``` - -## Error Reporting - -Errors use [ariadne](https://codeberg.org/zesterer/ariadne) for precise, visually clear diagnostics: - -``` -$ echo '_hello world' | quarto-markdown-pandoc -t json - -Error: [Q-2-5] Unclosed Underscore Emphasis - ╭─[<stdin>:1:13] - │ - 1 │ _hello world - │ ┬ ┬ - │ ╰────────────── This is the opening '_' mark. - │ │ - │ ╰── I reached the end of the block before finding a closing '_' for the emphasis. -───╯ -``` +This repository is a Rust implementation of the next version of [Quarto](https://quarto.org). The goal is to replace parts of the TypeScript/Deno runtime with a unified Rust implementation. ## Building Requires Rust nightly (edition 2024). ```bash -# Build all Rust crates and binaries; build hub-client and its TS test suite +# Installs nodejs dependencies for the vite/WASM dependencies + +npm install +# Build all Rust crates and binaries and test; build hub-client and its TS test suite cargo xtask verify +# Just build everything instead (use --release for optimized binaries) +cargo xtask build-all + # Run tests (uses nextest) cargo nextest run ``` @@ -111,7 +28,7 @@ cargo nextest run We welcome discussions about the project via GitHub issues. However, the Quarto team will be working on this codebase internally before we're ready to accept outside contributions or make public binary releases/announcements. -Please feel free to open issues for questions, suggestions, or bug reports. +Please feel free to use the discussions page for questions and suggestions. ## Status diff --git a/claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md b/claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md new file mode 100644 index 000000000..fc4364f9f --- /dev/null +++ b/claude-notes/2026-04-28-ci-disk-space-and-profile-ci.md @@ -0,0 +1,184 @@ +# CI disk space and the `[profile.ci]` Cargo profile + +Date: 2026-04-28 + +This note explains why the q2 workspace has a `[profile.ci]` Cargo profile that is **only** used in `.github/workflows/test-suite.yml`, what's different from the default `dev` profile, and how to recover the full debug info when reproducing a CI failure locally. + +If you stumbled here from a `target/` directory growing unexpectedly, or wondered why CI uses `--cargo-profile ci`, this is the right page. + +## TL;DR + +- CI on `ubuntu-latest` has very little disk space (~14 GB free after the runner image, partially recovered by a cleanup action). +- The default `dev` profile emits full debuginfo, which roughly **doubles** `target/` size on a workspace this big. +- We added a `[profile.ci]` profile (inherits from `dev`, strips most debuginfo) and the CI workflow uses it via `cargo nextest run --cargo-profile ci`. +- We also removed the redundant `cargo build` step from CI — `cargo nextest run --tests` already builds everything `cargo build` does, plus the test artifacts. (We initially tried `--all-targets` but that pulls in `harness = false` benches which nextest can't enumerate as tests; `--tests` is the correct flag.) +- We freed ~10 GB more on the runner by enabling `remove_tool_cache: true` on the existing free-disk-space step (no step uses `/opt/hostedtoolcache/`) and by pruning Docker images right after that step. +- **Locally, nothing changed.** `cargo build`, `cargo test`, and `cargo nextest run` (without `--cargo-profile ci`) still use the default `dev` profile with full debuginfo. + +## What triggered this + +Run [25062065055](https://github.com/quarto-dev/q2/actions/runs/25062065055/job/73418747660?pr=139) (PR #139, ubuntu-latest) failed with `No space left on device` during `cargo nextest run`, even though the existing `endersonmenezes/free-disk-space` step had already freed **18.8 GB** (Android 10.4 + .NET 4.6 + Haskell 3.7). + +The previous mitigation (PR #55, 2026-03-17) bought us several months of headroom; the workspace has since grown past it. + +## The two changes that need explaining + +The runner-side cleanup (tool_cache + docker prune) is mechanical — see the workflow file. The two changes worth documenting in detail are the Cargo profile and the workflow build/test consolidation. + +### Change 1: `[profile.ci]` Cargo profile + +Added to root `Cargo.toml`: + +```toml +[profile.ci] +inherits = "dev" +debug = "line-tables-only" + +[profile.ci.package."*"] +debug = false +``` + +What this does: + +- `inherits = "dev"` — start from the `dev` profile, including the existing `opt-level = "s"` wasm-bindgen workaround. +- `debug = "line-tables-only"` — emit only enough debug info for backtraces to show **file and line numbers**. Variable values and function-parameter info are dropped. +- `[profile.ci.package."*"] debug = false` — strip debug info entirely from **all dependencies**. Deps dominate `target/` size on this workspace, so this is where the bulk of the saving comes from. + +#### What's lost in CI panic logs + +Backtraces still show file/line per frame. They no longer show: + +- Variable values +- Function-parameter values +- The full type names of generic instantiations beyond what rustc records as part of the symbol + +In practice, panic output in CI logs only ever showed file/line anyway — variables aren't included unless you're attached with `gdb`/`lldb`. So this is essentially zero observable change for CI-log-only debugging. + +#### How to get full debuginfo back locally + +Just **don't pass `--cargo-profile ci`**. Every default cargo command uses the `dev` profile, which is unchanged: + +```bash +# Full debuginfo (default behavior, unchanged) +cargo build +cargo test +cargo nextest run + +# CI profile (matches what GitHub Actions runs) +cargo nextest run --cargo-profile ci +``` + +If you want to **reproduce a CI failure** under a debugger or with `RUST_BACKTRACE=full` and need rich frame info, run with the default `dev` profile. The `[profile.ci]` block does not affect any other profile. + +#### Why `line-tables-only` instead of `debug = 0` + +`line-tables-only` keeps file:line info in panic backtraces — readable in CI logs, no debugger needed. +`debug = 0` would drop that too, leaving only hex addresses, which makes any unexpected CI failure much harder to triage. + +The disk savings between `line-tables-only` and `debug = 0` are minor (line tables are tiny relative to full debug info). The big saving is on dependencies, where we use `debug = false` because deps are usually irrelevant to triaging q2-specific failures. + +### Change 2: Removed the redundant `cargo build` step in CI + +The old workflow had: + +```yaml +- name: Build + run: cargo build + env: + RUSTFLAGS: "-D warnings" + +- name: Test Rust code + run: cargo nextest run + env: + RUSTFLAGS: "-D warnings" +``` + +Per the [nextest design docs](https://nexte.st/docs/design/how-it-works/): + +> "cargo-nextest first builds all test binaries with `cargo test --no-run`" + +And per the [Cargo book on `cargo build`](https://doc.rust-lang.org/cargo/commands/cargo-build.html#target-selection), `--tests` builds "all targets that have the `test = true` manifest flag set. By default this includes the library and binaries built as unittests, and integration tests. Be aware that this will also build any required dependencies, so the lib target may be built twice (once as a unittest, and once as a dependency for binaries, integration tests, etc.)." + +That last clause is the key one — it confirms test-mode and non-test-mode rlibs are separate artifacts, which is what `cargo nextest run --tests` produces in one shot: + +```yaml +- name: Test Rust code + run: cargo nextest run --tests --cargo-profile ci + env: + RUSTFLAGS: "-D warnings" +``` + +#### Why `--tests`, not `--all-targets` + +`--all-targets` is officially defined as `--lib --bins --tests --benches --examples`. We tried it first, but it caused CI to fail on `quarto-yaml`'s benches: `crates/quarto-yaml/benches/{memory_overhead,scaling_overhead}.rs` are declared `harness = false` and print prose reports rather than libtest output. Nextest enumerates each bench binary with `--list --format terse` and errors on the unrecognized output (`line "..." did not end with the string ": test" or ": benchmark"`). + +The previous CI never built benches anyway — plain `cargo build` excludes them by default — so `--tests` matches the prior coverage exactly while still consolidating compilation into one nextest-driven step. + +#### Why this is safe (verified against Cargo docs) + +1. **Compilation coverage matches what `cargo build` was producing.** `cargo nextest run --tests` builds the lib (both as unittest and as a non-test dep for bins/integration tests), all bins (also as unittests), and all integration tests. That is a strict superset of plain `cargo build`'s default targets (lib + bins, non-test). Examples without `test = true` and benches were not built before either. +2. **`-D warnings` still fires.** `RUSTFLAGS` is a rustc env var, applied to every rustc invocation regardless of which cargo subcommand drives the build. Nextest invokes `cargo test --no-run` internally, which picks up `RUSTFLAGS` exactly as `cargo build` would. +3. **The redundancy that disappears:** `cargo build` and `cargo nextest run` share `target/debug/` (or in our case `target/ci/`) but **not artifacts** — library crates compiled with `--cfg test` have a different fingerprint and produce **separate `.rlib`s** alongside the dev-build ones. With ~35 crates, that duplication ran into multi-GB at peak disk. + +#### Edge case to be aware of + +`--tests` skips any target whose manifest sets `test = false`. The only such target in this repo is `crates/pampa/fuzz` (libfuzzer-sys is Linux/macOS only, so the crate is `exclude`d from the workspace — `cargo build` at workspace level wasn't building it either). If a future bin is added with `test = false` and is expected to be compile-checked in CI, either drop the `test = false`, add a separate `cargo build` step for that bin, or revisit this decision. + +### Change 3: Profile-aware binary discovery in `quarto-lsp` integration test + +`crates/quarto-lsp/tests/integration_test.rs` spawns the `q2` binary as a subprocess. The previous code hardcoded `target/debug/q2`, which broke under `--cargo-profile ci` (binary lands at `target/ci/q2`). + +#### Why this isn't a misuse of profiles + +`[profile.ci]` is a fully-supported Cargo pattern. The test was simply unaware of profiles. Cargo's `CARGO_BIN_EXE_<name>` env var would normally provide the production-bin path, but it's **package-scoped** — set only for integration tests in the same package as the bin. Our LSP test lives in `quarto-lsp` while the bin is defined in `quarto`, so that env var is never set here. + +#### The fix + +Derive the profile directory from the test binary's own location: + +```rust +let binary_path = std::env::current_exe() + .unwrap() + .parent().unwrap() // target/<profile>/deps + .parent().unwrap() // target/<profile> + .join("q2") + .with_extension(std::env::consts::EXE_EXTENSION); +``` + +Cargo always places the test binary in `target/<profile>/deps/`, so backing up two parents lands in the same `target/<profile>/` directory where the production `q2` is built. Profile-correct on Linux/macOS/Windows without env-var coupling or mtime heuristics. + +#### Why not `assert_cmd` + +`assert_cmd::cargo::cargo_bin("q2")` is the idiomatic crate-based answer and does exactly the same thing internally (with friendlier error handling and Windows `.exe` suffix logic). We chose the stdlib version for this fix because: + +- The LSP test does **not** use any of `assert_cmd`'s value — no `.assert()`, no stdout/stderr matchers, no exit-code checks. It speaks JSON-RPC over stdio. +- The only function we'd touch is `cargo_bin()`, replacing 4 lines of stdlib with one dev-dep. + +If a future test wants `cargo run --` style command-driving with output assertions, **switch to `assert_cmd` then** — `cargo_bin()` is its standard binary-discovery helper and pays for itself once `.assert()` joins the picture. + +## All the cleanup levers we used + +| Lever | Disk saving | Status | +|---|---|---| +| A. `[profile.ci]` debuginfo strip | ~30–50% of `target/` | Done. Biggest single lever, preserves panic backtraces. | +| B. Drop redundant `cargo build` | Multi-GB peak reduction | Done via `cargo nextest run --tests`. | +| C. `remove_tool_cache: true` on free-disk-space | ~6 GB | Done. Safe — no step uses `/opt/hostedtoolcache/`. | +| D. `docker image prune` + `docker builder prune` | ~3–8 GB | Done. Pre-pulled docker images aren't used by this job. | +| E. `remove_swap: true` on free-disk-space | ~4 GB | Held in reserve — small OOM risk for heavy linkers (deno_core, large LTO). | +| F. `df -h` diagnostic step | 0 GB | Held in reserve — adds log noise; useful for next failure triage if disk pressure returns. | +| G. Larger runner | 150 GB / 45 GB | Held in reserve — Posit `ubuntu-latest-4x` ($0.012/min) or `ubuntu-24.04-arm` (free for public repos, requires arm64 Rust toolchain). | + +## Cross-references + +- Previous CI cleanup: [PR #55](https://github.com/quarto-dev/q2/pull/55) (Mar 2026) +- Failed run that triggered this work: [run 25062065055](https://github.com/quarto-dev/q2/actions/runs/25062065055/job/73418747660?pr=139) +- Local Windows precedent (same pattern via `~/.cargo/config.toml`): see `memory://main/docs/rust-disk-space-strategy-for-windows-with-worktrees` +- Open follow-up tracking: `memory://main/tasks/optimize-q2-ci-workflow-disk-usage` + +## External sources + +- nextest: [How it works](https://nexte.st/docs/design/how-it-works/) — confirms nextest delegates compilation to `cargo test --no-run`. +- Cargo book: [`cargo test` target selection](https://doc.rust-lang.org/cargo/commands/cargo-test.html#target-selection) — what gets built by default. +- Cargo book: [Profiles](https://doc.rust-lang.org/cargo/reference/profiles.html) — `inherits`, `debug` levels, per-package overrides. +- Kobzol, June 2025: [Reducing Cargo target directory size with `-Zno-embed-metadata`](https://kobzol.github.io/rust/rustc/2025/06/02/reduce-cargo-target-dir-size-with-z-no-embed-metadata.html) — measured ~2× target size from debuginfo on a comparable workspace. +- `endersonmenezes/free-disk-space` action documentation — option semantics for `tool_cache`, `swap_storage`, etc. diff --git a/claude-notes/2026-05-01-bd-f5yi-sidebar-after-fix.png b/claude-notes/2026-05-01-bd-f5yi-sidebar-after-fix.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d4a2831b099b17a1f6aa32d4086ca9f38f7efb GIT binary patch literal 531566 zcmb4qcOaYX_kMZ1XzAufQLAdVX4R}ciW;FtXlw5lv0`+oDvDYatM-l(Gcnq#EmC4M zA!zLcu_CtL(|7jm_p^TfAbC9DzVCC+b*^)r^F-X%*JPk)r9X7&5QDasn$e*{r+}Bo zIF8c-KSo?sW)2-XeMnpFrinkz0^!Kr^O_^?R|t{(yviyn$9d~ea_7ZN3zPekkcNJH z_}V4lEAKr1ex6nZlfV)qm;WVSzi|naUvjtl@zeDqJ7O4gZ*T8X@2;<`|Bj-$n>J<V z^zloN4$=Pj?XEkGL-;>00e1{BPaN!N9-=vXTKUg!Pc+`=S6n(>MSJVwkC%VDp;YYs z$uoc5`NwD8Z`1ai{_ECDUk+<MVyuzt4f=i~-}_^K{pQbq@L&GO<4YGV(cIATl*elP z_K8b(j=Yii$5y`Y?2gSN7Ve+6_~;Sk$Qv%&<A-Yx(S809e2}8>*T<BXk6$(ZVUxcv z{aw=`3AI0$_4@{e-;!AGfoO!3>ZY&C=nK&DDxaWz{Lf>%Yfm%t{GXS8JITAx|2}V1 z=FgB4%+<Qt_C1EBoltHBKh3t<K<R^%-ant-AsW(&tE&HDY3~DRk=CD5Goqb|FpWDP zWug5hSK;I5nJ&>F-_eO2zjXH@P5!?!?2pU&V_|oLX&hbvMnC_V@^S6;WeIw6cB?q; zj7U=D`>2<J9P~bSd7O>_*27z3KK*9qC$}F7@cf%o{>j1a*t~x!F#s7p@hG};9yY^n z@wFA3sWU-;zNt(jl3JFGoJo0GkxWaI4A@5Wxaki^#dO!>?|1)P>5tb>7t$hiyeTJ} z-fM)EWMm#MAtCe6(1^V)QO82eoYcjT1?GV+uo+zL*(tzk$F_cXzy71EzW+vh>(qbq z#pAbVz|`KLK`Hb}wACmS;@xKj1qb_pd1%4P#*uJm_~$idy<}-LqT@MBG1ynzf5VW@ z;_=&Cz>%TQzaQBjLGj(Ij&sxGzx+>*a=MQ8i1!@`Iif=poXjL)1<n0%oM0u19wiAv z^!Rse-c#Z88R`Tjk<dOV=i74CPa>;Otn0hQC1Id<bg_rn-TczFj-n2&{WE~Sui!uW z6s_g^^u}UW7z?ak3k9F8)dEq4Vdn9PEHjtwl~25>HPQjg&=acP#5_%ysWFky`hKUV zYc!w#ci$L;VtRmceSGQMUF47E`OQoIaIl}Q4>8|;{#b0H*HR?5NiZ5IDstB4xzQk` z2&FiqGwf5Yj+jUCuexSj7To8bP~ax)_`1wI&u2yNly_&lv}qF0YDhJI&MPia8B)7S z59~V1FJ1Nzr&NAGch&Mg#LnNbed+4qQI?Xeh?4$nQl-GXsb*puHwYXY#X!g(adTKL zttcz5EHgze7~iY1Y&yP47f2AV b-#UVd<v8}QB)bGHSta}_sM#V`EMcq1PVWkmo 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 z≫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�+Pt4;IcXEun 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�mJ&|qfkk{qc=GXddf$JzN*$iv;e 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­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]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%0D?bL-^t!Cm_-mcc-7v@NZtz6z=UlCWoM%=4 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-1000.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-1000.png new file mode 100644 index 0000000000000000000000000000000000000000..f948cc0406a0308641813411cb23289dba01da06 GIT binary patch literal 104216 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⋘npx40xTav`` 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-1100.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-1100.png new file mode 100644 index 0000000000000000000000000000000000000000..7f154e8e5c0b3f60b12e1f058b2a4846bd0b6e58 GIT binary patch literal 105802 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[W_$Ukc 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-1200.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-1200.png new file mode 100644 index 0000000000000000000000000000000000000000..fd368fd25f1250a878505691c07d3ab3c8b0fdb2 GIT binary patch literal 106562 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%0Ac=O}*b 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-1400.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-1400.png new file mode 100644 index 0000000000000000000000000000000000000000..b1d8075b372e8e83f33c42263aff0729272773b7 GIT binary patch literal 106408 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 YgIrU*HavewVZ>o@|CoL|`x>(T2dL<8Z~y=R literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-1600.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-1600.png new file mode 100644 index 0000000000000000000000000000000000000000..954963b6d2adbc5880fed03fa2a48165a10c1d35 GIT binary patch literal 109349 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-767.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-767.png new file mode 100644 index 0000000000000000000000000000000000000000..95823dd969cd5aa5cbb4da2b3c032cbbf2b79913 GIT binary patch literal 88537 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 EAIGYsQ~&?~ literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-768.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-768.png new file mode 100644 index 0000000000000000000000000000000000000000..18dda3d25bcb1c6290e0a1b4f49b6addf6b033b2 GIT binary patch literal 95171 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�=_&*leM+k6@yDjTr73^NorK-=b(6= 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-800.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-800.png new file mode 100644 index 0000000000000000000000000000000000000000..ff0aaf73eeddd8bea5177430b15a67c81cf1002e GIT binary patch literal 94962 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­&N; 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 F{6F{CKK1|r literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/native-900.png b/claude-notes/2026-05-01-sidebar-breakpoints/native-900.png new file mode 100644 index 0000000000000000000000000000000000000000..4d63a9dc8b6ca50b0e88986b2a5d835c42f5e3e6 GIT binary patch literal 96813 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-1200.png b/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-1200.png new file mode 100644 index 0000000000000000000000000000000000000000..fd368fd25f1250a878505691c07d3ab3c8b0fdb2 GIT binary patch literal 106562 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%0Ac=O}*b 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-800.png b/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-800.png new file mode 100644 index 0000000000000000000000000000000000000000..e25513226d8a79edbdfc9d46760915ff432f3394 GIT binary patch literal 94013 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-900.png b/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-900.png new file mode 100644 index 0000000000000000000000000000000000000000..720acae16fc1e7415564a5ff1762e80a92a326e7 GIT binary patch literal 96041 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 beGgu)aLuFUI!X=r2JeibrotmR)0_Vf9YFb+ literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-992.png b/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-992.png new file mode 100644 index 0000000000000000000000000000000000000000..e233c491cbd4e1d8a6901809691fdaf5c1654d20 GIT binary patch literal 103793 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 literal 0 HcmV?d00001 diff --git a/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-hub-preview-1200.png b/claude-notes/2026-05-01-sidebar-breakpoints/post-fix-hub-preview-1200.png new file mode 100644 index 0000000000000000000000000000000000000000..814972f7aa48fc6446c5eb4306ccad760eb95ea6 GIT binary patch literal 108073 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�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 literal 0 HcmV?d00001 diff --git a/claude-notes/architecture/01-pipeline.md b/claude-notes/architecture/01-pipeline.md new file mode 100644 index 000000000..3b9139a9c --- /dev/null +++ b/claude-notes/architecture/01-pipeline.md @@ -0,0 +1,186 @@ +# Diagram 1 — Render Pipeline + +**SVG:** [`pipeline.svg`](./pipeline.svg) · **Set index & conventions:** [`README.md`](./README.md) + +Companion diagrams: [Crate & package map](./02-crates.md) · +[hub-client Automerge structure](./03-hub-client-automerge.md) · +[q2 vs hub-client (build & WASM)](./04-q2-preview-wasm.md). + +--- + +## How to read this + +This guide is the **middle tier** of a three-tier drill-down: + +> **diagram** (the shape) → **this guide** (what each part is) → **source** (the code). + +A reader skims [`pipeline.svg`](./pipeline.svg) for the overall shape, reaches +for this document when a box needs explaining, and follows the crate/file path +in each entry down to the actual module. Every box in the diagram prints its +own source file in monospace, so the diagram already points the way; the tables +below are the index. + +**Numbered markers** in the SVG (small circles ①②③, at the top-right corner of +the element they annotate) point to the [Notes](#notes) at the bottom of this +guide: + +- **Indigo** marker — a note with extra detail. +- **Amber** marker — *the diagram idealizes here; the current implementation + differs.* Read the note before trusting the box at face value. + +## One-sentence summary + +Quarto 2 renders a project in **two passes** over one shared stage graph +(`crates/quarto-core`): **Pass 1** is front-end work across all files (parse, +validate, extract a per-file profile, resolve inter-file dependencies); +**Pass 2** is per-file AST processing, internally split into format-agnostic +**generate** steps and format-specific **render** steps, ending in an HTML +document. The same stage graph — three stages dropped, one inserted — powers +`q2 preview` in WASM (see [diagram 4](./04-q2-preview-wasm.md)). + +## Box-by-box → source + +### Pass 1 — front-end (marker ① on the band) + +Per file, run in parallel with rayon; the head pipeline lives in +`orchestrator.rs` → `pass1_profile_single_file_live()`. All paths below are +under `crates/quarto-core/src/`. + +| Box | Source | Role | +|---|---|---| +| `parse-document` | `stage/stages/parse_document.rs` (parser: `pampa`) | qmd → Pandoc AST | +| `metadata-merge` | `stage/stages/metadata_merge.rs` | merge project/dir/doc/runtime metadata | +| `include-expansion` | `stage/stages/include_expansion.rs` | splice `{{< include … >}}` bodies in | +| `document-profile` **(checkpoint, marker ②)** | `document_profile.rs` | extract serializable `DocumentProfile` → `PipelineData::AtProfile` | +| `link-resolution` | `stage/stages/link_resolution.rs` | read-only AST walk → `profile.body_link_targets` | + +Output: each file's `DocumentProfile` (title, outline, includes, link targets, +resources) is collected into a shared `ProjectIndex` (`project/index.rs`). + +### Between passes + +`ProjectType::pre_render()` (`project/orchestrator.rs`); then +`ProjectDependencyGraph` (`project/dependency_graph.rs`) selects the render set — +`RenderMode::{Full, Subset, ActivePage}`. `ActivePage` is the single-page mode +used by `q2 preview` and the hub-client live preview. + +### Pass 2 — AST processing (marker ③ on the entry) + +The post-checkpoint spine of the full pipeline +(`pipeline.rs` → `build_html_pipeline_stages_with_options()`). Paths under +`crates/quarto-core/src/`. + +| Box | Source | Notes | +|---|---|---| +| `unwrap-profile` | `stage/stages/unwrap_profile.rs` | logical resume of the AST — **see Note ③** | +| `pre-engine-sugaring` | `stage/stages/pre_engine_sugaring.rs` | seed crossref registry, desugar shorthand | +| `engine-execution` | `stage/stages/engine_execution.rs` | run code cells (Jupyter, Knitr, markdown) | +| `compile-theme-css` | `stage/stages/compile_theme_css.rs` | Bootstrap SCSS → CSS (`quarto-sass`) | +| `asset-injection` *(native only)* | `stage/stages/bootstrap_js.rs`, `clipboard_js.rs` | inject bootstrap.js / clipboard.js as project artifacts | +| `attribution-generate` | `stage/stages/attribution_generate.rs` | populate author-attribution sidecar | +| `user-filters-pre` | `stage/stages/user_filters.rs` | user **Lua / JSON / citeproc** filters, before Quarto transforms | +| `ast-transforms` | `stage/stages/ast_transforms.rs` | the Quarto feature pipeline (below) | +| `user-filters-post` | `stage/stages/user_filters.rs` | user filters, after Quarto transforms | +| `resource-report` | `stage/stages/resource_report.rs` | finalize per-doc resource report | +| `code-highlight` | `stage/stages/code_highlight.rs` | annotate `data-hl-spans` on code | +| `math-js` | `stage/stages/math_js.rs` | populate `meta.math` (MathJax/KaTeX loader) | +| `render-html-body` | `stage/stages/render_html.rs` (writer in `pampa`) | AST → HTML body | +| `apply-template` | `stage/stages/apply_template.rs` (`quarto-doctemplate`) | wrap body in template | + +### `ast-transforms` — the generate/render split + +`build_transform_pipeline()` (`pipeline.rs`) runs five phases; transforms live +in `crates/quarto-core/src/transforms/*.rs`. The first three **generate** +format-agnostic structures; the last two **render** them to HTML: + +1. **Normalization** *(generate)* — callouts, shortcodes, metadata-normalize, title-block, sectionize, footnotes, theorem/proof/float sugar, equation labels. +2. **Cross-references** *(generate)* — `crossref-index` → `crossref-resolve` (assign numbers, build registry). +3. **Navigation** *(generate)* — toc, navbar, sidebar, page-nav, footer, listing → structured data. +4. **Navigation** *(render)* — `*-render` transforms, listing render, categories, RSS feeds → HTML strings. +5. **Finalization** *(render)* — link-rewrite (cross-doc), appendix, crossref-render, code-block-render, resource-collector, table classes, attribution-render. + +The generate/render duality recurs as **paired transforms**: +`TocGenerate`/`TocRender`, `ListingGenerate`/`ListingRender`, +`CrossrefIndex`/`CrossrefRender`, `CodeBlockGenerate`/`CodeBlockRender`. The +single `ast-transforms` stage dispatches a different transform list for HTML vs. +q2-preview, keyed on `ctx.format.pipeline_kind`. + +## Feature → pipeline location + +| Feature | Where | +|---|---| +| Includes | `include-expansion` (Pass 1), `include-resolve` (full pipeline — see Note ①) | +| Cross-references | `pre-engine-sugaring` + Crossref transform phase | +| Lua / JSON / **citeproc** filters | `user-filters-pre` / `user-filters-post` | +| Code execution (Jupyter/Knitr) | `engine-execution` | +| Shortcodes, callouts | Normalization phase of `ast-transforms` | +| Navigation (navbar/sidebar/TOC/footer) | Navigation generate + render phases | +| Listings (+ RSS feeds) | `listing-item-info` (full pipeline — see Note ①) + Navigation phases | +| Syntax highlighting | `code-highlight` | +| Math | `math-js` | +| Theme CSS / Bootstrap JS | `compile-theme-css` / `asset-injection` | + +## Data types flowing through (`PipelineData`) + +Defined in `crates/quarto-core/src/stage/data.rs`: + +`LoadedSource` → `DocumentAst` → **`AtProfile`** (checkpoint) → `DocumentAst` +→ … → `RenderedOutput` → final HTML. (`DocumentSource`, `ExecutedDocument`, and +`FinalOutput` variants also exist; the first is largely vestigial post-parse, +the latter two are reserved for future engine/SSG work.) + +## q2 preview — pipeline variant + +Same stage graph, reused in WASM (`wasm-quarto-hub-client`) for the live +in-browser preview. Built by `build_q2_preview_pipeline_stages()`; the dropped +set is `Q2_PREVIEW_STAGE_EXCLUDED`. See [diagram 4](./04-q2-preview-wasm.md) for +how this runs inside `q2 preview`. + +- Drops the three HTML-emitting stages: `math-js`, `render-html-body`, `apply-template`. +- Inserts `capture-splice` before `engine-execution` (`stage/capture_splice.rs`) — replays server-recorded engine output instead of re-running engines in the browser. +- Returns the Pandoc AST as JSON to the React renderer (`ts-packages/preview-renderer`), not an HTML string. +- Keeps `code-highlight` (AST-level `data-hl-spans`, read by the React `CodeBlock`). + +--- + +## Notes + +These match the numbered markers in [`pipeline.svg`](./pipeline.svg). Notes ① +and ③ are **amber** in the diagram: the figure shows the idealized two-pass +*design*; the current implementation differs as described here. + +### ① Pass-1 head pipeline is a 5-stage subset — *amber* + +`pass1_profile_single_file_live()` (`project/orchestrator.rs`) runs only five +stages: `parse-document → metadata-merge → include-expansion → document-profile +→ link-resolution`. The diagram's Pass-1 band shows exactly these. + +The **full single-document pipeline** +(`build_html_pipeline_stages_with_options`) runs two *additional* pre-checkpoint +stages — `include-resolve` and `listing-item-info` — whose own comments say they +run "pre-checkpoint so values land in `DocumentProfile`." In project mode those +two execute during **Pass 2's** full-pipeline run, not during the +index-building Pass 1. So a profile built in Pass 1 does not reflect them. +→ `crates/quarto-core/src/project/orchestrator.rs`, +`crates/quarto-core/src/pipeline.rs`. + +### ② `document-profile` is the checkpoint — *detail* + +`DocumentProfileStage` (`document_profile.rs`) extracts a typed, serializable +`DocumentProfile` into `PipelineData::AtProfile`, then `unwrap-profile` hands +the AST straight back. Profiles are **read-only**; project-scoped features +(sidebars, cross-document links, incremental rebuilds, eventual `freeze`) +consume the profile without re-running engines or user filters. Full contract: +[`claude-notes/designs/document-profile-contract.md`](../designs/document-profile-contract.md). +→ `crates/quarto-core/src/document_profile.rs`. + +### ③ Pass 2 re-runs rather than resumes — *amber* + +The design intent is that Pass 2 resumes each file from the cloned +`PipelineData::AtProfile` produced in Pass 1. The current **v1** implementation +(`orchestrator.rs`, module docs §"Pass-2 resumption (v1)") instead **re-runs the +head pipeline** per file (re-parse + re-merge), accepted as a scoped-rewiring +trade-off with a follow-up tracked. The diagram draws `unwrap-profile` as the +*logical* resume point. +→ `crates/quarto-core/src/project/orchestrator.rs` (see the module-level +"Two passes" / "Pass-2 resumption (v1)" docs). diff --git a/claude-notes/architecture/02-crates.md b/claude-notes/architecture/02-crates.md new file mode 100644 index 000000000..4a509cd14 --- /dev/null +++ b/claude-notes/architecture/02-crates.md @@ -0,0 +1,189 @@ +# Diagram 2 — Crate & Package Map + +**SVG:** [`crates.svg`](./crates.svg) · **Set index & conventions:** [`README.md`](./README.md) + +Companion diagrams: [Render pipeline](./01-pipeline.md) · +[hub-client Automerge structure](./03-hub-client-automerge.md) · +[q2 vs hub-client (build & WASM)](./04-q2-preview-wasm.md). + +--- + +## How to read this + +Same three-tier drill-down as the rest of the set +(**diagram → guide → source**). The SVG groups the workspace into a handful of +**subsystems** (labeled bands) and shows the principal dependency direction; it +does *not* draw every crate-to-crate edge. This guide lists the full adjacency +so any crate name in the diagram can be traced to its `crates/<name>/` +directory. Numbered markers ①② in the SVG point to the [Notes](#notes). + +The dependency data here is taken from `cargo metadata` (authoritative), not +hand-maintained. + +## At a glance + +- **45 Rust crates** in the main workspace (`crates/*`). +- **3 WASM-only crates outside the workspace** — `wasm-quarto-hub-client`, + `wasm-qmd-parser`, and a `tree-sitter-language` shim — excluded because they + build to `wasm32`/`cdylib` with a separate toolchain (see Note ①). +- **TypeScript** lives in npm workspaces: `ts-packages/*` (9 packages) plus the + apps `hub-client`, `q2-preview-spa`, `trace-viewer`, and `q2-demos/*`. + +## Subsystems (the bands) + +Ordered consumers → foundation. ★ marks the highest-fan-in "hub" crates. + +| Subsystem | Crates | Role | +|---|---|---| +| **Binaries** (native entry points) | `quarto` (the `q2` bin) ★, `hub`, `pampa` (bin), `qmd-syntax-helper`, `validate-yaml`, `perf-harness`, `reconcile-viewer`, `xtask` | user-facing commands & dev tools | +| **CLI features & LSP** | `quarto-preview`, `quarto-publish`, `quarto-test`, `quarto-trace-server`, `quarto-project-create`, `quarto-hub` (lib), `quarto-lsp`, `quarto-lsp-core` | per-command feature crates; language server | +| **Engine & orchestration** | `quarto-core` ★, `pampa` ★ | `pampa` = qmd parser + writers + filters; `quarto-core` = pipeline orchestrator (see [diagram 1](./01-pipeline.md)) | +| **Document features** | `quarto-doctemplate`, `quarto-citeproc`, `quarto-csl`, `quarto-highlight`, `quarto-sass`, `quarto-config`, `quarto-navigation`, `quarto-analysis` | domain libraries the engine composes | +| **AST & types** | `quarto-pandoc-types` ★, `quarto-ast-reconcile`, `comrak-to-pandoc` | the Pandoc AST definition + AST diff/convert | +| **Parsing & syntax** | `tree-sitter-qmd`, `tree-sitter-doctemplate`, `quarto-treesitter-ast`, `quarto-yaml`, `quarto-yaml-validation`, `quarto-parse-errors`, `quarto-xml` | grammars, tokenization, structured parse errors | +| **Foundation** | `quarto-source-map` ★, `quarto-error-reporting`, `quarto-util`, `quarto-trace`, `quarto-system-runtime`, `quarto-highlight-encoding`, `quarto-brand`, `quarto-error-message-macros` | shared infra; roots of the DAG | +| **WASM build** *(outside `[workspace]`)* | `wasm-quarto-hub-client` (cdylib), `wasm-qmd-parser` (cdylib+rlib), `wasm-printf-fmt`, `tree-sitter-language` (shim), `lua-src` (wasm), `wasm-bindgen-futures` (patch) | recompile the engine to `wasm32` for the browser | + +**The hubs.** `quarto-source-map` is the universal foundation — almost every +crate depends on it. `pampa` is the parser hub (largest fan-out: 17 workspace +deps) consumed by `quarto-core`, `quarto-lsp-core`, both WASM crates, +`qmd-syntax-helper`, `perf-harness`, `reconcile-viewer`. `quarto-core` is the +orchestration hub, consumed by `quarto`, `quarto-preview`, `quarto-publish`, +`quarto-test`, `quarto-lsp-core`, `perf-harness`, and `wasm-quarto-hub-client`. +`quarto-system-runtime` is the **native/WASM I/O seam** (filesystem vs. VFS) — +see [diagram 4](./04-q2-preview-wasm.md). + +## Full workspace adjacency (the source map) + +`crate [targets] → intra-workspace dependencies`. Each crate lives at +`crates/<name>/`. + +``` +comrak-to-pandoc [lib] → pampa, quarto-pandoc-types, quarto-source-map +pampa [bin,lib] → comrak-to-pandoc, quarto-ast-reconcile, quarto-citeproc, + quarto-config, quarto-csl, quarto-doctemplate, + quarto-error-message-macros, quarto-error-reporting, + quarto-highlight-encoding, quarto-pandoc-types, + quarto-parse-errors, quarto-source-map, + quarto-system-runtime, quarto-treesitter-ast, + quarto-util, quarto-yaml, tree-sitter-qmd +perf-harness [bin] → pampa, quarto-core, quarto-system-runtime +qmd-syntax-helper [bin,lib] → pampa, quarto-error-reporting +quarto (q2) [bin] → pampa, quarto-core, quarto-doctemplate, quarto-error-reporting, + quarto-hub, quarto-lsp, quarto-preview, quarto-publish, + quarto-sass, quarto-source-map, quarto-system-runtime, + quarto-test, quarto-trace, quarto-trace-server, quarto-util +quarto-analysis [lib] → quarto-error-reporting, quarto-pandoc-types, quarto-source-map +quarto-ast-reconcile [lib] → quarto-pandoc-types, quarto-source-map +quarto-brand [lib] → (none) +quarto-citeproc [bin,lib] → quarto-csl, quarto-error-reporting, quarto-pandoc-types, + quarto-source-map, quarto-xml +quarto-config [lib] → quarto-error-reporting, quarto-pandoc-types, + quarto-source-map, quarto-yaml +quarto-core [lib] → pampa, quarto-analysis, quarto-ast-reconcile, quarto-config, + quarto-doctemplate, quarto-error-reporting, quarto-highlight, + quarto-navigation, quarto-pandoc-types, quarto-sass, + quarto-source-map, quarto-system-runtime, quarto-trace, + quarto-util, quarto-yaml +quarto-csl [lib] → quarto-error-reporting, quarto-source-map, quarto-xml +quarto-doctemplate [lib] → quarto-error-reporting, quarto-parse-errors, quarto-source-map, + quarto-treesitter-ast, tree-sitter-doctemplate +quarto-error-reporting[lib] → quarto-source-map +quarto-highlight [lib] → quarto-highlight-encoding, quarto-pandoc-types, quarto-source-map +quarto-hub [bin,lib] → quarto-util +quarto-lsp [lib] → quarto-lsp-core +quarto-lsp-core [lib] → pampa, quarto-analysis, quarto-core, quarto-error-reporting, + quarto-pandoc-types, quarto-source-map, + quarto-system-runtime, quarto-yaml +quarto-navigation [lib] → quarto-config, quarto-pandoc-types, quarto-source-map +quarto-pandoc-types [lib] → quarto-source-map +quarto-parse-errors [lib] → quarto-error-message-macros, quarto-error-reporting, quarto-source-map +quarto-preview [lib] → pampa, quarto-core, quarto-error-reporting, quarto-hub, + quarto-pandoc-types, quarto-source-map, quarto-system-runtime, + quarto-trace +quarto-project-create [lib] → quarto-system-runtime +quarto-publish [lib] → quarto-config, quarto-core, quarto-error-reporting, + quarto-pandoc-types, quarto-source-map, + quarto-system-runtime, quarto-util +quarto-sass [lib] → quarto-brand, quarto-pandoc-types, quarto-source-map, + quarto-system-runtime +quarto-source-map [lib] → (none) +quarto-system-runtime [lib] → wasm-bindgen-futures +quarto-test [lib] → quarto-core, quarto-error-reporting, quarto-system-runtime +quarto-trace [lib] → (none) +quarto-trace-server [lib] → quarto-trace +quarto-treesitter-ast [lib] → (none) +quarto-util [lib] → (none) +quarto-xml [lib] → quarto-error-reporting, quarto-source-map +quarto-yaml [lib] → quarto-source-map +quarto-yaml-validation[lib] → quarto-error-reporting, quarto-source-map, quarto-yaml +reconcile-viewer [bin] → pampa, quarto-ast-reconcile, quarto-pandoc-types, quarto-source-map +tree-sitter-doctemplate[lib] → (none) +tree-sitter-qmd [bin,lib] → (none) +validate-yaml [bin] → quarto-error-reporting, quarto-source-map, quarto-yaml, + quarto-yaml-validation +xtask [bin] → (none) + +# outside the main workspace (WASM build): +wasm-quarto-hub-client[cdylib] → pampa, quarto-ast-reconcile, quarto-core, quarto-error-reporting, + quarto-highlight, quarto-lsp-core, quarto-pandoc-types, + quarto-project-create, quarto-sass, quarto-source-map, + quarto-system-runtime, quarto-trace, wasm-printf-fmt +wasm-qmd-parser [cdylib,rlib] → pampa +``` + +## TypeScript / web (npm workspaces) + +Packages in `ts-packages/*`; `name → @quarto/* deps`: + +``` +@quarto/pandoc-types → (none) # AST types, mirror of the Rust types +@quarto/mapped-string → (none) # source-mapped strings +@quarto/annotated-qmd → mapped-string, pandoc-types +@quarto/quarto-automerge-schema → (none) # the project-as-CRDT schema (see diagram 3) +@quarto/quarto-sync-client → quarto-automerge-schema +@quarto/preview-renderer → preview-runtime, quarto-automerge-schema +@quarto/preview-runtime → pandoc-types, preview-renderer, quarto-automerge-schema, quarto-sync-client +@quarto/hub-mcp → quarto-automerge-schema, quarto-sync-client +@quarto/sync-test-harness → quarto-automerge-schema, quarto-sync-client +@quarto/wasm-js-bridge → (none) +``` + +Apps (`name → key deps`): + +``` +hub-client → @automerge/automerge-repo(+network-websocket,+react-hooks,+storage-indexeddb), + @quarto/quarto-automerge-schema, @quarto/quarto-sync-client # collaborative editor +q2-preview-spa → @quarto/preview-renderer, @quarto/preview-runtime # embedded in the q2 binary +trace-viewer → (standalone trace visualizer) +``` + +**The Rust↔TS bridge.** The compiled `wasm-quarto-hub-client` `.wasm` is loaded +by `@quarto/preview-runtime` (`wasmRenderer.ts`) and directly by `hub-client`'s +services. That is the seam where the Rust engine enters the browser; both the +collaborative editor and the embedded `q2 preview` SPA render through it. See +[diagram 3](./03-hub-client-automerge.md) (Automerge + WASM preview) and +[diagram 4](./04-q2-preview-wasm.md) (build chain & embedding). + +--- + +## Notes + +### ① Three WASM crates live outside the main workspace — *amber* + +`wasm-quarto-hub-client`, `wasm-qmd-parser`, and the `tree-sitter-language` +shim are **not** members of the root `[workspace]` (confirmed via +`cargo metadata`: 45 members, none of these three). They build to +`wasm32-unknown-unknown` as `cdylib` with a separate toolchain/flags and pull +in patched dependencies (`lua-src` for wasm, a `wasm-bindgen-futures` patch), +which is incompatible with being ordinary workspace members. The diagram shows +them in a distinct "WASM build" band to make the boundary explicit. +→ `crates/wasm-quarto-hub-client/`, `crates/wasm-qmd-parser/`, root `Cargo.toml`. + +### ② `preview-renderer` ⇄ `preview-runtime` is a mutual dependency — *detail* + +`@quarto/preview-renderer` depends on `@quarto/preview-runtime` **and** +vice-versa. They are split by concern (React rendering vs. WASM/sync runtime) +but co-evolve; treat them as one unit when reasoning about the preview layer. +→ `ts-packages/preview-renderer/package.json`, +`ts-packages/preview-runtime/package.json`. diff --git a/claude-notes/architecture/03-hub-client-automerge.md b/claude-notes/architecture/03-hub-client-automerge.md new file mode 100644 index 000000000..56ef1efb5 --- /dev/null +++ b/claude-notes/architecture/03-hub-client-automerge.md @@ -0,0 +1,150 @@ +# Diagram 3 — hub-client Automerge Structure & WASM Preview + +**SVG:** [`automerge.svg`](./automerge.svg) · **Set index & conventions:** [`README.md`](./README.md) + +Companion diagrams: [Render pipeline](./01-pipeline.md) · +[Crate & package map](./02-crates.md) · +[q2 vs hub-client (build & WASM)](./04-q2-preview-wasm.md). + +--- + +## How to read this + +Same three-tier drill-down (**diagram → guide → source**). The diagram has two +halves: **(A)** how a Quarto project is represented as an Automerge document +(the CRDT schema), and **(B)** the WASM rendering infrastructure that turns +those documents into a live preview. Numbered markers ①② point to the +[Notes](#notes). + +`hub-client` is Quarto 2's collaborative writer. State is held in +[Automerge](https://automerge.org/) CRDT documents synced over WebSocket; +rendering happens in-browser via the `wasm-quarto-hub-client` `.wasm` +(see [diagram 2](./02-crates.md)). + +## A. The Automerge document model + +Schema types live in `ts-packages/quarto-automerge-schema/src/index.ts`. + +### `ProjectSetDocument` — the user's project list (root) + +Per-user, synced across browsers; each browser stores only *this document's id* +in IndexedDB. + +``` +ProjectSetDocument { + projects: Record<key, ProjectSetEntry> // key = indexDocId without 'automerge:' prefix + version: number // CURRENT_PROJECT_SET_SCHEMA_VERSION = 1 +} +ProjectSetEntry { + indexDocId: string // 'automerge:'-prefixed id of the project's IndexDocument + syncServer: string // WebSocket URL hosting the project + description: string + addedAt: string // ISO timestamp + lastAccessed: string // ISO timestamp +} +``` + +`projects[key].indexDocId` → an **`IndexDocument`**. + +### `IndexDocument` — one project (root of a project) + +``` +IndexDocument { + files: Record<path, docId> // path -> Automerge docId of the file + version?: number // CURRENT_SCHEMA_VERSION = 2 + identities?: Record<actorId, ActorIdentity> // collaborators (V1+) + captures?: Record<path, CaptureRef> // engine-capture sidecar (V2+) +} +ActorIdentity { name: string; color: string } // cursor color, e.g. "#E91E63" +CaptureRef { captureDocId: string; staleness?: boolean; + state?: 'idle'|'running'|'error'; lastError?: string } +``` + +- `files[path]` → a **file document** (separate Automerge doc, keyed by `docId`). +- `captures[path].captureDocId` → a **capture document** (serialized engine output). +- `migrateIndexDocument()` migrates V0→V1→V2 idempotently (see Note ①). + +### File documents (one Automerge doc per file) + +``` +FileDocumentContent = + | TextDocumentContent { text: string } // Automerge Text (CRDT) + | BinaryDocumentContent { content: Uint8Array; mimeType; hash } // hash = SHA-256, for dedup +``` + +Text files (`.qmd`, `.yml`) are collaborative `Text`; binaries (images, PDFs) +are content-addressed blobs. + +### Capture documents (one per `captureDocId`) + +A separate Automerge doc holding a serialized `EngineCapture` — recorded +post-engine output the preview replays instead of re-running engines in the +browser (`capture-splice` in [diagram 1](./01-pipeline.md); the `q2 preview` +server writes these — see [diagram 4](./04-q2-preview-wasm.md)). + +## B. Live-preview WASM infrastructure + +### Sync layer + +`@quarto/quarto-sync-client` wraps an Automerge `Repo` +(`@automerge/automerge-repo`) configured with: + +| Adapter kind | Browser | Node (auth/tests) | +|---|---|---| +| **Network** | `BrowserWebSocketClientAdapter` | `NodeWebSocketClientAdapter` | +| **Storage** | `IndexedDBStorageAdapter` | `MemoryStorageAdapter` | + +The network adapter connects to a sync server's WebSocket endpoint (`/ws`). The +client exposes callbacks: `onFileAdded`, `onFileChanged(path, text, patches)`, +`onBinaryChanged`, `onFileRemoved`, `onIdentitiesChange`, `onCapturesChange`, +`onConnectionChange`. **Presence** (live cursors/selections) is a *separate* +ephemeral-message channel (`presenceService.ts`), not document changes. + +### Render data flow (the numbered path) + +1. An Automerge doc change fires `onFileChanged(path, text)` in the sync client. +2. The hub-client service mirrors it into the **WASM VFS**: `vfs_add_file(path, text)` (paths use the `/project/` prefix — see Note ②). +3. The preview calls a WASM render entry point, e.g. `render_page_in_project_with_attribution(path, grammars, attribution)`. +4. Inside WASM, the **same `quarto-core` pipeline** runs in q2-preview mode over the VFS (see [diagram 1](./01-pipeline.md) — drops the HTML-emitting stages, splices recorded captures). +5. WASM returns the **Pandoc AST as JSON** (plus diagnostics, theme fingerprint, attribution). +6. The React renderer (`@quarto/preview-renderer`) renders the AST in an iframe; `/.quarto/…` artifact requests are served from the VFS (no network). + +### WASM entry-point surface (`wasm-quarto-hub-client`) + +Authoritative `#[wasm_bindgen]` exports, grouped: + +- **Render:** `render_qmd`, `render_qmd_content`, `render_page_in_project`, `render_page_in_project_with_attribution`, `render_page_for_preview` +- **Parse / convert:** `parse_qmd_content`, `parse_qmd_to_ast`, `parse_qmd_to_ast_with_attribution`, `ast_to_qmd`, `incremental_write_qmd` +- **VFS:** `vfs_add_file`, `vfs_add_binary_file`, `vfs_remove_file`, `vfs_clear`, `vfs_list_files`, `vfs_read_file`, `vfs_read_binary_file`, `vfs_set_runtime_metadata`, `vfs_get_runtime_metadata` +- **LSP:** `lsp_analyze_document`, `lsp_get_diagnostics`, `lsp_get_symbols`, `lsp_get_folding_ranges` +- **Theme / SCSS:** `compile_theme_css_by_name`, `compile_scss`, `compile_scss_with_bootstrap`, `compile_default_bootstrap_css` +- **Project:** `create_project`, `get_project_choices`, `get_builtin_template`, `prepare_template`, `init` + +### hub-client services (`hub-client/src/services/`) + +`authService`, `presenceService`, `projectSetService` / `projectSetReconciler` / +`projectSetStorage`, `projectStorage`, `resourceService`, `templateService`, +`intelligenceService` (LSP), `monacoProviders`, `userSettings`, +`attribution-runs`, `tsxTranspiler`, `debugApi`. + +--- + +## Notes + +### ① The Automerge schema is versioned and migrated in place — *detail* + +`IndexDocument.version` is `2`; `migrateIndexDocument()` runs V0→V1 (initialize +`identities`) then V1→V2 (activate the `captures` sidecar) idempotently, inside +an Automerge `change()`. `ProjectSetDocument.version` is `1`. Old documents +lacking `version`/`identities` are valid and upgraded on first write. +→ `ts-packages/quarto-automerge-schema/src/index.ts`. + +### ② The VFS is an ephemeral, one-way replica of Automerge — *amber* + +The Automerge documents are the source of truth. The WASM **VFS** is an +ephemeral replica rebuilt from Automerge on connect: data flows **Automerge → +VFS** (via `vfs_add_file`), never the reverse. The VFS is cleared on disconnect. +All VFS paths use the `/project/` prefix; build artifacts are served from +`/.quarto/…` within the VFS. Do not treat the VFS as durable state. +→ `crates/wasm-quarto-hub-client/src/lib.rs`, +`hub-client/src/services/` (the sync→VFS mirroring). diff --git a/claude-notes/architecture/04-q2-preview-wasm.md b/claude-notes/architecture/04-q2-preview-wasm.md new file mode 100644 index 000000000..0522ea462 --- /dev/null +++ b/claude-notes/architecture/04-q2-preview-wasm.md @@ -0,0 +1,106 @@ +# Diagram 4 — q2 vs hub-client: Build Chain & WASM-in-Binary + +**SVG:** [`q2-preview-wasm.svg`](./q2-preview-wasm.svg) · **Set index & conventions:** [`README.md`](./README.md) + +Companion diagrams: [Render pipeline](./01-pipeline.md) · +[Crate & package map](./02-crates.md) · +[hub-client Automerge structure](./03-hub-client-automerge.md). + +--- + +## How to read this + +Same three-tier drill-down (**diagram → guide → source**). This diagram covers +the relationship between the native `q2` command and the `hub-client` TypeScript +distribution, the **multi-step build** that produces the `q2` binary, and the +key nesting: `q2 preview` is a native command that runs a **WASM build of the +engine itself**. Numbered markers ①② point to the [Notes](#notes). + +## The core idea + +`q2 preview` starts a local web server that serves an embedded single-page app. +That SPA renders with `wasm-quarto-hub-client` — the **same `quarto-core`/`pampa` +engine compiled to `wasm32`**. So the native `q2` binary **ships a WASM build of +itself** alongside its native engine. That one fact drives the workspace layout +(the engine must stay native + WASM-clean) and the build chain below. + +## The build chain (produces the `q2` binary) + +Three steps, each consuming the previous artifact. (Full rationale: +`claude-notes/instructions/preview-spa-rebuild.md`.) + +| Step | Command | Does | Output artifact | +|---|---|---|---| +| 1 | `cd hub-client && npm run build:wasm` | `cargo build --target wasm32-unknown-unknown --release` on `crates/wasm-quarto-hub-client` (with `-Zbuild-std=std,panic_unwind`), then `wasm-bindgen --target web` | `crates/wasm-quarto-hub-client/pkg/` — `…_bg.wasm` + JS glue | +| — | *(import)* | `pkg/` is imported by `@quarto/preview-runtime` + `@quarto/preview-renderer` | — | +| 2 | `cargo xtask build-q2-preview-spa` | runs `npm run build` (`tsc -b && vite build`) in `q2-preview-spa/` (a Vite/React SPA depending on those two packages) | `q2-preview-spa/dist/` — `index.html` + JS + bundled `.wasm` | +| 3 | `cargo build --bin q2` | `crates/quarto-preview/build.rs` sets `QUARTO_PREVIEW_EMBED_DIR` to `q2-preview-spa/dist`; `crates/quarto-preview/src/lib.rs` embeds it: `static EMBEDDED_SPA = include_dir!("$QUARTO_PREVIEW_EMBED_DIR")` | the `q2` binary, SPA baked in | + +Build-chain source: `hub-client/scripts/build-wasm.js`, +`crates/xtask/src/build_q2_preview_spa.rs`, +`crates/quarto-preview/build.rs`, `crates/quarto-preview/src/lib.rs`. + +## Anatomy of the `q2` binary + +One native executable that contains **two builds of the engine**: + +- **Native engine** — `quarto-core` + `pampa` compiled natively. Used by `q2 render` (and `q2 preview`'s server-side re-execution). +- **Embedded SPA** — `q2-preview-spa/dist/` baked in via `include_dir!`, which bundles `wasm-quarto-hub-client_bg.wasm` = `quarto-core` + `pampa` compiled to `wasm32`. Used by `q2 preview`'s in-browser rendering. + +See Note ① for why this is two builds rather than one, and Note ② for the +stale-WASM trap this creates. + +## `q2 preview` runtime + +`crates/quarto/src/commands/preview.rs` + `crates/quarto-preview/src/lib.rs`: + +1. `q2 preview <path>` resolves the project/initial page, probes a port, opens the browser. +2. Boots an **ephemeral** hub server: `quarto_hub::server::run_server_with(...)` with state in a `tempfile::TempDir` (throwaway per run), bound to loopback, `HubConfig.register_root_ws = false` (the SPA owns `/`). +3. The server routes: + - `/` (+ unknown paths) → `spa_handler` serving `EMBEDDED_SPA` (the baked-in `dist/`). + - `/ws` → the **samod Automerge sync** endpoint (ephemeral, in the TempDir). + - `/api/preview/re-execute`, `/api/preview/deps`, `/api/preview/diagnostics` → preview-specific routes (`extend_with_preview`). +4. In the browser: the SPA loads the `.wasm`, connects to `/ws` (Automerge), mirrors files into the WASM **VFS**, and renders via the WASM pipeline — exactly the flow in [diagram 3](./03-hub-client-automerge.md). +5. Native side: a file watcher re-executes engines and records **capture documents** the WASM render replays (so engines don't run in the browser). + +## Three roles, one server + schema + +| Role | What it is | Server | UI | Rendering | +|---|---|---|---|---| +| `q2 render` | native CLI render | none | none | native engine (diagram 1) | +| `q2 preview` | native CLI live preview | **embedded** ephemeral hub (loopback, TempDir) | embedded SPA | WASM in browser | +| `hub` (bin) | standalone collab server | persistent, all interfaces, optional auth | none (serves clients) | clients render | +| `hub-client` | collaborative web app | needs an external server | full editor SPA | WASM in browser | + +All four share `quarto-hub::server` (HTTP/WS), the Automerge schema +([diagram 3](./03-hub-client-automerge.md)), and the engine +([diagram 2](./02-crates.md)). `q2 preview` is the unusual one: a *native* +binary that bundles a *WASM* renderer and an ephemeral sync server. + +--- + +## Notes + +### ① Why two builds of the same engine — *detail* + +The native engine can't run in a browser sandbox, and the WASM engine can't do +native file I/O or run subprocess engines. So `q2 preview` keeps the heavy/native +work (file watching, engine execution → capture documents) on the native side, +and does *rendering* in WASM so it shares the exact React preview stack with +`hub-client`. The price is shipping the engine twice (native + `wasm32`) and the +discipline that `quarto-core`/`pampa` and everything they touch must compile to +both targets — the I/O seam is `quarto-system-runtime` (see +[diagram 2](./02-crates.md)) and the async-trait rule is `.claude/rules/wasm.md`. + +### ② `cargo build --bin q2` does NOT rebuild the WASM — *amber* + +The three build steps are **not** chained automatically. A plain +`cargo build --bin q2` re-embeds whatever is already in `q2-preview-spa/dist/`; +it does not re-run steps 1–2. After Rust engine changes, `q2 preview` will +silently serve a **stale** WASM image — tests pass, the render path looks +correct, but the preview iframe runs pre-change code. To refresh, run the full +chain (steps 1→2→3). `cargo xtask verify` (without `--skip-hub-build`) runs +steps 1–2; step 3 is still manual. +→ `CLAUDE.md` ("Verifying Rust changes in `q2 preview`"), +`claude-notes/instructions/preview-spa-rebuild.md`. Documented incident: +2026-05-20 stale-WASM preview. diff --git a/claude-notes/architecture/README.md b/claude-notes/architecture/README.md new file mode 100644 index 000000000..ea94bd036 --- /dev/null +++ b/claude-notes/architecture/README.md @@ -0,0 +1,92 @@ +# Quarto 2 — Architecture Diagrams + +High-level architecture of Quarto 2 for team members, advanced users, and +future contributors. Each diagram is a hand-authored SVG plus a markdown +**content spec** that records what the figure shows and where every claim is +grounded in source. + +These figures are intended to be embedded in HTML (a Quarto 2 website or +slides), so each SVG is authored for the browser, not for Illustrator/Inkscape +(see *Conventions* below). + +## The set + +| # | Diagram | SVG | Spec | Status | +|---|---|---|---|---| +| 1 | **Render pipeline** — two-pass processing, generate/render split, feature locations, q2-preview variant | [`pipeline.svg`](./pipeline.svg) | [`01-pipeline.md`](./01-pipeline.md) | ✅ drafted | +| 2 | **Crate & package map** — Rust crates grouped into subsystems + TS packages | [`crates.svg`](./crates.svg) | [`02-crates.md`](./02-crates.md) | ✅ drafted | +| 3 | **hub-client Automerge structure** — project-as-CRDT schema + WASM preview infra | [`automerge.svg`](./automerge.svg) | [`03-hub-client-automerge.md`](./03-hub-client-automerge.md) | ✅ drafted | +| 4 | **q2 vs hub-client** — build chain, embedded SPA, `q2 preview` ephemeral server, WASM-inside-native | [`q2-preview-wasm.svg`](./q2-preview-wasm.svg) | [`04-q2-preview-wasm.md`](./04-q2-preview-wasm.md) | ✅ drafted | + +## Reading model — three tiers + +Each diagram is designed to be read as a drill-down: + +> **diagram** (the shape) → **guide** (what each part is) → **source** (the code). + +A reader skims the SVG, reaches for the companion markdown when a part needs +explaining, and follows the crate/file path there down to the module. To support +this: + +- **Every box prints its own source file** (monospace) in the SVG, so the + diagram itself points toward the code. +- **Numbered markers** (small drawn circles ①②③) sit at the **top-right + corner** of an element that has a matching entry in the guide's *Notes* + section (corner placement keeps them off the labels): + - **indigo** = a note with extra detail; + - **amber** = *the diagram idealizes here; the current implementation differs* + — read the note before trusting the box at face value. +- A **companion-guide pointer** in the SVG header names the markdown file. + +These documents **cross-link** each other and are written to eventually live in +`docs/` as user-facing Quarto 2 pages, so links assume joint consumption. + +## Conventions (apply to every SVG here) + +**Authoring** +- **Hand-authored SVG** is the source of truth (no DSL/toolchain step). +- A single `<style>` block with CSS classes holds colors/typography; per-element + attributes are kept minimal so restyling is one edit. +- **Comments must not contain `--`** (illegal in XML/SVG); use `==` instead. + +**For the browser** +- `viewBox` only — no fixed `width`/`height` — plus + `preserveAspectRatio="xMidYMid meet"`, so the figure scales to its HTML container. +- **System font stack** (`ui-sans-serif, system-ui, …`) and `ui-monospace` for + code refs — no embedded/loaded fonts. +- No external references (no `<image href>`, no web fonts, no external CSS). +- `role="img"` + `<title>`/`<desc>` for accessibility and search indexing. + +**Shared palette** +- Pass 1 / front-end: blue `#e9f2fb` fill, `#4a8fd4` stroke +- Pass 2 / AST: amber `#fdf4e3` fill, `#d6a23c` stroke +- Checkpoint: violet `#efe7fb` / `#7a4fbf` +- **Generate** (format-agnostic): green `#e8f5ee` / `#5aa66f` +- **Render** (format-specific): blue `#eef2fb` / `#6a7bd0` +- native-only stage: gray dashed `#f3f6f9` / `#aeb9c6` +- q2-preview / WASM accents: teal `#3fa3a3` +- stage box: white `#ffffff` / `#cdd5df`; ink `#16202e` + +## Editing / previewing + +```bash +# validate well-formedness (catches the -- in comments, unescaped &, etc.) +xmllint --noout claude-notes/architecture/pipeline.svg + +# preview in the real target (a browser); the SVG renders at viewBox size +open claude-notes/architecture/pipeline.svg # macOS default app +``` + +When embedding in a Quarto doc, reference the SVG as an image +(`![Render pipeline](pipeline.svg)`); it will scale to the column width. + +## Grounding & caveats + +Specs cite exact crate/file paths. Where the **current implementation diverges +from an idealized design** (e.g. the project Pass-2 currently re-runs the head +pipeline rather than resuming from the profile checkpoint), the spec flags it +and the SVG depicts the design with a footnote. See the "Source-vs-design +notes" section in each spec. The earlier `claude-notes/quarto-dependencies.dot` +/ `project-overview.md` artifacts predate the current architecture (they +reference `quarto-markdown`, Pandoc-as-external-tool, the "Kyoto" exploration +phase) and are **superseded** by these diagrams. diff --git a/claude-notes/architecture/automerge.svg b/claude-notes/architecture/automerge.svg new file mode 100644 index 000000000..0002f3ffa --- /dev/null +++ b/claude-notes/architecture/automerge.svg @@ -0,0 +1,169 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 900" + preserveAspectRatio="xMidYMid meet" role="img" + aria-labelledby="title desc" font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"> + <title id="title">hub-client Automerge structure and WASM preview + A Quarto project as an Automerge CRDT: a ProjectSetDocument lists projects, each + pointing to an IndexDocument that maps file paths to per-file Automerge documents and engine-capture + sidecars. The live preview mirrors document changes into a WASM virtual filesystem and renders them + with the in-browser quarto-core pipeline, returning a Pandoc AST that a React renderer paints. + + + + + + + + + + + + Quarto 2 — hub-client: Automerge + WASM Preview + A project as a CRDT document · live in-browser rendering via wasm-quarto-hub-client + + ▸ Companion reading guide + claude-notes/architecture/03-hub-client-automerge.md + numbered marker = note in guide · amber = note worth reading first + + + A · AUTOMERGE DOCUMENT MODEL + + + + ProjectSetDocument — the user’s project list (root) + per user · synced across browsers · each browser stores only this doc’s id + projects: Record<key, ProjectSetEntry> + version: 1 + ProjectSetEntry { + indexDocId, syncServer, description, + addedAt, lastAccessed } + + + projects[key].indexDocId → + + + + IndexDocument — root of one project + files: Record<path, docId> + version: 2 + identities: Record<actorId, {name, color}> + captures: Record<path, CaptureRef> (V2+) + CaptureRef { captureDocId, staleness, state, lastError } + 1 + + + + files[path] → + + captures[path] + .captureDocId → + + + + File documents + one Automerge doc per file (per docId) + Text { text } + ← CRDT Text + Binary { content, + mimeType, hash } + + + + Capture documents + one per captureDocId + serialized EngineCapture + recorded engine output, replayed + by capture-splice → diagram 1 + + + B · LIVE PREVIEW — WASM INFRASTRUCTURE + + + + Sync server  WebSocket /ws  (quarto-hub, or q2 preview ephemeral → diagram 4) + + + + + + @automerge/automerge-repo  Repo + net: Browser / Node WS adapter  ·  storage: IndexedDB / Memory adapter + + + + + @quarto/quarto-sync-client + onFileChanged(path,text) · onIdentities/Captures · presence (ephemeral cursors) + + + + + vfs_add_file(path, text) → WASM VFS  /project/… + 2 + + + + + render_page_in_project_with_attribution(path)  [WASM] + + + + + quarto-core q2-preview pipeline over the VFS  → diagram 1 + + + + + Pandoc AST (JSON) → React renderer (@quarto/preview-renderer) + renders in iframe · /.quarto/… artifacts served from the VFS (no network) + + + + WASM ENTRY-POINT SURFACE  #[wasm_bindgen] exports of wasm-quarto-hub-client + + Render + render_qmd · render_qmd_content + render_page_in_project[_with_attribution] + render_page_for_preview + Parse / convert + parse_qmd_content · parse_qmd_to_ast[_with_attribution] + ast_to_qmd · incremental_write_qmd + + VFS + vfs_add_file · vfs_add_binary_file · vfs_remove_file + vfs_clear · vfs_list_files · vfs_read_file/_binary_file + vfs_set/get_runtime_metadata + LSP + lsp_analyze_document · lsp_get_diagnostics + lsp_get_symbols · lsp_get_folding_ranges + + Theme / SCSS + compile_theme_css_by_name + compile_scss[_with_bootstrap] + compile_default_bootstrap_css + Project / init + create_project · get_project_choices + get_builtin_template · prepare_template · init + + + + KEY FACTS + Source of truth = Automerge. The VFS is an ephemeral, one-way replica (Automerge → VFS via vfs_add_file), cleared on disconnect — see note ②. + Same engine as the CLI. In-browser rendering runs the quarto-core pipeline compiled to wasm32 — identical stages to q2 render (diagram 1), via the WASM crate (diagram 2). + Two sync servers, one schema. The standalone quarto-hub server and the q2 preview ephemeral server both speak this Automerge schema — see diagram 4. + Presence is separate. Live cursors/selections travel as ephemeral messages (presenceService), not document changes. + diff --git a/claude-notes/architecture/crates.svg b/claude-notes/architecture/crates.svg new file mode 100644 index 000000000..ae1e13895 --- /dev/null +++ b/claude-notes/architecture/crates.svg @@ -0,0 +1,188 @@ + + Quarto 2 crate and package map + The Quarto 2 Rust workspace (45 crates) grouped into subsystems from binaries + down to a shared foundation, with the parser hub pampa and orchestrator quarto-core in the middle. + Three WASM-only crates outside the workspace recompile the same engine to wasm32 for the browser, + where the TypeScript npm-workspace packages and apps (hub-client, q2-preview-spa) consume it. + + + + + + + + + Quarto 2 — Crate & Package Map + 45 Rust workspace crates · 3 WASM-only crates outside the workspace · TypeScript in npm workspaces + + + ▸ Companion reading guide + claude-notes/architecture/02-crates.md + numbered marker = note in guide · amber = note worth reading first + + + RUST WORKSPACE  ·  crates/* + + + + + BINARIES — native entry points + quarto (q2) + hub + pampa + qmd-syntax-helper + validate-yaml + perf-harness + reconcile-viewer + xtask + + + + + CLI FEATURES & LSP + quarto-preview + quarto-publish + quarto-test + quarto-trace-server + quarto-project-create + quarto-hub + quarto-lsp + quarto-lsp-core + + + + + ENGINE & ORCHESTRATION + + ★ quarto-core + pipeline orchestrator + + ★ pampa + parser + writers + filters + + + + + + DOCUMENT FEATURES + quarto-doctemplate + quarto-citeproc + quarto-csl + quarto-highlight + quarto-sass + quarto-config + quarto-navigation + quarto-analysis + + + + + AST & TYPES + ★ quarto-pandoc-types + quarto-ast-reconcile + comrak-to-pandoc + + + + + PARSING & SYNTAX + tree-sitter-qmd + tree-sitter-doctemplate + quarto-treesitter-ast + quarto-yaml + quarto-yaml-validation + quarto-parse-errors + quarto-xml + + + + + FOUNDATION + ★ quarto-source-map + quarto-error-reporting + quarto-util + quarto-trace + quarto-system-runtime ◆ + quarto-highlight-encoding + quarto-brand + quarto-error-message-macros + + + + + + + + + depends on ↓ + + + TYPESCRIPT / WEB  ·  npm workspaces  (@quarto/ prefix omitted) + + + + + ts-packages/*  (9) + pandoc-types + mapped-string + annotated-qmd → mapped-string, pandoc-types + automerge-schema → diagram 3 + sync-client → automerge-schema + preview-renderer ⇆ preview-runtime + preview-runtime → pandoc-types, sync-client · loads .wasm + hub-mcp → automerge-schema, sync-client + sync-test-harness → schema, sync-client + wasm-js-bridge + ◆ mutual dep (renderer ⇆ runtime) — see note ② + 2 + + + + + apps + hub-client — collaborative editor + → automerge-repo, sync-client, automerge-schema + q2-preview-spa — embedded in the q2 binary + → preview-renderer, preview-runtime + trace-viewer — standalone + + + + RUST → BROWSER BRIDGE + The Rust engine enters the browser as the compiled + wasm-quarto-hub-client .wasm, loaded by + preview-runtime and hub-client. + Both the collaborative editor and the embedded + q2 preview SPA render through it. + → diagram 3 (Automerge + WASM) · diagram 4 (build & embedding) + + + + + WASM BUILD — outside the main [workspace] (separate wasm32 toolchain) + wasm-quarto-hub-client (cdylib) · wasm-qmd-parser (cdylib+rlib) · wasm-printf-fmt · tree-sitter-language (shim) · lua-src (wasm) · wasm-bindgen-futures (patch) + Recompiles the same engine crates (pampa, quarto-core, quarto-lsp-core, …) to wasm32 as a cdylib the browser loads. + This is why the engine must stay native+WASM-clean — the I/O seam is quarto-system-runtime ◆ (filesystem vs. VFS). See .claude/rules/wasm.md. + Reuses the Engine + Foundation crates above; produces the .wasm consumed by the TypeScript layer on the right. → diagram 4. + 1 + + + + compiled .wasm ↑ + + + ★ = highest fan-in (hub) crate  ·  ◆ = native/WASM I/O seam (quarto-system-runtime)  ·  arrows = “depends on”  ·  subsystem-level edges only (not every crate edge) + diff --git a/claude-notes/architecture/pipeline.svg b/claude-notes/architecture/pipeline.svg new file mode 100644 index 000000000..3d7d5325b --- /dev/null +++ b/claude-notes/architecture/pipeline.svg @@ -0,0 +1,317 @@ + + Quarto 2 render pipeline + Two-pass document processing in crates/quarto-core. Pass 1 performs front-end + parsing, validation, and inter-file dependency extraction across all project files. Pass 2 + performs per-file AST processing, split into format-agnostic "generate" steps and + format-specific "render" steps, ending in an HTML document. A variant pipeline powers q2 preview. + + + + + + + + + + Quarto 2 — Render Pipeline + Two-pass document processing · crates/quarto-core · one shared stage graph for native render & WASM preview + + + ▸ Companion reading guide + claude-notes/architecture/01-pipeline.md + numbered marker = note in guide · amber = diagram idealizes; current impl differs + + + + Project files  *.qmd  _quarto.yml + + + + + PASS 1 — FRONT-END + per file, run in parallel (rayon) · parse · validate · extract profile · resolve inter-file dependencies + 1 + + + + + + parse-document + stages/parse_document.rs · pampa + + + metadata-merge + stages/metadata_merge.rs + + + include-expansion + stages/include_expansion.rs + + + ⬡ document-profile + 2 + CHECKPOINT · document_profile.rs + + + link-resolution + stages/link_resolution.rs + + + + + + + + each file’s DocumentProfile (title, outline, includes, link targets, resources) is collected into a shared ProjectIndex + + + + + + BETWEEN PASSES + ProjectType::pre_render() · ProjectDependencyGraph selects the render set — Full / Subset / ActivePage (the q2-preview & hub-client live-preview mode) + + + + + + PASS 2 — AST PROCESSING + per file · generate format-agnostic structures, then render to format-specific output + + + + LEGEND + + + Pass 1 (front-end) + + Pass 2 (AST) + + checkpoint + + + GENERATE = format-agnostic + + RENDER = format-specific HTML + + + native-only stage (skipped on WASM) + + + + + + from checkpoint ▸ AtProfile + + + + + unwrap-profile + 3 + stages/unwrap_profile.rs · resume AST + + + pre-engine-sugaring + stages/pre_engine_sugaring.rs + + + engine-execution + stages/engine_execution.rs + + + compile-theme-css + stages/compile_theme_css.rs + + + asset-injection NATIVE + bootstrap_js.rs · clipboard_js.rs + + + attribution-generate + stages/attribution_generate.rs + + + user-filters-pre + stages/user_filters.rs + + + ast-transforms + stages/ast_transforms.rs — expand ▸ + + + user-filters-post + stages/user_filters.rs + + + resource-report + stages/resource_report.rs + + + code-highlight + stages/code_highlight.rs + + + math-js + stages/math_js.rs + + + render-html-body + stages/render_html.rs · pampa + + + apply-template + stages/apply_template.rs + + + + + + + + + + + + + + + + + + + DocumentAst + RenderedOutput + + + + Output — HTML document + + + + + + + + Cross-references: seed registry · sugar shorthand + + + + Code execution: Jupyter · Knitr · markdown engines + + + + Theme: Bootstrap SCSS → CSS (quarto-sass) + + + + Project assets: bootstrap.js · clipboard.js (code-copy) + + + + Author attribution sidecar + + + + USER EXTENSIBILITY + Lua · JSON · citeproc filters (pre) + + + + expand transform pipeline ▸ + + + + User filters (post) — Lua · JSON · citeproc + + + + Syntax highlighting → data-hl-spans on code + + + + Math: MathJax / KaTeX loader (meta.math) + + + + AST → HTML body (pampa writer) + + + + Template engine (quarto-doctemplate) + + + + + ast-transforms — transform pipeline + build_transform_pipeline() · transforms/*.rs + + + + + 1 · Normalization GENERATE + callouts · shortcodes · metadata-normalize + title-block · sectionize · footnotes + theorem / proof / float sugar · equation labels + + + 2 · Cross-references GENERATE + crossref-index → crossref-resolve (number, register) + + + 3 · Navigation GENERATE + toc · navbar · sidebar · page-nav · footer · listing + → build format-agnostic structured data + + + 4 · Navigation RENDER + *-render transforms · listing render · categories + RSS feeds → HTML strings for template injection + + + 5 · Finalization RENDER + link-rewrite (cross-doc) · appendix · crossref-render + code-block-render · resource-collector + table classes · attribution-render + + + The Generate / Render split recurs as paired transforms across the + pipeline: e.g. TocGenerate / TocRender, ListingGenerate / ListingRender, + CrossrefIndex / CrossrefRender, CodeBlockGenerate / CodeBlockRender. + + Phase dispatch: the same stage runs a different transform + list for HTML render vs. q2-preview, keyed on + ctx.format.pipeline_kind. + + + + q2 preview — PIPELINE VARIANT + same stage graph, reused in WASM (wasm-quarto-hub-client) for the live in-browser preview + + • Drops the three HTML-emitting stages: math-js · render-html-body · apply-template + • Inserts capture-splice before engine-execution — replays server-recorded engine output instead of re-running engines + • Returns the Pandoc AST as JSON to the React renderer (ts-packages/preview-renderer), not an HTML string + • Keeps code-highlight (AST-level data-hl-spans read by the React CodeBlock component) + + diff --git a/claude-notes/architecture/q2-preview-wasm.svg b/claude-notes/architecture/q2-preview-wasm.svg new file mode 100644 index 000000000..ed4513edd --- /dev/null +++ b/claude-notes/architecture/q2-preview-wasm.svg @@ -0,0 +1,146 @@ + + q2 binary build chain and the WASM-in-binary nesting + A three-step build compiles the engine to wasm32, bundles it into the q2-preview SPA, + and embeds that SPA into the native q2 binary via include_dir. The result ships two builds of the same + engine: native for q2 render, and wasm32 for q2 preview, which boots an ephemeral hub server and renders + in the browser. Four roles (q2 render, q2 preview, hub, hub-client) share one server and one schema. + + + + + + + + + Quarto 2 — q2 Binary, Build Chain & WASM-in-Binary + How the native q2 command ships — and runs — a WASM build of itself for q2 preview + + ▸ Companion reading guide + claude-notes/architecture/04-q2-preview-wasm.md + numbered marker = note in guide · amber = note worth reading first + + + BUILD CHAIN  (produces the q2 binary) + + + + crates/wasm-quarto-hub-client + Rust engine (quarto-core + pampa + …) — the WASM target + + Step 1 · npm run build:wasm + cargo wasm32 (-Zbuild-std) + wasm-bindgen --target web + + + + wasm-quarto-hub-client/pkg/ + …_bg.wasm + JS glue + + imported by @quarto/preview-runtime + preview-renderer + + + + q2-preview-spa (Vite + React SPA) + depends on preview-renderer + preview-runtime + + Step 2 · cargo xtask build-q2-preview-spa + npm run build  (tsc -b && vite build) + + + + q2-preview-spa/dist/ + index.html + JS + bundled .wasm + + Step 3 · cargo build --bin q2 + build.rs → QUARTO_PREVIEW_EMBED_DIR · include_dir! + + + + q2 — native binary + the SPA (with its .wasm) is baked in via include_dir! + 2 + + + + inside ▸ + + + + THE q2 BINARY — one native executable, two engine builds + 1 + + + + Native engine — quarto-core + pampa (native) + q2 render  (and q2 preview server-side re-execution) + + + + Embedded SPA — include_dir!(q2-preview-spa/dist/) + + wasm-quarto-hub-client.wasm = quarto-core + pampa (wasm32) + q2 preview in-browser rendering + + q2 ships TWO builds of the same engine: native (render) + wasm32 (preview). + + + + q2 preview — RUNTIME + Boots an ephemeral hub serverquarto_hub::server::run_server_with + tempfile::TempDir (throwaway per run) · loopback only · register_root_ws = false + Routes + / → embedded SPA (the baked-in dist/) + /ws → ephemeral Automerge sync (samod) + /api/preview/{re-execute, deps, diagnostics} + Browser: SPA loads .wasm → connects /ws → VFS → WASM render  → diagram 3 + Native: file watcher → re-execute engines → capture docs (replayed in WASM) + crates/quarto/src/commands/preview.rs · crates/quarto-preview/src/lib.rs + + + FOUR ROLES — one server, one schema, one engine + + + q2 render + native CLI render + no server + native engine + → diagram 1 + + + q2 preview + native CLI live preview + embedded ephemeral hub + embedded SPA · WASM render + ◆ this diagram + + + hub (bin) + standalone collab server + all interfaces · optional auth + no UI (serves clients) + clients render + + + hub-client + collaborative web app + needs an external server + full editor · WASM render + → diagram 3 + + All four share quarto-hub::server (HTTP/WS) + the Automerge schema (diagram 3) + the engine (diagram 2). q2 preview is the unusual one: a native binary bundling a WASM renderer + an ephemeral sync server. + diff --git a/claude-notes/designs/attribution-encoding-contract.md b/claude-notes/designs/attribution-encoding-contract.md new file mode 100644 index 000000000..5ad71867e --- /dev/null +++ b/claude-notes/designs/attribution-encoding-contract.md @@ -0,0 +1,129 @@ +# Attribution encoding contract + +**Status:** Active (Phase 5 of the attribution pipeline, see +`claude-notes/plans/2026-05-06-attribution-pipeline.md`). +**Conversion site:** `buildAttributionPayload` in +`hub-client/src/hooks/useAttribution.ts`. +**Key types:** `AttributionRun` (TS) in +`hub-client/src/services/attribution-runs.ts`, `AttributionRun` (Rust) +in `crates/quarto-core/src/attribution/types.rs`. + +## Summary + +Attribution intentionally uses **two coordinate spaces** for run +boundaries, joined at exactly one site. The JS side speaks UTF-16 +code units because that is what Automerge text patches, JS string +indexing, and Monaco editor offsets all natively produce. The Rust +side speaks UTF-8 byte offsets because that is what `&str` indexing +and `SourceInfo` ranges use. The conversion happens at the WASM +wire, immediately before the JSON payload is shipped to the Rust +pipeline. + +This is not a bug to be "harmonized." Both sides are correct for +their own domain; collapsing to a single encoding would force one +side to fight its primitives on every offset. + +## The two spaces + +| Side | Space | Why | +|---|---|---| +| Automerge (Rust crate, compiled with `utf16-indexing`) | UTF-16 code units | Crate default; verified at `crates/quarto-hub/src/automerge_api_tests.rs::test_text_encoding_is_utf16` | +| Automerge (JS via `@automerge/automerge`) | UTF-16 code units | Native to JS strings; `patch.value.length` and `patch.length` on `diff()` output are UTF-16 | +| Monaco editor (presence cursors) | UTF-16 code units | Native to `model.getOffsetAt` / `model.getPositionAt`; passes through `A.getCursorPosition` unchanged | +| Run-list replay (`attribution-runs.ts`) | UTF-16 code units | Direct passthrough of Automerge patches | +| Rust attribution (`AttributionRun`, `query_byte_range`, `GitBlameProvider`) | UTF-8 byte offsets | Aligns with `&str` indexing and the rest of `SourceInfo` | + +## Single conversion site + +`buildAttributionPayload(state, sourceText, identities)` in +`hub-client/src/hooks/useAttribution.ts` calls +`buildCharToByteMap(text)` (iterates `text.charCodeAt(i)` with +explicit surrogate-pair handling, returning a `Uint32Array` of byte +offsets keyed by UTF-16 index), then `runsCharToByteOffsets(runs, map)` +to translate each run's `start`/`end` from char offsets to byte +offsets before `JSON.stringify`. + +All Automerge-driven JS code upstream of `buildAttributionPayload` +stays in UTF-16. All Rust code downstream of the JSON wire stays in +UTF-8 bytes. The wire format itself carries bytes. + +## Surrogate-pair handling + +`buildCharToByteMap` walks UTF-16 code units, not code points. A +surrogate pair (e.g. an emoji or non-BMP CJK character) occupies two +consecutive UTF-16 indices, both of which receive a map entry: the +high-surrogate index maps to the byte offset *before* the 4-byte +UTF-8 sequence, the low-surrogate index to the offset *after*. +Automerge does not emit splice positions that land mid-surrogate, so +a run boundary on the low-surrogate index should not occur in +practice; if it does, the map keeps the translation well-defined. + +Test coverage: `hub-client/src/services/attribution-runs.test.ts` +exercises ASCII (identity), 2-byte (Latin-1 supplement), 3-byte +(CJK), and 4-byte (surrogate-pair) cases. + +## Failure modes if "harmonized" + +The encoding split is not a stylistic preference on either side. +Each side's encoding is forced by the substrate immediately beneath +it; collapsing to a single encoding doesn't simplify the design, it +relocates the translation cost to a worse place. + +**The encodings are inherited, not chosen.** On the Rust side, every +caller of `query_byte_range` already has `start` and `end` in byte +form because the layers below produce byte offsets natively: +tree-sitter returns node positions as bytes (`Range.start_byte` / +`end_byte`), `SourceInfo` carries those bytes through every AST +transform, `&str` indexing requires bytes, and `GitBlameProvider` +consumes line-based blame output which is byte-positional. On the +JS side, `string[i]`, `charCodeAt(i)`, `string.length`, Automerge +text splice positions, Monaco's `getOffsetAt`, and the DOM Selection +API all return UTF-16 code units natively. Attribution is the +*consumer* of coordinate systems chosen many layers below it on +both sides — there is no UTF-16 plane to ask tree-sitter for, and +no UTF-8 plane to ask Monaco for. + +**Force UTF-8 on the JS side.** Every Automerge patch position, +every Monaco cursor, and every `string[i]` would need byte +translation per use. Cost moves from one conversion per payload +(debounced at ~500 ms) to one conversion per editor interaction — +many orders of magnitude more work, in the editor hot path rather +than the producer's cold debounced path. + +**Force UTF-16 on the Rust side, option (a) — translate at every +query.** Every `query_byte_range` call becomes a +`byte_range → utf16_range → query` chain. For a document with +thousands of AST nodes, every render triggers thousands of +conversions. Translation cost moves from O(payloads) to +O(AST nodes × renders), into the rendering hot path. + +**Force UTF-16 on the Rust side, option (b) — translate the +substrate.** Rewrite tree-sitter integration, `SourceInfo`, every +AST transform, citeproc, link rewriting, diagnostics, and +serialization to track UTF-16 code units rather than bytes. Massive +ripple for no win — `&str` still indexes by bytes, so a byte ↔ +code-unit map would have to travel alongside every range anyway. + +The current design picks the WASM wire as the conversion point +because it is the smallest, coldest, most auditable surface: one +function, debounced, off the rendering hot path. + +## Soft floor on async desync + +`runsCharToByteOffsets` uses `charToByte[r.start] ?? r.start` rather +than asserting in-bounds. This is deliberate: between the moment a +run list is computed (via `buildRunListAttribution` / +`updateRunListAttribution`) and the moment `buildAttributionPayload` +reads `sourceTextRef.current`, the document can receive a remote +Automerge change. A deletion-shaped race produces runs whose `end` +exceeds the new `sourceText.length`. The `??` falls back to the raw +UTF-16 offset for that one frame; the next debounced update heals +it. Converting to a hard assertion would null the payload on benign +races for no correctness gain. + +## Related + +- `claude-notes/plans/2026-05-06-attribution-pipeline.md` — original Phase 5 plan +- `crates/quarto-hub/src/automerge_api_tests.rs` — UTF-16 feature check + emoji splice tests +- `crates/quarto-core/src/attribution/types.rs::AttributionRun` — Rust-side byte-offset types +- `crates/quarto-lsp-core/src/types.rs::Position` — a separate UTF-16 surface (LSP spec); not connected to attribution diff --git a/claude-notes/designs/body-link-resolution-contract.md b/claude-notes/designs/body-link-resolution-contract.md new file mode 100644 index 000000000..9feca6037 --- /dev/null +++ b/claude-notes/designs/body-link-resolution-contract.md @@ -0,0 +1,162 @@ +# Body-link resolution contract + +**Status:** Initial draft, 2026-04-27 (Phase 8 sub-phase 8.0). +**Code:** + +- `crates/quarto-core/src/transforms/navigation_href.rs` — + `resolve_doc_relative_target` (Pass-1 / static query) and + `resolve_doc_relative_href` (Pass-2 / rewrite). +- `crates/quarto-core/src/stage/stages/link_resolution.rs` — Pass-1 + stage that walks the AST and writes results to + `DocumentProfile.body_link_targets`. +- `crates/quarto-core/src/transforms/link_rewrite.rs` — Pass-2 + transform that rewrites `Inline::Link.target.0` in place. + +## What this contract is for + +Body-link resolution decides which **other project documents** a +given page links to from its body content. The Phase-8 dependency +graph reads this set — every entry becomes a graph edge from the +source page to the target — so it must be: + +1. **Statically derivable.** Computable from the parsed AST + the + project's file inventory, with no engine execution / Lua filter / + user-controllable computation in the loop. +2. **Deterministic.** Same input → same set of targets, every run. +3. **Equivalent across Pass-1 and Pass-2.** The set of targets the + Pass-1 stage records is the same set Phase 6's Pass-2 transform + would rewrite. A unit test asserts equivalence. + +This contract describes the algorithm so users (and future +implementations) have a stable target. + +## Inputs + +- `raw`: the link's `target.0` URL string as it appears in the AST + immediately after `IncludeExpansionStage` runs (so transitive + include content participates). +- `source_relative`: the page's project-relative source path, + forward-slash separated (e.g. `chapters/intro.qmd`, + `posts/2025/welcome.qmd`). + +**Note (Phase 8.2):** the Pass-1 helper does *not* take a +`ProjectIndex` argument. Pass-1 runs *during* index construction +— at the per-page profile checkpoint, before the index exists — +so an index parameter would be `None` at the point of need. The +helper instead returns the resolved project-relative path for +any internal `.qmd` reference; the dependency-graph builder +applies the index-existence filter when emitting edges. Phase 6's +Pass-2 helper (`resolve_doc_relative_href`) does take an index +because it runs after the index is fully built. + +## Output + +A project-relative `PathBuf` (forward-slash, e.g. `other.qmd`, +`docs/api.qmd`) for any internal `.qmd` reference; otherwise +`None` (external URLs, fragment-only anchors, non-`.qmd` paths). +The result reflects path normalization only — it is *not* a +guarantee that the target exists in the project. + +## Algorithm + +1. **External URLs and fragment-only anchors return `None`.** + Anything matching `is_external` (any scheme, `//host/...`, + `mailto:`, `tel:`, `ftp:`) or starting with `#` is not a project + reference. No further work. + +2. **Strip `?query` and `#fragment` tails.** The lookup is on the + path portion only. Tails are not retained at this layer (Pass-2 + re-appends them when rewriting; Pass-1 doesn't need them). + +3. **Non-`.qmd` paths return `None`.** Static resources (images, + CSS, downloadable files) are not project documents. Phase 6 + passes them through verbatim with no diagnostic; Phase 8's graph + ignores them. + +4. **Resolve to project root.** Apply the source-relative path + resolution rule: + + - A leading `/` in `raw`'s path part means project-root-absolute. + Strip the slash; the result is the project-relative path + (no `source_relative` involvement). + + - Otherwise, the path is relative to the source document's + *directory*: `dirname(source_relative)`. Walk the components, + collapsing `.` (drop) and `..` (pop the most recent kept + component). Extra `..` above the project root are clamped (no + error). + +5. **Return the resolved path.** Wrap as a `PathBuf` and return + `Some(p)`. The caller (the Phase-8 dependency-graph builder) + is responsible for any index-existence filter. Pass-2's + helper does its own index lookup for diagnostics + rewriting. + +## Examples + +| Source page | Raw href | Resolved target | +|---|---|---| +| `index.qmd` | `about.qmd` | `about.qmd` | +| `index.qmd` | `docs/api.qmd` | `docs/api.qmd` | +| `docs/api.qmd` | `../about.qmd` | `about.qmd` | +| `docs/api.qmd` | `/other.qmd` | `other.qmd` | +| `docs/api.qmd` | `tutorial.qmd` | `docs/tutorial.qmd` | +| `posts/p.qmd` | `../about.qmd?ref=foo` | `about.qmd` | +| `posts/p.qmd` | `../about.qmd#section` | `about.qmd` | +| any | `https://example.com` | None (external) | +| any | `#section` | None (fragment-only) | +| any | `image.png` | None (non-`.qmd`) | +| any | `missing.qmd` | None (no index hit) | + +## Equivalence with Pass-2 rewrite + +The two helpers agree on path resolution but differ on index +gating: + +- For internal `.qmd` references that path-resolve *and* exist in + the index: Pass-1 returns `Some(p)`; Pass-2 rewrites the href to + the target's `output_href`. Both produce the same `p`. + +- For internal `.qmd` references that path-resolve but *don't* + exist in the index: Pass-1 returns `Some(p)` (the resolved + path); Pass-2 leaves the href unchanged and emits a diagnostic. + The Phase-8 dependency-graph builder filters such targets out + before emitting edges, so the dep-graph view of body-link + edges still matches what Pass-2 actually rewrites. + +- For external URLs / fragment-only anchors / non-`.qmd` paths: + both return `None` / unchanged respectively. + +A unit test in `navigation_href.rs` +(`pass1_pass2_agree_on_resolved_path_when_both_hit`) asserts this +equivalence on shared fixtures. + +## What this contract does NOT cover + +- **Image hrefs** (`Image::target.0`). Phase 6 leaves them alone; + Phase 8 doesn't add edges for them. Images point at static + resources, not project documents. +- **Reference-style markdown links** (`[text][1]`). qmd doesn't + support them at all. +- **Cross-format reference resolution** (HTML→PDF). Out of website- + epic scope; the index keys on `(source_path, format_id)` and + cross-format edges are tracked separately if/when needed. +- **Draft-mode visibility filtering.** Phase 6's `bd-p4sc` (draft + mode) layers on top — body-link resolution returns the target + regardless of draft flag; the rewrite step decides what to do + about drafts. + +## When to bump this contract + +Any change to the algorithm above that would alter the set of +targets returned for an existing `(raw, source_relative, index)` +input requires: + +1. Updating this document. +2. Bumping `DOCUMENT_PROFILE_VERSION` (because + `body_link_targets` would shift on cached profiles). +3. Bumping `PROFILE_KEY_VERSION` (because the set of targets is a + profile-derived field and cache hits would otherwise serve + stale data). + +Pure refactors (private helper renaming, additional non-`.qmd` skip +shortcuts that don't change the result set) do not require a bump. diff --git a/claude-notes/designs/document-profile-contract.md b/claude-notes/designs/document-profile-contract.md new file mode 100644 index 000000000..091e3f69a --- /dev/null +++ b/claude-notes/designs/document-profile-contract.md @@ -0,0 +1,411 @@ +# `DocumentProfile` contract + +**Status:** Active (Phase 0 of the website epic, `bd-0tr6` / `bd-f3jc`; +extended in Phase 8 sub-phase 8.0, `bd-fegm` + `bd-r82e`). +**Version tag:** `DOCUMENT_PROFILE_VERSION = 2` +**Type:** `quarto_core::document_profile::DocumentProfile` +**Stage:** `quarto_core::stage::stages::DocumentProfileStage` (name +`"document-profile"`) + `UnwrapProfileStage` (`"unwrap-profile"`), +inserted between `MetadataMergeStage` and `PreEngineSugaringStage`. +**Plans:** `claude-notes/plans/2026-04-23-website-project-epic.md` +(parent), `claude-notes/plans/2026-04-23-websites-phase-0.md` (Phase 0). + +## Summary + +A `DocumentProfile` is a typed, serde-serializable, **static** snapshot +of a single document. It is produced at a fixed pipeline checkpoint — +after the full metadata merge, and before any AST mutation (sugar, +engine execution, user filters, transforms). Everything a +project-scoped feature needs to know about a document *without* +running engines or filters lives here. + +Phase 0 introduces the type, the checkpoint, and the resumability +contract. Phase 1 uses it to build the project-wide `ProjectIndex`. +Phases 2–9 build on that index for sidebars, navbars, cross-document +links, incremental rebuilds, and hub-client project nav. Eventually +the same checkpoint substrate will back `freeze`. + +## Pipeline position + +``` +Parse → Merge → [Profile checkpoint] → Sugar → Engine → ThemeCSS → +UserFilters(pre) → AstTransforms → UserFilters(post) → Highlight → +RenderBody → ApplyTemplate +``` + +The checkpoint is **deliberately pre-sugar**: outlines reflect the +author's heading hierarchy, not synthetic sections added by theorem / +float-target / callout sugaring. This keeps the contract stable +regardless of which sugar transforms are active. + +## Guarantees + +Per field, what a consumer can rely on. All guarantees presume the +document successfully reached the checkpoint; an earlier stage +failure aborts the pipeline with diagnostics and no profile is +produced. + +| Field | Guarantee | +|---|---| +| `profile_version` | Always equals [`DOCUMENT_PROFILE_VERSION`](../../crates/quarto-core/src/document_profile.rs). A deserialized profile with a different version value is rejected with `DocumentProfileError::VersionMismatch`. | +| `source_path` | Project-relative, forward-slash separated. For a single-file project, this is just the file name — see §"Project root invariant" in the Phase-0 plan. Never absolute. | +| `output_href` | Project-output-relative, forward-slash separated. Usable directly as an HTML `href`. | +| `format_id` | Mirrors `ctx.format.target_format` at the checkpoint (e.g. `"html"`, `"acm-html"`). | +| `title` | Plain-text title from merged metadata. `None` only when the frontmatter genuinely has no title and no fallback was applied by a pre-checkpoint stage. | +| `subtitle`, `description`, `date`, `image` | Plain-text extraction of the corresponding merged-metadata key, or `None`. | +| `authors` | Flat list of plain-text names, extracted from either the `author` or `authors` key. Supports scalar, array-of-strings, array-of-maps with a `name` key, and a single map with a `name` key. Structured author metadata (affiliation, email, ORCID, …) is deliberately dropped — a dedicated author-model design is a separate epic. | +| `categories`, `keywords` | Arrays of plain-text strings. A single scalar value is lifted into a one-element list. | +| `draft` | Boolean. Defaults to `false` when the key is missing or non-boolean. | +| `order` | `Option` sort key from `order:` frontmatter. `None` when the key is absent or non-integer. Consumed by Phase-2's auto-sidebar sort (`claude-notes/plans/2026-04-24-websites-phase-2.md`). Added v1-additive (no version bump). | +| `outline` | `Vec` built from the raw block sequence at `OUTLINE_MAX_DEPTH = 6`. **Always un-numbered**: `TocEntry::number == None` for every entry and every descendant. | +| `includes` | `Vec` recording every file whose contents were spliced into the parent AST via `{{< include child.qmd >}}`. Populated by `IncludeExpansionStage` via a side-channel on `DocumentAst.recorded_includes`, drained into the profile by `DocumentProfileStage`. Direct + transitive children appear; cycles are pre-truncated. **Phase-8 cache invalidation depends on this field** (`bd-r82e`). Default empty. | +| `nav_dependencies` | `Vec` of project-relative `.qmd` paths the user explicitly declares as cross-doc dependencies via `meta.project.nav-dependencies`. The Phase-8 dependency graph adds an edge to each declared target. The escape hatch for Lua filters that walk siblings without using sidebar / link / prev-next channels. Default empty. | +| `always_render` | `bool` from `meta.project.always-render`. When `true`, Mode B (subset render) pulls this page into the render set if any of its dependents is among the user-named targets. Mode A re-renders every page anyway, so this flag has no Mode-A effect. Default `false`. | +| `body_link_targets` | `Vec` of project-relative `.qmd` paths this page links to from its body content. Populated by `LinkResolutionStage` (Pass-1) using the same `resolve_doc_relative_target` helper Phase 6's `LinkRewriteTransform` calls in Pass-2 — equivalence test asserts the two produce the same set. The Phase-8 dependency graph turns each target into an edge. See `body-link-resolution-contract.md`. Default empty. | +| `resources` | `Vec` of document-level `resources:` patterns from the merged frontmatter (`bd-o8pr`). Raw patterns; expansion happens at the post-render collector. The snapshot of what the author declared at frontmatter-freeze time — engines and Lua filters that run later contribute through a separate channel (`DocumentResourceReport`) and cannot retroactively shrink this list. Default empty. | +| `categories_raw` | `Option` carrying the originating tagged value of the top-level `categories:` key (`bd-n8a4`). Mirrors `categories` but preserves `!prefer` / `!concat` merge tags so listings consumers can feed it (alongside `listing_item.categories_raw`) into `quarto_config::MergedConfig` for tag-aware merging. Most consumers should keep reading the flattened `categories`; only listings reach for the raw form. Default `None`. | +| `listing_content_globs` | `Vec` of unresolved glob strings from the host page's `listing.*.contents:` declarations (`bd-xbnf`, listings L6). Flattened across all listings on the page. The dependency-graph builder expands these against `ProjectIndex` at graph-build time (host-relative first, project-relative fallback — matches L3's render-time rule) to add forward edges from each listing host to its content files; hosts with non-empty entries are also added to the graph's `force_render` set so Mode B (`quarto render posts/foo.qmd`) pulls in listing hosts when any of their content files is targeted. Resolution is **not** cached on the profile (the per-doc cache cannot represent dependency on the full project source set safely). Default empty. | +| `listing_item` | `ListingItemInfo` advertising per-document data for listings consumers (`bd-n8a4`). **Scoped feature surface — listings only**; non-listing consumers must use the corresponding top-level fields (`title`, `description`, `image`, …). Author-supplied values populate during `DocumentProfile::extract`; `ListingItemInfoStage` (`bd-izqh`, L1, landed) auto-fills holes pre-checkpoint for `description` (full first paragraph), `image` (first inline image's URL), `word_count` (Q1-parity tokenization, footnote text excluded), `reading_time_minutes` (`ceil(word_count / 200)`), and `date_modified` (filesystem mtime via `SystemRuntime::path_metadata` formatted as `YYYY-MM-DD` UTC). Author values always win — the stage strictly fills holes. The nested `extra: BTreeMap` is the **only** open-shape field in the profile and is forbidden to non-listing consumers — see §"Scoped feature surfaces". Default empty (`ListingItemInfo::is_empty()`). | + +## Non-guarantees (explicit) + +What a profile **does not** contain: + +- **Engine output.** No values produced by executing code cells + (Jupyter, Knitr, Observable). Those require the engine stage, + which runs after the checkpoint. +- **Sugar-synthesized structure.** No callout custom nodes, no + theorem/float-target/equation-label canonicalization, no + crossref numbering (`TocEntry::number`), no appendix structure, + no sectionize-added div classes. Any consumer that needs these + must read them from the post-render AST. +- **User-filter mutations.** Nothing that `pre` or `post` user + filters would introduce (Lua, JSON, citeproc). +- **Theme CSS, code highlighting, rendered HTML body, applied + template.** All of those are downstream of the checkpoint. +- **Resolved shortcodes.** `{{< meta … >}}` and friends are resolved + during `AstTransformsStage`, after the checkpoint. +- **Cross-document information.** A `DocumentProfile` describes a + single file. Merged across siblings by Phase 1's `ProjectIndex` + (future work). +- **Absolute filesystem paths.** Everything path-shaped is + project-relative by construction. + +## Scoped feature surfaces + +Most profile fields are typed, narrowly defined, and globally +readable: any consumer that needs `title`, `categories`, +`outline`, etc. reaches for the top-level field directly. The +contract is closed-shape, versioned, and stable. + +The `listing_item` field is an **explicit exception**, scoped to +one feature (listings) by name and by convention. + +**Allowed:** the listings code path (planned +`L3 ListingResolveTransform`, `L5 CategoriesSidebarTransform`, +`L7 post-render upgrade`, `L9 RSS feeds`) reads +`profile.listing_item` to materialize listing items. + +**Forbidden:** any code outside the listings module reaches into +`profile.listing_item` (and especially into +`profile.listing_item.extra`). Sidebar generation, navbar +rendering, cross-doc link rewriting, freeze, and other features +must continue to use the typed top-level fields. If a future +feature finds itself wanting to read `listing_item`, that is a +**redesign trigger** — either widen the typed top-level field set +with a versioned bump, or define a new scoped feature surface. Do +not silently broaden listings' scope. + +The discipline is enforced by code review, not the type system. +The `listing_item` field is `pub` for serde and for listings' own +use; the contract above is the boundary that matters. + +This is the same discipline `bd-fegm` (Phase 8) used when it +declined to add a generic `extras: HashMap` field for filter- +introduced data and chose typed fields instead. The exception +here is granted because (a) custom listing templates genuinely +need access to author-declared free-form metadata, and (b) the +"named, scoped" framing keeps the cost of the exception locally +bounded. + +The companion field `categories_raw: Option` and its +sibling `listing_item.categories_raw` are likewise listings-only +surfaces: their purpose is to preserve `!prefer` / `!concat` +merge tags so listings consumers can apply tag-aware merging via +`quarto_config::MergedConfig`. Non-listing consumers continue to +read the flattened `categories: Vec`. See +`claude-notes/plans/2026-05-05-listings-L0-profile-extension.md` +§"D7" for the design rationale. + +## Mutability + +**Profiles are read-only.** A Phase 1+ user filter that wants to +observe cross-document state reads `&[DocumentProfile]` through +`ProjectIndex`, but has no API for mutating individual profiles. Any +mutation would undermine caching and cross-document invariants. + +If a profile "should" reflect some piece of state that can only be +computed after the checkpoint today, the fix is to move the producing +logic earlier in the pipeline — not to back-patch the profile. One +tracked case is the `ref_type_registry`: Phase 0 populates it in +`PreEngineSugaringStage` (i.e. after the checkpoint), but eventually +it should move before the checkpoint so cross-document validation of +custom crossref types is possible without full renders. When that +happens, the registry (or its static subset) may become a profile +field, guarded by a `profile_version` bump. + +## Serialization and versioning + +`DocumentProfile` derives `Serialize + Deserialize` and uses +`serde_json` via `to_json` / `from_json`. The latter checks +`profile_version` before returning the value. + +Bump `DOCUMENT_PROFILE_VERSION` whenever the serialized shape changes +in a way that a v1 consumer would misread: + +- adding a new **required** field, +- removing or renaming a field, +- changing the semantics or units of an existing field. + +Additive, backward-compatible changes (new `Option<_>` field with a +`None` default, new `Vec<_>` field with an empty default) **do not** +require a bump — but the contract doc must be updated. + +Consumers reading a profile off disk (Phase 8 incremental rebuild, +future freeze) must handle `DocumentProfileError::VersionMismatch` +gracefully by invalidating the cached profile and re-running the +head pipeline. + +## Checkpoint resumability + +The pipeline data at the checkpoint is `PipelineData::AtProfile`, +wrapping `DocumentAtProfile { profile, ast }`. `DocumentAtProfile` +derives `Clone`, so a Phase 1+ orchestrator can: + +1. Run the head pipeline once per file, collecting every + `DocumentAtProfile`. +2. Build the `ProjectIndex`. +3. For each file, clone the bundle and run the tail pipeline to + completion, passing the shared index via `StageContext`. + +The load-bearing integration test +`pipeline_at_profile_to_end_produces_expected_html` in +`crates/quarto-core/tests/document_profile_pipeline.rs` asserts +byte-identical HTML between an end-to-end render and a render that +pauses, clones, and resumes at the checkpoint. + +For Phase 0, an `UnwrapProfileStage` runs immediately after the +checkpoint and discards the profile, re-emitting the inner +`DocumentAst` so downstream stages keep their existing input kind. +Phase 1 replaces that with a real consumer. + +## Writing a consumer (for future-phase authors) + +1. Obtain a `&DocumentProfile` (or `&[DocumentProfile]` from the + future `ProjectIndex`) — never clone profiles just to mutate them. +2. Treat `None` / empty-vec fields as "the author did not specify + this"; do not synthesize defaults in the consumer unless your + feature's user-facing semantics require it. +3. If you need post-merge state that is not in the profile today, + either read it from the post-transform AST at your own stage + position, or file a bd issue to move its producer pre-checkpoint + and add it as a profile field (with a version bump). +4. Never add a branch on `ProjectContext::is_single_file` — see + §"Project root invariant" in the Phase-0 plan. + +## Failure surface and the strict-vs-lenient consumer contract + +### Engine policy + +A document that fails to reach the checkpoint (parse error, +metadata error, missing required `_metadata.yml`, …) is dropped +from the project's `ProjectIndex` and surfaced as a +`FileFailure` on the orchestrator's `ProjectRenderSummary`: + +```rust +pub struct FileFailure { + pub input: PathBuf, + pub error: String, // pre-rendered ariadne text for parse errors + pub diagnostics: Vec, // structured form + pub source_context: Option, // for offset → line/column mapping +} + +pub struct ProjectRenderSummary { + pub outputs: Vec, + pub pass1_failures: Vec, // profile-pass dropouts + pub pass2_failures: Vec, // renderer errors + pub project_diagnostics: Vec, +} +``` + +The orchestrator is **policy-free**: it does not decide whether +a `pass1_failures` entry should abort the run, change the exit +code, or be displayed inline. Pass-2 simply runs over whatever +files succeeded Pass-1; any references to the dropped file from +sibling navigation get the project-scoped warning +`" references missing document information for ''"` +(emitted in `quarto_core::transforms::navigation_href`). + +### Consumer contract + +Two consumers exist today: + +| Consumer | Policy | What it does | +|---------------------------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `quarto render` (CLI / CI) | Strict | Any non-empty `pass1_failures` *or* `pass2_failures` causes a non-zero exit. Headless renders must not silently drop pages. | +| `quarto preview` / hub-client (interactive) | Lenient | Surfaces failures in the preview overlay with source-file attribution; keeps rendering everything that did succeed. Partial progress lets a user fix one error at a time without losing live preview elsewhere. | + +The `RenderResponse` wire format the WASM hub-client returns +mirrors the orchestrator surface: + +```ts +interface RenderResponse { + success: boolean; // active page render + error?: string; // active-page failure message + html?: string; + diagnostics?: Diagnostic[]; // active-page errors + warnings?: Diagnostic[]; // page-local + project-scoped warnings + pass1_failures?: Pass1Failure[]; // sibling-page Pass-1 failures +} + +interface Pass1Failure { + source_file: string; + error: string; // ariadne snippet for parse errors + diagnostics: Diagnostic[]; // structured form for Monaco markers +} +``` + +`Diagnostic` carries an optional `source_file` attribution for +project-scoped warnings whose origin isn't pinned by their +location (e.g. nav warnings). + +### Adding a new consumer + +A planned third consumer is a `quarto preview` binary that wraps +hub-client infrastructure for local previews. New consumers must: + +1. **Not modify the engine.** Pass-1 failures, project + diagnostics, and per-page diagnostics all flow through + `ProjectRenderSummary` (native) or `RenderResponse` (WASM) + unchanged. +2. **Choose a policy explicitly.** Strict is appropriate for + one-shot / CI-style consumers; lenient is appropriate for + live / iterative consumers. +3. **Preserve attribution.** When showing a Pass-1 failure to + the user, name the failing file. The hub-client overlay's + "Sibling page 'X' failed to parse" pattern is the reference + implementation. + +Tracking: `bd-creo` (CLI strictness), `bd-mwtf` / +`bd-rqba` (hub-client leniency + attribution), +`bd-0tr6` (websites epic). Plan: +`claude-notes/plans/2026-05-01-hub-client-website-render-ux.md`. + +## Change log + +- **2026-04-23 — v1.** Initial version. Fields: `profile_version`, + `source_path`, `output_href`, `format_id`, `title`, `subtitle`, + `description`, `authors`, `date`, `categories`, `keywords`, + `image`, `draft`, `outline`. (`bd-f3jc`) +- **2026-04-24 — v1-additive.** Added `order: Option` field + from `order:` frontmatter, consumed by Phase-2 auto-sidebar sort. + `#[serde(default)]` so v1-serialized profiles still deserialize. + No `profile_version` bump. (`bd-9svl`) +- **2026-04-27 — v2 (`bd-fegm` / `bd-r82e`).** `DOCUMENT_PROFILE_VERSION` + bumped 1 → 2. Four new fields, all collection-shaped with + `#[serde(default, skip_serializing_if = ...)]` so default profiles + serialize without bloat: + - `includes: Vec` — closes `bd-r82e`. Required for + Phase-8 cache invalidation when transitive `{{< include … >}}` + children change. + - `nav_dependencies: Vec` — user-declared cross-doc + dependency channel for filter-introduced edges. + - `always_render: bool` — per-page Mode-B opt-in for non- + deterministic / non-modelable filters. + - `body_link_targets: Vec` — populated by the new + `LinkResolutionStage` for Phase-8 dependency-graph edges. + v1 cache entries on disk are rejected with + `DocumentProfileError::VersionMismatch` and silently + regenerated. + See companion contracts: + `claude-notes/designs/body-link-resolution-contract.md`, + `claude-notes/designs/sidebar-auto-expansion-contract.md`. +- **2026-04-29 — v3 (`bd-o8pr`).** `DOCUMENT_PROFILE_VERSION` + bumped 2 → 3. One new field: + - `resources: Vec` — document-level `resources:` + patterns from frontmatter, snapshot at frontmatter-freeze + time. The post-render collector expands the patterns and + augments them with engine/filter contributions through a + separate channel (`DocumentResourceReport`); the profile + field is read-only and immutable downstream of the + checkpoint. Default empty. + v2 cache entries on disk are rejected with + `DocumentProfileError::VersionMismatch` and silently + regenerated. +- **2026-05-05 — v4 (`bd-n8a4`, listings epic L0).** + `DOCUMENT_PROFILE_VERSION` bumped 3 → 4. Two new fields, both + additive at the on-disk layer (`skip_serializing_if` keeps + default profiles compact): + - `listing_item: ListingItemInfo` — scoped per-feature + surface for listings consumers. Curated typed sub-fields + plus `extra: BTreeMap` for custom + listing-template fields. Default empty + (`ListingItemInfo::is_empty()`). Outer profile shape + stable; additions or removals of keys inside `extra` do + **not** require a future bump. Non-listing consumers are + forbidden from reading this field — see new §"Scoped + feature surfaces". + - `categories_raw: Option` — tagged form of the + top-level `categories:` value, preserving `!prefer` / + `!concat` merge tags for listings consumers' tag-aware + merging via `quarto_config::MergedConfig`. Most consumers + keep reading the flattened `categories: Vec`; + only listings reach for the raw form. Default `None`. + v3 cache entries on disk are rejected with + `DocumentProfileError::VersionMismatch` and silently + regenerated, identical to the v2 → v3 cascade. + Plan: `claude-notes/plans/2026-05-05-listings-L0-profile-extension.md`. + Parent epic: `bd-61cd` + (`claude-notes/plans/2026-05-05-listings-epic.md`). +- **2026-05-06 — `ListingItemInfoStage` lands (`bd-izqh`, listings + epic L1).** No version bump; the field shape is unchanged. New + pre-checkpoint stage between `IncludeExpansionStage` and + `DocumentProfileStage` auto-fills `meta.listing-item.{description, + image, word-count, reading-time-minutes, date-modified}` from the + post-include AST (and filesystem mtime via + `SystemRuntime::path_metadata`) when the author hasn't supplied + them. `DocumentProfileStage` then extracts the enriched + `ListingItemInfo` via the same path it used for purely + author-supplied values in v4. `categories` is **not** auto-filled + by L1 (D8 — listings consumers do their own L0-`categories_raw`-aware + merge). The hub-client/WASM pipeline runs the same stage, but + `date_modified` stays `None` until `bd-a3we` teaches the Automerge + VFS to surface change-history time. Plan: + `claude-notes/plans/2026-05-05-listings-L1-autofill-stage.md`. +- **2026-05-07 — v5 (`bd-xbnf`, listings epic L6).** + `DOCUMENT_PROFILE_VERSION` bumped 4 → 5. One new field, additive + at the on-disk layer (`skip_serializing_if` keeps default + profiles compact): + - `listing_content_globs: Vec` — flattened glob strings + from the host page's `listing.*.contents:` declarations. + *Unresolved* globs only; resolution happens at graph-build + time inside + `crate::project::dependency_graph::ProjectDependencyGraph::build`, + which expands each glob against the full project source set + (host-relative first, project-relative fallback — same rule + `ListingGenerateTransform` uses at render time) to add forward + edges from each listing host to its content files. Hosts with + non-empty entries are also added to the graph's + `force_render` set so Mode B (`quarto render posts/foo.qmd`) + automatically pulls in listing hosts when any of their + content files is in the user-named target set. Resolution is + **not** cached on the profile because it depends on the full + project source set, which a per-doc profile can't represent + safely (a new sibling `.qmd` would not invalidate the host's + profile cache, leaving the resolution stale). Default empty. + v4 cache entries on disk are rejected with + `DocumentProfileError::VersionMismatch` and silently + regenerated, identical to every prior bump. + Plan: `claude-notes/plans/2026-05-07-listings-L6-dep-graph.md`. + Parent epic: `bd-61cd` + (`claude-notes/plans/2026-05-05-listings-epic.md`). diff --git a/claude-notes/designs/sidebar-auto-expansion-contract.md b/claude-notes/designs/sidebar-auto-expansion-contract.md new file mode 100644 index 000000000..9deb15afc --- /dev/null +++ b/claude-notes/designs/sidebar-auto-expansion-contract.md @@ -0,0 +1,158 @@ +# Sidebar `auto:` expansion + membership contract + +**Status:** Initial draft, 2026-04-27 (Phase 8 sub-phase 8.0). +**Code:** + +- `crates/quarto-core/src/transforms/sidebar_auto.rs` — + `expand_auto` (the underlying expansion algorithm). +- `crates/quarto-core/src/project/sidebar_membership.rs` — + `resolve_sidebar_membership` (Pass-1 / static membership query). +- `crates/quarto-core/src/transforms/sidebar_generate.rs` — + Pass-2 transform that adds enrichment, active-state marking, + and per-page sidebar selection on top of the same underlying + expansion. +- `crates/quarto-navigation/src/sidebar.rs` — + `Sidebar::parse_list_from_config`, `sidebar_for_page`, + `resolve_active_state` (the format-agnostic data-model layer). + +## What this contract is for + +A Quarto sidebar can be declared statically in `_quarto.yml` (or +in a document's frontmatter) with one or more `auto:` directives +that enumerate pages from the project. The Phase-8 dependency +graph needs to know **which project documents are members of which +sidebar** at Pass-1 time (read-only, no engine / filter / Pass-2 +transform involvement) so it can: + +1. Add a co-membership edge for every pair of pages that share a + sidebar (a title change to one ripples to siblings' + rendered output). +2. Identify prev/next neighbors from the sidebar's flattened + member order. + +The same expansion algorithm runs in Pass-2 to render the actual +sidebar HTML. The two halves must agree on the membership set — +otherwise the dependency graph could miss an edge that ends up in +the rendered output, and warm renders would show stale sidebars. + +## Inputs + +- `meta`: the document's merged metadata. Read-only. +- `index`: the project's `ProjectIndex` (every rendered page's + `DocumentProfile`). Read-only. +- `diagnostics`: a mutable buffer for warnings emitted during + expansion (unresolved `auto:` paths, draft pages, etc.). The + Pass-1 helper appends to this; Pass-2 channels them through to + the per-doc `RenderContext`. + +## Output + +A `Vec`, one entry per sidebar +declared under `meta.website.sidebar`. Each `members` list is the +project-relative source paths of every page that appears in the +resolved sidebar, in document order, deduplicated by path +(first-occurrence wins). + +## Algorithm + +1. **Read `meta.website.sidebar`.** Absent → return empty Vec. + Present-but-empty → return one empty `ResolvedSidebar`. + +2. **Parse the config slice into one or more `Sidebar` values.** + `Sidebar::parse_list_from_config` accepts: + - A single `Sidebar` object: `{ id, title, contents, ... }`. + - An array of `Sidebar` objects. + - A bare contents array (treated as a single anonymous sidebar). + +3. **For each sidebar, run `expand_auto` against `index`.** This + walks `sidebar.contents` and replaces every `SidebarEntry::Auto(spec)` + with a flat list of `SidebarEntry::Link` entries chosen + from the index according to `spec`: + + - `auto: true` → every non-draft, non-top-`index.qmd` page in + the index. + - `auto: ` → every page under that subdirectory. + - `auto: [a.qmd, b.qmd]` → exactly those listed pages. + - Order: the index's discovery order (which is deterministic + by Phase-1 invariant), filtered to match the spec. + - Drafts (`profile.draft == true`) are skipped silently. + - Unresolved entries (paths with no profile) emit a warning + diagnostic and are dropped. + +4. **Walk the resolved entries and collect member paths.** For + each entry: + - `Link { item }` with an `href` that's not external (no + scheme, not `//`, not starting with `#`): record `href` as + a project-relative path. + - `Section { href, contents, ... }`: if `href` is project- + relative, record it; recurse into `contents`. + - `Separator`, `Heading(_)`, unexpanded `Auto(_)` (defensive; + should not survive `expand_auto`): skip. + - Dedupe by path: a page that appears twice in the same + sidebar (rare but legal) gets one membership entry. + +## Examples + +| Config | Resolved members | +|---|---| +| `contents: [a.qmd, b.qmd]` | `[a.qmd, b.qmd]` | +| `contents: [{auto: true}]` (index has 3 pages) | `[a.qmd, b.qmd, c.qmd]` | +| `contents: [{section: "Group", contents: [a.qmd, b.qmd]}]` | `[a.qmd, b.qmd]` | +| `contents: [a.qmd, https://example.com]` | `[a.qmd]` (external dropped) | +| `contents: [a.qmd, a.qmd]` | `[a.qmd]` (deduped) | + +## Equivalence with Pass-2 sidebar render + +For a fixed `(meta, index)`: + +- `resolve_sidebar_membership(meta, index, _)` returns the same + member set per sidebar that `SidebarGenerateTransform` would + produce after `expand_auto` runs but before + enrichment / active-state / rendering. + +- The two helpers literally call the same `expand_auto` function, + so any future change to expansion logic is shared automatically. + +## What this contract does NOT cover + +- **Active-state marking.** Phase-2's + `resolve_active_state` flips `active` flags on entries so the + current page is highlighted in the rendered sidebar. The + dependency graph doesn't need this; Pass-1 membership skips it. +- **Bare-href text enrichment.** Phase 2 fills in display text + from index titles when the user supplied only a path. The + dependency graph doesn't need text either. +- **Sidebar-for-page selection.** + `sidebar_for_page(sidebars, page_source, meta)` picks *which* + declared sidebar applies to a given page (e.g. the one that + contains the page, or the one whose `id` matches an explicit + `site-sidebar:` override). Phase-1 membership returns *all* + sidebars; the graph builder uses every one. +- **Per-page sidebar overrides via `site-sidebar:`.** Same + reason — the membership contract returns sidebars uniformly, + and the graph is built against all of them. +- **Sidebar ordering for prev/next.** The Pass-2 page-nav + transform orders prev/next by traversing the fully-resolved + sidebar; Phase 8's dependency graph derives prev/next neighbor + edges from the same flattened member sequence (which `members` + here exposes in document order). +- **Multi-sidebar ambiguity diagnostics.** If a page appears in + more than one declared sidebar, both are reported; the user + resolves the ambiguity via `site-sidebar:` (which is Pass-2 / + per-page concern, not membership). + +## When to bump this contract + +Any change to `expand_auto`'s behavior that would alter the set +of pages a `auto:` directive resolves to, or to the +`collect_member_paths` walk, requires: + +1. Updating this document. +2. Bumping `PROFILE_KEY_VERSION` in `cache_key.rs` (Phase 8.1) — + the dependency-graph structure changes, so cache hits would + serve stale data. + +Adding new sidebar entry kinds (e.g. a new `SidebarEntry::Foo` +variant) requires extending the walk explicitly. The default +match arms are exhaustive; the compiler will surface any missed +case. diff --git a/claude-notes/designs/wire-format-source-info-codes.md b/claude-notes/designs/wire-format-source-info-codes.md new file mode 100644 index 000000000..590ed5ffc --- /dev/null +++ b/claude-notes/designs/wire-format-source-info-codes.md @@ -0,0 +1,101 @@ +# Source-info wire-format code allocation + +**Status:** Active. Codes 0–3 in production; codes 4–5 reserved for q2-preview plan 5. +**Source of truth:** `crates/pampa/src/writers/json.rs:54-91` (writer types +`SourceInfoJson`, `AstContextJson`, `NodeJson`). +**Rust enum:** `quarto_source_map::SourceInfo` at `crates/quarto-source-map/src/source_info.rs`. +**Plans:** [q2-preview plan 2a](../plans/2026-05-04-q2-preview-plan-2a-iframe-foundation.md) +(first formal TS reader); [q2-preview plan 5](../plans/2026-05-04-q2-preview-plan-5-wire-format.md) +(`Synthetic` / `Derived` variants). + +## Purpose + +The source-info pool is a JSON-encoded structure emitted by the Pandoc +JSON writer alongside every AST. Each AST node carries an integer +`s` field that indexes into the pool. Pool entries discriminate on a +small integer code in the `t` field. This document is the policy for +allocating those codes. + +The reason it needs a written policy: the codes cross language +boundaries (Rust writer → TS iframe reader, with future cross-process +readers possible) and they are encoded as integers, so semantic drift +produces silent wrong behavior, not type errors. + +## Allocation policy + +1. **Codes are append-only.** Once a number has been emitted by a + released writer, the variant shape at that number is frozen. + New variants get new numbers. This is standard wire-format + hygiene; it's the policy a reader can rely on without + negotiating versions. + +2. **Variant removal burns the number.** If a variant is dropped + from the Rust enum, the wire number is documented as burnt in + this file rather than recycled. A future variant that "feels + like" the removed one still gets a fresh number. + +3. **Forward-reservations are explicit.** A plan that reserves codes + ahead of the writer (e.g., q2-preview plan 2a pre-declaring TS + types for codes 4 and 5) records the reservation here. + Pre-declared reader types are inert until the writer emits. + +4. **Number-to-shape changes are synchronized.** Any change to the + shape at an existing code requires writer + every reader (Rust + reader, hub-client iframe TS reader, any future reader) updated + in a single PR or coordinated series. This is the highest-coupling + cross-language change in the stack. + +5. **The writer types are the source of truth.** TS mirrors lag, + never lead — same convention as `hub-client/src/types/diagnostic.ts` + ↔ `DiagnosticMessage` and `hub-client/src/utils/pipelineKind.ts` ↔ + `PipelineKind`. + +## Current allocations + +| Code | Variant | `d` shape | Writer | Native reader | TS reader | +|------|---------|-----------|--------|---------------|-----------| +| 0 | `Original` | `file_id: number` | Emits | Reads | Reads (q2-preview plan 2a) | +| 1 | `Substring` | `parent_id: number` | Emits | Reads | Reads (q2-preview plan 2a) | +| 2 | `Concat` | `Array<[piece_id, offset_in_concat, length]>` | Emits | Reads | Reads (q2-preview plan 2a) | +| 3 | `FilterProvenance` | `[filter_path: string, line: number]` | Emits | Reads | Reads (q2-preview plan 2a) | +| 4 | `Synthetic` (reserved) | `By` (`{ kind: string; data?: unknown }`) | Reserved for q2-preview plan 5 | Reserved for q2-preview plan 5 | Forward-declared (q2-preview plan 2a) | +| 5 | `Derived` (reserved) | `{ from: number; by: By }` | Reserved for q2-preview plan 5 | Reserved for q2-preview plan 5 | Forward-declared (q2-preview plan 2a) | + +The `r` field on every entry is `[start_offset, end_offset]` — +constant across all codes. Codes 4 and 5 have `r: [0, 0]` because +their variants are not anchored to a file range. + +## Burnt numbers + +| Code | Removed variant | Original shape | Removed in | Status | +|------|-----------------|----------------|------------|--------| +| (3) | `Transformed` | `[parent_id, ...]` | Pre-`Substring`-pool refactor | **Grandfathered exception.** Code 3 was recycled into `FilterProvenance`. This predates the policy and shipped without bite because no AST JSON is persisted anywhere. Counts as one-off, not precedent. | + +There are no other burnt numbers as of this writing. + +## Procedure for adding a new code + +1. **Reserve the number** in this file (add a row to "Current + allocations" with status "Reserved for ``"). Mention the + intended `d` shape. +2. **Forward-declare the TS type** in `hub-client/src/types/sourceInfo.ts` + so reader code can compile against the shape before the writer + emits. +3. **Implement the writer** in `crates/pampa/src/writers/json.rs` — + add the variant to `SerializableSourceMapping` and the match arm + in `to_json`. +4. **Update the Rust enum** in `crates/quarto-source-map/src/source_info.rs` + if the variant is new to the Rust side too. +5. **Update consumers** — native reader, TS accessors in + `hub-client/src/utils/sourceInfo.ts`, and any other readers. +6. **Update this doc** — promote the row from "Reserved" to live, + adjust the writer / reader columns, and link the plan PR. + +## Synchronization invariant + +For any released writer version V, every reader that processes +output from V must agree on the shape at every emitted code. Drift +between Rust and TS readers is a silent wrong-behavior bug, not a +type error. Reviewers of any PR that touches `json.rs`'s wire types +must verify the corresponding TS types in `sourceInfo.ts` move in +lockstep. diff --git a/claude-notes/instructions/auth-verification.md b/claude-notes/instructions/auth-verification.md new file mode 100644 index 000000000..971844800 --- /dev/null +++ b/claude-notes/instructions/auth-verification.md @@ -0,0 +1,340 @@ +# Auth verification — hub-client (SPA cookie) + hub-mcp (device flow) + +End-to-end verification for the two auth paths into Quarto Hub: +SPA Google sign-in → HttpOnly cookie → WS upgrade, and hub-mcp's +RFC 8628 device flow → OS-keyring bundle → Bearer-token WS upgrade. + +Use this when re-running the user-driven half of Phase 9 verification +described in +[`claude-notes/plans/2026-05-05-hub-mcp-device-flow-implementation.md`](../plans/2026-05-05-hub-mcp-device-flow-implementation.md) +§ "Deferred to user-driven verification". The autonomous half is +already recorded in that plan; what's below needs a real browser, a +real Google consent, a real MCP client, or grant revocation. + +Targets macOS. Linux/Windows keyring equivalents are in +[`ts-packages/quarto-hub-mcp/README.md`](../../ts-packages/quarto-hub-mcp/README.md). + +## One-time setup + +### 1. Google Cloud Console — SPA OAuth client + +The SPA's "Web application" OAuth client (matching `OIDC_CLIENT_ID`) +must list the local dev URLs, or Google rejects sign-in with +`Error 400: unsupported_response_type`: + +1. Open . +2. Click the SPA "Web application" OAuth client. +3. **Authorized JavaScript origins** → add `http://localhost:5173`. +4. **Authorized redirect URIs** → add `http://localhost:5173/auth/callback`. +5. Save. + +The hub-mcp "TV and Limited Input devices" client has no redirect URIs +— leave it untouched. + +### 2. Register hub-mcp with Claude Code CLI + +User-scope so it overrides any project-level `.mcp.json` while +verifying against the local hub. Run from the repo root so `$(pwd)` +resolves to the absolute path Claude Code stores in the registration: + +```bash +cd + +claude mcp remove quarto-hub -s user 2>/dev/null || true + +claude mcp add quarto-hub -s user \ + -- node "$(pwd)/ts-packages/quarto-hub-mcp/dist/index.js" \ + --server ws://localhost:3000/ + +claude mcp get quarto-hub # confirm +``` + +## Per-session setup (every new terminal) + +### Env vars + +```bash +export OIDC_CLIENT_ID=$(grep ^OIDC_CLIENT_ID= ~/.Renviron | cut -d= -f2-) +export QUARTO_HUB_MCP_CLIENT_ID=$(grep ^QUARTO_HUB_MCP_CLIENT_ID= ~/.Renviron | cut -d= -f2-) +export QUARTO_HUB_MCP_CLIENT_SECRET=$(grep ^QUARTO_HUB_MCP_CLIENT_SECRET= ~/.Renviron | cut -d= -f2-) +``` + +### Rebuild after code changes + +```bash +cd +cargo build -p quarto-hub --bin hub +(cd ts-packages/quarto-hub-mcp && npm run build) +``` + +### Terminal A — authenticated hub + +Stays running for items 3, 4, 5, 6, 4b. Audit log on stdout. + +```bash +DATA_DIR=$(mktemp -d -t phase9-hub-auth) +trap 'rm -rf "$DATA_DIR"' EXIT +RUST_LOG="quarto_hub=info,quarto_hub::audit=info,info" \ + target/debug/hub \ + --data-dir "$DATA_DIR" \ + --port 3000 --host 127.0.0.1 \ + --oidc-client-id "$OIDC_CLIENT_ID" \ + --additional-audiences "$QUARTO_HUB_MCP_CLIENT_ID" \ + --allowed-domains posit.co \ + --allow-insecure-auth +``` + +## Optional: keyring helpers + +Quality-of-life shell functions used by the items below. Skip if +you'd rather run the underlying `security` commands directly — the +helpers do nothing the macOS Keychain CLI can't. + +```bash +inspect-kr() { + local account="https://accounts.google.com:$QUARTO_HUB_MCP_CLIENT_ID" + security find-generic-password -s dev.quarto.hub-mcp -a "$account" -w 2>/dev/null \ + | jq '{schema_version, issuer, client_id, scopes, id_token_expires_at, + id_token_segments: (.id_token|split(".")|length), + refresh_token_len: (.refresh_token|length)}' \ + || echo "(no keyring entry)" +} +clear-kr() { + local account="https://accounts.google.com:$QUARTO_HUB_MCP_CLIENT_ID" + security delete-generic-password -s dev.quarto.hub-mcp -a "$account" 2>/dev/null \ + && echo "cleared" || echo "(no entry to clear)" +} +expire-kr() { + local account="https://accounts.google.com:$QUARTO_HUB_MCP_CLIENT_ID" + local blob; blob=$(security find-generic-password -s dev.quarto.hub-mcp -a "$account" -w 2>/dev/null) \ + || { echo "(no entry — run the auth flow first)"; return 1; } + local patched; patched=$(echo "$blob" | jq -c '.id_token_expires_at = "1970-01-01T00:00:00Z"') + security add-generic-password -s dev.quarto.hub-mcp -a "$account" -w "$patched" -U + echo "expired" +} +``` + +## Verification matrix + +| Item | Path | Goal | +|------|----------|--------------------------------------------------------------| +| 3 | Cookie | SPA Google sign-in works; cookie path unaffected by Phase 2. | +| 4 | Bearer | hub-mcp full device flow + keyring round-trip. | +| 5 | Bearer | Force a proactive refresh; observe one `/token` POST. | +| 6 | Bearer | Grant revocation surfaces typed `ReauthRequired`. | +| 4b | Both | Allowlist parity — byte-identical 403 audit lines. | +| 4a | Bearer | No-auth hub doesn't trigger device flow; short-circuit works.| + +Order below minimises hub restarts. + +--- + +## Item 3 — SPA cookie path (browser) + +In a second terminal: + +```bash +cd /hub-client +VITE_GOOGLE_CLIENT_ID="$OIDC_CLIENT_ID" npm run dev +``` + +Open , click "Sign in with Google", complete +consent with your `@posit.co` account. + +**Record** from terminal A: one event +`action="auth_ok" outcome="allow" credential_kind="cookie" sub=`. +Keep the `sub` — item 4 should produce the same one on Bearer. + +Close the tab when done. + +--- + +## Item 4 — hub-mcp full device-flow E2E + +```bash +clear-kr # fresh slate +``` + +In a fresh terminal: `cd /tmp && claude`. + +**4.1 — trigger AuthRequired.** Ask the agent: + +> Use the `quarto-hub` MCP server. Call `connect_project` with +> project_id `phase9-test-project`. (If the project does not exist, +> that's fine — I just need to see the error path.) + +Expect: typed `AuthRequired` naming `authenticate_start`. + +**4.2 — start the device flow.** + +> Yes, call `authenticate_start`. + +Expect tool response with `https://www.google.com/device` (the +hard-coded canonical URL), a `user_code`, expiry seconds. + +**4.3 — finish.** Complete the flow in your browser, then: + +> Now call `authenticate_finish`. + +Expect: `Authenticated as .` + +**4.4 — retry.** + +> Retry the `connect_project` call from earlier. + +Expect: succeeds (or `project not found` — auth path is what matters). + +**Record:** + +- Terminal A: + `action="auth_ok" outcome="allow" credential_kind="bearer" sub=`. + Subject should match item 3. +- `inspect-kr` shows `schema_version: 1`, scopes + `["openid","email","profile"]`, expiry ≈ 1 h from now. +- `ls ~/Library/Application\ Support/quarto/ 2>/dev/null` → no such + directory (no plaintext fallback). + +--- + +## Item 5 — Force refresh + +```bash +expire-kr # rewrites id_token_expires_at to 1970 +inspect-kr # confirms 1970 +``` + +In Claude Code: + +> Use the `quarto-hub` MCP tool to call `list_files` against +> project_id `phase9-test-project`. + +Expect: + +- Terminal A: one new `auth_ok credential_kind="bearer"` event. +- hub-mcp's MCP-server stderr (`claude --debug`) shows exactly one + request to `https://oauth2.googleapis.com/token`. + +```bash +inspect-kr # expiry is now ~1h in the future +``` + +--- + +## Item 6 — Force re-auth + +1. Open . +2. Third-party apps → hub-mcp client → **Remove Access**. + +In Claude Code: + +> Call `list_files` against the same project again. + +Expect typed `ReauthRequired`: + +> Your Quarto Hub credentials have expired or were revoked. Ask me to +> authenticate again. + +`RefreshManager` catches `invalid_grant` from `/token`, clears the +store, throws. Verify: + +```bash +inspect-kr # "(no keyring entry)" — store.clear() ran +``` + +Decline if the agent proposes `authenticate_start` again — verification +is complete. + +--- + +## Item 4b — Allowlist parity (two accounts) + +Hub already runs with `--allowed-domains posit.co`. Needs an +allowlisted (`@posit.co`) and a non-allowlisted (e.g. `@gmail.com`) +Google account. + +**Cookie path.** In the SPA, sign out if needed, then sign in with the +non-allowlisted account. Expect 403 on `/auth/callback`. + +Terminal A: +`action="auth_fail" outcome="deny" credential_kind="cookie" detail="user_not_allowlisted"`. + +**Bearer path.** + +```bash +clear-kr +``` + +In Claude Code: + +> Run `authenticate_start`, complete with my @gmail.com account, then +> `authenticate_finish` and `connect_project`. + +Expect: device flow succeeds (Google has no allowlist), then any +tool that opens the WS gets 403 surfaced as typed error. + +Terminal A: +`action="auth_fail" outcome="deny" credential_kind="bearer" detail="user_not_allowlisted"`. + +The `detail` field must be byte-identical between the two paths. + +**Happy-path retest:** `clear-kr`, re-run with `@posit.co`. Bearer +path back to `auth_ok`. + +--- + +## Item 4a — No-auth hub + short-circuit + +```bash +clear-kr +# Stop terminal A (Ctrl-C). Relaunch hub with no auth: +DATA_DIR=$(mktemp -d -t phase9-hub-noauth) +trap 'rm -rf "$DATA_DIR"' EXIT +RUST_LOG="quarto_hub=info,info" \ + target/debug/hub --data-dir "$DATA_DIR" --port 3000 --host 127.0.0.1 +``` + +Same `ws://localhost:3000/` registration; no re-register needed. + +**Restart Claude Code** (`/exit`, `claude`) so the MCP subprocess +respawns with fresh `lastObservedAuthMode = 'unknown'`. + +**4a.1 — no-auth probe.** + +> Call `connect_project` against project_id `phase9-test-project`. + +Expect: succeeds — no `AuthRequired`, no device flow. `inspect-kr` +stays empty. + +**4a.2 — explicit-authenticate short-circuit.** + +> Now run `authenticate_start`. + +Expect: +"The configured hub does not require authentication; no action needed." +No request to `oauth2.googleapis.com` (visible in `claude --debug`). + +**4a.3 — unknown-state baseline.** `/exit` and relaunch `claude` so +`lastObservedAuthMode` resets to `'unknown'`. **Before** any other hub +call: + +> Run `authenticate_start`. + +Expect: device flow **does** initiate — confirms the short-circuit is +gated on positive observation, not absence of evidence. Abort or +complete the flow. + +--- + +## Teardown + +```bash +# Stop terminal A. +clear-kr +claude mcp remove quarto-hub -s user +``` + +## Logging results + +After each item, append observed output to the plan under a new +`#### Phase 9 user-driven verification — @ ` +sub-heading. The verification log is append-only. diff --git a/claude-notes/instructions/hub-mcp-operator-runbook.md b/claude-notes/instructions/hub-mcp-operator-runbook.md new file mode 100644 index 000000000..50460df8d --- /dev/null +++ b/claude-notes/instructions/hub-mcp-operator-runbook.md @@ -0,0 +1,195 @@ +# Hub-mcp operator runbook + +One-time setup for hub operators who want to expose `quarto-hub-mcp` to +end users. Sits alongside the SPA OAuth registration in +[`claude-notes/plans/2026-02-24-oauth2-middleware-design.md`](../plans/2026-02-24-oauth2-middleware-design.md); +both clients live in the same Google Cloud project. + +Design context: +[`claude-notes/plans/2026-05-28-hub-mcp-loopback-pkce.md`](../plans/2026-05-28-hub-mcp-loopback-pkce.md). + +## What you're registering + +`quarto-hub-mcp` authenticates to the hub via Google's OAuth 2.0 +Authorization Code grant with PKCE and a loopback redirect (RFC 8252). +That requires a second Google OAuth client of type **"Desktop app"** +in the same Google Cloud project as the SPA's existing "Web +application" client. The hub accepts ID tokens from either audience. + +## Step 1 — register the OAuth client + +1. Open on the + project that already hosts the SPA OAuth client. +2. **Create Credentials → OAuth client ID**. +3. **Application type → "Desktop app"**. +4. Name it something the audit log will read clearly, e.g. + `quarto-hub-mcp`. +5. Click **Create**. Copy the **client_id** and **client_secret** off + the confirmation dialog. + +Notes: + +- The OAuth consent screen, brand assets, and verified scopes are + shared with the SPA client. No extra consent-screen submission. +- The Desktop-app client also issues a **client_secret**, and Google + requires it on the token exchange and the refresh-token grant; PKCE + is layered on top of the confidential-client flow, not a replacement + for the secret. Google documents the installed-app secret as "not + treated as a secret," but it must still be distributed and set in the + env. No bundled default ships in the npm package for v1 — operators + (including the canonical-hub operator) publish both values to end + users. + +## Step 2 — configure the hub + +Add the new client_id to the hub's audience allowlist. The SPA's +client_id stays as the primary `--oidc-client-id`; the hub-mcp +client_id goes into `--additional-audiences`. + +```bash +hub \ + --oidc-client-id ".apps.googleusercontent.com" \ + --additional-audiences ".apps.googleusercontent.com" \ + ... +``` + +Equivalent env vars (e.g. for `docker compose` or systemd): + +``` +OIDC_CLIENT_ID=.apps.googleusercontent.com +QUARTO_HUB_ADDITIONAL_AUDIENCES=.apps.googleusercontent.com +``` + +`--additional-audiences` accepts a comma-separated list — multiple +hub-mcp clients (for staging vs production, etc.) are supported. +Exact matches only; no wildcards. The hub validates `azp` against the +same allowlist whenever the claim is present (OIDC §3.1.3.7). + +Restart the hub. The startup log will show one `Discovered JWKS URL +from OIDC issuer` line and one signing-algorithm-lock line; the +audience allowlist itself is not logged. + +## Step 3 — publish the values to end users + +Each end user needs **both** values to run `quarto-hub-mcp`: + +- `QUARTO_HUB_MCP_CLIENT_ID` — the hub-mcp client_id from step 1. +- `QUARTO_HUB_MCP_CLIENT_SECRET` — the matching secret. + +`hub-mcp` reads them only from `process.env`. It does not look in +`.mcp.json`, the OS keyring, source literals, or any well-known file +path. Partial config (one set, one unset) is a startup error naming +both vars literally. + +The recommended path is to publish them in your deployment's +end-user docs (the same place you publish the hub's WebSocket URL), +e.g. an internal handbook page or onboarding README. Each developer +then pastes them into their per-user MCP-client config — most +commonly `~/.config/claude/mcp.json` on Linux/macOS or +`%APPDATA%\Claude\mcp.json` on Windows. The package's README +(`ts-packages/quarto-hub-mcp/README.md`) carries a copy-pasteable +example. + +The end-user `.mcp.json` is **not** intended to be checked into a +shared repo — the secret would leak. If you need to ship MCP config +to many users, distribute the secret through your normal +secret-management channel (1Password Connect, Kubernetes Secret + +init script, AWS Secrets Manager, etc.) and have each user's +`.mcp.json` reference an env var rather than the literal. + +## Step 4 — verify + +Once a user has set both env vars and configured the MCP client, +their first agent action triggers the documented flow: + +1. The MCP server probes the hub. Hub returns 401 (no creds). +2. hub-mcp surfaces `AuthRequired`, prompting the agent to call the + `authenticate` MCP tool. +3. The tool binds a `127.0.0.1` listener and opens the user's browser + to Google's sign-in page (also printing the URL for headless/SSH + users). +4. User signs in and approves consent; the redirect lands on the local + listener. +5. The tool exchanges the authorization code (PKCE verifier + + client_secret) and persists the bundle to the user's OS keyring + under service `dev.quarto.hub-mcp`, account + `https://accounts.google.com:`. On success the agent + sees `"Authenticated as ."` and retries the original action. + +Users on headless or remote machines forward the loopback port over +SSH — see the package README's "Headless / SSH sessions" section +(`quarto-hub-mcp --redirect-port N` + `ssh -L N:127.0.0.1:N`). + +Subsequent connects refresh the ID token automatically and reuse the +keyring entry until the user revokes the grant. + +## Auditing and observability + +The hub emits one `tracing::event!` per auth decision on the +`quarto_hub::audit` target. Set `RUST_LOG=quarto_hub::audit=info` to +include them in stdout. Each event carries: + +- `action` — `auth_ok` / `auth_fail` +- `outcome` — `allow` / `deny` +- `credential_kind` — `cookie` / `bearer` (so MCP traffic is + distinguishable from SPA traffic) +- `sub` — the Google subject identifier on accepted requests +- `detail` — failure reason on `auth_fail` (e.g. + `user_not_allowlisted`, `conflicting_credentials`) + +Tokens themselves are never logged; `tower-http`'s `MakeSpan` is +overridden to drop the `Authorization` / `Cookie` headers from the +request span (`crates/quarto-hub/src/server.rs::RedactedMakeSpan`). + +## Secret rotation + +If the `client_secret` leaks (committed to a public repo, exposed in +CI logs, etc.): + +1. **Reset the secret in Google Cloud Console** — same Credentials + page, click the client, **Reset Secret**. The old value stops + working immediately. +2. **Update the secret in your secret-management system.** Every + end user picks up the new value the next time their MCP client + restarts (env vars are read at process start). +3. Existing user keyring entries are **not** invalidated — they hold + ID + refresh tokens that were issued by the old secret but remain + redeemable against the new one (the refresh grant authenticates with + whatever secret is currently configured). No user-side action + required after rotation unless an existing refresh token itself is + also compromised, in which case ask affected users to revoke the + grant (see below). + +If a **user's** refresh token leaks (rather than the operator's +secret), the quickest fix is `authenticate_clear`, which best-effort +revokes the refresh token at Google before clearing the local copy. +The manual equivalent is → +"Third-party apps with account access" → the hub-mcp client → "Remove +Access". Their next agent action surfaces `ReauthRequired` and runs +through the loopback sign-in again with a new bundle. + +## Residual risk to communicate to operators + +- **Stolen ID tokens are valid for up to ≤1 h** regardless of grant + revocation at Google. JWTs are self-contained; the hub does not + consult Google on each request. Closing this window requires a + hub-side `sub_denylist` — not in v1; tracked in the plan's + "Future work" section. +- **A stolen refresh token is an indefinite foothold** until the user + revokes the grant (via `authenticate_clear` or + myaccount.google.com). hub-mcp persists a `refresh_token` only when + Google returns one and keeps the prior value otherwise, so rotation + behaviour does not change the residual; whichever value is current is + the one to revoke. (The Desktop-app client's exact rotation behaviour + is pending confirmation by the loopback+PKCE plan's Spike A.) +- **The loopback redirect closes the remote no-malware phishing class** + that device flow enabled: tokens are delivered only to the user's own + `127.0.0.1` listener, and PKCE binds the code to a verifier held in + the hub-mcp process. An attacker needs local code execution to + capture tokens — at which point the keyring is already exposed. +- **Headless Linux without Secret Service / libsecret cannot persist + credentials.** The credential store refuses silent fallback to a + plaintext file. Users on those hosts use the SPA cookie path. + +See the implementation plan's *Threat model* and *Residual risks +accepted for v1* sections for the full enumeration. diff --git a/claude-notes/instructions/performance-profiling.md b/claude-notes/instructions/performance-profiling.md index 0cd8dda22..e7430fc72 100644 --- a/claude-notes/instructions/performance-profiling.md +++ b/claude-notes/instructions/performance-profiling.md @@ -159,6 +159,45 @@ top-N self-time table. The head of the script documents both the profile format and the samply sidecar structure — if samply's format changes, patch there. +#### When the hotspot is in a system library, use `sample` + +samply's `.syms.json` sidecar symbolicates **our** binary, but it does +**not** resolve system libraries (`libsystem_c.dylib`, +`libsystem_malloc.dylib`, …). Frames inside them show up as bare +addresses (`0x4a83 [libsystem_c.dylib]`). If a hotspot — or, in a +multithreaded profile, the frame *holding a contended lock* — lands in a +system library, the address tells you nothing, and **guessing what it is +will burn your session.** + +macOS ships `sample`, which symbolicates system libraries from the dyld +shared cache: + +```bash +target/release-perf/ & # or run it and grab the pid +sample $! 4 -file /tmp/s.txt # sample the live process for 4s +# then read /tmp/s.txt — system frames now have names +``` + +Real example (bd-b7eb7): a multithreaded `q2 render` showed ~75 % +`__ulock_wait2`/`os_unfair_lock` with the waits charged to tree-sitter's +`ts_lexer__advance`, and the libc frame below it unsymbolicated. We +**guessed "malloc" and it was wrong** — swapping in mimalloc (both as +`#[global_allocator]` *and* via `tree_sitter::set_allocator` for the C +allocations) changed nothing. `sample` revealed the truth: +`ts_lexer__advance → snprintf → __vfprintf → localeconv_l` — the +contended lock was the **global locale lock**, taken by `snprintf` +formatting tree-sitter's per-lex logger string, not the allocator. + +Lessons: +- **A negative result from a cheap fix (swap the allocator) is decisive + evidence**, not a dead end — it ruled out an entire class of cause. +- When samply leaves a hot/lock-holding frame as a system-lib address, + reach for `sample` (or Instruments) before theorizing. +- `#[global_allocator]` only intercepts **Rust** allocations; a C library + vendored into the build (tree-sitter) calls libc `malloc` directly + unless separately redirected (`ts_set_allocator`). Don't assume a Rust + allocator swap covers C-side allocation. + ### Where native drivers live `crates/perf-harness/` — an internal (non-published, `publish = false`) diff --git a/claude-notes/instructions/preview-spa-rebuild.md b/claude-notes/instructions/preview-spa-rebuild.md new file mode 100644 index 000000000..60b38c0a8 --- /dev/null +++ b/claude-notes/instructions/preview-spa-rebuild.md @@ -0,0 +1,144 @@ +# Preview SPA rebuild chain + +When you change Rust code and want to verify the change in `q2 preview`, +the rebuild chain is **not** captured by `cargo build`. This note +explains the chain, the reasons it exists, and the minimal commands to +force a fresh preview. + +## The trap, in one paragraph + +`q2 preview` boots a server that serves an embedded React SPA. The SPA +runs in a sandboxed iframe and renders documents in the browser via a +WASM build of `wasm-quarto-hub-client`. When you change Rust code in +`quarto-core`, `pampa`, or any crate the WASM transitively depends on, +none of the following are sufficient: + +- `cargo build --bin q2` +- `cargo build --workspace` +- `cargo nextest run --workspace` +- `cargo xtask verify --skip-hub-build` + +All of them succeed, the preview command starts, the page loads, the +document renders — but the iframe is executing **pre-change WASM**. +Tests pass, end-to-end of `q2 render` looks right, and yet the preview +silently shows old behavior. This is exactly the situation +"End-to-end verification before declaring success" in `CLAUDE.md` +warns about — verifying through the binary a user runs is necessary, +and for preview the *real* user binary loads a sub-bundle that your +build didn't refresh. + +## The artifact chain + +``` +crates/wasm-quarto-hub-client/ ──build:wasm──▶ hub-client/wasm-quarto-hub-client/wasm_quarto_hub_client_bg.wasm + │ + ▼ + q2-preview-spa/ (Vite, alias 'wasm-quarto-hub-client') + │ + build-q2-preview-spa + ▼ + q2-preview-spa/dist/ + │ + include_dir! (build.rs) + ▼ + crates/quarto-preview/ (EMBEDDED_SPA) + │ + ▼ + cargo build --bin q2 + │ + ▼ + target/debug/q2 +``` + +Each arrow is its own build step. None of them cascade automatically: + +- `cargo build --bin q2` only re-embeds `q2-preview-spa/dist/` if a + file inside that directory changed (see + `crates/quarto-preview/build.rs`'s `rerun-if-changed` directives). + Files inside that dist are themselves Vite output — they only change + when you re-run the SPA build. +- `cargo xtask build-q2-preview-spa` runs `npm run build` inside + `q2-preview-spa/`, which is `tsc -b && vite build`. Vite picks up + the WASM via an alias that resolves to + `hub-client/wasm-quarto-hub-client/wasm_quarto_hub_client_bg.wasm`. + If that file is stale, the SPA build will *successfully* bundle the + stale WASM. +- `hub-client/wasm-quarto-hub-client/wasm_quarto_hub_client_bg.wasm` + is the output of `npm run build:wasm` (a wrapper around + `wasm-pack build` + `wasm-bindgen`). It only refreshes when you + explicitly run that script. + +So there are three caches in series, and a Rust change in `quarto-core` +has to march through all three before it reaches the preview iframe. + +## The minimal command sequence + +```bash +cd hub-client && npm run build:wasm +cd .. +cargo xtask build-q2-preview-spa +cargo build --bin q2 +``` + +Then restart any running preview (`q2 preview` does not hot-reload its +embedded SPA on file change — the dist is baked in at compile time). + +## When `cargo xtask verify` does and doesn't help + +- `cargo xtask verify --skip-hub-build`: skips both the WASM rebuild + and the SPA rebuild. **The preview will be stale.** +- `cargo xtask verify` (no skip flags): runs `npm run build:all` in + `hub-client`, which rebuilds the WASM, and also runs + `cargo xtask build-q2-preview-spa`. After verify finishes you still + need `cargo build --bin q2` to re-embed the fresh dist before the + next `q2 preview` invocation sees the change. (Verify does not + rebuild the q2 binary as its final step.) + +## How to recognize stale-WASM symptoms + +If you've made a Rust change you expect to see in the preview and +don't, check this *first* before assuming the pipeline is buggy: + +1. Note the timestamp of + `hub-client/wasm-quarto-hub-client/wasm_quarto_hub_client_bg.wasm`. + If it predates your Rust edit, the WASM is stale. +2. Note the timestamp of + `q2-preview-spa/dist/assets/wasm_quarto_hub_client_bg-*.wasm` + (the hashed file). If it predates the file above, the SPA bundle + is stale. +3. Note the timestamp of `target/debug/q2`. If it predates the dist + file above, the binary is stale. + +The first stale link in this chain is your culprit. Run the +corresponding step in §"The minimal command sequence" and re-check. + +## Why the chain isn't automated + +Two structural reasons: + +1. **`cargo` doesn't see across the npm boundary.** The WASM artifact + lives in a directory that npm writes to and Vite reads from; cargo + has no idea that a change to `crates/quarto-core/src/transforms/x.rs` + should re-emit `hub-client/wasm-quarto-hub-client/*.wasm`. Wiring + this in via a build script is possible but would couple every + `cargo build` to a node-side build, which is expensive and noisy. +2. **The dev-server path doesn't have this problem.** When the + hub-client UI is being iterated on via `cd hub-client && npm run + dev`, Vite watches the WASM file and the hot-reload covers it. + `q2 preview` is the production-style boot — it intentionally + freezes the SPA at compile time so the binary is self-contained. + +The trade-off, then, is: a self-contained binary the user can run +without npm — at the cost of a manual rebuild chain when iterating on +the Rust→preview path. + +## Related + +- `crates/quarto-preview/build.rs` — the `include_dir!` build script + that wires `q2-preview-spa/dist/` into the embedded SPA. +- `crates/xtask/src/build_q2_preview_spa.rs` — the `cargo xtask` + command that runs Vite for the SPA. +- `hub-client/scripts/build-wasm.js` — the script `npm run build:wasm` + invokes. +- `q2-preview-spa/vite.config.ts` — the alias that pins the WASM path. +- bd-kw93 (q2 preview epic) — the broader feature this all supports. diff --git a/claude-notes/instructions/replay-engine.md b/claude-notes/instructions/replay-engine.md new file mode 100644 index 000000000..79911d61b --- /dev/null +++ b/claude-notes/instructions/replay-engine.md @@ -0,0 +1,149 @@ +# Replay Engine (bd-45yw) + +The replay engine reproduces a previously-recorded engine execution in +pure Rust. It exists to make engine-channel tests cheap to run (no R, +Python, or Jupyter required) and bug reports cheap to reproduce (a +trace file pinned to a single document). + +It is a debugging / QA tool — not a substitute for the real engines. + +## When to use it + +- **Regression tests** for engine-emitted features (resources, filters, + `ExecuteResult.includes`, etc.) that would otherwise require a real + engine install in CI. +- **Reproducing user bug reports** where the user can attach a trace + file produced by their failing render. You replay that trace + locally; the recorded engine output is byte-identical to what the + user saw. +- **Pinning a flaky engine result** for repeatable debugging. + +It is **not** intended for general use during normal renders. + +## Recording a trace + +Add `trace: true` to the document's metadata and run a normal render: + +```yaml +--- +title: My Document +trace: true +--- +``` + +```bash +q2 render path/to/doc.qmd +``` + +Quarto writes `path/to/.quarto/trace//latest.json`. When the +document declared a non-markdown engine that actually executed, the +trace's top-level `engine_capture` block carries the engine name, the +verbatim QMD that was passed to `engine.execute()`, and the full +`ExecuteResult` (markdown, supporting files, includes, filters, +post-process flag). + +The markdown engine is a no-op passthrough — `engine_capture` is +absent for documents that did not run a real engine. That is correct +behavior; replay against such a trace fails loudly rather than +silently degrading (see "Miss policy" below). + +## Replaying a trace + +```bash +q2 render path/to/doc.qmd --replay path/to/trace.json +``` + +Or via env var (useful in scripted CI): + +```bash +QUARTO_REPLAY=path/to/trace.json q2 render path/to/doc.qmd +``` + +The flag wins over the env var. Both surface the same +`load_replay_capture` path. + +The replay reads the trace, extracts `engine_capture`, builds an +`EngineRegistry` with `ReplayEngine` substituted under the recorded +engine's name, and hands it to `EngineExecutionStage` via +`HtmlRenderConfig.engine_registry`. Everything else in the pipeline +(parse, metadata-merge, transforms, render, template-apply) runs +against the real implementations. + +## Miss policy: hard fail, no fallback + +The replay engine compares the QMD `EngineExecutionStage` hands to +`execute()` against `engine_capture.input_qmd` byte-for-byte. On any +mismatch (one byte difference, different metadata, a renamed +heading), `execute()` returns +`ExecutionError::ExecutionFailed` with a "replay miss" diagnostic and +the byte counts of recorded vs. observed inputs. + +This is intentional. Quiet fallbacks on a debugging tool send +investigators on wild-goose chases — when replay fails, we make sure +they know. + +If the document genuinely changed since the trace was recorded, +re-record the trace. + +## Source-info caveat + +Replay does **not** restore the original engine's source provenance +for engine-emitted content. Diagnostics that map source positions +into engine output (e.g. Jupyter cell line numbers in error messages, +knitr line attribution into `_files/` figures) will not match between +a real engine run and its replay. + +This is a documented v1 limitation. If a use case for source-info +parity surfaces, the trace already carries the recorded `SourceInfo` +on engine-emitted blocks; restoring it requires plumbing during +replay, not a format change. + +## Authoring regression-test fixtures + +For checked-in CI fixtures that exercise engine-channel behavior: + +1. On a development machine with R/Python/Jupyter installed, render + the fixture once with `trace: true`. +2. Copy the produced `latest.json` into the test fixture tree (e.g. + `crates//tests/fixtures//`). +3. In your test, use `RenderToFileOptions.replay_capture` (set from + `quarto_trace::read::read_trace(...).engine_capture`) and assert + on the rendered output. + +For an example, see +`crates/quarto-core/tests/project_resources.rs::orchestrator_engine_channel::orchestrator_drains_replay_engine_report_to_output_dir`, +which uses the probe-then-replay technique to fabricate a capture +without needing R/Python at test-write time. + +## Trace size + +Recorded traces can be large because they capture the full pipeline +state (per-stage data + the engine capture). On-disk size optimization +is bd-5qnj's concern; the in-memory representation stays as-is. + +For checked-in fixtures, prefer the smallest possible reproducer +(small QMD, minimal supporting files). For user-attached bug reports, +size is whatever the user's failing render produced; we accept the +cost in exchange for byte-faithful reproduction. + +## Activation surfaces summary + +| Surface | Effect | +|---------|--------| +| `trace: true` in metadata | Records `engine_capture` into the trace. | +| `q2 render --replay ` | Replays the trace's `engine_capture`. | +| `QUARTO_REPLAY=` | Same as `--replay` (CLI flag wins). | +| `RenderToFileOptions.replay_capture` | Library-level activation. | +| `RenderToFileOptions.engine_registry_override` | Test escape hatch (takes precedence over `replay_capture`). | + +## Code references + +- `crates/quarto-trace/src/lib.rs` — `EngineCapture`, `TraceDocument.engine_capture` +- `crates/quarto-core/src/engine/replay.rs` — `ReplayEngine` +- `crates/quarto-core/src/engine/registry.rs` — `EngineRegistry::with_replay` +- `crates/quarto-core/src/stage/stages/engine_execution.rs` — `ENGINE_CAPTURE_KIND` and the recording emit +- `crates/quarto-core/src/stage/trace.rs` — `JsonTraceObserver::on_auxiliary_data` routing +- `crates/quarto-core/src/render_to_file.rs` — `RenderToFileOptions.replay_capture` and `engine_registry_override` +- `crates/quarto/src/commands/render.rs` — `--replay` / `QUARTO_REPLAY` plumbing + +Plan: `claude-notes/plans/2026-05-03-replay-engine.md`. diff --git a/claude-notes/instructions/testing.md b/claude-notes/instructions/testing.md index 3e9b8b3e2..2cd33b859 100644 --- a/claude-notes/instructions/testing.md +++ b/claude-notes/instructions/testing.md @@ -1,3 +1,4 @@ +- **Engine-channel tests** that need to exercise jupyter / knitr / a custom Jupyter kernel without requiring those runtimes: use the **replay engine** (bd-45yw). Record a trace once with `trace: true` on a development machine, check it in, and replay it via `RenderToFileOptions.replay_capture`. See `claude-notes/instructions/replay-engine.md`. - **CRITICAL - TEST FIRST**: When fixing bugs using tests, you MUST run the failing test BEFORE implementing any fix. This is non-negotiable. Verify the test fails in the expected way, then implement the fix, then verify the test passes. - Always strive for minimal test documents as small as possible. Create many small test documents instead of a few large test documents. - You are encouraged to spend time and tokens on thinking about good tests. @@ -170,4 +171,80 @@ npx playwright test smoke-all --grep kbd To render a fixture directly and inspect its output: ```bash cargo run --bin q2 -- render crates/quarto/tests/smoke-all/path/to/doc.qmd -v -``` \ No newline at end of file +``` + +## Pipeline traces (`quarto-trace`) + +Setting `trace: true` in a document's metadata enables the +`JsonTraceObserver`, which writes a typed snapshot of every pipeline +stage to `.quarto/trace//latest.json.gz`. Traces are useful as +regression-test fixtures (small enough to check in and load offline) +and as user-attached bug-report artifacts. See +`claude-notes/plans/2026-05-03-trace-size-for-replay.md` (bd-5qnj) for +the design and budget rationale. + +### On-disk format + +- **Compressed compact JSON** at `.quarto/trace//latest.json.gz`. + Pretty-print accounted for ~80% of bytes on real traces; gzip on top + collapses what's left. +- **Schema version 2** with content-addressed AST dedup: every unique + AST is stored once in a top-level `asts` map, and pipeline entries + refer to it via `{ "$ref": "" }` sentinels. The reader + rehydrates these into inline AST values, so consumers see a v1-shaped + in-memory `TraceDocument`. Hand-written v1 traces (no `asts`, no + `$ref`) still parse via the rehydration no-op path. +- See `crates/quarto-trace/src/lib.rs` for the schema struct and + `claude-notes/plans/5qnj-trace-size-investigation/measurements.md` + for size measurements on real fixtures. + +### Inspecting a trace + +```bash +# List traces under ./.quarto/trace/ +q2 trace list + +# Show the full trace for a doc, pretty-printed (rehydrated AST refs) +q2 trace show --doc + +# Show one stage's entry only +q2 trace show --doc --stage parse + +# Open the trace-viewer SPA (auto-binds a free port, prints URL) +q2 trace view + +# Raw on-disk bytes (compact gzipped JSON; use jq after gunzip) +gunzip -c .quarto/trace//latest.json.gz | jq '.schema_version, (.asts | length)' +``` + +### Writing tests against a trace fixture + +When writing a regression test that consumes a trace, prefer +`quarto_trace::read::read_trace` over hand-parsing JSON — it handles +both v1 and v2 inputs uniformly, and rehydrates `$ref` sentinels. For +hand-authored fixtures, write valid v1 JSON (no `asts` map, inline +ASTs); the reader accepts them. + +```rust +use quarto_trace::read::read_trace; + +let doc = read_trace(&fixture_path).expect("parse trace"); +assert_eq!(doc.pipeline.len(), expected); +// `data.ast` (or bare `data` for transform: entries) is fully inlined +// regardless of on-disk format. +``` + +### Size budgets + +Provisional ceilings, not hard targets: + +- **Checked-in CI fixture**: ≤ 100 KB (compressed). Keeps `.git/` + manageable as fixtures accumulate. +- **User-attached bug-report artifact**: ≤ 1 MB (compressed). Fits a + GitHub issue attachment without effort. + +A 6.1 KB qmd fixture currently produces a 62 KB compressed trace — +well within both budgets. If you find a fixture exceeding the CI +budget, capture the measurement and file an issue rather than checking +in the oversize artifact; the dedup pass may need extension (e.g. for +new stage types that emit large non-AST payloads). \ No newline at end of file diff --git a/claude-notes/issue-reports/152/exp-mixed.qmd b/claude-notes/issue-reports/152/exp-mixed.qmd new file mode 100644 index 000000000..a9fe1bcfe --- /dev/null +++ b/claude-notes/issue-reports/152/exp-mixed.qmd @@ -0,0 +1,5 @@ +| Col 1 | Col 2 | +|-------|-------| +| A | B | + +: Table caption {#tbl-mytable .special tbl-colwidths="[30,70]"} diff --git a/claude-notes/issue-reports/152/exp-prefix.qmd b/claude-notes/issue-reports/152/exp-prefix.qmd new file mode 100644 index 000000000..27bec81a9 --- /dev/null +++ b/claude-notes/issue-reports/152/exp-prefix.qmd @@ -0,0 +1,6 @@ +{tbl-colwidths="[30,70]"} +| A | B | +|---|---| +| 1 | 2 | + +: ABCD diff --git a/claude-notes/issue-reports/152/exp-suffix.qmd b/claude-notes/issue-reports/152/exp-suffix.qmd new file mode 100644 index 000000000..568c6a399 --- /dev/null +++ b/claude-notes/issue-reports/152/exp-suffix.qmd @@ -0,0 +1,5 @@ +| A | B | +|---|---| +| 1 | 2 | + +: ABCD {tbl-colwidths="[30,70]"} diff --git a/claude-notes/issue-reports/152/q236-repro-variants.qmd b/claude-notes/issue-reports/152/q236-repro-variants.qmd new file mode 100644 index 000000000..38dab44bc --- /dev/null +++ b/claude-notes/issue-reports/152/q236-repro-variants.qmd @@ -0,0 +1,58 @@ +# Q-2-36 cases: knitr-style headers (rejected) vs. Pandoc-style headers (accepted) + +Sections (1)–(7) are knitr-style chunk headers — `{lang ...}` with no +leading `.` on the language — that should fire Q-2-36. Section (8) is +the Pandoc-style class form `{.lang ...}` that must stay valid; included +as a negative control so the discrimination is exercised in fixtures. + +The block body is the same `1+1` everywhere so any non-header error is +easy to spot. + +## (1) Bare label (reporter's case) + +```{r test} +1+1 +``` + +## (2) Space + key=value (single arg, R) + +```{r echo=FALSE} +1+1 +``` + +## (3) Space + key=value (quoted, R) + +```{r label="foo"} +1+1 +``` + +## (4) Comma + space + key=value (canonical knitr, R) + +```{r, label="foo", echo=FALSE} +1+1 +``` + +## (5) Space + key=value (Python) + +```{python echo=FALSE} +1+1 +``` + +## (6) Space + key=value (Julia) + +```{julia label="foo"} +1+1 +``` + +## (7) Mixed: old header + new #| option (per scope decision, must still error) + +```{r echo=FALSE} +#| label: mixed +1+1 +``` + +## (8) Pandoc class form — MUST stay valid (negative control) + +```{.r echo=FALSE} +1+1 +``` diff --git a/claude-notes/issue-reports/152/q236-repro.qmd b/claude-notes/issue-reports/152/q236-repro.qmd new file mode 100644 index 000000000..adc47412e --- /dev/null +++ b/claude-notes/issue-reports/152/q236-repro.qmd @@ -0,0 +1,7 @@ +The reporter's exact case from issue #152 (2026-05-04 comment) — a +chunk header with a bare label, which old knitr accepts but Quarto 2 +does not. + +```{r test} +1+1 +``` diff --git a/claude-notes/issue-reports/152/q236-triage.md b/claude-notes/issue-reports/152/q236-triage.md new file mode 100644 index 000000000..0bd0e90b1 --- /dev/null +++ b/claude-notes/issue-reports/152/q236-triage.md @@ -0,0 +1,144 @@ +# Triage: issue #152 (chunk-options half) — old-style knitr chunk options + +- **GitHub:** https://github.com/quarto-dev/q2/issues/152 +- **Reporter:** @rundel (Colin Rundel), 2026-05-03 (first half closed via PR #154; this triage covers the second half flagged in the 2026-05-04 comment) +- **Triage date:** 2026-05-14 +- **Worktree:** `.worktrees/issue-152` (branch `issue-152`, based on `bugfix/issue-184` @ `e2d224f6`) +- **Beads issue:** bd-XXXX (filed alongside this triage; see Outcome) +- **Scope:** the *chunk-options* half of issue #152. The earlier table-captions half lives in `triage.md` / `repro.qmd` / `exp-*.qmd` in this directory (closed via #154). All Q-2-36 fixtures and docs use a `q236-` prefix to keep the two record-sets visually distinct. + +## Summary + +Old-style knitr chunk headers (`{r echo=FALSE}`, `{r test}`, `{r, label="foo"}`, etc.) need to fire a clean Q-2-36 parse error directing users to the `#| key: value` body syntax. Crucially, the **Pandoc class form** `{.r echo=FALSE}` (leading `.` on the language) **stays valid** — it is the supported Quarto 2 spelling. + +Reproduced all three behavioral classes at HEAD; the work crosses the **existing Q-2-8 warning site** in `crates/pampa/src/pandoc/treesitter.rs` and the **Merr error table** in `crates/pampa/resources/error-corpus/`. **No scanner change is required**, contrary to the Q-2-35 template originally suggested as the model. See *Approach* below. + +## Reproduction at HEAD (`bugfix/issue-184` @ `e2d224f6`) + +All inputs share the same body (`1+1`) so any visible error is header-shaped. Fixtures: `q236-repro.qmd` (the reporter's exact case) and `q236-repro-variants.qmd` (all seven knitr forms + one Pandoc-form negative control). + +Three distinct behaviors observed today: + +### (A) Forms that already parse, with a Q-2-8 *warning* + +``` +$ printf '%s\n' '```{r echo=FALSE}' '1+1' '```' | cargo run --bin pampa -- +Warning: [Q-2-8] Code block options in header + ╭─[ :1:1 ] + 1 │ ╭─▶ ```{r echo=FALSE} + ... +[ CodeBlock ( "" , ["{r}"] , [("echo", "FALSE")] ) "1+1" ] +``` + +Same with `{r label="foo"}`, `{python echo=FALSE}`, `{julia label="foo"}`. The grammar (`grammar.js:459-490`) **explicitly accepts** these via the `language_specifier → _language_specifier_token + _commonmark_specifier_start_with_kv` rule. The class becomes the literal `"{r}"` (braces kept) and the kv pairs land in the attribute list. The warning is emitted in `crates/pampa/src/pandoc/treesitter.rs:1121-1144`, gated on `classes[0].starts_with('{') && classes[0].ends_with('}')` and `!attrs.is_empty()`. + +### (B) Forms that already produce a parse error (generic message) + +``` +$ printf '%s\n' '```{r test}' '1+1' '```' | cargo run --bin pampa -- +Error: Parse error + 1 │ ```{r test} + │ ──┬── + │ ╰──── unexpected character or token here +``` + +Same with `{r, label="foo", echo=FALSE}` (comma form). The grammar has no rule for "language token followed by a bare identifier" or "language token followed by comma," so tree-sitter raises a parse error at the first offending token. The `(state, sym)` pair is in the Merr table but unmapped, so the user sees the generic fallback message. + +### (C) Pandoc class form — **passes cleanly, must stay valid** + +``` +$ printf '%s\n' '```{.r echo=FALSE}' '1+1' '```' | cargo run --bin pampa -- +[ CodeBlock ( "" , ["r"] , [("echo", "FALSE")] ) "1+1" ] +``` + +No warning, no error. Class is `"r"` (no braces) because it came from the CommonMark class form `.r`, not the language-token form `r`. This is the supported Pandoc spelling in Quarto 2; the existing Q-2-8 gate already excludes it because `classes[0]` doesn't start with `{`. + +## Localization + +| Site | File / line | What it does | +| --- | --- | --- | +| Existing Q-2-8 warning emission | `crates/pampa/src/pandoc/treesitter.rs:1121-1144` | Detects `{lang ...}` with kv attrs, emits warning. **The single most important site for this fix** — upgrade message + level. | +| Existing Q-2-8 test | `crates/pampa/tests/test_warnings.rs:498-563` | Asserts `{r eval=FALSE}` produces a `Q-2-8` warning. Will need to flip to expect Q-2-36 error. The companion `test_code_block_with_class_no_warning` (`{python .marimo}`) stays as-is — it's the negative control for the discrimination. | +| Grammar rules that accept knitr-style | `crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js:459-490` | `language_specifier` accepts `_language_specifier_token` + optional commonmark kv block. **Not changed** under Approach 1 — we keep the parse path so we have a structural location for the diagnostic. | +| Merr error table — existing entries | `crates/pampa/resources/error-corpus/Q-*.json` (esp. `Q-2-32.json`, `Q-2-35.json`) | Template for adding `Q-2-36.json` with the bare-label and comma-form cases. | +| Build script for the Merr table | `crates/pampa/scripts/build_error_table.ts` | Runs the parser against each case file, captures `(state, sym)`, writes `_autogen-table.json`. Must be re-run after editing `Q-2-36.json`. | +| Source-info helper for whole-line highlight | `crates/pampa/src/readers/qmd_error_messages.rs::widen_diagnostic_to_line` | For the Merr-mapped error forms (B), widens the highlight from the offending token to the whole header line, per the scope decision. The treesitter.rs warning currently spans the whole code block — for case (A) we may need to clip it to *just the header line* (line 1 of the code block) so the highlight matches the scope of the offence. | + +## Approach (confirmed with user, 2026-05-14) + +**Approach 1: upgrade Q-2-8 warning → Q-2-36 error, plus Merr-map the parse-error forms.** No scanner.c change, no grammar.js change. Q-2-36 is structurally unlike Q-2-35 (and the rejected Q-2-32 / TRIPLE_STAR template) because nothing is being *silently consumed* — half the bad forms already error out, the other half already produce a warning at a structural site. + +### Plan-of-record (TDD shape, to be expanded in the plan doc) + +1. **Phase 0 – test scaffolding** + - Move the `test_code_block_with_header_options_produces_warning` assertion logic into a new error-expectation form (asserts Q-2-36 *error*, not Q-2-8 warning). Keep `test_code_block_with_class_no_warning` (the `{.python .marimo}` case) as the negative control. + - Add `Q-2-36.json` to the error corpus with at least these cases: + - `bare-label` — `{r test}` + - `comma-args` — `{r, echo=FALSE}` + - `comma-and-kv` — `{r, label="foo", echo=FALSE}` + - (the space-kv form is the one upgraded inline, but we may add a Merr case anyway for documentation symmetry) + - Run `crates/pampa/scripts/build_error_table.ts` to regenerate `_autogen-table.json`. Confirm tests fail with the expected "no entry" or wrong-code messages. + +2. **Phase 1 – upgrade Q-2-8 site to Q-2-36 error** + - In `treesitter.rs:1121-1144`, replace `DiagnosticMessageBuilder::warning(...)` with `error(...)`, code `"Q-2-36"`, message+hints pointing at `#| key: value`. Clip the highlight to just the header line. + - Run the updated warning tests; they should now expect (and find) a Q-2-36 error. + +3. **Phase 2 – wire up Merr for (B)** + - With `Q-2-36.json` in place and the table regenerated, the bare-label and comma-form parse errors should pick up the Q-2-36 mapping automatically. If not, add the `(state, sym)` entries by hand following the Q-2-32 pattern. + - Apply `widen_diagnostic_to_line` (or a sibling helper) so the highlight covers the full header line, per scope. + +4. **Phase 3 – end-to-end verification** + - Run `cargo run --bin pampa -- claude-notes/issue-reports/152/q236-repro.qmd` and confirm the reporter's case produces a clean Q-2-36 error. + - Run the variants fixture; cases (1)–(7) error, case (8) parses cleanly. + - `cargo nextest run --workspace`, `cargo xtask verify` (full, including hub-build, since pampa is a WASM-dep crate). + +### Why **not** scanner emit (notes for plan-doc author) + +Scanner-emit would either (a) be redundant with the existing grammar acceptance (we'd emit a token but the grammar would also produce a valid parse — confusing), or (b) require deleting `_commonmark_specifier_start_with_kv` from `language_specifier`, which changes the Merr `(state, sym)` table for *other* error codes and rebuilds the parser. The user explicitly approved "be willing to backtrack if grammar changes become unwieldy"; this is exactly the kind of unwieldy that earns us nothing. + +## Scope decisions (confirmed with @cscheid) + +1. **Discrimination:** `{r ...}` (no leading dot on the language) → Q-2-36 error. `{.r ...}` (Pandoc class form) → unchanged, valid. The existing Q-2-8 gate already implements this discrimination by checking for literal `{...}` braces in `classes[0]`. +2. **Forms flagged:** comprehensive — space+kv, comma+kv, bare label, any engine (R / Python / Julia / others). User's framing: *"be willing to backtrack if the grammar changes become unwieldy. This is, in the end, meant as a kindness to the users."* Approach 1 needs no grammar changes, so the comprehensive scope is cheap to implement. +3. **Engine scope:** any engine (R, Python, Julia, etc.). Approach 1 inherits this for free because the Q-2-8 gate already keys on the braces, not the engine name. +4. **Mixed-mode (`{r echo=FALSE}` with `#| label: ...` in body):** always error on the header; ignore the body. The Q-2-8 gate already fires regardless of body content, so this is automatic. +5. **Highlight span:** whole chunk header line. For the upgraded Q-2-8 site, clip `cb.source_info` to line 1 (currently it spans the entire code block). For the Merr-mapped forms, apply `widen_diagnostic_to_line`. + +## Open questions resolved during triage + +| Question | Resolution | +| --- | --- | +| Which forms should fire Q-2-36? | All knitr-style headers: comma+kv, space+kv, bare label, any engine. Pandoc class form (`.lang`) stays valid. | +| Engine scope? | Any engine. | +| Mixed-mode behavior? | Always error if header is knitr-style. | +| Highlight span? | Whole header line. | +| **Scanner-emit or no?** | **No scanner-emit.** Grammar already accepts the warning forms structurally; upgrading the existing Q-2-8 site is the surgical fix. Bare-label and comma-form parse errors get Merr mappings. (User confirmed Approach 1, 2026-05-14.) | + +## Outcome / recommended next step + +- File beads `bd-XXXX` ("Q-2-36: clean parse error for knitr-style chunk options (issue #152)") with the plan-of-record above and a pointer to this triage doc. +- Write the implementation plan at `claude-notes/plans/2026-05-14-q-2-36-knitr-style-chunk-options.md` with the four TDD phases expanded. +- Commit this triage doc + fixtures on branch `issue-152`. +- *Discovered incidental work* (filed separately): `cargo xtask create-worktree --issue 152 --base bugfix/issue-184` printed `Branch: issue-152` but actually checked out `bugfix/issue-184` directly in the worktree (no `issue-152` branch was created — `git reflog` confirms). Recovered in-place via `git checkout -b issue-152`. File a beads issue so the xtask is fixed before the next person hits the same surprise. + +## Verification commands used + +```bash +gh issue view 152 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments +cargo xtask verify --skip-hub-build --skip-hub-tests # green at e2d224f6 +cargo run --bin pampa -- claude-notes/issue-reports/152/q236-repro.qmd +cargo run --bin pampa -- claude-notes/issue-reports/152/q236-repro-variants.qmd +# Spot checks of individual variants and the .r negative control +printf '%s\n' '```{.r echo=FALSE}' '1+1' '```' | cargo run --bin pampa -- +printf '%s\n' '```{r echo=FALSE}' '1+1' '```' | cargo run --bin pampa -- +printf '%s\n' '```{r test}' '1+1' '```' | cargo run --bin pampa -- +printf '%s\n' '```{r, label="foo", echo=FALSE}' '1+1' '```' | cargo run --bin pampa -- +cargo run --bin pampa -- -v /tmp/q236-bare.qmd 2>&1 | head -40 +``` + +## Cross-references + +- bd-7l1u — Q-2-35 (issue #184). Cited as template by the user; in practice Q-2-36 diverges (see *Approach*). Still the right reference for error-corpus mechanics, Merr `(state, sym)` mapping, and `widen_diagnostic_to_line` usage. +- bd-f3pl — Q-2-152-tables (closed via #154). The first half of issue #152. +- `crates/pampa/CLAUDE.md` — error-corpus authoring conventions. +- `crates/tree-sitter-qmd/tree-sitter-markdown/CONTRIBUTING.md` — Known Limitations entries (precedent: Q-2-32 / Q-2-35). diff --git a/claude-notes/issue-reports/152/repro.qmd b/claude-notes/issue-reports/152/repro.qmd new file mode 100644 index 000000000..568c6a399 --- /dev/null +++ b/claude-notes/issue-reports/152/repro.qmd @@ -0,0 +1,5 @@ +| A | B | +|---|---| +| 1 | 2 | + +: ABCD {tbl-colwidths="[30,70]"} diff --git a/claude-notes/issue-reports/152/triage.md b/claude-notes/issue-reports/152/triage.md new file mode 100644 index 000000000..a712a0857 --- /dev/null +++ b/claude-notes/issue-reports/152/triage.md @@ -0,0 +1,139 @@ +# Issue #152 — Table caption attributes are dropped by qmd writer + +- **GitHub**: https://github.com/quarto-dev/q2/issues/152 +- **Reporter**: @rundel (Colin Rundel), 2026-05-03 +- **Triage date**: 2026-05-03 +- **Worktree**: `.worktrees/issue-152` (branch `issue-152`, based on `main` @ `132c13c8`) +- **Beads issue**: bd-f3pl ("qmd writer drops table caption attributes (issue #152)", priority 1, bug) +- **Scope**: this report covers only the **second** issue in #152 ("Table caption attributes are not written"). The first issue (old-style code-block options being mangled in qmd output) is being deprecated upstream and is intentionally not addressed here. + +## Summary + +When a table caption carries a Quarto attribute block (`: caption {tbl-colwidths="[30,70]"}`), the parser correctly attaches the attribute to the `Table` node, but the **pipe-table branch** of the qmd writer drops it on output. The list-table branch already handles this correctly. Round-tripping is therefore lossy for any pipe-formatted table that has attributes. + +## Reproduction + +Fixture: `claude-notes/issue-reports/152/repro.qmd` + +``` +| A | B | +|---|---| +| 1 | 2 | + +: ABCD {tbl-colwidths="[30,70]"} +``` + +### Native AST output (parser is fine) + +``` +$ cargo run --bin pampa -- < claude-notes/issue-reports/152/repro.qmd +[ Table ( "" , [] , [("tbl-colwidths", "[30,70]")] ) + (Caption Nothing [ Plain [Str "ABCD"] ]) + ... ] +``` + +`Table.attr.2` (the keyvals slot) correctly contains `("tbl-colwidths", "[30,70]")`. The desugaring contract documented in `docs/syntax/desugaring/table-captions.qmd` is honored by the reader path. + +### Round-tripped qmd output (writer drops the attr) + +``` +$ cargo run --bin pampa -- -t qmd < claude-notes/issue-reports/152/repro.qmd +| A | B | +| --- | --- | +| 1 | 2 | + +: ABCD ← attribute block missing +``` + +Expected output: + +``` +| A | B | +| --- | --- | +| 1 | 2 | + +: ABCD {tbl-colwidths="[30,70]"} +``` + +## Localization + +**File**: `crates/pampa/src/writers/qmd.rs` + +There are two table-writer code paths: + +| Branch | Function | Lines | Handles `table.attr`? | +|--------|----------|-------|------------------------| +| pipe table | `write_table` | 1120–1239 | **No** — `table.attr` is never read; only the caption's inline content is emitted at lines 1217–1235. | +| list-table sugar | `write_list_table` | 928–1118 | **Yes** — id at lines 983–987, classes at 935, keyvals at 977–980 (copied into the div attribute block). | + +The bug therefore lives in the pipe-table branch: it writes `:
\n` (lines 1228–1234) but never emits the table's id/classes/keyvals. + +The companion JSON parser snapshot at `crates/pampa/tests/snapshots/json/table-caption-attr.qmd` exercises exactly this fixture for the read path, but there is no corresponding round-trip test in `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/`. Adding that fixture (and any related ones) is part of the fix. + +## Surface syntax + +Per `docs/syntax/desugaring/table-captions.qmd`, table-caption attributes are extracted from the caption inline content during postprocessing and merged into `Table.attr` (id, classes, keyvals). The writer must reverse this: when emitting the caption line, append `{}` if `Table.attr` is non-empty. + +The existing `write_attr` helper in `qmd.rs` (line 396) already handles the formatting for inline attribute blocks, so no new formatting machinery is needed — only a call site at the end of the pipe-table caption. + +## Suggested fix scope + +1. **Test first** (per `crates/pampa/CLAUDE.md`): add a failing round-trip fixture under `tests/roundtrip_tests/qmd-json-qmd/`. Candidate files (split per CLAUDE.md "many small fixtures" guidance): + - `table-caption-with-keyval.qmd` — `: cap {tbl-colwidths="[30,70]"}` + - `table-caption-with-id.qmd` — `: cap {#tbl-foo}` + - `table-caption-with-classes.qmd` — `: cap {.striped .hover}` + - `table-caption-with-mixed-attrs.qmd` — id + classes + keyvals together (mirrors the docs example) +2. Confirm each new fixture **fails** the round-trip equality check before any code change. +3. In `write_table` (pipe-table branch, around lines 1228–1234), after the caption text is written but before the trailing newline, emit ` {...}` via `write_attr(&table.attr, buf, ctx)?` if `!is_empty_attr(&table.attr)`. The exact placement (` {…}\n` vs. `\n: caption {…}\n`) should match what the parser accepts and what `table-caption-attr.qmd`'s native AST round-trips to. +4. Run the new fixtures and the full pampa suite. Confirm no existing snapshots regress (`table-caption.qmd` should be unchanged because that fixture has empty `Table.attr`). +5. Run `cargo xtask verify --skip-hub-build` (Rust-only change in pampa, no quarto-core/pandoc-types touched, so the WASM leg is not affected). + +Estimated diff size: < 20 lines in `qmd.rs`, plus 4 small fixtures and their `.snap` files. + +## Open questions — resolved during triage + +### 1. Empty-id auto-suppression — **NOT NEEDED** + +Resolved by reading `crates/pampa/src/pandoc/treesitter_utils/pipe_table.rs:148–200`. The only path that writes to `Table.attr.0` is the `Inline::Attr` extraction at lines 191–195, which fires only when the user explicitly authored `{#id ...}` in the caption attribute block. There is no equivalent of figures' implicit-`fig-` numbering for tables. The reader does record `attr_source` (line 149), so if implicit `tbl-foo` numbering is ever introduced, the writer can adopt the same `attr_source.id.is_none()` guard headers use (`qmd.rs:557–561`). For this fix, no guard is required — emit `Table.attr.0` unconditionally when non-empty. + +### 2. Table-attr-prefix vs. caption-suffix — **suffix is the only valid form** + +Tested both shapes against pandoc 3.9.0.2 and pampa at `issue-152` HEAD. + +| Fixture | Form | Pandoc native AST | Pampa native AST | +|---------|------|--------------------|------------------| +| `exp-prefix.qmd` | `{attrs}\n` line, then table, then `: caption` | **Not a table.** One `Para` containing literal `Str "{tbl-colwidths="`, `Quoted`, `Str "}"`, `SoftBreak`, then the pipe rows as `Str "|"`/`Space`/`Str "A"`/etc. The caption becomes a separate `Para [Str ":", Space, Str "ABCD"]`. | **Not a table.** Emits `Q-0-99` ("Caption found without a preceding table") and `Q-3-32` ("Standalone attributes not supported"). | +| `exp-suffix.qmd` | table, then `: caption {attrs}` | Proper `Table` with `attr = ("", [], [("tbl-colwidths", "[30,70]")])`. | Identical: `Table ( "" , [] , [("tbl-colwidths", "[30,70]")] ) ...`. | +| `exp-mixed.qmd` | suffix form with id + classes + keyvals (the docs example) | `Table ( "tbl-mytable" , ["special"] , [("tbl-colwidths", "[30,70]")] ) ...` | Byte-identical attr triple; same caption inlines. | + +Both engines treat caption-suffix as the **only** way to attach attrs to a pipe table. The prefix form is a parser-level non-starter, not a valid alternative we'd ever want to emit. The writer fix is therefore unambiguous: append `{...}` to the caption line. (The list-table branch's div-attr placement is unrelated — that's the sugared form, which has its own surface syntax and is not a writer choice for pipe tables.) + +Fixture files retained under `claude-notes/issue-reports/152/exp-{prefix,suffix,mixed}.qmd` for the record. + +### 3. Comment in `write_table` at line 575 — **orthogonal, no action** + +Confirmed: the `// FIXME` comment lives inside `write_cell_content` (the helper at line 575), not the caption-emission code we'll touch. The newline-in-pipe-cells limitation it warns about is a real bug but unrelated to this round-trip fix. + +## Verification commands used during triage + +```bash +# Worktree bootstrap +git worktree add -b issue-152 .worktrees/issue-152 main +echo "../../../.beads" > .worktrees/issue-152/.beads/redirect +cd .worktrees/issue-152 +npm install # required on fresh worktrees; see bd-7giz +cargo xtask verify # all 9 steps green at HEAD before any change + +# Reproduction (from worktree root) +cargo run --bin pampa -- -t qmd < claude-notes/issue-reports/152/repro.qmd +cargo run --bin pampa -- < claude-notes/issue-reports/152/repro.qmd # native AST +``` + +Both confirmed at branch `issue-152` HEAD `132c13c8`. + +## Cross-references + +- bd-7giz — `cargo xtask setup` for fresh-worktree bootstrap (discovered while preparing this triage). +- `docs/syntax/desugaring/table-captions.qmd` — defines the read-side desugaring contract this writer should reverse. +- `crates/pampa/tests/snapshots/json/table-caption-attr.qmd` — existing parser-side snapshot covering this fixture. +- `crates/pampa/CLAUDE.md` — TDD workflow for round-trip bug fixes (`tests/roundtrip_tests/qmd-json-qmd`). diff --git a/claude-notes/issue-reports/161/repro.qmd b/claude-notes/issue-reports/161/repro.qmd new file mode 100644 index 000000000..2c17f4bf2 --- /dev/null +++ b/claude-notes/issue-reports/161/repro.qmd @@ -0,0 +1,3 @@ +::: {data-foo="\[1,2\]"} +hello +::: diff --git a/claude-notes/issue-reports/161/round-trip-1.qmd b/claude-notes/issue-reports/161/round-trip-1.qmd new file mode 100644 index 000000000..78d937716 --- /dev/null +++ b/claude-notes/issue-reports/161/round-trip-1.qmd @@ -0,0 +1,5 @@ +::: {data-foo="\\[1,2\\]"} + +hello + +::: diff --git a/claude-notes/issue-reports/161/triage.md b/claude-notes/issue-reports/161/triage.md new file mode 100644 index 000000000..cf2dfba04 --- /dev/null +++ b/claude-notes/issue-reports/161/triage.md @@ -0,0 +1,135 @@ +# Issue #161 — qmd writer doubles backslashes in attribute values + +- **Reporter:** @rundel (Colin Rundel) +- **Filed:** 2026-05-06 +- **GH URL:** https://github.com/quarto-dev/q2/issues/161 +- **Triage branch:** `issue-161` at `.worktrees/issue-161/` +- **HEAD at triage:** rebased onto `eefff6e1` (post-#163, the #160 fix). Bug re-verified at this HEAD; the #160 fix did not touch the same code path. + +## Summary + +Round-tripping a div with backslash-escaped characters in an attribute +value is **not stable**: each round trip *doubles* the backslashes. + +``` +input: ::: {data-foo="\[1,2\]"} +after qmd→native: data-foo = "\[1,2\]" (correct: backslashes preserved) +after native→qmd: ::: {data-foo="\\[1,2\\]"} (writer: doubled) +after second qmd→native: data-foo = "\\[1,2\\]" (reader: literal two backslashes) +``` + +User-visible impact: any qmd file containing `tbl-colwidths="\[N,N\]"` +(used widely in `quarto-web`) accumulates an extra backslash per round +trip. Reporter linked four occurrences in the docs site. + +## Reproduced at HEAD + +Repro file: `repro.qmd` (35 bytes, exact bytes from the issue). +Round-trip output: `round-trip-1.qmd`. Both committed alongside this +doc. + +```bash +$ cargo run --bin pampa -- claude-notes/issue-reports/161/repro.qmd +[ Div ( "" , [] , [("data-foo", "\\[1,2\\]")] ) [Para [Str "hello"]] ] + +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/161/repro.qmd +::: {data-foo="\\[1,2\\]"} +hello +::: + +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/161/repro.qmd \ + | cargo run --bin pampa -- +[ Div ( "" , [] , [("data-foo", "\\\\[1,2\\\\]")] ) [Para [Str "hello"]] ] +``` + +Bug reproduces exactly as reported. + +## Comparison against Pandoc + +Pandoc treats backslash inside a double-quoted attribute value as a +generic escape: `\X` → `X` for any `X`. + +```bash +$ printf -- '::: {data-foo="\\[1,2\\]"}\nhello\n:::\n' | pandoc -f markdown -t native +... ( "" , [] , [ ( "data-foo" , "[1,2]" ) ] ) ... + +$ printf -- '::: {data-baz="a\\\\b"}\nhi\n:::\n' | pandoc -f markdown -t markdown +::: {data-baz="a\\b"} # one literal backslash → \\ on write + +$ printf -- '::: {data-q="a\\"b"}\nhi\n:::\n' | pandoc -f markdown -t markdown +::: {data-q="a\"b"} # one literal quote → \" on write +``` + +So Pandoc's contract is: +- **read:** `\X` (any `X`) is a backslash escape; emit `X` only. +- **write:** the only characters that need escaping inside a `"..."` + attribute value are `\` itself and `"`; both are escaped with a + leading `\`. Brackets are *not* escaped. + +## Where the bug is in our code + +The asymmetry is on the **reader** side, not the writer. + +- **Writer (correct, matches Pandoc):** + `crates/pampa/src/writers/qmd.rs:392-394` — + ```rust + fn escape_quotes(s: &str) -> String { + s.replace('\\', "\\\\").replace('"', "\\\"") + } + ``` + This emits `\` as `\\` and `"` as `\"`, matching Pandoc's writer. + +- **Reader (incomplete, does not match Pandoc):** + `crates/pampa/src/pandoc/treesitter_utils/text_helpers.rs:25-37` — + `extract_quoted_text` un-escapes only `\"` (in `"..."`) or `\'` (in + `'...'`). It does not un-escape `\\`, and it does not un-escape any + other `\X` (e.g. `\[`, `\]`). So a written `\\` survives as two + backslashes on the next read, and a user-typed `\[` survives as `\[` + rather than collapsing to `[`. + +`extract_quoted_text` is also used at `treesitter.rs:980` for link +titles (`"..."` after a URL), so any fix needs to reason about whether +the same escaping rules apply there. Pandoc's CommonMark reader does +treat `\X` as escapes inside link titles, so the same fix likely +applies, but link-title round-tripping is **out of scope for this +triage** — confirm before assuming. + +## Scope decision + +In scope: backslash handling in **div / span / code-block / +inline-attribute** values (everything that flows through +`key_value_value`). Out of scope: link titles (different surface, same +helper — needs its own check). + +## Suggested fix shape (not implemented) + +Update `extract_quoted_text` so that, inside the quotes, **any** `\X` +collapses to `X` (Pandoc-style generic backslash escape). The writer +does not need to change. + +A regression test belongs at +`tests/roundtrip_tests/qmd-json-qmd/` (per +`crates/pampa/CLAUDE.md` § "When fixing roundtripping bugs"). Cover at +least: +1. `data-foo="\[1,2\]"` (the reported case — round-trips to + `data-foo="[1,2]"`, then stable), +2. `data-baz="a\\b"` (literal backslash — round-trips to itself), +3. `data-q="a\"b"` (escaped quote — already works; lock it in). + +Whoever picks this up should TDD: write the round-trip test, confirm +it fails, then change `extract_quoted_text`. + +## Related issues + +- **#160** ("qmd writer drops `=` from raw block fence") — different + bug, neighboring area (qmd writer attribute serialization). Not a + duplicate; should be tracked separately. The reporter's comment + thread on #161 references "this and #161" which appears to be a + typo for "this and #160" — the OP author is the same and the comment + about a "deeper bit of confusion around `\` in strings" is + consistent with cross-issue reflection. + +## Outcome + +Filed as **bd-tpjg** (priority 1, bug). Implementation TBD by whoever +picks it up — TDD per `crates/pampa/CLAUDE.md`. diff --git a/claude-notes/issue-reports/173/repro.qmd b/claude-notes/issue-reports/173/repro.qmd new file mode 100644 index 000000000..f029d47c0 --- /dev/null +++ b/claude-notes/issue-reports/173/repro.qmd @@ -0,0 +1,4 @@ +```markdown +foo + +``` diff --git a/claude-notes/issue-reports/173/repro.sh b/claude-notes/issue-reports/173/repro.sh new file mode 100755 index 000000000..46d9d7820 --- /dev/null +++ b/claude-notes/issue-reports/173/repro.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Minimal repro for issue #173. +# A CodeBlock whose AST text ends with `\n` loses that newline on round-trip +# through the qmd writer. +set -euo pipefail + +HERE="$(cd "$(dirname "$0")" && pwd)" +REPRO="$HERE/repro.qmd" +cd "$HERE"/../../.. + +echo "=== input bytes ===" +od -c "$REPRO" | head -3 + +echo +echo "=== first parse (text should be \"foo\\n\") ===" +cargo run --quiet --bin pampa -- "$REPRO" + +echo +echo "=== qmd writer output (closing fence is glued to 'foo\\n', BUG) ===" +cargo run --quiet --bin pampa -- "$REPRO" -t qmd | od -c | head -3 + +echo +echo "=== round-trip parse (text is now \"foo\", BUG — trailing \\n lost) ===" +cargo run --quiet --bin pampa -- "$REPRO" -t qmd | cargo run --quiet --bin pampa -- diff --git a/claude-notes/issue-reports/173/triage.md b/claude-notes/issue-reports/173/triage.md new file mode 100644 index 000000000..303fd9f0b --- /dev/null +++ b/claude-notes/issue-reports/173/triage.md @@ -0,0 +1,148 @@ +# Issue #173 — qmd writer drops trailing blank line inside a code block + +- **GitHub**: https://github.com/quarto-dev/q2/issues/173 +- **Reporter**: @rundel (Colin Rundel), 2026-05-11 +- **Triage date**: 2026-05-11 +- **Worktree**: `.worktrees/issue-173` (branch `issue-173`, based on `main` @ `37f78170`) +- **Beads issue**: bd-v1qc +- **Scope**: the fenced-code-block round-trip bug only. The three quarto-web links in the issue body are example sites of the same bug; they will be fixed by the same change and don't need separate triage. + +## Summary + +Real bug, fix is small and lives in the writer. A `CodeBlock` whose AST `.text` ends with one or more `\n` round-trips with the final `\n` removed, because `write_codeblock` in `crates/pampa/src/writers/qmd.rs` only emits a separator newline before the closing fence when the content does not already end in `\n`. The reader's AST shape matches Pandoc exactly (verified) so the AST contract is not the problem — only the writer is wrong. Reproduced verbatim against the reporter's example and on three additional edge cases (empty content, content of only blank lines, content with two trailing blank lines). + +## Reproduction + +Input fixture: `claude-notes/issue-reports/173/repro.qmd` (bytes: `` ```markdown\nfoo\n\n```\n ``). +Driver: `claude-notes/issue-reports/173/repro.sh` (runs all three stages and dumps bytes). + +Observed: + +``` +$ ./claude-notes/issue-reports/173/repro.sh +=== first parse (text should be "foo\n") === +[ CodeBlock ( "" , ["markdown"] , [] ) "foo\n" ] + +=== qmd writer output (closing fence glued to 'foo\n', BUG) === +0000000 ` ` ` m a r k d o w n \n f o o \n +0000020 ` ` ` \n + +=== round-trip parse (text is now "foo", BUG — trailing \n lost) === +[ CodeBlock ( "" , ["markdown"] , [] ) "foo" ] +``` + +Expected: the writer emits `` ```markdown\nfoo\n\n```\n ``, so the re-parse yields `"foo\n"`. + +## Reader vs writer — where to fix + +The user explicitly asked which side this should be fixed on. Decision: **writer-only.** The reasoning: + +### Pandoc parity check (the deciding evidence) + +The pampa reader currently joins content lines with `\n` and emits **no trailing `\n`** for the last content line. That is *not* what a literal reading of the CommonMark spec produces (the spec's HTML examples always show a trailing newline before ``), but it is **exactly** what Pandoc 3.9 does. Six side-by-side cases — pandoc 3.9.0.2 vs pampa, native parse, identical inputs: + +| input between fences | pandoc `CodeBlock` text | pampa `CodeBlock` text | +|----------------------|-------------------------|------------------------| +| `foo` | `"foo"` | `"foo"` | +| `foo\n` (1 trailing blank) | `"foo\n"` | `"foo\n"` | +| `foo\n\n` (2 trailing blanks) | `"foo\n\n"` | `"foo\n\n"` | +| (empty) | `""` | `""` | +| `\n` (one blank) | `""` | `""` | +| `\n\n` (two blanks) | `"\n"` | `"\n"` | +| `\n ` (CommonMark spec ex. 100 input) | `"\n "` | `"\n "` | + +So: + +1. Pampa's reader matches Pandoc 1:1 on every case I checked. +2. Pandoc itself diverges from a literal reading of the CommonMark spec in the same way (and has done so for many years). For example, CommonMark spec example 100 (`external-sources/commonmark/spec.txt:2107`) expects the rendered HTML to be `
\n  \n
` (two newlines inside ``), but `pandoc -f markdown -t html5` on the same input emits `
\n  
` (one newline). Pampa is following Pandoc here, not the literal spec. +3. This project does not promise CommonMark compliance, and matching Pandoc is the dominant convention in this codebase. + +Changing the reader to be strictly spec-compliant would (a) diverge from Pandoc, (b) change the AST shape for every code block in the corpus, (c) invalidate a large fraction of `crates/pampa/snapshots/`, and (d) gain no functionality. So the reader stays as is. + +### The writer's contract under that reader + +Given the Pandoc-matching reader, the writer's job is the inverse: it must emit text such that re-parsing yields the same `.text` it was given. The rule that falls out of the table above is: + +- Non-empty `.text` C → write `C` followed by exactly one `\n`, then the closing fence on its own line. +- Empty `.text` → write nothing between the fences (or one blank line — both round-trip to `""`). + +The current writer instead writes `C` then conditionally adds `\n` only if `C` didn't already end with one. That's correct for `"foo"` but wrong for any C ending in `\n`, which is exactly the bug. + +## Localization + +`crates/pampa/src/writers/qmd.rs:628-634`: + +```rust +// Write the code content +write!(buf, "{}", codeblock.text)?; + +// Ensure we end on a newline +if !codeblock.text.ends_with('\n') { + writeln!(buf)?; +} +``` + +The conditional is the bug. The minimal fix is to remove the `if` and always emit a newline after non-empty content. A clean form: + +```rust +write!(buf, "{}", codeblock.text)?; +if !codeblock.text.is_empty() { + writeln!(buf)?; +} +``` + +This makes `write_codeblock` round-trip correctly on all seven cases in the table above, including the previously-broken cases where `.text` ends with `\n`. + +Note: this fix also silently corrects a secondary round-trip defect that the issue did not call out. The current writer renders empty content (`.text = ""`) as `` ```\n\n```\n `` (one blank content line), which happens to re-parse to `""` because the reader collapses one blank content line to `""`. With the proposed fix, empty content renders as `` ```\n```\n `` (zero content lines) — also re-parses to `""`, and is the canonical form. Either is correct under round-trip, but the proposed form is the canonical one and matches what a human writes. + +## Open questions — resolved during triage + +**Q1: Should we fix the reader to be CommonMark-spec-compliant (always include trailing `\n`) instead?** +Resolved: no. See § "Reader vs writer". Pampa's reader matches Pandoc exactly, and Pandoc itself diverges from a literal reading of the CommonMark spec. Changing the reader would break parity with Pandoc, invalidate snapshots, and offer no user-visible benefit. + +**Q2: What does Pandoc actually emit as the writer output? Could pampa also "fix" round-trip by stripping the trailing `\n` in the reader?** +Resolved: not investigated for the *writer* side because the choice is already constrained — pampa's reader output is what user filters/tests inspect, and that already matches Pandoc. Stripping `\n` in the reader would change the AST contract; doing it only on round-trip is worse. The clean fix is writer-only. + +**Q3: How many existing round-trip / snapshot tests could break with this change?** +Resolved (sample): only three fixtures under `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/` mention fenced code (`codeblock_with_attrs.qmd`, `rawblock_latex.qmd`, plus the note-definition family). None has trailing blank lines inside a code block, so the new writer behavior would produce identical bytes on existing inputs. The empty-code-block case (see Localization note) might affect a handful of snapshots that include `` ```\n\n```\n ``; the fix can keep the current empty-block output (`` ```\n\n```\n ``) if those snapshots are too numerous to update, since both forms are correct. + +## Outcome / recommended next step + +Filed bd-v1qc with the fix scope below. + +1. Write a TDD round-trip test under `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/` covering: content with one trailing `\n`, content with two trailing `\n`, content of only blank lines, and an empty code block. Verify it fails on the trailing-`\n` cases. +2. Apply the writer change at `crates/pampa/src/writers/qmd.rs:628-634` as shown. +3. Re-run `cargo nextest run -p pampa` and update any snapshots that change. Document any non-fence-trailing snapshot changes in the commit message per `CLAUDE.md` § Snapshot Test Changes. +4. End-to-end verify per the project rule: run `cargo run --bin pampa -- .qmd -t qmd | cargo run --bin pampa --` on the four cases above and confirm `.text` round-trips. + +Also: durable CommonMark spec lookup scaffolding produced during this triage was landed separately on `main` under `claude-notes/research/commonmark-spec/` — it's small, self-contained, and was useful for resolving Q1. + +## Verification commands used + +```bash +gh issue view 173 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments + +# Reader behavior on five inputs (showed pampa matches pandoc) +for input in '```markdown\nfoo\n\n```\n' '```markdown\nfoo\n```\n' \ + '```markdown\nfoo\n\n\n```\n' '```\n```\n' '```\n\n\n```\n'; do + printf -- "$input" | cargo run --quiet --bin pampa -- + printf -- "$input" | pandoc -f markdown -t json | jq -c '.blocks' +done + +# CommonMark spec example 100 (showed pandoc diverges from spec, pampa follows pandoc) +printf -- '```\n\n \n```\n' | pandoc -f markdown -t html5 +printf -- '```\n\n \n```\n' | cargo run --quiet --bin pampa -- + +# Round-trip + writer output bytes +./claude-notes/issue-reports/173/repro.sh + +# Existing fenced-code coverage in the round-trip suite +ls crates/pampa/tests/roundtrip_tests/qmd-json-qmd/ | grep -i -E 'code|fence' +``` + +## Cross-references + +- `crates/pampa/src/writers/qmd.rs:628-634` — the buggy conditional. +- `crates/pampa/CLAUDE.md` — TDD round-trip workflow that the fix should follow. +- `claude-notes/research/commonmark-spec/` (on `main`) — CommonMark spec lookup scaffolding produced during this triage (index, examples-index, and two helper scripts). +- `external-sources/commonmark/spec.txt:1934-2359` — Fenced code blocks section consulted for the AST-shape question. diff --git a/claude-notes/issue-reports/175/exp-empty-body-row.qmd b/claude-notes/issue-reports/175/exp-empty-body-row.qmd new file mode 100644 index 000000000..b80af41b6 --- /dev/null +++ b/claude-notes/issue-reports/175/exp-empty-body-row.qmd @@ -0,0 +1,4 @@ +| A | B | +|-----|-----| +| | | +| c | d | diff --git a/claude-notes/issue-reports/175/repro.qmd b/claude-notes/issue-reports/175/repro.qmd new file mode 100644 index 000000000..00ba1404a --- /dev/null +++ b/claude-notes/issue-reports/175/repro.qmd @@ -0,0 +1,4 @@ +| | | +|-----|-----| +| a | b | +| c | d | diff --git a/claude-notes/issue-reports/175/triage.md b/claude-notes/issue-reports/175/triage.md new file mode 100644 index 000000000..0ea8663fc --- /dev/null +++ b/claude-notes/issue-reports/175/triage.md @@ -0,0 +1,173 @@ +# Issue #175 — qmd writer drops empty header row from pipe tables, promotes first body row to header + +- **GitHub**: https://github.com/quarto-dev/q2/issues/175 +- **Reporter**: @rundel (Colin Rundel), 2026-05-11 +- **Triage date**: 2026-05-11 +- **Worktree**: `.worktrees/issue-175` (branch `issue-175`, based on `main` @ `53394156`) +- **Beads issue**: bd-7mpv +- **Scope**: the single round-trip bug described in the issue body. No other reports. + +## Summary + +A pipe table whose header row is all empty cells is parsed as `Table` with +`TableHead [] []` (zero header rows). The qmd writer's `write_table` path +unconditionally emits the first collected row as the header line, so when +there are no header rows it promotes the first body row instead, and the +re-parser then reads that body row as the header. Round-trip loses one +body row and gains one (wrong) header row. Real bug, root cause is one +function in `crates/pampa/src/writers/qmd.rs`, fix scope is small. Pandoc's +`gfm` writer demonstrates the expected output (emit an empty header line +`| | |`). + +## Reproduction + +Fixture: `claude-notes/issue-reports/175/repro.qmd` + +``` +| | | +|-----|-----| +| a | b | +| c | d | +``` + +``` +$ cargo run --quiet --bin pampa -- claude-notes/issue-reports/175/repro.qmd +[ Table … (TableHead ("",[],[]) []) + [TableBody ("",[],[]) (RowHeadColumns 0) [] + [Row … [Cell … [Plain [Str "a"]], Cell … [Plain [Str "b"]]] + ,Row … [Cell … [Plain [Str "c"]], Cell … [Plain [Str "d"]]]]] + …] +# ✓ parser correctly produces zero header rows +``` + +``` +$ cargo run --quiet --bin pampa -- -t qmd claude-notes/issue-reports/175/repro.qmd +| a | b | +| --- | --- | +| c | d | +# ✗ writer emits 'a | b' as the header line; the empty original header is gone +``` + +``` +$ cargo run --quiet --bin pampa -- -t qmd claude-notes/issue-reports/175/repro.qmd \ + | cargo run --quiet --bin pampa -- +[ Table … (TableHead ("",[],[]) [Row … [Cell … [Plain [Str "a"]], Cell … [Plain [Str "b"]]]]) + [TableBody … [Row … [Cell … [Plain [Str "c"]], Cell … [Plain [Str "d"]]]]] + …] +# ✗ on re-parse, the first body row has become the header, body has 1 row instead of 2 +``` + +Asymmetry check (`claude-notes/issue-reports/175/exp-empty-body-row.qmd`): +an all-empty *body* row round-trips correctly (`Plain []` cells are +preserved); the bug is specifically in the header path. + +Pandoc reference behavior on the same input: + +``` +$ pandoc -f markdown -t native claude-notes/issue-reports/175/repro.qmd +… (TableHead ("",[],[]) []) … # same AST as ours +$ pandoc -f markdown -t gfm claude-notes/issue-reports/175/repro.qmd +| | | +|-----|-----| +| a | b | +| c | d | # round-trips faithfully +``` + +## Localization + +`crates/pampa/src/writers/qmd.rs:1120-1214` `write_table`: + +- Line 1130-1143: builds a flat `all_rows: Vec<&Row>` from + `table.head.rows` followed by every body row in `table.bodies`. +- Line 1145-1147: bails on empty. +- Line 1184-1190: writes `row_contents[0]` as the header line **without + checking whether it came from `table.head.rows`**. +- Line 1206-1213: emits the remaining rows as body. + +The fix needs to branch on `table.head.rows.is_empty()`: + +- If zero header rows, emit one synthetic empty header line (cells of + the configured width filled with spaces) and the separator, then emit + *all* `row_contents` as body. This matches Pandoc `gfm` and matches + what the parser will read back. +- If one header row (current happy path), keep current behavior. +- If more than one header row, the pipe-table format cannot represent + it; `table_can_use_pipe_format` should be extended to reject + multi-header tables and fall through to `write_list_table`. + +The `table_can_use_pipe_format` predicate at lines 870-910 currently +inspects only cell shape and content, not header-row count, so the +multi-header check would be a small addition there. + +## Open questions — resolved during triage + +**Q1. Is this a parser bug or a writer bug?** +Experiment: parsed `repro.qmd` with both `pampa` and `pandoc 3.9.0.2`. +Both produce `TableHead [...] []` (zero header rows). The Pandoc data +model permits zero-header tables, so the parser is correct. +**Conclusion**: writer-only bug. + +**Q2. Does the writer also corrupt all-empty *body* rows?** +Experiment: `exp-empty-body-row.qmd` (header `A|B`, empty body row, +then `c|d`). Round-trips faithfully — the empty body row stays as +`| | |`. The bug is scoped to the header path. +**Conclusion**: header line only; body rows are fine. + +**Q3. What output should the fix produce?** +Experiment: `pandoc -t gfm` on the same input produces +`| | |` then the separator then the body rows verbatim. +**Conclusion**: emit a synthetic empty header line. This matches the +reporter's stated expectation and is consistent with at least one +established markdown writer. + +**Q4. Are there impacted real-world docs?** +The issue links two quarto-web files (`docs/authoring/callouts.qmd`, +`docs/output-formats/all-formats.qmd`) that use this construct. Anyone +running these through `qmd-syntax-helper` or any other round-tripping +tool would silently lose a row. +**Conclusion**: not a hypothetical; user-visible impact on existing +content. + +## Outcome / recommended next step + +File a beads bug with the fix scope captured in Localization. No +follow-on GH response needed — the reporter already documented the +expected behavior. Recommend P1 (silent data loss in round-trip, real +content affected, small fix surface). + +## Verification commands used + +```bash +# Pre-flight (from main repo root) +cargo xtask verify --skip-hub-build + +# Worktree setup +git worktree add -b issue-175 .worktrees/issue-175 main +echo "../../../.beads" > .worktrees/issue-175/.beads/redirect +cd .worktrees/issue-175 && npm install + +# Reproduce +cargo run --quiet --bin pampa -- claude-notes/issue-reports/175/repro.qmd +cargo run --quiet --bin pampa -- -t qmd claude-notes/issue-reports/175/repro.qmd +cargo run --quiet --bin pampa -- -t qmd claude-notes/issue-reports/175/repro.qmd \ + | cargo run --quiet --bin pampa -- + +# Pandoc reference +pandoc -f markdown -t native claude-notes/issue-reports/175/repro.qmd +pandoc -f markdown -t gfm claude-notes/issue-reports/175/repro.qmd + +# Asymmetry check +cargo run --quiet --bin pampa -- -t qmd claude-notes/issue-reports/175/exp-empty-body-row.qmd +``` + +## Cross-references + +- `crates/pampa/src/writers/qmd.rs:1120-1214` — `write_table` (root cause) +- `crates/pampa/src/writers/qmd.rs:870-910` — `table_can_use_pipe_format` + (predicate that should grow a multi-header guard) +- `tests/roundtrip_tests/qmd-json-qmd` — per `crates/pampa/CLAUDE.md`, + this is the directory for round-trip regression tests; the fix should + add a fixture there. +- quarto-web files exercised by the bug (from the GH issue): + - `docs/authoring/callouts.qmd:87` + - `docs/output-formats/all-formats.qmd:33` diff --git a/claude-notes/issue-reports/180/repro-figure-figure.qmd b/claude-notes/issue-reports/180/repro-figure-figure.qmd new file mode 100644 index 000000000..3415bd001 --- /dev/null +++ b/claude-notes/issue-reports/180/repro-figure-figure.qmd @@ -0,0 +1,3 @@ +![A](a.png){#fig-a} + +![B](b.png){#fig-b} diff --git a/claude-notes/issue-reports/180/repro-figure-para.qmd b/claude-notes/issue-reports/180/repro-figure-para.qmd new file mode 100644 index 000000000..a5c123f41 --- /dev/null +++ b/claude-notes/issue-reports/180/repro-figure-para.qmd @@ -0,0 +1,3 @@ +![cap](img.png){#fig-x} + +Follow up text. diff --git a/claude-notes/issue-reports/180/repro-layout-div.qmd b/claude-notes/issue-reports/180/repro-layout-div.qmd new file mode 100644 index 000000000..933806fec --- /dev/null +++ b/claude-notes/issue-reports/180/repro-layout-div.qmd @@ -0,0 +1,8 @@ +::: {#fig-x layout-ncol=2} + +![A](a.png){#fig-a} + +![B](b.png){#fig-b} + +Caption text +::: diff --git a/claude-notes/issue-reports/180/repro-para-figure-OK.qmd b/claude-notes/issue-reports/180/repro-para-figure-OK.qmd new file mode 100644 index 000000000..f20687ad9 --- /dev/null +++ b/claude-notes/issue-reports/180/repro-para-figure-OK.qmd @@ -0,0 +1,3 @@ +Lead-in text. + +![cap](img.png){#fig-x} diff --git a/claude-notes/issue-reports/180/triage.md b/claude-notes/issue-reports/180/triage.md new file mode 100644 index 000000000..2756df640 --- /dev/null +++ b/claude-notes/issue-reports/180/triage.md @@ -0,0 +1,184 @@ +# Issue #180 — qmd writer drops trailing newline after implicit-figure shape, collapsing the next block + +- **GitHub**: https://github.com/quarto-dev/q2/issues/180 +- **Reporter**: @rundel (Colin Rundel), 2026-05-11 +- **Triage date**: 2026-05-12 +- **Worktree**: `.worktrees/issue-180` (branch `issue-180`, based on `main` @ `c5770004`) +- **Beads issue**: bd-cpzp +- **Scope**: Covers both reports in the issue — the original body ("Figure + Para collapse") and the comment ("layout/subfigure div children collapse"). They are the same root cause; this triage treats them as one bug. + +## Summary + +Both reports reproduce exactly as filed at `main` @ c5770004. They share a single root cause: in `write_figure`, the implicit-figure branch delegates to `write_image` and returns directly, skipping the trailing newline that every block writer is expected to emit. When such a Figure is followed by any other block (top-level *or* as a child of a `Div`), only one `\n` ends up between the two — not a blank line — and the re-parser glues the two blocks into one `Para`. Fix is one line in `write_figure`; the existing roundtrip corpus does not cover "implicit figure followed by another block," which is why this slipped through. + +## Reproduction + +All commands run from the worktree root, `main` @ c5770004. + +### Bug A — top-level Figure + Para collapses (issue body) + +Fixture: `claude-notes/issue-reports/180/repro-figure-para.qmd` + +``` +![cap](img.png){#fig-x} + +Follow up text. +``` + +``` +$ cargo run --quiet --bin pampa -- < repro-figure-para.qmd +[ Figure ( "fig-x" , ... ) ..., Para [Str "Follow", Space, Str "up", Space, Str "text."] ] + +$ cargo run --quiet --bin pampa -- -t qmd < repro-figure-para.qmd +![cap](img.png){#fig-x} +Follow up text. + +$ cargo run --quiet --bin pampa -- -t qmd < repro-figure-para.qmd \ + | cargo run --quiet --bin pampa -- +[ Para [Image ( "fig-x" , ... ) [Str "cap"] ("img.png" , ""), SoftBreak, Str "Follow", Space, Str "up", Space, Str "text."] ] +``` + +Observed: writer emits one `\n` between the image and the paragraph, no blank line. Round-trip collapses two blocks into one `Para`. + +Expected: a blank line between the two, so re-parsing yields the original `[Figure, Para]` pair. + +### Bug B — layout/subfigure div children collapse (comment) + +Fixture: `claude-notes/issue-reports/180/repro-layout-div.qmd` + +``` +::: {#fig-x layout-ncol=2} + +![A](a.png){#fig-a} + +![B](b.png){#fig-b} + +Caption text +::: +``` + +``` +$ cargo run --quiet --bin pampa -- -t qmd < repro-layout-div.qmd +::: {#fig-x layout-ncol="2"} + +![A](a.png){#fig-a} +![B](b.png){#fig-b} +Caption text + +::: +``` + +Observed: the three child blocks (`Figure`, `Figure`, `Para`) come out on consecutive lines with only single `\n`s between them. Re-parsing flattens the Div's content into one `Para`. + +Expected: each child separated by a blank line; round-trip preserves the three child blocks. + +### Counter-example — Para followed by Figure round-trips fine + +Fixture: `claude-notes/issue-reports/180/repro-para-figure-OK.qmd` + +``` +Lead-in text. + +![cap](img.png){#fig-x} +``` + +``` +$ cargo run --quiet --bin pampa -- -t qmd < repro-para-figure-OK.qmd +Lead-in text. + +![cap](img.png){#fig-x} +$ # (and round-trip back to native shows [Para, Figure] unchanged) +``` + +This confirms the bug is *asymmetric*: the missing newline only matters when the implicit-figure shape is **not** the last block in its container. When it is the last block, the loop never emits another separator, so the deficit is invisible. + +### Extra coverage — Figure followed by Figure + +Fixture: `claude-notes/issue-reports/180/repro-figure-figure.qmd` + +``` +![A](a.png){#fig-a} + +![B](b.png){#fig-b} +``` + +Writer output collapses to two lines with one `\n` between them; re-parser yields a single `Para` with both images and a `SoftBreak`. Same root cause. + +## Localization + +`crates/pampa/src/writers/qmd.rs:759` + +```rust +fn write_figure( + figure: &Figure, + buf: &mut dyn std::io::Write, + ctx: &mut QmdWriterContext, +) -> std::io::Result<()> { + if let Some(image) = match_implicit_figure_shape(figure) { + let mut merged = image.clone(); + merged.attr.0 = figure.attr.0.clone(); + return write_image(&merged, buf, ctx); // <-- bug: returns with no trailing '\n' + } + ... +} +``` + +The block-writer contract in this file: each top-level block writer ends its output with exactly one `\n`. See `write_paragraph` (`qmd.rs:2197`), `write_plain` (`qmd.rs:2209`), `write_figure`'s own fallback path that closes with `writeln!(buf, "\n:::")?` (`qmd.rs:805`), etc. The top-level driver `write_impl` (`qmd.rs:2331`) and `write_div` (`qmd.rs:442`) both rely on this: they emit *one* additional `\n` between blocks, which only becomes a blank line if the previous block already ended in `\n`. + +`write_image` (`qmd.rs:1490`) is an inline writer and correctly does *not* emit a trailing newline. The bug is the early-return in `write_figure`: it bypasses the block-level wrap-up and reuses the inline writer's output verbatim as a block. + +## Fix scope + +One-line fix in the implicit-figure branch of `write_figure` — replace the early-return with a call that delegates and then appends `writeln!(buf)?`. Conceptually: + +```rust +if let Some(image) = match_implicit_figure_shape(figure) { + let mut merged = image.clone(); + merged.attr.0 = figure.attr.0.clone(); + write_image(&merged, buf, ctx)?; + writeln!(buf)?; + return Ok(()); +} +``` + +Test coverage to add (TDD-first per `crates/pampa/CLAUDE.md`): + +1. `tests/roundtrip_tests/qmd-json-qmd/figure_implicit_then_para.qmd` — bug A. +2. `tests/roundtrip_tests/qmd-json-qmd/layout_div_subfigures.qmd` — bug B. +3. Optionally: `figure_implicit_then_figure.qmd` to lock in the second extra case. + +The existing roundtrip corpus has only `figure_implicit_with_id.qmd` and `figure_implicit_id_and_classes.qmd`, both single-block documents that never exercise the inter-block separator. + +## Open questions — resolved during triage + +- **Are both reports the same bug?** Yes. Both reduce to "implicit-figure write path violates the block-trailing-newline contract." Verified by reproducing each separately and observing that the byte-level output matches the prediction in both cases. +- **Is this related to bd-emr4** (existing Figure round-trip beads issue)? No. bd-emr4 is about *non-implicit* Figure shapes (caption ≠ alt, multi-block content, etc.) round-tripping through a fallback fenced div that the reader can't turn back into a Figure. This bug is in the *implicit* path, which today does round-trip *its own block* correctly — it just corrupts the *next* block. Different code paths, different fixes. +- **Does the fallback (non-implicit) path have the same trailing-newline problem?** No. The fallback at `qmd.rs:805` ends with `writeln!(buf, "\n:::")?`, which writes `\n:::\n`. Block contract satisfied. +- **Why does Para → Figure round-trip cleanly when Figure → Para does not?** Because the trailing-newline deficit only matters when there's a *next* block to separate from. When the implicit Figure is the last block in its container, the missing `\n` is harmless. + +## Outcome / recommended next step + +Real bug, single root cause, small fix. **Filing as a beads issue** with the fix scope above, after the triage commit lands. + +## Verification commands used + +```bash +gh issue view 180 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments +cargo xtask verify --skip-hub-build --skip-hub-tests # pre-flight green +cargo run --quiet --bin pampa -- < repro-figure-para.qmd +cargo run --quiet --bin pampa -- -t qmd < repro-figure-para.qmd +cargo run --quiet --bin pampa -- -t qmd < repro-figure-para.qmd | cargo run --quiet --bin pampa -- +# (same three commands against repro-layout-div.qmd, repro-para-figure-OK.qmd, repro-figure-figure.qmd) +br search "Figure" # ruled out duplicate +br show bd-emr4 --json # confirmed scope differs +``` + +## Cross-references + +- Related (different code path, not a duplicate): bd-emr4 — qmd writer/reader: explicit Figure shapes don't round-trip. +- Writer contract: `crates/pampa/src/writers/qmd.rs` — `write_paragraph` (`:2197`), `write_plain` (`:2209`), `write_div` (`:442`), `write_impl` (`:2325`). +- TDD rule for roundtrip fixes: `crates/pampa/CLAUDE.md` — "When fixing roundtripping bugs: FIRST add the failing test to `tests/roundtrip_tests/qmd-json-qmd`." + +## Pre-flight note + +`cargo xtask verify --skip-hub-build` fails at the hub-client test step on `main` @ c5770004 with `Cannot find package 'compression'` (vitest config can't resolve a transitive dep). This is unrelated to the qmd writer and appears to be an `npm install` state issue. The Rust portion (`cargo build --workspace`, `cargo nextest run --workspace`) plus trace-viewer build + tests pass cleanly under `cargo xtask verify --skip-hub-build --skip-hub-tests`. Mentioning here so a follow-up agent doesn't get derailed by it. diff --git a/claude-notes/issue-reports/181/exp-blank-lines.qmd b/claude-notes/issue-reports/181/exp-blank-lines.qmd new file mode 100644 index 000000000..1a9ce11d8 --- /dev/null +++ b/claude-notes/issue-reports/181/exp-blank-lines.qmd @@ -0,0 +1,7 @@ +> Before +> +> $$ +> p = q +> $$ +> +> After diff --git a/claude-notes/issue-reports/181/exp-fenced-code-in-bq.qmd b/claude-notes/issue-reports/181/exp-fenced-code-in-bq.qmd new file mode 100644 index 000000000..b31a9d65d --- /dev/null +++ b/claude-notes/issue-reports/181/exp-fenced-code-in-bq.qmd @@ -0,0 +1,5 @@ +> Before +> ``` +> p = q +> ``` +> After diff --git a/claude-notes/issue-reports/181/exp-no-blockquote.qmd b/claude-notes/issue-reports/181/exp-no-blockquote.qmd new file mode 100644 index 000000000..2ff7733cd --- /dev/null +++ b/claude-notes/issue-reports/181/exp-no-blockquote.qmd @@ -0,0 +1,3 @@ +$$ +p = q +$$ diff --git a/claude-notes/issue-reports/181/exp-only-math.qmd b/claude-notes/issue-reports/181/exp-only-math.qmd new file mode 100644 index 000000000..2c00ef9ef --- /dev/null +++ b/claude-notes/issue-reports/181/exp-only-math.qmd @@ -0,0 +1,3 @@ +> $$ +> p = q +> $$ diff --git a/claude-notes/issue-reports/181/repro.qmd b/claude-notes/issue-reports/181/repro.qmd new file mode 100644 index 000000000..544aa8559 --- /dev/null +++ b/claude-notes/issue-reports/181/repro.qmd @@ -0,0 +1,5 @@ +> Before +> $$ +> p = q +> $$ +> After diff --git a/claude-notes/issue-reports/181/triage.md b/claude-notes/issue-reports/181/triage.md new file mode 100644 index 000000000..79194d818 --- /dev/null +++ b/claude-notes/issue-reports/181/triage.md @@ -0,0 +1,189 @@ +# Issue #181 — Display math inside a blockquote has its `> ` prefix doubled on round trip + +Upstream: https://github.com/quarto-dev/q2/issues/181 +Reporter: Colin Rundel (@rundel), 2026-05-11 +Worktree branch: `issue-181` +Beads fix issue: bd-q6ed + +## Verdict + +**Confirmed bug, in the tree-sitter grammar.** Reporter's diagnosis is correct: the parser produces `Math DisplayMath` whose content string includes the literal `> ` block-continuation prefix on every line of the math body. The qmd writer is doing the right thing — when emitting a multi-line math block inside a blockquote, every body line needs a `> ` prefix — but because the parser already left `> ` in the content, the writer's correct re-prefix yields `> > ` and each round trip adds one more level. + +## Reproduction (at branch HEAD on `main` = 90e29165) + +Input (`repro.qmd`): + +``` +> Before +> $$ +> p = q +> $$ +> After +``` + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/181/repro.qmd +[ BlockQuote [Para [Str "Before", SoftBreak, Math DisplayMath "\n> p = q\n> ", SoftBreak, Str "After"]] ] +``` + +Note the `"\n> p = q\n> "` — the `> ` continuation markers from lines 3 and 4 of the input are inside the math content. + +Round-tripping `repro.qmd -> qmd` then re-parsing: + +``` +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/181/repro.qmd +> Before +> $$ +> > p = q +> > $$ +> After + +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/181/repro.qmd | cargo run --bin pampa -- +[ BlockQuote [Para [Str "Before", SoftBreak, Math DisplayMath "\n> > p = q\n> > ", SoftBreak, Str "After"]] ] +``` + +## Investigation + +### Localised to the parser, not the writer + +Feeding a clean `DisplayMath` value (no `> ` bytes inside) directly into the writer through Pandoc-JSON input produces the correct output (see `claude-notes/issue-reports/181/exp-only-math.qmd` and the JSON-driven round trip in this session): + +``` +$ printf '{"pandoc-api-version":[1,23,1],"meta":{},"blocks":[{"t":"BlockQuote","c":[{"t":"Para","c":[{"t":"Math","c":[{"t":"DisplayMath"},"\\np = q\\n"]}]}]}]}\n' \ + | cargo run --bin pampa -- -f json -t qmd +> $$ +> p = q +> $$ +``` + +So the writer's blockquote-aware re-prefix logic is correct. The defect is entirely upstream — the parser hands the writer dirty content. + +### CST shows the parser swallowing the prefix bytes + +`pampa -v` on `exp-only-math.qmd`: + +``` +pandoc_block_quote: {Node pandoc_block_quote (0, 0) - (3, 0)} + block_quote_marker: {Node block_quote_marker (0, 0) - (0, 2)} + pandoc_paragraph: {Node pandoc_paragraph (0, 2) - (3, 0)} + pandoc_display_math: {Node pandoc_display_math (0, 2) - (2, 4)} + $$: {Node $$ (0, 2) - (0, 4)} + $$: {Node $$ (2, 2) - (2, 4)} +``` + +There is exactly **one** `block_quote_marker` token for the entire blockquote — only the first line. The continuation `> ` characters on lines 1 and 2 are never matched as `block_continuation`; they fall inside `pandoc_display_math`'s body span, which is the literal byte range `(0, 2) - (2, 4)`. + +### Root cause in `grammar.js` + +`crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js:367`: + +```js +pandoc_display_math: $ => seq( + '$$', + /([^$]|[$][^$]|\\\$)+/, + '$$' +), +``` + +`pandoc_display_math` is registered as an **inline** element (`grammar.js:511`, inside `_inline_element`). Its body is a single regex match that consumes every byte (including `\n` and `> ` continuation prefixes) between the two `$$` delimiters. None of the block-continuation machinery (`$._newline` / `optional($.block_continuation)`) ever runs while the body regex is matching. + +By contrast, the body of `pandoc_code_block` (`grammar.js:828`) is `code_fence_content: repeat1(choice($._newline, $._code_line))`. `$._newline` is `seq($._line_ending, optional($.block_continuation))` (`grammar.js:886`), so on each line of a fenced code block, the `block_continuation` (the leading `> ` inside a blockquote) is consumed as its own token and never ends up in the captured content. That is why the analogous round trip with fenced code blocks works correctly — verified with `exp-fenced-code-in-bq.qmd`: + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/181/exp-fenced-code-in-bq.qmd +[ BlockQuote [Para [Str "Before"], CodeBlock ( "" , [] , [] ) "p = q", Para [Str "After"]] ] +``` + +The code-block body is the clean `"p = q"` — no `> ` bytes leak through. + +### Where the AST extraction reads the content + +`crates/pampa/src/pandoc/treesitter.rs:502-513`: + +```rust +"pandoc_display_math" => { + let full_text = node.utf8_text(input_bytes).unwrap(); + let content = &full_text[2..full_text.len() - 2]; // Strip leading and trailing $$ + ... + Inline::Math(Math { math_type: MathType::DisplayMath, text: content.to_string(), ... }) +} +``` + +It reads the node text verbatim from the input bytes and strips only the `$$` delimiters. There is no awareness of the surrounding blockquote indentation, so any `> ` prefix bytes that the grammar didn't consume are passed straight into `Math.text`. + +## Fix shape (not implemented by this triage) + +Two viable approaches, both at the grammar layer: + +1. **Make `pandoc_display_math` line-structured like `pandoc_code_block`.** Replace the single regex body with `repeat($._newline | $._math_line)` (or similar), so that `block_continuation` is consumed on each interior line and never enters the captured content. This is the structurally correct fix and mirrors the existing pattern used for code fences and fenced divs. + +2. **Keep the regex body but strip `block_continuation` markers in `treesitter.rs` at AST construction time.** This is a smaller patch and may be appealing as a quick fix, but it duplicates blockquote-awareness logic that the grammar should already own, and it's fragile if math ends up inside nested blockquotes or list continuations. + +Either way: also verify `pandoc_math` (inline `$...$`) does not have a similar latent issue when an inline-math span gets soft-broken across a `> ` boundary. (Not investigated here — flagging for the implementor.) + +Once a fix lands, a round-trip regression test belongs in `crates/pampa/tests/roundtrip_tests/qmd-json-qmd` (per `crates/pampa/CLAUDE.md`) using `repro.qmd` as the input. + +## Fix applied (this session) + +After attempting approach (1) — grammar restructuring — I hit a structural conflict between `_inlines`-level soft line breaks and `pandoc_display_math` as an inline element spanning multiple `_line`s, with downstream tests (`Display math with list markers`, `Display math inside fenced div`) regressing into `ERROR` nodes. The fix that landed is a refined version of approach (2): + +**Column-based prefix strip in the AST extractor** (`crates/pampa/src/pandoc/treesitter.rs`): + +The opening `$$` sits at some source column `C` = `node.start_position().column`. The math body "should" start at column `C` on every interior line; bytes at columns `0..C` on those lines are the accumulated continuation prefix added by the chain of enclosing blocks (any combination of blockquotes, list items, fenced divs, etc.). The new `strip_continuation_prefix(content, C)` helper: + +- Splits the body on `\n`. +- Leaves the first piece (content immediately following the opening `$$` on the same line) untouched. +- For every subsequent piece, strips the first `C` bytes — but **only if** every one of those bytes is in `{>, space, tab}`. Otherwise the line was matched via lazy continuation and we leave it alone rather than chewing real content off it. + +This handles arbitrarily-nested combinations (`> - $$`, `- > $$`, `> - > $$`, `> > $$`, `> ::: ... > $$`, etc.) uniformly without enumerating block types or computing per-ancestor offsets, because column position already encodes the cumulative prefix width. + +**Files changed:** +- `crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js` — unchanged (the attempted grammar restructuring was reverted). +- `crates/pampa/src/pandoc/treesitter.rs` — added `strip_continuation_prefix` helper; `pandoc_display_math` arm now passes the extracted body through it. + +**Regression coverage** in `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/`: +- `display_math_in_blockquote.qmd` (the reporter's exact input) +- `display_math_in_nested_blockquote.qmd` +- `display_math_in_list_in_blockquote.qmd` +- `display_math_in_blockquote_in_list.qmd` +- `display_math_in_bq_list_bq.qmd` + +All five fixtures previously diverged on `qmd → JSON → qmd → JSON` and now round-trip cleanly. + +**End-to-end check.** Reporter's repro: + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/181/repro.qmd +[ BlockQuote [Para [Str "Before", SoftBreak, Math DisplayMath "\np = q\n", SoftBreak, Str "After"]] ] + +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/181/repro.qmd +> Before +> $$ +> p = q +> $$ +> After + +$ cargo run --bin pampa -- -t qmd claude-notes/issue-reports/181/repro.qmd | cargo run --bin pampa -- +[ BlockQuote [Para [Str "Before", SoftBreak, Math DisplayMath "\np = q\n", SoftBreak, Str "After"]] ] +``` + +Output inspected: `Math DisplayMath` content is clean (`\np = q\n`), round-tripped qmd has the correct `> ` prefix on every line, and re-parsing the output yields the same AST as the original — fully idempotent. + +**Verification:** `cargo nextest run -p pampa` (3685 passed, 2 skipped); `cargo xtask verify --skip-hub-tests` (full Rust workspace + WASM hub-client build + trace-viewer tests) all pass. Hub-client tests were not run because there is a pre-existing `ERR_MODULE_NOT_FOUND` issue in `vitest run` on `main` HEAD that is unrelated to this change. + +## Scope decision + +Issue contains a single defect; no scope question. Triaging the whole thing. + +## Investigative artifacts + +- `repro.qmd` — exactly the reporter's input. +- `exp-no-blockquote.qmd` — display math at top level, parses cleanly (baseline). +- `exp-only-math.qmd` — minimal blockquoted display math, reproduces the bug. +- `exp-blank-lines.qmd` — blockquote with blank `>` separators around the math block, still buggy. +- `exp-fenced-code-in-bq.qmd` — fenced code in a blockquote, parses cleanly (contrast). + +## Outcome + +- Beads issue filed for the fix (see commit footer). +- No upstream documentation needs updating; this is purely a parser correctness defect. diff --git a/claude-notes/issue-reports/182/repro-no-space.qmd b/claude-notes/issue-reports/182/repro-no-space.qmd new file mode 100644 index 000000000..378a8ac58 --- /dev/null +++ b/claude-notes/issue-reports/182/repro-no-space.qmd @@ -0,0 +1 @@ +See `func()`link done. diff --git a/claude-notes/issue-reports/182/repro-with-space.qmd b/claude-notes/issue-reports/182/repro-with-space.qmd new file mode 100644 index 000000000..1cf0451a4 --- /dev/null +++ b/claude-notes/issue-reports/182/repro-with-space.qmd @@ -0,0 +1 @@ +See `func()` link done. diff --git a/claude-notes/issue-reports/182/triage.md b/claude-notes/issue-reports/182/triage.md new file mode 100644 index 000000000..deb5d86eb --- /dev/null +++ b/claude-notes/issue-reports/182/triage.md @@ -0,0 +1,189 @@ +# Issue #182 — Reader drops whitespace between `pandoc_code_span` and `html_element` siblings + +- **GitHub**: https://github.com/quarto-dev/q2/issues/182 +- **Reporter**: @rundel (Colin Rundel), 2026-05-11 +- **Triage date**: 2026-05-12 +- **Worktree**: `.worktrees/issue-182` (branch `issue-182`, based on `main` @ `16a8d67c`) +- **Beads issue**: bd-nkx4 +- **Scope**: covers the *whitespace-loss* part of the report (reporter's follow-up comment). Explicitly does **not** attempt to fix the underlying ambiguity of two adjacent Code/RawInline spans with no separator in the AST (cscheid's first reply). That case has no unambiguous qmd surface form and isn't the user's actual complaint. + +## Summary + +The reporter's qmd-web sources contain inputs like: + +``` +See `func()` link done. +``` + +with a real space between the closing backtick of the inline code span and the `<` of the bare HTML. After parsing, the AST has `Code` immediately followed by `RawInline` with no intervening `Space`, so the qmd writer emits `` `func()```{=html}…``` and the result is unparseable. The bug is in the **reader**: the space is being dropped during tree-sitter → AST conversion. The writer is innocent. + +The fix is small and local: the `"html_element"` branch in `crates/pampa/src/pandoc/treesitter.rs` already handles leading/trailing whitespace correctly for the anchor-shorthand case (it splits the whitespace out into adjacent `Space` inlines). The same handling is missing from the sibling RawInline case in the same `match` arm. + +## Reproduction + +Fixtures live at: + +- `claude-notes/issue-reports/182/repro-with-space.qmd` — `See \`func()\` link done.\n` +- `claude-notes/issue-reports/182/repro-no-space.qmd` — `See \`func()\`link done.\n` + +### Observed (pampa @ `16a8d67c`) + +Both inputs produce the **same** AST — the space is gone: + +``` +$ cargo run --bin pampa -- < repro-with-space.qmd +[ Para [ Str "See", Space, Code ( "" , [] , [] ) "func()" + , RawInline (Format "html") "" + , Str "link", RawInline (Format "html") "" + , Space, Str "done." ] ] +``` + +(Identical when run on `repro-no-space.qmd`.) + +The writer then collapses `Code` against `RawInline`, and the resulting qmd fails to re-parse: + +``` +$ cargo run --bin pampa -- -t qmd < repro-with-space.qmd +See `func()```{=html}link``{=html} done. + +$ cargo run --bin pampa -- -t qmd < repro-with-space.qmd | cargo run --bin pampa -- +Error: Parse error (offset 13, near ``) +``` + +### Pandoc reference behaviour + +Pandoc *does* distinguish the two inputs and inserts a `Space` between `Code` and the `RawInline` when one was in the source: + +``` +$ pandoc -f markdown -t native < repro-with-space.qmd +[ Para [ Str "See", Space, Code ( "" , [] , [] ) "func()" + , Space ← present + , RawInline (Format "html") "" + , Str "link", RawInline (Format "html") "" + , Space, Str "done." ] ] + +$ pandoc -f markdown -t native < repro-no-space.qmd +[ Para [ Str "See", Space, Code "func()" + , RawInline (Format "html") "" ← no Space + , Str "link", RawInline (Format "html") "" + , Space, Str "done." ] ] +``` + +So fixing the reader to preserve the space brings us into line with Pandoc on the "with space" form. The "no space" form (cscheid's original reply) remains ambiguous and is out of scope here. + +## Localization + +The bug lives in **`crates/pampa/src/pandoc/treesitter.rs`**, in the `"html_element"` arm of the inline visitor (≈ lines 1076–1187 on `main` @ `16a8d67c`). + +### Tree-sitter behaviour observed (with `-v`) + +``` +pandoc_code_span: {Node pandoc_code_span (0, 3) - (0, 12)} + code_span_delimiter: (0, 3) - (0, 5) ← includes the leading space at col 3 + code_span_delimiter: (0,11) - (0,12) +html_element: {Node html_element (0,12) - (0,25)} ← includes leading space at col 12 +html_element: {Node html_element (0,29) - (0,33)} +``` + +Both adjacent inline nodes claim a piece of the surrounding whitespace. The code-span helper handles its half cleanly (see below); the html_element handler doesn't handle its half at all in the RawInline path. + +### How the analogous (working) cases handle it + +1. **`pandoc_code_span` opening delimiter** — `crates/pampa/src/pandoc/treesitter_utils/code_span_helpers.rs:43-57, 109-113`. The helper inspects the opening `code_span_delimiter`; if it starts with ASCII whitespace it emits an explicit `Space` inline *before* the `Code` node. (This is why `See ` ends up as `Str "See", Space, Code …` and not `Str "See", Code …`.) Comment on line 45 confirms: *"The closing delimiter never includes trailing space in the grammar"* — so the trailing-side whitespace is always owned by the following sibling node. + +2. **`html_element` → anchor shorthand `<#id>`** — `crates/pampa/src/pandoc/treesitter.rs:1084-1162`. Computes `leading_ws` and `trailing_ws` from `raw_text.len() - raw_text.trim_start().len()` (resp. `trim_end`), pushes a `Space` inline before the synthesized `Link` if `leading_ws > 0`, and pushes another after if `trailing_ws > 0`. This is exactly the pattern needed for the RawInline branch. + +### The buggy branch + +`crates/pampa/src/pandoc/treesitter.rs:1076-1187`: + +```rust +"html_element" => { + let raw_text = node.utf8_text(input_bytes).unwrap(); + let text = raw_text.trim().to_string(); // ← silently drops both edges + if let Some(anchor_id) = parse_anchor_shorthand(&text) { + // anchor branch: correctly splits whitespace into Space inlines + … + } else { + // RawInline branch: emits a single RawInline, leading/trailing whitespace gone + PandocNativeIntermediate::IntermediateInline(Inline::RawInline(RawInline { + format: "html".to_string(), + text, + source_info: node_source_info_with_context(node, context), + })) + } +} +``` + +The RawInline branch needs the same leading_ws/trailing_ws → `IntermediateInlines(…)` splitting that the anchor branch already does. + +## Open questions — resolved during triage + +**Q1.** Is the root cause in the writer (failing to add a separating space) or in the reader (dropping an existing space)? + +*Experiment.* Compared the AST emitted by `cargo run --bin pampa --` on the with-space and no-space fixtures. Both ASTs are byte-identical and contain no `Space` between `Code` and `RawInline`. The reader is collapsing the two inputs into one AST; the writer cannot recover information that isn't there. + +*Conclusion.* Root cause is in the reader. The writer is doing the best it can with the AST it gets. + +**Q2.** Does this require redesigning whitespace handling across the parser, or is there a local fix? + +*Experiment.* Read the visitor for `"html_element"` and the helper for `"pandoc_code_span"`. Found that: + +- The code-span helper already cleanly handles its half (leading whitespace via the opening delimiter; closing delimiter never includes trailing space, per the comment in code_span_helpers.rs:45). +- The anchor-shorthand branch of the html_element visitor already implements the leading_ws/trailing_ws → adjacent-`Space` pattern. + +*Conclusion.* Local fix is feasible: mirror the anchor branch's leading_ws/trailing_ws handling into the RawInline branch of the same `match` arm. No cross-parser whitespace redesign is required. + +**Q3.** Does fixing this regress the "no separator" ambiguity case (cscheid's original reply)? + +*Experiment / reasoning.* The fix only adds `Space` inlines when the *html_element node text* actually contained leading/trailing whitespace in the source. The pathological case (`` `foo`` ``: two adjacent inline nodes with no whitespace between them) still emits an AST with no `Space`, which is the correct representation and still has no unambiguous qmd surface form. Reporter agrees the "no space" case is a separate, harder problem and out of scope (issue #182 thread, 2026-05-12). + +*Conclusion.* No regression for the "truly adjacent" case. Round-trip there remains a known-impossible problem. + +## Outcome / recommended next step + +**Filed as bd-nkx4** for the reader-side fix. Scope (recommended for the implementer, not part of triage): + +1. **Test first** (per `crates/pampa/CLAUDE.md` TDD rule): + - Add `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/code_space_html_inline.qmd` (or similar) containing `` See `func()` link done. `` to lock in the round-trip. + - Add a focused AST test asserting that `Code` followed by an `html_element` separated by whitespace produces `Code, Space, RawInline` (mirror of an existing anchor-branch test). + - Verify both fail before any code change. +2. **Fix** in `crates/pampa/src/pandoc/treesitter.rs` `"html_element"` arm: in the RawInline (non-anchor) branch, compute `leading_ws` / `trailing_ws` from `raw_text` and return `IntermediateInlines(vec![Space?, RawInline, Space?])` instead of a single `IntermediateInline`. The anchor branch above (lines 1084–1162) is the model — adapt the `Space` source-info construction directly. +3. **Verify**: + - `cargo nextest run -p pampa` (and workspace, per CLAUDE.md step 5). + - `cargo xtask verify --skip-hub-build` (Rust-only change; no `quarto-core`/`pandoc-types` touched). + - End-to-end check: both reproduction fixtures here should now AST → qmd → AST round-trip cleanly and the qmd intermediate should contain the separating space. +4. **Watch for snapshot churn.** Any existing snapshot test whose qmd contained `` adjacent to whitespace will likely have its AST change from `RawInline` to `Space, RawInline` (or `RawInline, Space`). Each change needs to be inspected — if a snapshot starts emitting an *extra* `Space` that wasn't in the source, that is the fix going too far. + +I will respond on the GH issue once the beads issue is filed, linking it and confirming we accept the reporter's framing of the bug. + +## Verification commands used + +```bash +# Issue body + comments +gh issue view 182 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments + +# Pre-flight (green at 16a8d67c) +cargo xtask verify --skip-hub-build + +# Reproduction +cargo run --bin pampa -- < claude-notes/issue-reports/182/repro-with-space.qmd +cargo run --bin pampa -- -t qmd < claude-notes/issue-reports/182/repro-with-space.qmd +cargo run --bin pampa -- -t qmd < claude-notes/issue-reports/182/repro-with-space.qmd \ + | cargo run --bin pampa -- + +# Pandoc reference +pandoc -f markdown -t native < claude-notes/issue-reports/182/repro-with-space.qmd +pandoc -f markdown -t native < claude-notes/issue-reports/182/repro-no-space.qmd + +# Tree-sitter CST +cargo run --bin pampa -- -v < claude-notes/issue-reports/182/repro-with-space.qmd 2>&1 \ + | grep -E "(html_element|code_span)" +``` + +## Cross-references + +- `crates/pampa/src/pandoc/treesitter.rs:1076` — `"html_element"` arm (bug site). +- `crates/pampa/src/pandoc/treesitter.rs:1084-1162` — anchor branch (working model to copy). +- `crates/pampa/src/pandoc/treesitter_utils/code_span_helpers.rs:43-57, 109-113` — code span side, also a working model; note line 45 comment confirming the closing delimiter never carries trailing whitespace (so the html_element is the right place to emit the post-Code space). +- `crates/pampa/CLAUDE.md` — TDD-first rule for parser fixes. diff --git a/claude-notes/issue-reports/183/exp-single-codeblock.qmd b/claude-notes/issue-reports/183/exp-single-codeblock.qmd new file mode 100644 index 000000000..e4a745fd9 --- /dev/null +++ b/claude-notes/issue-reports/183/exp-single-codeblock.qmd @@ -0,0 +1,6 @@ +::: {.list-table} +- - foo + - ```python + x + ``` +::: diff --git a/claude-notes/issue-reports/183/exp-two-paras.qmd b/claude-notes/issue-reports/183/exp-two-paras.qmd new file mode 100644 index 000000000..dad74283e --- /dev/null +++ b/claude-notes/issue-reports/183/exp-two-paras.qmd @@ -0,0 +1,6 @@ +::: {.list-table} +- - foo + - Add values: + + Then more text. +::: diff --git a/claude-notes/issue-reports/183/expected-output.qmd b/claude-notes/issue-reports/183/expected-output.qmd new file mode 100644 index 000000000..b5c5fe7f5 --- /dev/null +++ b/claude-notes/issue-reports/183/expected-output.qmd @@ -0,0 +1,9 @@ +::: {.list-table} + +* - foo + - Add values: + + ```python + x + ``` +::: diff --git a/claude-notes/issue-reports/183/observed-output.qmd b/claude-notes/issue-reports/183/observed-output.qmd new file mode 100644 index 000000000..8e18ea4b7 --- /dev/null +++ b/claude-notes/issue-reports/183/observed-output.qmd @@ -0,0 +1,9 @@ +::: {.list-table} + +* - foo + - + Add values: + ```python + x + ``` +::: diff --git a/claude-notes/issue-reports/183/repro.qmd b/claude-notes/issue-reports/183/repro.qmd new file mode 100644 index 000000000..b2888efb5 --- /dev/null +++ b/claude-notes/issue-reports/183/repro.qmd @@ -0,0 +1,8 @@ +::: {.list-table} +- - foo + - Add values: + + ```python + x + ``` +::: diff --git a/claude-notes/issue-reports/183/triage.md b/claude-notes/issue-reports/183/triage.md new file mode 100644 index 000000000..380edc2a5 --- /dev/null +++ b/claude-notes/issue-reports/183/triage.md @@ -0,0 +1,250 @@ +# Issue #183 — qmd writer emits list-table cell with multiple blocks as a broken bullet item + +- **GitHub**: https://github.com/quarto-dev/q2/issues/183 +- **Reporter**: @rundel (Colin Rundel), 2026-05-11 +- **Triage date**: 2026-05-14 +- **Worktree**: `.worktrees/issue-183` (branch `issue-183`, based on `main` @ `76b8fe3e`) +- **Beads issue**: bd-oxsr +- **Scope**: Writer bug in `write_list_table` (qmd writer). Related to #174 and #180 only in the broad category of "writer produces qmd that the reader rejects"; mechanism is independent. + +## Summary + +A `.list-table` div is parsed into a real `Table`. When any cell holds **more than one block** (e.g. a `Para` followed by a `CodeBlock`), the qmd writer emits the inner row-marker line with **no inline content** (` - \n`) and then writes every block in the cell at 4-space indent with **no blank-line separation between blocks**. The resulting shape is rejected by the qmd reader, so the writer output fails to round-trip and any document containing this pattern cannot be regenerated. Reproduced at HEAD `76b8fe3e`. Root cause is local to the multi-block / non-Plain-non-Para path in `write_list_table` in `crates/pampa/src/writers/qmd.rs:1075-1115`. Fix scope is small and contained. + +## Reproduction + +Repro file: `claude-notes/issue-reports/183/repro.qmd` + +```qmd +::: {.list-table} +- - foo + - Add values: + + ```python + x + ``` +::: +``` + +### Parse (Pandoc AST) + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/183/repro.qmd +[ Table … [Row … [Cell … [Para [Str "foo"]], + Cell … [Para [Str "Add", Space, Str "values:"], + CodeBlock ( "" , ["python"] , [] ) "x"]] …] ] +``` + +Two cells; the second cell holds **two blocks** — a `Para` and a `CodeBlock`. + +### Writer output (observed) + +`claude-notes/issue-reports/183/observed-output.qmd`: + +```qmd +::: {.list-table} + +* - foo + - + Add values: + ```python + x + ``` +::: +``` + +Two distinct defects: + +1. **Empty inner-marker line** — ` - ` (followed by a trailing space and newline) instead of putting the first `Para` inline with the marker. +2. **No blank line between blocks** — `Add values:` (a `Para`) is followed immediately by the opening `` ```python `` fence on the next indented line, with no blank line separating them. + +### Re-parse of writer output (observed failure) + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/183/observed-output.qmd +Error: Parse error (line 5, col 5 — `Add`) +``` + +The reader does not accept the writer's emitted shape. + +### Hand-fixed shape (round-trips cleanly) + +`claude-notes/issue-reports/183/expected-output.qmd`: + +```qmd +::: {.list-table} + +* - foo + - Add values: + + ```python + x + ``` +::: +``` + +Re-parsing this hand-fixed shape yields the same AST as the original input: + +``` +[ Table … [Row … [Cell … [Para [Str "foo"]], + Cell … [Para [Str "Add", Space, Str "values:"], + CodeBlock ( "" , ["python"] , [] ) "x"]] …] ] +``` + +So the reader is fine; only the writer is wrong. + +## Bug surface — what triggers it + +Three cell shapes were exercised. Two trigger the bug, one does not: + +| Cell content | Writer emits empty marker line | Roundtrips? | Path in writer | +|--- |--- |--- |--- | +| Single `Plain` / `Para` | no | yes | line 1078-1089 | +| Single non-`Plain`/non-`Para` block (e.g. `CodeBlock`) | **yes** | **no** | line 1090-1100 (`other` arm) | +| Multiple blocks | **yes** | **no** | line 1102-1113 (`else` arm) | + +Both broken paths share the same two defects: + +- They `writeln!(buf)?` immediately after writing `- `, so the marker line ends up empty. +- They emit each block back-to-back with no blank-line separator between blocks within the cell. + +Fixture for the single-non-Para case: `claude-notes/issue-reports/183/exp-single-codeblock.qmd`. +Fixture for the two-paragraph case: `claude-notes/issue-reports/183/exp-two-paras.qmd`. + +The two-paragraph fixture also fails to round-trip and confirms that the missing blank line — not anything code-block-specific — is the second defect: any two consecutive blocks at indent-4 collapse into a single paragraph or otherwise misparse. + +## Localization + +**File**: `crates/pampa/src/writers/qmd.rs` +**Function**: `write_list_table` (introduced at line 937) + +The two broken arms are: + +```rust +// crates/pampa/src/writers/qmd.rs:1078-1115 (excerpted) + +if cell.content.len() == 1 { + match &cell.content[0] { + Block::Plain(plain) => { /* inline — OK */ } + Block::Paragraph(para) => { /* inline — OK */ } + other => { + writeln!(buf)?; // ← writes "- \n" — defect #1 (empty marker line) + let mut block_buf = Vec::::new(); + write_block(other, &mut block_buf, ctx)?; + let content = String::from_utf8_lossy(&block_buf); + for line in content.lines() { + writeln!(buf, " {}", line)?; + } + continue; + } + } +} else { + // Multiple blocks — write on new lines with indentation + writeln!(buf)?; // ← defect #1 again + for block in &cell.content { + let mut block_buf = Vec::::new(); + write_block(block, &mut block_buf, ctx)?; + let content = String::from_utf8_lossy(&block_buf); + for line in content.lines() { + writeln!(buf, " {}", line)?; + } + // ← defect #2: no blank-line separator between consecutive blocks + } + continue; +} +``` + +The analogous *working* model — first block inline with the marker, blank line, then remaining blocks indented — is how regular markdown loose bullet lists handle multi-block items. The single-`Para`/single-`Plain` arms already do the first half (inline emission); the rest of the fix is to extend that treatment into the other two arms. + +## Fix sketch (for the beads issue) + +In `write_list_table`'s cell-emission loop: + +1. **Multi-block case**: if the first block is `Plain` or `Paragraph`, emit its inlines on the marker line. Then for each subsequent block (or for all blocks if the first wasn't `Plain`/`Paragraph`): + - emit a blank line + - emit the block at 4-space indent +2. **Single non-Plain/non-Para case**: same shape — empty inline content on the marker line is OK only if it's `[]`-marked, otherwise write a blank line first, then the indented block. (The hand-fixed fixture shows the blank-line variant reparses cleanly; the `[]` variant should be checked but is likely unnecessary if defect #2 is also fixed.) + +In both cases, between any two consecutive blocks inside one cell, emit a blank line. + +This mirrors what the writer already does for top-level loose bullet lists (and what issues #174/#180 are about for *those* writers — but those bugs are separate). + +## Open questions — resolved during triage + +**Q1**: Is the reader at fault? Maybe it should accept the writer's current shape. +**Experiment**: Hand-fixed the writer output and re-parsed it (`expected-output.qmd`). It produces the original AST. So the reader is correct for the canonical loose-list-item shape; the writer is the one producing an off-spec form. +**Conclusion**: Writer-side fix only. + +**Q2**: Is this purely a `.list-table` problem, or does it affect regular nested bullet lists too? +**Experiment**: Inspected the writer code path. `write_list_table` is the only caller of this particular multi-block / 4-space-indent emission. Regular `BulletList` emission lives elsewhere (and has its own loose/tight bugs — see #174 — but the mechanism is independent). +**Conclusion**: Scoped to `write_list_table`. #174 is related in *symptom* but is in a different code path. + +**Q3**: Does the bug fire for a single non-`Plain`/non-`Para` block (e.g. a row with one cell that's just a code block)? +**Experiment**: `exp-single-codeblock.qmd`. +**Conclusion**: Yes — the `other` arm at line 1090 has defect #1 too. Both the single-non-Para arm and the multi-block arm need the same fix. + +**Q4**: Should the writer prefer a pipe table for these tables that don't need list-table features? +**Conclusion**: Out of scope. The `should_use_pipe_table` decision (line 874) already opts cells with `CodeBlock`/multi-block content into list-table, which is correct. The bug is that the list-table writer emits a broken shape for the cases where list-table is the only option. + +## Outcome / recommended next step + +Filed bd-oxsr (see § Cross-references). Fix is small, single-file (`crates/pampa/src/writers/qmd.rs`), TDD-able through `tests/roundtrip_tests/qmd-json-qmd` with the three fixtures already captured under `claude-notes/issue-reports/183/`. + +### Fix applied — 2026-05-14 + +Fix landed on this branch. Plan: `claude-notes/plans/2026-05-14-list-table-multiblock-cell-fix.md`. + +Summary of the change in `crates/pampa/src/writers/qmd.rs`: + +- Replaced the cell-emission block in `write_list_table` (~lines 1069-1116 of the pre-fix file) with a uniform three-shape algorithm: empty cell / first block is `Plain`/`Paragraph` / first block is anything else. Subsequent blocks (2nd … nth) within any cell are emitted as blank-line-separated 4-space-indented stanzas. +- Added two helpers: `write_cell_block_on_marker_line` (for the first block when it is not `Plain`/`Paragraph` — puts its first line on the marker line, indents continuation lines) and `write_cell_block_indented` (for every subsequent block). + +One refinement vs. the triage's original fix sketch: the case where the first block is non-`Plain`/non-`Paragraph` (e.g. a `CodeBlock`-only cell) does **not** leave the marker line empty followed by a blank line — that shape introduced a phantom empty `Paragraph` in the reparsed AST. Instead the block's first line continues the marker line, mirroring how a regular CommonMark list item with non-`Plain` content looks. Verified by probing the reader before committing. + +Validated: + +- `test_qmd_roundtrip_consistency` (was the regression sentinel): all three new fixtures green. +- `cargo nextest run --workspace`: 8859/8859 pass. +- End-to-end CLI repro: writer output for the bug-report input round-trips back to a byte-identical AST. +- No snapshot deltas: the change does not affect any existing `list-table-*` snapshot (all use single-`Plain` cells, an unchanged path). + +## Verification commands used + +```bash +gh issue view 183 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments + +# Pre-flight (in main checkout) +cargo xtask verify --skip-hub-build + +# In the worktree +cargo xtask verify --skip-hub-build --skip-hub-tests + +# Reproduce +cargo run --bin pampa -- claude-notes/issue-reports/183/repro.qmd +cargo run --bin pampa -- -t qmd claude-notes/issue-reports/183/repro.qmd +cargo run --bin pampa -- -t qmd claude-notes/issue-reports/183/repro.qmd \ + | tee claude-notes/issue-reports/183/observed-output.qmd +cargo run --bin pampa -- claude-notes/issue-reports/183/observed-output.qmd # parse error + +# Side fixtures +cargo run --bin pampa -- claude-notes/issue-reports/183/exp-single-codeblock.qmd +cargo run --bin pampa -- -t qmd claude-notes/issue-reports/183/exp-single-codeblock.qmd +cargo run --bin pampa -- claude-notes/issue-reports/183/exp-two-paras.qmd +cargo run --bin pampa -- -t qmd claude-notes/issue-reports/183/exp-two-paras.qmd + +# Hand-fixed shape +cargo run --bin pampa -- claude-notes/issue-reports/183/expected-output.qmd +``` + +## Cross-references + +- **bd-oxsr** — beads issue filed from this triage. Carries the fix-scope description and TDD plan. +- GitHub #174 — loose-bullet-list writer drops looseness when a nested sublist is present. Related symptom (round-trip failure caused by writer output), independent code path. +- GitHub #180 — Figure-then-Para spacing bug. CLOSED. Same family ("writer emits qmd the reader rejects"), independent code path. +- `crates/pampa/CLAUDE.md` — mandatory TDD checklist for any fix in this crate. +- `crates/pampa/src/writers/qmd.rs:937` — `write_list_table` (target of the fix). +- `crates/pampa/src/writers/qmd.rs:1124-1128` — incremental-writer coupling note: tables are always fully rewritten, so the fix does not need to handle incremental splicing. +- Reporter-cited quarto-web usages (real-world hits): + - `docs/extensions/lua-api.qmd:292` + - `docs/blog/posts/2026-03-24-1.9-release/index.qmd:91` + - `docs/blog/posts/2026-03-24-1.9-release/index.qmd:114` diff --git a/claude-notes/issue-reports/184/repro.qmd b/claude-notes/issue-reports/184/repro.qmd new file mode 100644 index 000000000..8a5710191 --- /dev/null +++ b/claude-notes/issue-reports/184/repro.qmd @@ -0,0 +1,7 @@ +Before. + + categories: + - A + - B + +After. diff --git a/claude-notes/issue-reports/184/triage.md b/claude-notes/issue-reports/184/triage.md new file mode 100644 index 000000000..c6d2d2c61 --- /dev/null +++ b/claude-notes/issue-reports/184/triage.md @@ -0,0 +1,101 @@ +# Triage: issue #184 — Indented (4-space) code blocks parsed as paragraphs + +- **GH:** https://github.com/quarto-dev/q2/issues/184 +- **Reporter:** @rundel (2026-05-11) +- **Branch:** `issue-184` +- **Verdict:** Real bug. Project policy (per @cscheid's comment on the issue) is that Quarto Markdown does **not** support 4-space indented code blocks; the parser must reject them with a high-quality error message rather than silently rewriting them. +- **Plan:** `claude-notes/plans/2026-05-14-q-2-35-indented-code-block-error.md` +- **Beads:** [bd-7l1u](.beads) — _Q-2-35: Reject 4-space indented code blocks with a custom parse error (issue #184)_ + +## What the user reported + +CommonMark indented code blocks (lines starting with four spaces) are not recognized by pampa's parser. The indented content is parsed as a series of `Para` blocks (with the indentation **stripped**), so the file silently changes shape on a qmd → qmd round-trip. + +Reporter's example, reproduced verbatim by `claude-notes/issue-reports/184/repro.qmd`: + +``` +Before. + + categories: + - A + - B + +After. +``` + +## Reproduction at HEAD (`main` of issue-184 worktree, 2026-05-14) + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/184/repro.qmd +[ Para [Str "Before."] +, Para [Str "categories:"] +, Para [Str "-", Space, Str "A"] +, Para [Str "-", Space, Str "B"] +, Para [Str "After."] +] +``` + +Round-trip through the qmd writer: + +``` +$ cargo run --bin pampa -- claude-notes/issue-reports/184/repro.qmd -t qmd +Before. + +categories: + +- A + +- B + +After. +``` + +The indentation is gone; a second pass would now read this as a real `BulletList`. Confirms the issue exactly. + +## Diagnosis + +The block-level scanner already tracks per-line leading whitespace as `s->indentation` (and `s->column` for tab expansion). After the per-block matchers consume their share (e.g. `list_item_indentation(block)` for a list-item context, the `>` plus optional space for a blockquote), a non-zero `s->indentation` is what's "leftover" — the indentation that the user wrote *beyond* what the surrounding container required. + +Every block-start emitter in `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c` gates on `s->indentation <= 3` (e.g. `THEMATIC_BREAK` at line 742, ATX heading at line 868, the various list-marker emitters at 888 / 933 / 1007 / 1081, fenced code at line 639). When `s->indentation >= 4` and *none* of those emitters match, control falls through and the line is consumed as paragraph content. That fall-through is the trap. + +There is **no existing diagnostic** for this case. The scanner silently consumes the whitespace, and the leading spaces never reach the AST or the writer — which is why round-tripping rewrites the file. + +## Resolution direction (decided with the user) + +Adopt the **same scheme** the parser already uses for Q-2-32 (`***` triple-star emphasis): + +1. Detect the disallowed construct in `scanner.c`. +2. Emit an external token that is declared in `grammar.js`'s `externals` list **but never consumed by any rule body**. +3. The grammar then has nowhere to shift the token, so tree-sitter raises a parse error at exactly that point. +4. The Merr-style error table in `crates/quarto-parse-errors/` maps the resulting `(state, sym)` pair to a templated user-facing message rendered through `quarto-error-reporting`. + +Confirmed wiring of the existing Q-2-32 example: + +| Stage | File / line | +| --- | --- | +| Token enum | `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c:132` (`TRIPLE_STAR`) | +| Detection logic | `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c:733-735` | +| Externals declaration (unused) | `crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js:1052` (`$._triple_star_error`) | +| Error corpus | `crates/pampa/resources/error-corpus/Q-2-32.json` | +| Error table generation script | `crates/pampa/scripts/build_error_table.ts` | +| Generated lookup table | `crates/pampa/resources/error-corpus/_autogen-table.json` | +| `(state, sym)` → message | `crates/quarto-parse-errors/src/error_table.rs:65-94` (`lookup_error_entry`) | +| Diagnostic rendering | `crates/quarto-parse-errors/src/error_generation.rs:30-200` | +| QMD reader integration | `crates/pampa/src/readers/qmd_error_messages.rs:24-36` (called from `qmd.rs:124`) | +| Snapshot tests | `crates/pampa/tests/test_error_corpus.rs` (`crates/pampa/snapshots/error-corpus/text/`) | + +The infrastructure is in place; this is a small additive change. + +## Scope decisions (confirmed with @cscheid in this triage) + +1. **List-item context:** Error fires whenever the **leftover** `s->indentation` (after all container matchers have consumed their share) is `>= 4`. So a continuation paragraph properly indented to a list item's level is unaffected, but a list-item continuation that itself has 4 *additional* leading spaces is also rejected. +2. **Error code & wording:** `Q-2-35` (next free in the Q-2 sequence). Title: *"Indented code blocks are not supported"*. Message: *"Quarto Markdown does not support 4-space indented code blocks. Use a fenced code block (` ``` `) instead, or remove the leading indentation."* +3. **Documentation:** Add a Known Limitations entry in `crates/tree-sitter-qmd/tree-sitter-markdown/CONTRIBUTING.md` (and a comment in `grammar.js` near the new external) following the Q-2-32 precedent. User docs in `docs/` updated only if there is an obvious place. + +## Outcome + +- One beads issue filed (the implementation work). +- This triage doc + `repro.qmd` committed on branch `issue-184`. +- Plan document (TDD-shaped) committed alongside, referenced from the beads issue. + +No incidental sub-issues discovered during triage. diff --git a/claude-notes/issue-reports/195/repro-list-table.qmd b/claude-notes/issue-reports/195/repro-list-table.qmd new file mode 100644 index 000000000..0b6e45751 --- /dev/null +++ b/claude-notes/issue-reports/195/repro-list-table.qmd @@ -0,0 +1,6 @@ +:::{.list-table} +- - H1 + - H2 +- - X + - +::: diff --git a/claude-notes/issue-reports/195/repro-plain.qmd b/claude-notes/issue-reports/195/repro-plain.qmd new file mode 100644 index 000000000..5c394789c --- /dev/null +++ b/claude-notes/issue-reports/195/repro-plain.qmd @@ -0,0 +1,4 @@ +- - H1 + - H2 +- - X + - diff --git a/claude-notes/issue-reports/195/triage.md b/claude-notes/issue-reports/195/triage.md new file mode 100644 index 000000000..63c40d6ea --- /dev/null +++ b/claude-notes/issue-reports/195/triage.md @@ -0,0 +1,207 @@ +# Issue #195 — Empty bullet-list items do not round-trip: dropped in plain `BulletList`, mutated to `[Plain []]` in list-table cells + +- **GitHub**: https://github.com/quarto-dev/q2/issues/195 +- **Reporter**: @rundel (Colin Rundel), 2026-05-14 +- **Triage date**: 2026-05-14 +- **Worktree**: `.worktrees/issue-195` (branch `issue-195`, based on `main` @ `59e8003f`) +- **Beads issue**: bd-u50w +- **Scope**: both reported facets — (a) plain `BulletList` dropping a trailing empty item on round-trip, and (b) `:::{.list-table}` cells mutating empty cells from `[]` to `[Plain []]`. Both have the same root cause class (writer emits the wrong text for a *truly* empty AST item / cell, i.e. `Vec` of length 0). + +## Summary + +Two qmd-writer bugs reported as one issue, both reproduced exactly as +described. Reader behavior is correct: input `-` (bare bullet marker, no +content) parses to a `Vec` of length 0 (`[]`). The writer, however, +has no codepath that emits a bare `-` marker line. For plain `BulletList` +the truly-empty item falls through to a loop that writes nothing, so the +item disappears. For list-table cells the writer emits literal `- []`, +which the reader reparses as `[Plain []]` (`[]` becomes inline text inside +a `Plain` block). + +The fix is small and localized to two functions in +`crates/pampa/src/writers/qmd.rs`. The reporter's suggested approach +(emit a bare `-` marker for empty items) matches existing reader behavior +and is the right shape. + +## Reproduction + +Fixtures committed alongside this doc: + +- `repro-plain.qmd` — plain `BulletList` with a trailing empty item +- `repro-list-table.qmd` — `:::{.list-table}` with an empty cell + +### Plain bullet list (item dropped) + +``` +$ cat claude-notes/issue-reports/195/repro-plain.qmd +- - H1 + - H2 +- - X + - + +$ cargo run --quiet --bin pampa -- < claude-notes/issue-reports/195/repro-plain.qmd +[ BulletList [[BulletList [[Plain [Str "H1"]], [Plain [Str "H2"]]]], + [BulletList [[Plain [Str "X"]], []]]] ] + +$ cargo run --quiet --bin pampa -- -t qmd < claude-notes/issue-reports/195/repro-plain.qmd +* * H1 + * H2 + +* * X + # ← no marker line for the empty item + +$ | qmd -> qmd -> AST: +[ BulletList [[BulletList [[Plain [Str "H1"]], [Plain [Str "H2"]]]], + [BulletList [[Plain [Str "X"]]]]] ] + # ← the empty [] child is gone +``` + +### List-table cell (`[]` mutated to `[Plain []]`) + +``` +$ cat claude-notes/issue-reports/195/repro-list-table.qmd +:::{.list-table} +- - H1 + - H2 +- - X + - +::: + +$ cargo run --quiet --bin pampa -- -t qmd < claude-notes/issue-reports/195/repro-list-table.qmd +::: {.list-table} + +* - H1 + - H2 +* - X + - [] # ← writer emits literal "- []" +::: + +# After round-trip, the second cell on the last row goes from +# Cell ... [] (empty content) +# to +# Cell ... [Plain []] (Plain block containing zero inlines) +``` + +## Localization + +Both bugs live in `crates/pampa/src/writers/qmd.rs`. + +**Bug A — plain `BulletList` drops truly-empty items.** `write_bulletlist` +at L461–502. The `is_empty_item` predicate at L480–485 only matches +items of `item.len() == 1` whose single block is an empty `Plain` / +`Paragraph`: + +```rust +let is_empty_item = item.len() == 1 + && match &item[0] { + Block::Plain(plain) => plain.content.is_empty(), + Block::Paragraph(para) => para.content.is_empty(), + _ => false, + }; +``` + +A truly empty item (`item.is_empty()`, i.e. `Vec` of length 0) +falls through to the `else` branch at L490–499, where the inner +`for (j, block) in item.iter().enumerate()` loop runs zero times and +writes nothing. The outer `BulletListContext`'s prefix machinery is +all that's left, producing the ` ` (two-space) blank line we saw — +not a `*` marker. There is no codepath in this function that ever +emits a bare `*` (or `*\n`) marker. + +**Bug B — list-table empty cells written as `- []`.** `write_list_table` +at L986–1163. The empty-cell branch at L1129–1133: + +```rust +if cell.content.is_empty() { + if !needs_attrs { + write!(buf, "[]")?; + } + writeln!(buf)?; +} +``` + +The marker `- ` has already been written at L1095. So an empty cell with +no special attrs becomes the literal line `- []`. The reader then parses +`[]` as inline text inside the cell's content, producing `[Plain []]`. + +**Model for the fix.** The reader already accepts a bare `-` line as an +empty item — the input `repro-plain.qmd` parses to `[Plain "X"], []` +exactly because of that. The fix in both functions is to emit a bare +marker (e.g. `*` or `-` followed by `\n`) instead of nothing (Bug A) or +`- []` (Bug B). The existing fixture +`crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_list_item.qmd` +covers a *different* shape — `[Plain []]` writing back to `* []` — and +should keep round-tripping; only the truly-empty (`[]`) case needs new +behavior. + +## Open questions — resolved during triage + +- **Q: Is the same bug present in `write_orderedlist` (L504+) for + ordered lists?** + Inspected the function. `write_orderedlist` has no `is_empty_item` + check at all, so an empty item iterates zero blocks and writes + nothing (analogous to Bug A). Not reported in #195, but the same + fix-shape applies. Flagging in the beads issue's "in scope?" section + rather than triaging separately — bundled work is small. +- **Q: Does `- ` with trailing whitespace round-trip the same as bare + `-`?** + Not tested in this triage. The fix should prefer no trailing + whitespace to keep snapshot diffs clean. The implementer should + verify by reading the existing reader behavior or adding a fixture. + +## Outcome / recommended next step + +Filed bd-u50w with the fix scope: emit bare marker lines for truly-empty +items in (1) `write_bulletlist`, (2) `write_orderedlist` (covered by the +same root cause; flagged as a discovered defect), and (3) the empty-cell +branch of `write_list_table`. Add round-trip fixtures for each of the +two reported AST shapes under `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/`. + +## Triage-time side quest: beads JSONL corruption (resolved) + +During this triage, `br` refused to operate due to a pre-existing JSONL +inconsistency (`dependencies row count mismatch — expected 900, found +882`). Root cause: two parallel branches both touched +`.beads/issues.jsonl`; a merge landed a state that dropped five records +(`bd-kw93`, `bd-mrx1`, `bd-hfjj`, `bd-pf63`, `bd-z529`) while keeping +later commits that referenced them as parents/deps, leaving 18 dangling +edges. All five records were restored verbatim from git history in a +separate commit on `main` (see commit message +"sync beads: restore 5 records dropped by branch merge"). After +restore: `br doctor` reports HEALTH OK. Unrelated to issue #195 itself. + +## Verification commands used + +```bash +# Pre-flight +cargo xtask verify --skip-hub-build + +# Issue retrieval +gh issue view 195 --repo quarto-dev/q2 \ + --json title,body,author,createdAt,labels,comments + +# Reproduce both bugs +cargo build --bin pampa +cargo run --quiet --bin pampa -- \ + < claude-notes/issue-reports/195/repro-plain.qmd +cargo run --quiet --bin pampa -- -t qmd \ + < claude-notes/issue-reports/195/repro-plain.qmd +cargo run --quiet --bin pampa -- -t qmd \ + < claude-notes/issue-reports/195/repro-plain.qmd \ + | cargo run --quiet --bin pampa -- +# (and likewise for repro-list-table.qmd) + +# Localize +grep -n "BulletList\|list_table\|list-table" crates/pampa/src/writers/qmd.rs +``` + +## Cross-references + +- `crates/pampa/src/writers/qmd.rs` — `write_bulletlist` (L461), + `write_orderedlist` (L504), `write_list_table` (L986). +- `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/empty_list_item.qmd` + — existing coverage for `[Plain []]`, **not** for `[]`. +- `crates/pampa/CLAUDE.md` — round-trip test workflow (test first, fail + first, then fix). +- In-the-wild instance cited by the reporter: + https://github.com/quarto-dev/quarto-web/blob/baeab38627fcc3f3a9ea3ca3ea689ece413df65d/docs/extensions/lua-api.qmd#L322 diff --git a/claude-notes/issue-reports/196/exp-bullet-list.qmd b/claude-notes/issue-reports/196/exp-bullet-list.qmd new file mode 100644 index 000000000..108f7be75 --- /dev/null +++ b/claude-notes/issue-reports/196/exp-bullet-list.qmd @@ -0,0 +1,3 @@ +* Outer: + + ![](img.png){.border} diff --git a/claude-notes/issue-reports/196/exp-no-trailing-ws.qmd b/claude-notes/issue-reports/196/exp-no-trailing-ws.qmd new file mode 100644 index 000000000..146258d3b --- /dev/null +++ b/claude-notes/issue-reports/196/exp-no-trailing-ws.qmd @@ -0,0 +1,3 @@ +4) Outer: + + ![](img.png){.border} diff --git a/claude-notes/issue-reports/196/exp-tab-on-blank.qmd b/claude-notes/issue-reports/196/exp-tab-on-blank.qmd new file mode 100644 index 000000000..d8b9e21f7 --- /dev/null +++ b/claude-notes/issue-reports/196/exp-tab-on-blank.qmd @@ -0,0 +1,3 @@ +4) Outer: + + ![](img.png){.border} diff --git a/claude-notes/issue-reports/196/exp-trailing-ws-text.qmd b/claude-notes/issue-reports/196/exp-trailing-ws-text.qmd new file mode 100644 index 000000000..c4581cff7 --- /dev/null +++ b/claude-notes/issue-reports/196/exp-trailing-ws-text.qmd @@ -0,0 +1,3 @@ +4) Outer: + + second paragraph text diff --git a/claude-notes/issue-reports/196/exp-two-trailing-spaces.qmd b/claude-notes/issue-reports/196/exp-two-trailing-spaces.qmd new file mode 100644 index 000000000..4a93c9069 --- /dev/null +++ b/claude-notes/issue-reports/196/exp-two-trailing-spaces.qmd @@ -0,0 +1,3 @@ +4) Outer: + + ![](img.png){.border} diff --git a/claude-notes/issue-reports/196/repro.qmd b/claude-notes/issue-reports/196/repro.qmd new file mode 100644 index 000000000..e3696cfaa --- /dev/null +++ b/claude-notes/issue-reports/196/repro.qmd @@ -0,0 +1,3 @@ +4) Outer: + + ![](img.png){.border} diff --git a/claude-notes/issue-reports/196/triage.md b/claude-notes/issue-reports/196/triage.md new file mode 100644 index 000000000..538fc4290 --- /dev/null +++ b/claude-notes/issue-reports/196/triage.md @@ -0,0 +1,120 @@ +# Issue #196 — Reader rejects valid 4-space-indented list-item continuations as a parse error + +- **GitHub:** https://github.com/quarto-dev/q2/issues/196 +- **Reporter:** @rundel (Colin Rundel) +- **Status:** Confirmed regression introduced by PR #194 (closes #184, Q-2-35). +- **Verdict:** Real bug. Filed as bd-3mgb (discovered-from bd-7l1u, the Q-2-35 implementation). +- **Worktree branch:** `issue-196` at `.worktrees/issue-196/`. + +## Scope + +A single regression. No sub-bugs bundled in the report. + +## Repro + +```text +4) Outer: + + ![](img.png){.border} +``` + +The blank line on row 2 contains four trailing spaces (hex dump: `20 20 20 20 0a`). With `pampa` reading from stdin: + +``` +$ cargo run --bin pampa -- < repro.qmd +Error: Parse error + ╭─[ :3:5 ] + │ + 3 │ ![](img.png){.border} + │ ┬ + │ ╰── unexpected character or token here +───╯ +``` + +Expected (pre-#194 behaviour, reported by @rundel): an `OrderedList` whose single item contains two `Para` children — verified locally against `exp-no-trailing-ws.qmd`, which strips the trailing whitespace and parses cleanly to: + +``` +[ OrderedList (4, Decimal, OneParen) [[Para [Str "Outer:"], Para [Image (...) [] ("img.png" , "")]]] ] +``` + +## Fixtures (all under `claude-notes/issue-reports/196/`) + +| File | Trailing whitespace on blank line | Result | +| --------------------------------- | --------------------------------------- | ------------- | +| `repro.qmd` | 4 spaces | **Parse error** | +| `exp-no-trailing-ws.qmd` | none (pure `\n\n`) | Parses OK | +| `exp-two-trailing-spaces.qmd` | 2 spaces | Parses OK | +| `exp-tab-on-blank.qmd` | 1 tab (= 4 columns of indentation) | **Parse error** | +| `exp-trailing-ws-text.qmd` | 4 spaces, continuation is plain text | **Parse error** | +| `exp-bullet-list.qmd` | 4 spaces, bullet list (`*`) instead of `4)` | **Parse error** | + +Conclusions: + +1. The trigger is the **amount** of trailing whitespace on the intervening blank line, not the kind of continuation content. The threshold is exactly 4 columns (a tab counts). +2. The bug is generic across list marker kinds (ordered, bullet) and content kinds (image, text). +3. The continuation line is **not** the issue — its indent is the standard 4 spaces required for a list-item continuation. Stripping trailing whitespace from the blank line above (a no-op for the AST) makes the same continuation line parse. + +## Root cause (confirmed by tree-sitter trace) + +PR #194 added an `INDENTED_CODE_BLOCK_DISALLOWED` external token in `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c:2128`: + +```c +// Parse any preceeding whitespace and remember its length. +for (;;) { + if (lexer->lookahead == ' ' || lexer->lookahead == '\t') { + s->indentation += advance(s, lexer); + } else { + break; + } +} + +// Q-2-35: ... +if (s->indentation >= 4 && + (valid_symbols[ATX_H1_MARKER] || valid_symbols[BLANK_LINE_START]) && + lexer->lookahead != '\n' && lexer->lookahead != '\r') { + mark_end(s, lexer); + EMIT_TOKEN(INDENTED_CODE_BLOCK_DISALLOWED); +} +``` + +Running `pampa -v` on `repro.qmd` shows the scanner emitting that token during the recovery path while at `row:2`: + +``` +recover_to_previous state:345, depth:2 +... +lex_external state:5, row:2, column:16 +lexed_lookahead sym:_indented_code_block_error, size:0 +detect_error lookahead:_indented_code_block_error +``` + +So the regression is specifically the new check firing where it shouldn't. The PR's own description listed the cases the conservative gate was meant to skip — and "list-item continuations after a blank line" was one of them. What the gate misses is the case where the blank line itself carries enough whitespace to push `s->indentation >= 4`: after consuming the blank line, the scanner re-enters at the continuation line with state that makes `valid_symbols[ATX_H1_MARKER] || valid_symbols[BLANK_LINE_START]` true (parser is at a block-start position) and the freshly accumulated indentation `>= 4`, so it fires the indented-block error. + +@rundel's diagnosis lands exactly here: *"the regression is in the column accounting around whitespace-only lines inside list items rather than in the indented-code-block detector itself — Q-2-35 would have surfaced as `[Q-2-35] Indented code blocks are not supported`, not a bare 'Parse error'."* The Q-2-35 user-facing message is keyed on a specific `(state, sym)` pair in `quarto-parse-errors`; the recovery state hit here (`state:5`) is not in that table, which is also why the error renders as a generic "unexpected character or token" instead of the friendly Q-2-35 message. + +## Severity + +High. The reporter has three real-world hits in `quarto-dev/quarto-web`: + +- https://github.com/quarto-dev/quarto-web/blob/baeab38627fcc3f3a9ea3ca3ea689ece413df65d/docs/authoring/diagrams.qmd#L98 +- https://github.com/quarto-dev/quarto-web/blob/baeab38627fcc3f3a9ea3ca3ea689ece413df65d/docs/extensions/engine.qmd#L92 +- https://github.com/quarto-dev/quarto-web/blob/baeab38627fcc3f3a9ea3ca3ea689ece413df65d/docs/publishing/netlify.qmd#L119 + +Editors commonly insert trailing whitespace on indented blank lines (auto-indent on Enter), so the input pattern is realistic. The failure mode is total parse rejection, not a degraded render — every document with this pattern is unreadable to Rust Quarto. + +## Where the fix should land + +Tree-sitter scanner in `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c` around line 2128. The detector needs to distinguish "true block-start with 4+ leading spaces of content" from "list-item lazy continuation whose preceding blank line contained whitespace". The PR's intent was already to skip the latter; the gate just doesn't express that condition. + +Possible angles (for the fix session, not this triage): + +1. **Reset/decrement `s->indentation` when entering through the BLANK_LINE_START path of the previous scan.** If the blank-line case at line 2150 cleared any accumulated indentation, the next call would start fresh. Need to verify whether that is sound elsewhere. +2. **Tighten the gate so it does not fire when inside an open list item that is awaiting a continuation paragraph.** The list-item container state should be inspectable; if the parser would accept a list continuation here, the indented-code-block check should defer. +3. **Add a corpus test for trailing-whitespace blank lines** to whichever fix is chosen, and a positive Q-2-35 regression to confirm the original PR's diagnostic still fires on real top-level indented blocks. + +The reporter's note about a `(state, sym)` mapping miss (the bare "Parse error" instead of Q-2-35) is a separate observation — once the false-positive is silenced, that mapping question goes away for this input. No need to widen the error corpus to cover the recovery state if we stop emitting the token in the first place. + +## What I did not do + +- I did not write a fix. This is a triage record. +- I did not add a tree-sitter corpus regression test. That belongs to the fix PR (TDD: red test first). +- I did not run `cargo xtask verify` on the worktree to full green; only the Rust legs were exercised. Hub-client tests fail with `vitest: command not found` because no `npm install` has been run in this clone. The bug is scanner-only; hub-client is not in scope. diff --git a/claude-notes/issue-reports/201/repro.qmd b/claude-notes/issue-reports/201/repro.qmd new file mode 100644 index 000000000..9e1d11df8 --- /dev/null +++ b/claude-notes/issue-reports/201/repro.qmd @@ -0,0 +1 @@ +reveal.js\' jump-to-slide. diff --git a/claude-notes/issue-reports/201/triage.md b/claude-notes/issue-reports/201/triage.md new file mode 100644 index 000000000..67f3c2174 --- /dev/null +++ b/claude-notes/issue-reports/201/triage.md @@ -0,0 +1,130 @@ +# Issue #201 — Writer drops `\'` escape on apostrophes that the reader would re-reject as quote opens + +- **GitHub**: https://github.com/quarto-dev/q2/issues/201 +- **Reporter**: @rundel (Colin Rundel), 2026-05-15 +- **Triage date**: 2026-05-15 +- **Worktree**: `.worktrees/issue-201` (branch `issue-201`, based on `main` @ `26b8943c`) +- **Beads issue**: bd-8lcm (filed during triage) +- **Scope**: The reader/writer asymmetry around the ASCII apostrophe `'` in the qmd writer (`crates/pampa/src/writers/qmd.rs`). No reader changes are in scope — the reader's behavior is the spec the writer must satisfy. + +## Summary + +Real bug, reproduces at HEAD. The qmd writer emits a bare `'` for an apostrophe whose source form required a `\'` escape, so `qmd → AST → qmd` is not a fixed point: the second round-trip through the reader fails with `Q-2-10` (Closed Quote Without Matching Open Quote). Fix is small in scope (one writer function plus context-aware lookahead across inline boundaries) but not literally one-line — see § Localization. + +## Reproduction + +Fixture: `claude-notes/issue-reports/201/repro.qmd` + +``` +reveal.js\' jump-to-slide. +``` + +Three commands, exactly as reported in the issue: + +```bash +# 1. Reader accepts \' and produces an apostrophe in the AST. +$ printf -- "reveal.js\\\\' jump-to-slide.\n" | cargo run --bin pampa -- +[ Para [Str "reveal.js’", Space, Str "jump-to-slide."] ] + +# 2. Writer round-trips the AST as qmd, but DROPS the escape: +$ printf -- "reveal.js\\\\' jump-to-slide.\n" | cargo run --bin pampa -- -t qmd +reveal.js' jump-to-slide. + +# 3. Feeding that output back into the reader fails with Q-2-10: +$ printf -- "reveal.js\\\\' jump-to-slide.\n" \ + | cargo run --bin pampa -- -t qmd 2>/dev/null \ + | cargo run --bin pampa -- +Error: [Q-2-10] Closed Quote Without Matching Open Quote + ╭─[ :1:11 ] + │ + 1 │ reveal.js' jump-to-slide. + │ ┬┬ + │ ╰─── This is the opening quote. ... + │ │ + │ ╰── A space is causing a quote mark to be interpreted as a quotation close. +───╯ +``` + +Inspected output: confirmed by hand; the bare `'` between `js` and the trailing space is exactly the position Q-2-10 fires on. + +### Trigger boundary (probed during triage) + +The Q-2-10 trigger is precisely **letter-on-left AND whitespace+content-on-right**, matching the issue body's description and the `Q-2-10.json` corpus case (`a' b.`). Two adjacent probes: + +```bash +# Apostrophe at end of paragraph (no whitespace after): reader is happy. +$ printf "reveal.js\\\\'\n" | cargo run --bin pampa -- +[ Para [Str "reveal.js’"] ] + +# Apostrophe followed by " end." — Q-2-10 fires. +$ printf "reveal.js' end.\n" | cargo run --bin pampa -- +Error: [Q-2-10] ... +``` + +So the writer must consider both sides of the apostrophe, including across inline boundaries (the `Space` after `Str "reveal.js'"` is a separate inline). + +### Real-world incidence + +The reporter cites two quarto-web sources that contain this pattern (`reveal.js' jump-to-slide`, and another in `tables.qmd`). This means the writer regression is observable on real documents the project already publishes — not a synthetic edge case. + +## Localization + +- **Writer escape table**: `crates/pampa/src/writers/qmd.rs:1379` (`fn escape_markdown`). Currently has no `'` arm — the comment at line 1405 explicitly notes "characters that don't need escaping in most contexts: . , - + ! ? = : ; / ( ) % & ' \""`. That comment is wrong about `'` in the letter-then-whitespace context. +- **Str writer entry point**: `crates/pampa/src/writers/qmd.rs:1414` (`fn write_str`). Currently has signature `(s: &Str, buf, ctx)` and calls `escape_markdown(reverse_smart_quotes(&s.text))`. A correct fix needs at least lookahead to the next inline (Space vs other) and lookbehind to the previous inline's trailing character. The `ctx: &mut QmdWriterContext` is the natural place to thread that state — or `write_inline` (line 2159) could pre-compute boundary flags and pass them down. +- **Reverse smart-quote helper**: `crates/pampa/src/writers/qmd.rs:1371` (`fn reverse_smart_quotes`). Already turns U+2019 (`’`) into ASCII `'`. The fix interacts with this: post-conversion, any ASCII `'` produced by this helper is a candidate for escaping based on context. +- **Reader-side trigger (reference only, not modified)**: `Q-2-10` error corpus at `crates/pampa/resources/error-corpus/Q-2-10.json` defines the canonical trigger `a' b.`. Existing roundtrip test `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/smart_quotes_apostrophes.qmd` only exercises the *safe* contexts (`project's`, `can't`, `it's`, `We're`) and so doesn't catch this regression. A new roundtrip fixture in the same directory (e.g. `apostrophe_before_space.qmd` containing `reveal.js\' jump-to-slide.`) is the obvious TDD entry point. + +## Open questions — resolved during triage + +**Q1. Is the trigger letter-on-left-only, or letter-on-left AND whitespace-on-right?** +Experiment: ran `printf "reveal.js\\'\n"` (no trailing whitespace) and confirmed the reader accepts it. +Conclusion: the trigger requires *both* sides. A writer fix that escaped every letter-then-apostrophe occurrence would over-escape `project's`, `can't`, etc. The fix must look at the next inline (or end-of-block) too. + +**Q2. Does the Str body itself ever contain the boundary?** +Experiment: inspected the AST from the failing input. The boundary lives across inlines: `[Str "reveal.js'", Space, Str "jump-to-slide."]`. The `'` is at the end of one Str; the Space is the next inline. +Conclusion: a fix that only looks within a single Str body is insufficient. The writer must know what inline follows the current Str (Space, SoftBreak, end-of-block, etc.). + +**Q3. Is the writer's current "don't escape `'`" comment defensible at all?** +Experiment: read the comment at `qmd.rs:1405–1407`. +Conclusion: the comment is correct that escaping `'` everywhere would be verbose (every contraction). It is wrong that "very specific contexts" can be ignored — the letter+whitespace case is exactly such a context and it is what this bug is about. The right fix is context-aware escaping, not blanket escaping. + +## Outcome / recommended next step + +Filed beads issue with the fix scope below. No GH comment needed yet — issue is already specific and well-reproduced; the bd-XXXX will be referenced when the fix PR lands. + +**Fix scope (for the beads issue):** + +1. **Test first (TDD per `crates/pampa/CLAUDE.md`)**: + - Add `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/apostrophe_before_space.qmd` containing `reveal.js\' jump-to-slide.` (or similar). Confirm the round-trip test fails at HEAD. +2. **Implement**: Extend `write_str` (or the surrounding `write_inline` driver) to detect a trailing `letter + '` at the end of a `Str` whose **next** inline is `Space`/`SoftBreak`/etc., and emit `\'` instead of `'`. The minimal correct rule is: escape ASCII `'` in a `Str` body iff the char immediately to its left is a Unicode letter AND the next byte the writer would emit is ASCII whitespace. +3. **Verify**: Round-trip test passes; `cargo nextest run --workspace` clean; the two quarto-web fixtures from the issue round-trip cleanly through `pampa -t qmd | pampa`. + +Out of scope: any reader changes; over-escaping `'` in the safe contexts (`project's`, `can't`). + +## Verification commands used + +```bash +# Pre-flight (Rust-only; hub-client & trace-viewer skipped due to missing node_modules — unrelated bootstrap) +cargo xtask verify --skip-hub-build --skip-hub-tests + +# Reproduction +printf -- "reveal.js\\\\' jump-to-slide.\n" | cargo run --bin pampa -- +printf -- "reveal.js\\\\' jump-to-slide.\n" | cargo run --bin pampa -- -t qmd +printf -- "reveal.js\\\\' jump-to-slide.\n" | cargo run --bin pampa -- -t qmd 2>/dev/null | cargo run --bin pampa -- + +# Boundary probes +printf "reveal.js\\\\'\n" | cargo run --bin pampa -- +printf "reveal.js' end.\n" | cargo run --bin pampa -- + +# Issue intake +gh issue view 201 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments +``` + +## Cross-references + +- Reader-side spec: `crates/pampa/resources/error-corpus/Q-2-10.json` +- Existing apostrophe roundtrip coverage (does NOT cover this case): `crates/pampa/tests/roundtrip_tests/qmd-json-qmd/smart_quotes_apostrophes.qmd` +- Real-world incidence (quarto-web): + - https://github.com/quarto-dev/quarto-web/blob/41a5a98d20449d970821b59be1711a0710a9cee3/docs/presentations/revealjs/presenting.qmd#L85 + - https://github.com/quarto-dev/quarto-web/blob/41a5a98d20449d970821b59be1711a0710a9cee3/docs/authoring/tables.qmd#L772 +- Writer file: `crates/pampa/src/writers/qmd.rs` (escape table + `write_str` + `write_inline` driver) diff --git a/claude-notes/issue-reports/205/repro.json b/claude-notes/issue-reports/205/repro.json new file mode 100644 index 000000000..67f45ced2 --- /dev/null +++ b/claude-notes/issue-reports/205/repro.json @@ -0,0 +1 @@ +{"pandoc-api-version":[1,23,1],"meta":{},"blocks":[{"t":"Para","c":[{"t":"Code","c":[["",[],[]],"x"]},{"t":"Str","c":"'s"},{"t":"Space"},{"t":"Str","c":"end"}]}]} diff --git a/claude-notes/issue-reports/205/repro.qmd b/claude-notes/issue-reports/205/repro.qmd new file mode 100644 index 000000000..779dc093e --- /dev/null +++ b/claude-notes/issue-reports/205/repro.qmd @@ -0,0 +1 @@ +`x`\'s end diff --git a/claude-notes/issue-reports/205/triage.md b/claude-notes/issue-reports/205/triage.md new file mode 100644 index 000000000..940d31cdf --- /dev/null +++ b/claude-notes/issue-reports/205/triage.md @@ -0,0 +1,223 @@ +# Issue #205 — Writer drops `\'` escape when `'` starts a Str whose preceding inline ends in non-alnum + +- **GitHub**: https://github.com/quarto-dev/q2/issues/205 +- **Reporter**: @rundel (Colin Rundel), 2026-05-15 +- **Triage date**: 2026-05-15 +- **Worktree**: `.worktrees/issue-205` (branch `issue-205`, based on `main` @ `09b2de7e`) +- **Beads issue**: bd-nsb9 (filed; see Outcome) +- **Scope**: covers the writer-only escape gap described in the issue + body. The reader's smart-quote classification is **not** in scope — + its stricter behavior (compared to what the issue's first command + shows) is intentional and is what motivated the writer fix in #201. + +## Summary + +Follow-up to #201 / bd-8lcm. The writer's `escape_markdown` decides +whether to emit `\'` from purely *intra-`Str`* context (`prev_char` and +the peeked `next_char` inside the current `Str` body). When `'` sits at +**index 0** of a `Str`, `prev_char` is `None`, so the local rule treats +it as "not after alphanumeric" and emits a bare `'`. The reader's +smart-quote-apostrophe classifier, however, is keyed off the +*surrounding byte stream* — not Str boundaries — so it sees the closing +backtick of a preceding `Code` (or `*` of an `Emph`, `)` of an +`Image`, etc.) on the left and `s` on the right, classifies the `'` +as an unclosed opening single quote, and emits **Q-2-7**. Round-trip +fails. Confirmed locally with a JSON-AST repro and with a parseable +qmd repro (`` `x`\'s end ``) that exercises the same path through the +existing `qmd-json-qmd` roundtrip harness. + +## Reproduction + +Two equivalent repros are committed alongside this doc: + +- `repro.qmd` — a parseable qmd whose AST contains the offending + inline shape (`Code` followed by `Str "'s"`). Suitable for the + existing `tests/roundtrip_tests/qmd-json-qmd/` harness. +- `repro.json` — the AST directly, for bypassing the parser when + demonstrating the writer in isolation. + +### Parser bypass — writer in isolation + +``` +$ cat claude-notes/issue-reports/205/repro.json | ./target/debug/pampa -f json -t qmd +`x`'s end +$ cat claude-notes/issue-reports/205/repro.json | ./target/debug/pampa -f json -t qmd | ./target/debug/pampa +Error: [Q-2-7] Unclosed Single Quote + ╭─[ :1:10 ] + │ + 1 │ `x`'s end + │ ┬ ┬ + │ ╰────── This is the opening quote. If you need an apostrophe, escape it with a backslash. + │ │ + │ ╰── I reached the end of the block before finding a closing "'" for the quote. +───╯ +``` + +### Through the parser — `qmd-json-qmd` round-trip + +``` +$ cat claude-notes/issue-reports/205/repro.qmd +`x`\'s end +$ ./target/debug/pampa claude-notes/issue-reports/205/repro.qmd +[ Para [Code ( "" , [] , [] ) "x", Str "’s", Space, Str "end"] ] +$ ./target/debug/pampa claude-notes/issue-reports/205/repro.qmd -t qmd +`x`'s end # ← the escape is dropped +$ ./target/debug/pampa claude-notes/issue-reports/205/repro.qmd -t qmd | ./target/debug/pampa +Error: [Q-2-7] Unclosed Single Quote … # ← re-parse fails +``` + +The issue's original first-command output `[Para [Code "x", Str "'s", +…]]` from raw `` `x`'s end `` no longer reproduces — the reader now +rejects that input at parse time (today, `pampa ` emits Q-2-7 +directly). That stricter reader behavior is **the reason the writer +needs to escape** in this position; it does not change the bug. + +### Generalization — not Code-specific + +The same defect fires whenever a `Str "'..."` follows *any* inline +whose last emitted byte is non-alphanumeric, and also when the `Str` +is the first inline of a block: + +``` +=== Str starting at block start === +$ echo '{…blocks:[{Para:[{Str:"'\''sup"},{Space},{Str:"end"}]}]…}' | pampa -f json -t qmd +'sup end # unescaped — would Q-2-7 + +=== After Emph === +$ echo '{…[{Emph:[{Str:"hi"}]},{Str:"'\''s"}]…}' | pampa -f json -t qmd +*hi*'s # unescaped — would Q-2-7 + +=== After Image === +$ echo '{…[{Image:[…,"url",…]},{Str:"'\''s"}]…}' | pampa -f json -t qmd +![alt](url)'s # unescaped — would Q-2-7 +``` + +In every case the bytes immediately surrounding the `'` are +` ' ` — exactly what the reader's classifier +rejects. + +## Localization + +- `crates/pampa/src/writers/qmd.rs:1388` — `escape_markdown` (the + function added in #201). Its `prev_char` is the previous char *of + the current `Str` body*; it has no view of inter-inline state. +- `crates/pampa/src/writers/qmd.rs:1436` — `write_str` calls + `escape_markdown(&text)` and writes the result. This is the only + call site, so the fix can either: + 1. accept an additional `prev_byte: Option` argument here + and thread it through every inline-list iteration site + (≈20 call sites of `write_inline` — see grep below), or + 2. track "last emitted byte in the current inline stream" on + `QmdWriterContext` (single field, written by every leaf + emitter, reset at block boundaries). Less invasive at call + sites but requires discipline at every place that writes + bytes. +- Iteration sites that would need to participate (per + `grep -n 'write_inline(' crates/pampa/src/writers/qmd.rs`): lines + 268, 579, 688, 726, 835, 861, 1173, 1179, 1336, 1479, 1502, 1579, + 1600, 1621, 1633, and within `write_inline` itself at 2205. + +## Open questions — resolved during triage + +**Q1.** Does the issue's first-command output (`pampa ` +producing `[Code "x", Str "'s", …]` from raw `` `x`'s end ``) +reproduce today? +*Experiment.* Ran exactly that command on `main` @ `09b2de7e`. +*Result.* No — the reader now rejects with Q-2-7 at parse time. The +reader's classifier has tightened (or always was strict and the issue +was written from an older snapshot). This **does not** invalidate the +bug, because: +- the writer's job is round-trip fidelity for any AST it is given, + including ASTs that originate from other tools (TS Quarto, pandoc, + filters); +- the wild quarto-web links in the issue body contain the same + `Code'…` shape, and any AST produced from those that goes through + this writer round-trips lossily. + +**Q2.** Is the bug Code-specific? +*Experiment.* Fed ASTs with `Emph`, `Image`, and "Str at block start" +as the preceding context (see Reproduction § Generalization). +*Result.* All produce unescaped `'`. The bug is "previous emitted byte +is non-alphanumeric", not "previous inline is `Code`". + +**Q3.** Is there a parseable qmd that exercises the bug through the +existing `tests/roundtrip_tests/qmd-json-qmd/` harness? +*Experiment.* `` `x`\'s end `` parses to `[Code "x", Str "'s", Space, +Str "end"]` (the `\'` is an explicit escape that becomes a literal +apostrophe in the `Str` body). Confirmed end-to-end: +- parse: produces the offending AST shape; +- qmd writer: emits `` `x`'s end `` (drops the escape); +- re-parse: Q-2-7. +*Result.* Yes — a single fixture `qmd-json-qmd/apostrophe_after_code_inline.qmd` +(or similar) will lock in the fix using the existing harness, parallel +to the two fixtures `apostrophe_before_space.qmd` / +`apostrophe_before_punct.qmd` that #201 added. + +**Q4.** Does the same defect fire on the symmetric *trailing* case +(`Str "abc'"` followed by `Code "x"`)? +*Experiment.* Reading `escape_markdown` again: at end of a `Str`, the +in-`Str` peek of `next_char` is `None`, so the rule sees +`prev_is_alnum=true, next_is_alnum=false` → emits `\'`. So a trailing +`'` is already escaped today. +*Result.* The trailing case is already handled by the existing logic. +Only the *leading* case is broken. The fix can be asymmetric or +symmetric (the latter is cleaner and matches the issue body's +suggestion). Recommend symmetric — easier to reason about. + +## Outcome / recommended next step + +**Filed bd-nsb9 with the fix scope below.** Concrete writer work; not +duplicate, not docs, not WAI. + +### Fix scope (for the beads issue) + +- **Approach.** Option 2 (track last emitted byte on + `QmdWriterContext`) is preferred. Rationale: it keeps the call-site + signatures untouched and naturally generalizes if other escape + rules later need inter-inline context. +- **Reset points.** Reset the tracked last-byte to `None` at the + start of each block, and at every newline emission inside a block + (line breaks reset the reader's surrounding-byte context too). +- **Escape rule (symmetric).** Inside `escape_markdown`, the + `prev_char` source becomes "the in-`Str` previous char if any, else + the context's last-emitted-byte (treated as a `char` for the + alphanumeric check)". The rest of the logic is unchanged. +- **TDD.** Add `tests/roundtrip_tests/qmd-json-qmd/apostrophe_after_code_inline.qmd` + (content: `` `x`\'s end ``) **first**, watch + `test_qmd_roundtrip_consistency` fail, then implement. +- **Coverage to add alongside.** Two more fixtures to cover the + generalization: one with `*hi*\'s end` (preceding Emph) and one + with `\'sup end` (Str at block start, no preceding inline). Both + parse today and both fail the round-trip with the current writer. + +## Verification commands used + +```bash +gh issue view 205 --repo quarto-dev/q2 --json title,body,author,createdAt,labels,comments + +cargo xtask verify --skip-hub-build --skip-hub-tests +cargo build --bin pampa + +# parser-bypass repro +./target/debug/pampa -f json -t qmd < claude-notes/issue-reports/205/repro.json +./target/debug/pampa -f json -t qmd < claude-notes/issue-reports/205/repro.json | ./target/debug/pampa + +# parseable repro through the qmd-json-qmd harness shape +./target/debug/pampa claude-notes/issue-reports/205/repro.qmd +./target/debug/pampa claude-notes/issue-reports/205/repro.qmd -t qmd +./target/debug/pampa claude-notes/issue-reports/205/repro.qmd -t qmd | ./target/debug/pampa + +# generalization probes — see Reproduction § Generalization +``` + +## Cross-references + +- #201 / bd-8lcm — original apostrophe-escape fix; introduced + `escape_markdown`'s intra-`Str` `prev_char/next_char` logic at + `crates/pampa/src/writers/qmd.rs:1388`. +- `claude-notes/issue-reports/201/triage.md` — sibling triage. +- `claude-notes/plans/2026-05-15-issue-201-apostrophe-escape.md` — + sibling plan; this issue's fix should follow the same TDD shape + (fixture first, then writer change). +- `crates/pampa/CLAUDE.md` — the mandatory test-first checklist that + governs the fix. diff --git a/claude-notes/issue-reports/206/exp-blank-line.qmd b/claude-notes/issue-reports/206/exp-blank-line.qmd new file mode 100644 index 000000000..cc5ac2b83 --- /dev/null +++ b/claude-notes/issue-reports/206/exp-blank-line.qmd @@ -0,0 +1,6 @@ +::: foo +| | | +|:-:|:-:| +| a | b | + +::: diff --git a/claude-notes/issue-reports/206/exp-caption-no-div.qmd b/claude-notes/issue-reports/206/exp-caption-no-div.qmd new file mode 100644 index 000000000..7334294bd --- /dev/null +++ b/claude-notes/issue-reports/206/exp-caption-no-div.qmd @@ -0,0 +1,4 @@ +| | | +|:-:|:-:| +| a | b | +: This is a caption diff --git a/claude-notes/issue-reports/206/exp-heading-after.qmd b/claude-notes/issue-reports/206/exp-heading-after.qmd new file mode 100644 index 000000000..ac3b6aebc --- /dev/null +++ b/claude-notes/issue-reports/206/exp-heading-after.qmd @@ -0,0 +1,4 @@ +| | | +|:-:|:-:| +| a | b | +# heading diff --git a/claude-notes/issue-reports/206/exp-heading-between.qmd b/claude-notes/issue-reports/206/exp-heading-between.qmd new file mode 100644 index 000000000..36e51f462 --- /dev/null +++ b/claude-notes/issue-reports/206/exp-heading-between.qmd @@ -0,0 +1,6 @@ +::: foo +| | | +|:-:|:-:| +| a | b | +# heading +::: diff --git a/claude-notes/issue-reports/206/exp-no-div-just-colons.qmd b/claude-notes/issue-reports/206/exp-no-div-just-colons.qmd new file mode 100644 index 000000000..7c49f2289 --- /dev/null +++ b/claude-notes/issue-reports/206/exp-no-div-just-colons.qmd @@ -0,0 +1,4 @@ +| | | +|:-:|:-:| +| a | b | +::: diff --git a/claude-notes/issue-reports/206/exp-para-after.qmd b/claude-notes/issue-reports/206/exp-para-after.qmd new file mode 100644 index 000000000..d2fa77187 --- /dev/null +++ b/claude-notes/issue-reports/206/exp-para-after.qmd @@ -0,0 +1,4 @@ +| | | +|:-:|:-:| +| a | b | +paragraph text diff --git a/claude-notes/issue-reports/206/repro.qmd b/claude-notes/issue-reports/206/repro.qmd new file mode 100644 index 000000000..b0b1035ee --- /dev/null +++ b/claude-notes/issue-reports/206/repro.qmd @@ -0,0 +1,5 @@ +::: foo +| | | +|:-:|:-:| +| a | b | +::: diff --git a/claude-notes/issue-reports/206/triage.md b/claude-notes/issue-reports/206/triage.md new file mode 100644 index 000000000..a58bb1957 --- /dev/null +++ b/claude-notes/issue-reports/206/triage.md @@ -0,0 +1,141 @@ +# Issue #206 — Fenced div close `:::` immediately after a pipe table fails to parse + +- **GitHub**: https://github.com/quarto-dev/q2/issues/206 +- **Reporter**: @rundel (Colin Rundel), 2026-05-15 +- **Triage date**: 2026-05-15 +- **Worktree**: `.worktrees/issue-206` (branch `issue-206`, based on `main` @ `09b2de7e`) +- **Beads issue**: bd-expy +- **Scope**: the specific parse failure when a `:::` line directly follows a pipe table row. Adjacent oddities found during triage (pipe table absorbing trailing block content as cells) are flagged but **not** in scope for this issue. + +## Summary + +Reproduced cleanly. The reporter's hypothesis — that the pipe-table parser mis-handles `:::` after a row — is confirmed and refines to a specific cause: **the first `:` of `:::` is consumed as the start of a `caption`** (which is the only block construct, besides another `pipe_table_row`, that the grammar accepts in that position after a row terminator). Once that `:` is shifted, the parser is committed to the `caption` rule and the next `:` is a parse error because `caption` requires inline whitespace immediately after the colon. A blank line between the table and `:::` breaks the table out of "looking for more rows / a caption" state, which is why the reporter's workaround succeeds. + +This matches the user's suspicion exactly: table-caption detection (which also starts with `:`) is what's getting confused. + +## Reproduction + +Failing input (`claude-notes/issue-reports/206/repro.qmd`): + +``` +::: foo +| | | +|:-:|:-:| +| a | b | +::: +``` + +``` +$ cargo run --bin pampa -- < claude-notes/issue-reports/206/repro.qmd +Error: Parse error + ╭─[ :5:2 ] + │ + 5 │ ::: + │ ┬ + │ ╰── unexpected character or token here +───╯ +``` + +Working: with a blank line before `:::` (`exp-blank-line.qmd`) it parses into a `Div` containing the `Table`. + +Caption sanity check (`exp-caption-no-div.qmd`): `: This is a caption` after the table parses correctly into a `Caption` — confirms the caption path is functional and the bug is specifically the `:::` × caption-start collision. + +The fenced div wrapper is **not required to trigger the bug.** Even without `::: foo` on top, a bare pipe table followed by `:::` fails identically (`exp-no-div-just-colons.qmd`, error at the second `:`). + +## Localization + +`crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js`: + +- `caption` rule, line 235: + ``` + caption: $ => seq(":", $._inline_whitespace, $._inlines, choice($._newline, $._eof)), + ``` +- `pipe_table` rule, lines 245–253. After the row repeat, the rule has + `optional(seq($._pipe_table_newline, $.caption))`. After consuming the + `_pipe_table_newline` that ends `| a | b |`, the parser sees `:` and the only + productions reachable with `:` are this `caption` and the top-level + `caption` at line 125 (which has the same prefix). Either way the first `:` + is shifted; only `_inline_whitespace` is acceptable next, so the second `:` + errors. + +Concrete syntax-tree trace evidence (`cargo run --bin pampa -- -v`): + +``` +state:949, row:4, col:0 # just finished pipe_table_row +lexed_lookahead sym::, size:1 # the first colon of ":::" +reduce sym:_pipe_table_newline # consume the newline +shift state:2957 # SHIFT the ':' — committed to caption +state:2957, row:4, col:1 +lexed_lookahead sym::, size:1 # second colon +detect_error lookahead:: # bang +``` + +So the commit point is the shift of the first `:`. After that, tree-sitter cannot back-track because the `optional()` wrapper has already been resolved by lookahead. + +The reasonable fix shapes (to be decided in the fix issue, not here): + +1. **Tighten `caption`'s first token via the external scanner.** Have the scanner emit a `_caption_start` token only when it sees a `:` that is *not* immediately followed by another `:` (and is followed by whitespace). The internal `caption` rule then keys off `_caption_start` rather than the literal `:`. This is the most surgical fix and matches the spirit of how the scanner already disambiguates `_pipe_table_delimiter` from prose `|`. +2. **Have the scanner refuse `_pipe_table_newline` when the next non-blank line starts with `:::`.** Lets the pipe_table close before the parser commits to a caption start. Slightly broader — it also helps the table-rows-absorbing-following-content issue below. +3. **Refuse to shift `:` as the start of `caption` when followed by another `:`.** Could be done with a GLR/multi-version branch but tree-sitter handles ambiguity via the external scanner, so this collapses to (1). + +The `scanner.c` already has the necessary line-start lookahead machinery for `_pipe_table_line_ending` (see lines 970–1041 of `grammar.js` for the externals list), so adding a `_caption_start` external token alongside is the natural shape. + +## Adjacent finding (NOT in scope for this issue) + +While testing variations, I found the pipe-table parser absorbs trailing non-pipe block content as additional cells: + +``` +$ printf '| | |\n|:-:|:-:|\n| a | b |\n# heading\n' | cargo run --bin pampa -- +[ Table ... [Row ... [Cell ... [Plain [Str "a"]] ... [Plain [Str "b"]] ] , + Row ... [Cell ... [Plain [Str "#", Space, Str "heading"]] ] ] ] +``` + +The `# heading` is silently swallowed as a one-cell row. Same with bare paragraph text. The reporter's claim "Other block successors (headings, paragraphs) immediately following a pipe table parse fine" is therefore **not quite right** — they don't error, but they don't parse as separate blocks either. This is a distinct bug worth filing separately, but it's out of scope for issue #206, which is specifically about the `:::` parse failure. I'll note this in the beads issue's description so it can be picked up as a related follow-up if desired. + +## Open questions — resolved during triage + +- **Is the fenced-div wrapper required for the bug?** No. Bare pipe table + `:::` reproduces the same parse failure. The fenced div is incidental; the real interaction is "pipe-table row context" × "`:` caption start". (Confirmed via `exp-no-div-just-colons.qmd`.) +- **Does the working caption path still work?** Yes (`exp-caption-no-div.qmd`). The fix must not regress single-`:`-as-caption. +- **Does TS Quarto accept this in the wild?** The reporter cites `quarto-dev/quarto-web` `docs/websites/website-navigation.qmd` lines 155–159, which is shipped quarto-web documentation. Strong evidence that this is expected-to-work syntax for users coming from TS Quarto, so the fix should make it parse rather than improve the error message. + +## Outcome / recommended next step + +**Filed bd-expy and fixed on branch `issue-206` (commit `19e4ce9a`, 2026-05-15).** + +Fix details: see the plan at `claude-notes/plans/2026-05-15-fix-pipe-table-caption-collision.md`. The fix turned out to need *two* scanner changes, not one — the caption-start disambiguation alone left `:::` absorbed as a phantom pipe_table_row, so a second peek-for-`:::` gate was added to the PIPE_TABLE_LINE_ENDING dispatch to terminate the table when the next line is a fenced-div marker. + +--- + +Original recommended fix scope (kept here for record): + +- Disambiguate the `:` caption-start from `:::` (and likely `::` in fenced-div opener too) at the scanner level so the parser doesn't commit to `caption` when the next character is also `:`. Approach (1) above is the recommended starting point. +- Add a tree-sitter test in `crates/tree-sitter-qmd/tree-sitter-markdown/test/corpus/` covering: `:::`-after-table (the bug), `: caption`-after-table (must still work), and bare `:::` after table (no fenced div). +- Add a pampa round-trip test against `repro.qmd`. +- Re-test on `quarto-dev/quarto-web` `docs/websites/website-navigation.qmd` after the fix. +- **Not in scope**: the table-absorbs-following-blocks behaviour; file as a separate follow-up if desired. + +## Verification commands used + +```bash +# Pre-flight +cargo xtask verify --skip-hub-build --skip-hub-tests + +# Reproduce +cargo run --bin pampa -- < claude-notes/issue-reports/206/repro.qmd + +# Verbose CST trace +cargo run --bin pampa -- -v < claude-notes/issue-reports/206/repro.qmd + +# Comparison fixtures (under claude-notes/issue-reports/206/) +cargo run --bin pampa -- < exp-caption-no-div.qmd # caption alone — works +cargo run --bin pampa -- < exp-no-div-just-colons.qmd # table + ::: no div — same error +cargo run --bin pampa -- < exp-heading-after.qmd # table absorbs heading as row +cargo run --bin pampa -- < exp-para-after.qmd # table absorbs paragraph as row +cargo run --bin pampa -- < exp-blank-line.qmd # workaround — parses +``` + +## Cross-references + +- Grammar: `crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js` lines 117–253 +- Scanner: `crates/tree-sitter-qmd/tree-sitter-markdown/src/scanner.c` (externals list at `grammar.js` lines 970–1041) +- In-the-wild example cited by reporter: `quarto-dev/quarto-web/blob/.../docs/websites/website-navigation.qmd` L155–L159 diff --git a/claude-notes/issue-reports/222/repro.qmd b/claude-notes/issue-reports/222/repro.qmd new file mode 100644 index 000000000..3b85cfefa --- /dev/null +++ b/claude-notes/issue-reports/222/repro.qmd @@ -0,0 +1 @@ +The "_blank" word. diff --git a/claude-notes/issue-reports/222/triage.md b/claude-notes/issue-reports/222/triage.md new file mode 100644 index 000000000..3699fe197 --- /dev/null +++ b/claude-notes/issue-reports/222/triage.md @@ -0,0 +1,157 @@ +# Issue #222 — Non-deterministic diagnostic output + +- **GitHub**: https://github.com/quarto-dev/q2/issues/222 +- **Reporter**: @rundel (Colin Rundel), 2026-05-21 +- **Triage date**: 2026-05-20 +- **Worktree**: `.worktrees/issue-222` (branch `issue-222`, based on `main` @ `99e7f89c`) +- **Beads issue**: bd-hwdlq +- **Scope**: the variable second diagnostic (Q-2-5 Underscore vs. second Q-2-11 Double Quote) on the reported input. Both variants share the same first diagnostic, which is not in scope. + +## Summary + +Reproduced. The tree-sitter parse trace is byte-identical across runs (verified across 15 runs), so the GLR parser itself is deterministic on this input. **All of the nondeterminism is downstream**, in `quarto-parse-errors`: a `HashMap` keyed by GLR version number is iterated by `.values()` to extract diagnostic states, and a `(row, column)` dedupe drops every state but the first. With three GLR branches all hitting `detect_error` at `(row=0, col=18)`, whichever HashMap bucket is iterated first wins. Default `RandomState` randomizes per process. Confirmed by swapping `HashMap` → both `BTreeMap` and `hashlink::LinkedHashMap` locally — each gives 30/30 runs the same diagnostic (Variant A). Fix is one line; the recommendation below uses `LinkedHashMap` to match the convention already used elsewhere in the workspace. + +The user's clarification on the ticket is "either diagnostic is acceptable, as long as the tie is always broken consistently to one of them." Both `LinkedHashMap` (preserves insertion order — tree-sitter inserts version 0 first) and `BTreeMap` (sorts by key — version 0 is lowest) satisfy that. They give identical output on this input because tree-sitter inserts GLR versions in numeric order. + +## Reproduction + +```bash +printf -- 'The "_blank" word.' | cargo run --bin pampa -- --no-prune-errors +``` + +Run repeatedly. Across 30 runs at `99e7f89c` on macOS arm64: + +| Variant | Second diagnostic | Count | +|---|---|---| +| A | `Q-2-5` Unclosed Underscore Emphasis @ col 19 | 19 / 30 (63%) | +| B | `Q-2-11` Unclosed Double Quote with opener at col 5 @ col 19 | 11 / 30 (37%) | + +The first diagnostic — `Q-2-11` Unclosed Double Quote with opener at col 13 — is the same in both. + +Fixture: `repro.qmd` next to this file. + +## Investigation + +### Step 1 — is the tree-sitter parse itself deterministic? + +Captured the verbose tree-sitter parse trace (`-v`) into `/tmp/issue222/run-1.txt … run-15.txt`. Diffed the trace portion (`tree-sitter parse:` … `---`) across all 15 runs. **Byte-identical, every pair.** Runs that produced Variant A and runs that produced Variant B have the same parse trace. + +This rules out tree-sitter (the upstream C library), the `tree-sitter-qmd` grammar, and the GLR scheduling — those all run identically every time. The trace itself records three concurrent GLR versions (`version_count:3`) splitting at column 12 after the `_whitespace` recovery, then condensing at the close of the block. + +### Step 2 — where does the variation enter? + +The diagnostic generator pulls error states off the parse log, not off the final concrete syntax tree: + +- `crates/pampa/src/readers/qmd.rs:124` calls `produce_diagnostic_messages(input_bytes, &log_observer, …)`. +- `crates/quarto-parse-errors/src/error_generation.rs:43-62`: + + ```rust + for parse in &tree_sitter_log.parses { + for process_log in parse.processes.values() { // <-- HashMap iteration + for state in process_log.error_states.iter() { + if seen_errors.contains(&(state.row, state.column)) { + continue; + } + seen_errors.insert((state.row, state.column)); + let diagnostic = error_diagnostic_from_parse_state(…); + result.push(diagnostic); + } + } + } + result.sort_by_key(|diag| diag.location.as_ref().map_or(0, |loc| loc.start_offset())); + ``` + +- `crates/quarto-parse-errors/src/tree_sitter_log.rs:48`: + + ```rust + pub processes: HashMap, + ``` + + with `use std::collections::HashMap` at line 11. Default `RandomState` ⇒ iteration order varies per process. + +The three GLR branches each push a `ProcessMessage` to their own `error_states` at the same `(row=0, column=18)` (this is what tree-sitter reports for col 19 1-indexed). The dedupe lets exactly one through. *Which one* depends on HashMap iteration order — which is the bug. + +The final `sort_by_key` on `start_offset` is a red herring: the first diagnostic is at col 13, the second at col 19, so the sort never changes the order; it just confirms the second slot is always "whatever survives the dedupe." + +### Step 3 — confirm the fix + +Two local experimental changes to `tree_sitter_log.rs`, each tried independently: + +1. `use std::collections::BTreeMap as HashMap;` — 30/30 runs produce Variant A. BTreeMap iterates keys in ascending order ⇒ GLR version 0 wins. +2. `use hashlink::LinkedHashMap as HashMap;` (plus `hashlink = "0.11"` added to `crates/quarto-parse-errors/Cargo.toml`) — 30/30 runs produce Variant A. LinkedHashMap preserves insertion order; tree-sitter inserts version 0 first on this trace, so version 0 wins. + +Both reverted before recording this triage. Recommended fix is LinkedHashMap because the rest of the workspace already uses `hashlink::LinkedHashMap` for the same kind of deterministic-iteration requirement (8 crates, including `crates/pampa/src/readers/json.rs`). + +### Step 4 — audit for other order-dependent HashMap/HashSet in the diagnostic path + +Grep across `crates/quarto-parse-errors/`, `crates/pampa/src/readers/`, and `crates/quarto-error-reporting/`. Findings: + +- `tree_sitter_log.rs:48` — `processes: HashMap`. **Iterated in `error_generation.rs:44` and `tree_sitter_log.rs:72` (`is_good`).** The `is_good` iteration is a boolean AND over all values — order-independent. The `error_generation.rs:44` iteration is the bug. +- `error_generation.rs:40` — `seen_errors: HashSet<(usize, usize)>`. Used only for `contains` / `insert`. Set membership is order-independent. +- `error_generation.rs:358` and `pampa/.../qmd_error_messages.rs:100` — both reach into `parse.processes[&0]` (hardcoded GLR version 0). Already deterministic. +- `error_generation.rs:648` — `kept_set: HashSet` built from a `kept_indices` Vec; used for membership only. +- `error_generation.rs:666` — HashMap inside a unit test. Not user-facing. + +So the production fix is one site. The audit conclusion is that there is no other latent non-determinism in this pipeline. + +## Localization + +- **The bug**: `crates/quarto-parse-errors/src/tree_sitter_log.rs:48` (HashMap declaration) → `crates/quarto-parse-errors/src/error_generation.rs:44` (iteration site). +- **Working analogue**: `error_generation.rs:361` and `qmd_error_messages.rs:103` already pin to `parse.processes[&0]`, which sidesteps the issue but loses information from non-zero GLR versions. Fine for the JSON-corpus path which only needs the main parse; not appropriate for `produce_diagnostic_messages` which needs to see all versions. + +## Open questions — resolved during triage + +- *Is the tree-sitter parse non-deterministic?* No. Trace is byte-identical across 15 runs. +- *Is the variation only in the second diagnostic?* Yes. The first diagnostic (Q-2-11 at col 13) comes from a process that hits its `detect_error` at a different `(row, column)` than the others (col 12-ish vs col 18), so the dedupe doesn't apply. Only the col-18 trio competes. +- *Does the final `sort_by_key` matter?* No. The first/second diagnostics are at different columns, so sorting never reorders them. +- *Is "GLR version 0 wins" the right tie-break?* Acceptable per the user's clarification ("either diagnostic is acceptable, as long as the tie is always broken consistently"). Variant A is also the trace's "main line" (version 0 is the version that continued through the recovery), so it has weak intuitive grounding. +- *LinkedHashMap or BTreeMap?* LinkedHashMap, to stay consistent with the workspace's existing convention for "iteration order must be deterministic" containers (see `pampa/src/readers/json.rs`, plus 7 other crates using `hashlink`). On this trace they produce identical output because tree-sitter inserts GLR versions in numeric order. + +## Outcome / recommended next step + +Filed bd-hwdlq with the fix scope: + +1. **Fix**: change `processes: HashMap` to `hashlink::LinkedHashMap` in `crates/quarto-parse-errors/src/tree_sitter_log.rs:48`. Localized: one import swap (`use std::collections::HashMap;` → `use hashlink::LinkedHashMap as HashMap;` keeps the in-file name `HashMap` working), one initializer (`HashMap::new()` at line 181 stays compiled-the-same thanks to the alias), and `hashlink = "0.11"` added to `crates/quarto-parse-errors/Cargo.toml`. No other call sites need to change. + +2. **Regression test**: add a test that parses the issue-222 input N times in-process (e.g. N=20) and asserts that all N runs produce byte-identical diagnostic output. The test will fail on the current code (probabilistically — N=20 has ≥99.9% chance of failure with the observed 63/37 split) and pass under the fix. Place under `crates/pampa/tests/` or in a new test on `quarto-parse-errors`. + +3. **Audit follow-up** *(optional, not required for this fix)*: grep for `HashMap<.*Log\|HashMap<.*Diagnostic\|HashMap<.*Error` across the crate tree and verify each iteration site either preserves insertion order or sorts. We did the diagnostic-path audit here; broader codebase audit is orthogonal. + +## Verification commands used + +```bash +# Pre-flight (Rust side only — hub-client tests fail on this fresh worktree +# due to wasm-quarto-hub-client not being built, unrelated to issue #222) +cargo xtask verify --skip-hub-build --skip-hub-tests --skip-shared-package-tests \ + --skip-trace-viewer-build --skip-trace-viewer-tests \ + --skip-q2-preview-spa-build + +# Reproduce (with variant counter) +for i in $(seq 1 30); do + out=$(printf -- 'The "_blank" word.' | cargo run --bin pampa --quiet -- --no-prune-errors 2>&1) + if echo "$out" | grep -q "Q-2-5"; then echo "A"; else echo "B"; fi +done | sort | uniq -c + +# Trace determinism check +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do + printf -- 'The "_blank" word.' | cargo run --bin pampa --quiet -- --no-prune-errors -v \ + > /tmp/issue222/run-$i.txt 2>&1 +done +for i in 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do + diff -q <(awk '/tree-sitter parse:/,/^---$/' /tmp/issue222/run-1.txt) \ + <(awk '/tree-sitter parse:/,/^---$/' /tmp/issue222/run-$i.txt) +done + +# Fix-confirmation experiment (REVERTED before committing this triage): +# `use std::collections::HashMap;` -> `use std::collections::BTreeMap as HashMap;` +# in crates/quarto-parse-errors/src/tree_sitter_log.rs +# then re-run the variant counter -> 30/30 Variant A. +``` + +## Cross-references + +- Issue: https://github.com/quarto-dev/q2/issues/222 +- Reporter: @rundel +- Code: `crates/quarto-parse-errors/src/{tree_sitter_log.rs, error_generation.rs}` +- Caller: `crates/pampa/src/readers/qmd.rs:124` +- Project rule on HashMap nondeterminism: noted in passing in the conversation; no explicit `CLAUDE.md` rule yet (recommend one if the audit follow-up surfaces more instances). diff --git a/claude-notes/plans/2026-04-23-website-project-epic.md b/claude-notes/plans/2026-04-23-website-project-epic.md new file mode 100644 index 000000000..1ad038687 --- /dev/null +++ b/claude-notes/plans/2026-04-23-website-project-epic.md @@ -0,0 +1,878 @@ +# Website Projects (Epic) + +**Date:** 2026-04-23 +**Beads:** `bd-0tr6` (epic); phases 0–9 as sub-issues; docs spun out as `bd-tr81`. +**Status:** Design approved; phase sub-plans to be written in separate sessions. + +## Overview + +Design and implement **multi-page website projects** for Quarto 2. A website +project is a directory with a `_quarto.yml` declaring `project.type: website`, +containing multiple `.qmd` files that render to a coherent website with +shared navigation, cross-document references, and deduplicated resources. + +This epic sits at the intersection of four features that interlock: + +1. **A "static document snapshot" contract** — a typed, serializable summary of + everything knowable about a document without running its engines or user + filters. Sidebars, navbars, cross-references, incremental rebuild cache, + and (eventually) `freeze` all depend on this. +2. **Sidebars** — new navigational affordance, following the `generate/render` + pattern established by TOC, navbar, footer. +3. **Project-scoped shared resources** — `site_libs/` style dedup of CSS, JS, + themes, fonts across pages. A reshape of `ArtifactStore` so stores know how + to relocate themselves based on project scope. +4. **Hub-client project rendering** — hub-client caches a project's navigation + state and re-renders only the active page on edit. This foreshadows the + bigger architectural move: **`quarto preview` in Quarto 2 will be a local + hub-client instance** (ephemeral sync server + file watcher), not a + standalone preview server. + +## Reference material + +This plan was written after reviewing: + +- **Q2 pipeline design:** `claude-notes/plans/2026-01-06-pipeline-stage-design.md`, + `2025-12-27-unified-render-pipeline.md`, `2025-12-29-config-integration-pipeline.md`, + `2026-03-09-metadata-merge-stage.md`, `2026-03-16-user-filters-pipeline.md`, + `2026-04-01-lua-api-pipeline-wiring.md`, `2026-04-13-pipeline-tracing.md`. +- **Q2 navigation model:** `claude-notes/plans/2026-04-18-navbar-footer-design.md`, + `2026-01-28-phase6-toc-rendering.md`, `2026-01-10-hub-client-nav-refactor.md`. +- **Q2 dependencies/resources:** `claude-notes/plans/2026-04-18-html-js-deps-design.md`, + `2026-03-09-css-in-pipeline*.md`, `2025-12-20-minimal-website-render-resources.md`. +- **Hub-client:** `claude-notes/plans/2025-12-22-quarto-hub-web-frontend-and-wasm.md`, + `2026-01-28-unify-hub-client-pipeline.md`. +- **Q1 website analysis (stale but useful):** `claude-notes/website-project-rendering.md`, + `claude-notes/book-project-rendering.md`. +- **Source code** in `crates/quarto-core/src/pipeline.rs`, + `crates/quarto-core/src/stage/`, `crates/quarto-navigation/src/`, + `crates/quarto-core/src/transforms/`, `crates/wasm-quarto-hub-client/src/`, + and Q1 reference in `external-sources/quarto-cli/src/project/types/website/`. + +## Key decisions (from design conversation) + +These are settled as of this draft; sub-plans will execute on them. + +1. **Static snapshot is a typed, serializable value.** New type (working name + `DocumentProfile` — see naming TBD below) produced at a fixed pipeline + checkpoint. Downstream code that needs cross-document information reads + `Vec`. User filters at later stages may read profiles but + **cannot mutate them**. +2. **Pipeline stages up to the snapshot are resumable.** Pass 1 advances each + file to the snapshot checkpoint and stores the intermediate pipeline state. + Pass 2 **resumes from the checkpoint** rather than re-running. Avoids + redundant execution. Also the substrate for future `freeze`. +3. **Project orchestration uses a `ProjectType` trait** with `pre_render` / + per-file contributions / `post_render` hooks. Websites, books, + manuscripts, and default all implement it. Single-document renders + continue to work as a degenerate "default" project. +4. **MVP scope explicitly excludes:** search, listings+RSS, aliases, + announcements, analytics, 404 page, reader-mode, repo-actions, + breadcrumbs. These are follow-up epics. +5. **`quarto preview` is out of scope for this epic** but the design must not + paint us into a corner — it will be rebuilt as a local hub-client instance + in a separate project. +6. **Artifact stores are scope-aware and relocatable.** A single-document + project resolves relative to the document; a multi-document project + resolves relative to the project's output dir (`_site/site_libs/`). +7. **One new user-filter position:** after the snapshot checkpoint, where + filters can read `Vec` but cannot mutate the snapshot. + Pre-snapshot mutation is reserved for future Quarto-1-style pre-render + scripts. + +## Naming decisions + +- **Static-document snapshot type**: **`DocumentProfile`**. Final. Used + throughout the rest of this plan. +- **Trait naming**: `ProjectType` (matches Q1 terminology users already know). +- **Snapshot stage name**: finalize in phase 0 when the code shape is + concrete. Candidates: `ProfileStage`, `DocumentProfileStage`, + `ProjectSnapshotStage`. + +## Scope + +### In scope + +**Core machinery:** +- `DocumentProfile` type + stage + checkpoint in the pipeline. +- Pipeline resumability at the checkpoint boundary. +- `ProjectType` trait and `WebsiteProjectType` implementation. +- Project orchestration: two-pass render across all files in a project. +- Cross-document index available to per-file rendering. + +**Website-specific features (MVP):** +- Project-level **navbar** (extends existing single-doc navbar). +- Project-level **page-footer** (extends existing single-doc footer). +- **Sidebar** (new): manual + auto + nested sections, multiple sidebars + keyed by `id` or path-prefix, sidebar-for-page resolution. +- **Page navigation** (prev/next from sidebar position). +- **Cross-document link rewriting** (`[link](other.qmd)` → `other.html`). +- **Project output directory** (`_site/` by default). +- **Shared `site_libs/`** for deduplicated CSS/JS/theme resources. +- **`sitemap.xml`** (when `site-url` is set). +- **Favicon** (`website.favicon`). +- **Site title / title prefix** (`website.title`). + +**Incremental rebuilds (v1):** +- Cache serialized `DocumentProfile`s keyed by source hash/mtime. +- Reuse cached profiles for unchanged files in the project sweep. +- Update sitemap in place. + +**Hub-client integration:** +- Project-level nav state cached in hub-client. +- "Render single page in project context" entry point in the WASM API. +- Invalidation protocol when a sibling's profile changes. + +### Out of scope (explicit defers to separate epics) + +- **Breadcrumbs.** Non-trivial because the same document can be reachable from + multiple sidebar paths; design separately. +- **Search / `search.json` / client search UI.** Significant client-side + infrastructure with its own data model. +- **Listings / RSS feeds.** Its own design with schemas, sorts, filters, + per-category pages. +- **Aliases / redirects.** +- **Announcements.** +- **Google Analytics / other analytics.** +- **Custom 404.** +- **Reader mode.** +- **Repo actions** (`edit`, `source`, `issue` links). +- **`quarto preview` in Q2** (separate epic; this plan must not block it). +- **Book project type.** Will reuse the project machinery but has its own + structure (chapters, parts, appendices, cross-ref numbering). +- **`freeze` (cached engine outputs).** Shares the serializable-checkpoint + substrate but is its own epic. + +## Architecture sketch + +### Pipeline with snapshot checkpoint + +Current pipeline (simplified): `Parse → Merge → Sugar → Engine → ThemeCSS → +UserFilters(pre) → AstTransforms → UserFilters(post) → CodeHighlight → +RenderBody → ApplyTemplate`. + +Proposed shape: + +``` +┌──────────────────────────────┐ +│ Parse │ +│ Merge │ +│ ── [Profile checkpoint] ──── │ ← DocumentProfile extracted here +│ Sugar │ +│ Engine │ +│ ThemeCSS │ +│ UserFilters(pre) │ ← first filter position that reads +│ AstTransforms │ the project-wide Vec +│ UserFilters(post) │ +│ CodeHighlight │ +│ RenderBody │ +│ ApplyTemplate │ +└──────────────────────────────┘ +``` + +The checkpoint sits **after `Merge`** (metadata fully resolved) and **before +`Sugar`** (no AST mutation yet). This means the profile sees parsed-but-raw +content and fully merged metadata, but not engine output — which is exactly +the static contract we want. + +`DocumentProfile` contents (first cut; sub-plan will finalize): + +- `source_path: PathBuf` (relative to project root) +- `output_href: String` (the URL other pages should use to link to this doc) +- `title: Option` (markdown-rich, following Q2 meta + interpretation) +- `subtitle`, `description`, `author(s)`, `date`, `categories`, `keywords`, + `image` (each `Option<…>`) +- `draft: bool` +- `outline: Vec` (id/text/level hierarchy used by sidebar auto, + page-navigation, and in-page TOC) +- `format_id` (which format-variant this page outputs as) +- `profile_version` (bumped if we ever change the serialized shape) +- Room to grow: the type is `serde`-serializable from day one. + +### Pipeline resumability + +`PipelineData` today is an enum threading between stages. Two changes: + +1. **Checkpoint variant** (e.g. `PipelineData::AtProfile { ... }`) is a + dedicated halting point. +2. **Clone at checkpoint.** Pass 1 produces `PipelineData::AtProfile` for each + file and keeps a clone; the extracted `DocumentProfile` is stored in the + project's cross-doc index. Pass 2 takes the stored `AtProfile`, injects the + cross-doc index into the per-file runtime context, and resumes into `Sugar` + onwards. + +For the CLI on a cold project: the full pass 1 happens in memory; pass 2 +happens in memory immediately after. For incremental rebuilds: pass 1 may be +satisfied from disk cache (see §Incremental). + +This pattern also lets hub-client serialize checkpoint state into the VFS, +and eventually serves as the mechanism for `freeze`. + +### `ProjectType` trait + +Rough shape (sub-plan will finalize names, async shape, error type): + +```rust +pub trait ProjectType { + fn kind(&self) -> &'static str; // "website", "book", "default" + fn output_dir(&self) -> &'static str; // "_site" for website, "." for default + fn lib_dir(&self) -> &'static str; // "site_libs" for website, "{stem}_files" for default + + // Called after config is loaded, before any files are processed. + fn pre_render( + &self, + ctx: &mut ProjectContext, + ) -> Result<()>; + + // Transforms/stages to add to the per-file pipeline for this project type. + fn per_file_transforms(&self) -> Vec>; + + // Called after all files have rendered. + fn post_render( + &self, + ctx: &ProjectContext, + outputs: &[RenderedPage], + incremental: bool, + ) -> Result<()>; +} +``` + +The "default" project type (single-doc or directory-without-`_quarto.yml`) +implements no-op hooks. Website adds the per-file navigation transforms plus +sitemap/favicon emission in post-render. + +### Cross-document index + +Shape: + +```rust +pub struct ProjectIndex { + pub profiles: Vec, + pub by_source_path: HashMap, + pub by_output_href: HashMap, + // Helpers for sidebar/link rewriting: + pub fn lookup_by_source(&self, path: &Path) -> Option<&DocumentProfile>; + pub fn lookup_by_href(&self, href: &str) -> Option<&DocumentProfile>; +} +``` + +Available to per-file pipeline via the runtime context, shared read-only in +pass 2. + +### Artifact store scoping and relocation + +Today: `ArtifactStore` holds keyed blobs (CSS, JS, intermediate docs). +Problem: nothing tells it whether it's writing to a per-page directory or a +project-shared directory. + +Proposed reshape: + +- Every artifact entry has a **scope**: `Page` (per-file) or `Project` + (shared). +- An artifact writer (part of project orchestration) resolves scopes into + concrete paths: + - Default project (single doc): both scopes resolve under + `{stem}_files/...` alongside the output. + - Website project: `Page` scope → `{stem}_files/` per-page; `Project` scope + → `_site/site_libs/{name}/...` shared. +- Theme CSS, navbar/sidebar JS, bootstrap, and similar shared assets are + tagged `Project`. Per-page figures, cached plots, and engine outputs stay + `Page`. +- The rendered HTML for a page rewrites artifact URLs through a relocator + that knows the project's layout, so that `index.html` and `docs/api.html` + each produce the correct relative or absolute reference to the same shared + file. + +This reshape is the one piece of this epic that touches code outside of +website-specific modules. The sub-plan must carefully sequence the change so +single-document rendering remains a pure refactor (no behavior change). + +### Template slot changes + +Following navbar/footer/TOC, sidebar and page-navigation get their own slots: + +- `$rendered.navigation.sidebar$` (left column, when applicable) +- `$rendered.navigation.page_navigation$` (prev/next block, bottom of page) + +Existing slots (`$rendered.navigation.navbar$`, `$rendered.navigation.toc$`, +`$rendered.navigation.footer$`) already exist. The template remains a +substitution target; project context flows through `ast.meta.navigation.*` +and the pre-rendered HTML strings. + +### Hub-client integration shape + +Two new WASM API surfaces (or extensions of existing ones): + +1. **`build_project_nav(project_dir)`** — runs pass 1 for all files in the + project, returns a serializable `ProjectNavState` (profiles + resolved + sidebar/navbar/footer). Called once when the user opens a project. +2. **`render_page_in_project(file_path, project_nav_state)`** — resumes + from the cached `AtProfile` (if we serialize it, or re-runs pass-1 for + that one file cheaply), then runs pass 2 with `project_nav_state` injected + into the context. + +On edits: +- Profile-affecting changes (title, draft flag, frontmatter, sidebar YAML in + `_quarto.yml`) → rebuild `ProjectNavState`, re-render active page. +- Body-only changes → re-render active page only; nav state unchanged. + +**Preview coupling:** this is the same API shape the future `quarto preview` +CLI wants, backed by an ephemeral hub server instead of a browser session. +Designing these entry points well is how we avoid painting ourselves into a +corner. + +### Incremental rebuilds + +For the CLI and for hub-client: + +- Compute a content hash of each source file (plus the merged metadata that + affects it — project config files, parent `_metadata.yml`). +- Key the cached `DocumentProfile` on that hash; key cached pass-2 output on + the same hash plus the project's nav-state hash. +- On re-run, recompute hashes; reuse cached profile if unchanged; rebuild + nav state (cheap); re-render only pages whose body hash or whose + nav-relevant context changed. +- Sitemap updates in place: parse existing `sitemap.xml`, update/add entries + for changed files, write back. + +v1 can be conservative (hash-based, single cache dir per project). More +aggressive strategies (dependency tracking across files) are follow-ups. + +## Phases + +### Phase 0 — Foundations (snapshot contract, resumability, naming) + +Sub-plan: `claude-notes/plans/2026-04-23-websites-phase-0.md` +(beads `bd-f3jc`). Contract doc (to be written during +implementation): `claude-notes/designs/document-profile-contract.md`. + +Deliverables: +- Final names for `DocumentProfile`, `ProjectType`, and the snapshot stage. +- `DocumentProfile` type (in `quarto-core` or a new `quarto-project` crate — + to be decided in phase 0), `serde`-serializable. +- Pipeline checkpoint: `PipelineData::AtProfile { … }` (or equivalent), + `Clone` at this boundary. +- Tests: round-trip serialization, stage advances to checkpoint from a + fixture and clones cleanly. +- Documentation in `CLAUDE.md` or `claude-notes/` describing the contract: + "what is guaranteed present in a profile and under what conditions". + +Cross-cutting invariant from Phase 0 that later phases must respect: +**no code added for the website epic may branch on "is this a +project?"** — a bare file is a single-file project rooted at its +directory, and the project-relative / output-relative math works +uniformly. See Phase-0 sub-plan §"Project root invariant" for detail. +This inverts a recurring Q1 bug source. + +### Phase 1 — Project orchestration + +Deliverables: +- `ProjectType` trait. +- `DefaultProjectType` (single-doc + loose-directory fallback, no-ops). +- `ProjectPipeline` driver: discovers files, runs pass 1, builds + `ProjectIndex`, runs pass 2 per file. +- Integration point in the `quarto` binary so `quarto render` in a directory + with `_quarto.yml` invokes `ProjectPipeline`. +- Regression: existing single-doc renders still pass all tests (they go + through `DefaultProjectType` now). + +### Phase 2 — Sidebar (data model, generate, render, template) + +Deliverables: +- Schema: parse `website.sidebar` as `Vec`. Each sidebar has + `id`, `title`, `contents`, `style`, `collapse-level`. Contents supports + string (path), `{href, text, icon}`, `{section, contents}`, `{auto: …}`. +- Data types in `quarto-navigation`: `Sidebar`, `SidebarEntry`, + `SidebarContents`. +- `SidebarGenerateTransform` — reads `_quarto.yml` sidebar config and the + `ProjectIndex` to resolve `auto:` and expand entries with real titles/hrefs. +- `SidebarRenderTransform` — emits HTML (Bootstrap 5 compatible, matches + Q1 classnames where possible so Q1 CSS continues to work). +- Template slot + integration tests with both manual and auto contents. +- Sidebar-for-page selection (which sidebar applies to which href). + +### Phase 3 — Navbar / footer project integration + +Deliverables: +- Extend existing `NavbarGenerateTransform` and `FooterGenerateTransform` to + read project-level config and cross-doc hrefs via `ProjectIndex`. +- Active-item highlighting in rendered navbar (current page). +- Navbar *tools* stay stubs for now (search button disabled — search is a + follow-up epic). +- Tests: navbar entries pointing at `.qmd` files correctly render as + `.html` links; external URLs pass through. + +### Phase 4 — Page navigation (prev / next) + +Deliverables: +- New `PageNavGenerateTransform` / `PageNavRenderTransform` pair, pattern + identical to the other nav transforms. +- Compute prev/next from flattened sidebar entries. +- Opt in/out per page and per project via `page-navigation: false`. + +### Phase 5 — Scoped artifact store and `site_libs/` + +Deliverables: +- Add `scope: ArtifactScope { Page, Project }` to artifact entries. +- Project-aware artifact writer that emits `Project`-scoped artifacts once + to `_site/site_libs/{name}/…`. +- Relocator that rewrites per-page HTML to point at the shared path. +- Migrate theme CSS, Bootstrap, quarto-nav JS, etc. to `Project` scope when + rendering inside a website project. +- Single-doc renders: both scopes still resolve under `{stem}_files/` to + preserve current behavior. + +### Phase 6 — Cross-document link rewriting + +Deliverables: +- HTML post-render transform that rewrites `href` attributes pointing at + project-relative `.qmd` paths to the corresponding output hrefs, using + `ProjectIndex`. +- Handles query strings, hash fragments, subdirectories. +- Warning (diagnostic) for broken `.qmd` links. + +### Phase 7 — Post-render (sitemap, favicon, site-url/title) + +Deliverables: +- `WebsiteProjectType::post_render` orchestration. +- Sitemap generation (`_site/sitemap.xml`, gated on `website.site-url`). + Incremental-aware: read existing, update, write. +- `robots.txt` referencing sitemap, if not present. +- Favicon copied to output dir and referenced in page ``. +- Title prefix: pages render with `` in + ``. + +### Phase 8 — Incremental rebuilds + +Deliverables: +- Content hashing for source + merged metadata contributions. +- On-disk cache dir (in `.quarto/` per project) for serialized profiles and + pass-2 output stubs. +- CLI: detect and reuse unchanged pages. +- Tests: edit one page's body, verify only that page re-renders; edit + `_quarto.yml` sidebar, verify sidebar rebuilds but bodies don't. + +### Phase 9 — Hub-client project rendering + +Deliverables: +- WASM API surface: `build_project_nav`, `render_page_in_project`. +- Hub-client state: project-scoped nav cache, invalidation on profile- + affecting edits. +- Live preview: editing a page's title updates siblings' sidebars within one + render cycle. +- End-to-end smoke test in a real browser session (per CLAUDE.md policy). + +### Documentation — spun out into its own epic (`bd-tr81`) + +Originally this epic included a Phase 10 for documentation. We've promoted +it to its own epic (`bd-tr81`) because the motivation for doing websites +*now* is to unblock Quarto 2's own documentation site, and that docs effort +is bigger than a single phase of this epic. The docs epic covers **both** +existing Q2 features and the new website features, all built using Q2 +itself (bootstrapping). + +The docs epic depends on this one reaching a minimum functional state +(phases 0–2 plus 5–7 — enough to render a navbar + sidebar + shared +resources website). See `bd-tr81` for its own plan. + +## Test strategy (cross-cutting, all phases) + +- **Fixture projects** under a new `crates/quarto-core/tests/fixtures/websites/`: + - `minimal/` — two pages, one sidebar, no other features. + - `auto-sidebar/` — sidebar with `auto: true`. + - `nested-sections/` — sidebar with nested section groups. + - `mixed-engines/` — mix of markdown and code-executing pages to exercise + pass 1 without engine execution. + - `site-url/` — exercises sitemap and title prefix. + - `shared-theme/` — exercises scoped artifact relocation. +- **End-to-end CLI verification** per CLAUDE.md §"End-to-end verification" + for every phase that produces user-visible output (cargo run --bin quarto + -- render <fixture>; inspect output). +- **Snapshot tests** for rendered HTML fragments (sidebar, page-nav) with + explicit call-outs when snapshots change. +- **Hub-client smoke test** in phase 9: real browser session showing a + live-preview update affecting the sidebar. +- **Full-workspace verification** (`cargo xtask verify`) before every commit + touching `quarto-core` or `quarto-pandoc-types`. + +## Open questions to resolve during phase 0 + +- **Naming** (Document* type, Trait, Stage). +- **Crate placement:** does `DocumentProfile` + `ProjectType` live in + `quarto-core`, or a new `quarto-project` crate that depends on + `quarto-core`? Depends on circular-dep analysis. +- **Async vs sync `ProjectType`.** The existing per-file pipeline is sync; + some Q1 hooks (network, shell out) would benefit from async. Decide in + phase 1 based on what Website's pre-render needs in MVP. +- **Snapshot location precisely:** is it after metadata merge, or after + metadata merge + pre-engine sugaring? Sugar mutates the AST (callouts, + theorems). If sidebars only need title/heading-outline from the raw AST, + pre-sugar is the cleaner cut. Confirm during phase 0. +- **Profile hashing strategy:** source file only, or include relevant + `_quarto.yml` / `_metadata.yml` content too? Relevant to phase 8. +- **Cache location:** `{project}/.quarto/cache/`? Gitignored? Shared with + any existing cache? Relevant to phase 8. + +## Explicit non-goals for this epic + +- No search, listings/RSS, aliases, announcements, analytics, reader mode, + repo-actions, breadcrumbs. Each is a follow-up. +- No book project type. (`ProjectType` trait enables it, but book-specific + features like part/chapter numbering, cross-ref adjustments, appendices + are out of scope.) +- No `quarto preview` in Quarto 2. (Separate epic; shape of hub-client APIs + here must support it.) +- No `freeze`. (Shares the serializable-checkpoint substrate; follow-up.) +- No parallel per-file rendering in v1. (The two-pass structure allows it + cleanly, but v1 ships sequential. A follow-up can add parallelism within + pass 2.) + +## Risks and mitigations + +- **Risk:** artifact-store reshape regresses single-doc rendering. + *Mitigation:* phase 5 must ship a pure refactor first (new scope API, + identical behavior when all scopes resolve under `{stem}_files/`), then + switch websites to use `Project` scope as a second step. +- **Risk:** pipeline resumability breaks existing stage invariants. + *Mitigation:* phase 0 adds a cloneable checkpoint *without* changing the + rest of the pipeline, and an integration test that clones at the + checkpoint and resumes produces byte-identical output to running end to + end. +- **Risk:** hub-client nav invalidation is easy to get wrong (stale + sidebars, flicker). *Mitigation:* phase 9 adds an explicit invalidation + log and a smoke test that covers the tricky cases (rename, draft toggle, + title edit, new file). +- **Risk:** `ProjectType` trait calcifies too early. *Mitigation:* trait + starts minimal in phase 1. Book/manuscript additions will grow it, but + only once we know what they actually need. + +## Work items + +These will be filed as `br` sub-issues under the epic. They mirror the +phases above. + +- [x] **Phase 0:** Foundations (snapshot type, checkpoint, naming). + Closed `bd-f3jc` (commit `e8674612` on `feature/websites`). + Sub-plan: `claude-notes/plans/2026-04-23-websites-phase-0.md`. + Contract: `claude-notes/designs/document-profile-contract.md`. +- [x] **Phase 1:** `ProjectType` trait + orchestration. + Closed `bd-w5os` (commits `5bd92a4a` rename + `c00ee7eb` + orchestration on `feature/websites`). + Sub-plan: `claude-notes/plans/2026-04-23-websites-phase-1.md`. +- [x] **Phase 2:** Sidebar data model, generate, render, template. + Closed `bd-9svl` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-24-websites-phase-2.md`. +- [x] **Phase 3:** Navbar / footer project integration. + Closed `bd-fqyg` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-24-websites-phase-3.md`. +- [x] **Interphase merge:** `main` → `feature/websites` to thread + `IncludeExpansionStage` (from main, 2026-04-20) through the + DocumentProfile checkpoint. Post-merge pipeline order runs + `IncludeExpansion` immediately before `DocumentProfile`, so + profiles reflect content spliced in via `{{< include … >}}`. + Closed `bd-xfwx` (merge commit `c3bcfb76` on + `feature/websites`). Sub-plan: + `claude-notes/plans/2026-04-24-include-expansion-merge.md`. + Follow-up `bd-r82e` tracks the deferred + `DocumentProfile.includes: Vec<…>` field needed for Phase-8 + cache invalidation (see §Epic-wide follow-ups). +- [x] **Phase 4:** Page navigation (prev/next). + Closed `bd-nwun` (commit `4a59a9dd` on `feature/websites`). + Sub-plan: `claude-notes/plans/2026-04-24-websites-phase-4.md`. + Adds 48 new tests (42 unit + 6 integration) and a Q1-matching + prev/next strip emitted from the already-resolved sidebar. +- [x] **Phase 5:** Scoped artifact store + `site_libs/`. + Closed `bd-u5pr` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-24-websites-phase-5.md`. + Adds `ArtifactScope { Page, Project }`, + `ResourceResolverContext` (single_doc / website / vfs_root + flavors), fingerprinted theme CSS keying, scope-aware + drain/merge with byte-equality dedup. Single-doc + byte-identity preserved against pre-Phase-5 baseline. + Multi-doc websites now emit one shared + `_site/site_libs/quarto/quarto-theme-<fingerprint>.css` + with correct relative URLs in nested-page `<link>` tags. + Follow-ups: `bd-b9za` (ext-dep dedup integration test), + `bd-78ud` (empty `{stem}_files/` cleanup), `bd-apvo` + (`project.lib-dir:` user-config override), `bd-vdl8` + (retire `DEFAULT_CSS_ARTIFACT_PATH`). +- [x] **Phase 6:** Cross-document link rewriting. + Closed `bd-v30t` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-24-websites-phase-6.md`. + Adds `LinkRewriteTransform` (start of Finalization Phase), + `resolve_doc_relative_href` helper in `navigation_href.rs` + (with private path-normalization helper), `page_url_for` + method on `ResourceResolverContext`, and a new + `resource_resolver` field on both `RenderContext` and + `StageContext` (bridged through `AstTransformsStage`). + Adds 49 new tests (10 unit + 21 helper + 11 integration + + 7 resolver) and validates against `/tmp/q2-phase6-smoke/` + end-to-end. Follow-ups: `bd-p4sc` (draft-mode), `bd-fo1r` + (index-forgiveness), `bd-nb32` (data-noresolveinput), + `bd-j3a0` (diagnostic dedup), `bd-gdrv` (cross-format — + `related` not parent-child), `bd-td2a` (footer text-region + rewrite, supersedes `bd-jfyl`). +- [x] **Phase 7:** Post-render (sitemap, favicon, site-url/title). + Closed `bd-b9mz` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-27-websites-phase-7.md`. + Adds three per-page Pass-2 transforms + (`WebsiteTitlePrefixTransform`, `WebsiteFaviconTransform`, + `WebsiteCanonicalUrlTransform`), the `website_config` helper + module, and the `website_post_render` module + (`flush_site_libs` extracted from orchestrator + new + `copy_favicon` / `write_sitemap` / `write_robots_txt`). + `WebsiteProjectType::post_render` is now a four-line + composition. Trait signature gained + `&mut Vec<DiagnosticMessage>` for non-fatal warnings; + `ProjectRenderSummary` gained `project_diagnostics`. Adds + 46 new tests (8 + 8 + 10 + 9 + 12 + 10 across helper / + transforms / post-render / integration). Validated + end-to-end with `/tmp/q2-phase7-smoke/` (3-page website + with title, site-url, favicon) — all four post-render + outputs (`sitemap.xml`, `robots.txt`, `_site/favicon.ico`, + copied favicon) verified plus per-page `<title>`, + `<link rel="icon">`, `<link rel="canonical">` inspected + and matched. Follow-ups: `bd-7h6a` (per-page favicon + override — user-flagged), `bd-pphv` (sitemap incremental + merge), `bd-tyvt` (Open Graph / social meta), `bd-ochm` + (brand-aware favicon), `bd-4zdf` (multi-format favicon), + `bd-1hdz` (draft-mode sitemap), `bd-97yc` (home-page + title carve-out), `bd-82dn` (empty-index sitemap filter). +- [x] **Phase 8:** Incremental rebuilds. + Closed `bd-fegm` on `feature/websites`. + Sub-plan: `claude-notes/plans/2026-04-27-websites-phase-8.md`. + Sub-phases 8.0 (DocumentProfile v2 — `includes`, + `nav_dependencies`, `always_render`, `body_link_targets`; + `DOCUMENT_PROFILE_VERSION` 1 → 2), 8.1 (cache infrastructure + — `cache_key`, `profile_cache`), 8.2 (dependency graph + + Mode B render selection + orchestrator profile cache wiring), + 8.3 (sitemap incremental merge — closes `bd-pphv`), + 8.4 (CLI surface — `inputs: Vec<String>`, `--clean-cache`, + mode dispatch via `classify_inputs`, summary line), 8.5 + (integration + CLI e2e tests at the binary level), 8.6 + (WASM/hub-client cache-no-op audit). Closes `bd-r82e` + (DocumentProfile.includes) and `bd-pphv` (sitemap merge). + Follow-ups filed at close-out: `bd-par3`, `bd-nv5c`, + `bd-pp89`, `bd-k8ol`, `bd-nqcv`, `bd-3a0o`, `bd-o505`. +- [x] **Phase 9:** Hub-client project rendering. + Sub-plan `claude-notes/plans/2026-04-27-websites-phase-9.md`. + Sub-phases 9.0 (Pass2Renderer trait extraction), 9.1 + (un-gate `ProjectPipeline` for WASM), 9.2 (WASM Pass-2 + renderer + cross-platform `flush_site_libs` driven by the + resolver), 9.3 (`render_page_in_project` WASM entry point + with new `RenderMode::ActivePage` variant), 9.4 (hub-client + switch — `renderToHtml` now drives the project-aware + renderer; `Preview`'s re-render `useEffect` depends on + `fileContents` so any sibling edit triggers a re-render), + 9.5 (hub-smoke fixture + native integration tests + pinning the WASM code path), 9.6 (close-out). Closes + `bd-ayj6`. Browser smoke GIF + manual recipe deferred to a + follow-up session; the native integration test + (`crates/quarto-core/tests/render_page_in_project.rs`) + exercises the same Rust code path the browser would. + +Documentation is tracked separately as `bd-tr81`. + +Each phase will get its own `claude-notes/plans/YYYY-MM-DD-*.md` sub-plan +before implementation begins. + +## Epic-wide follow-ups surfaced by sub-plans + +Issues that transcend a single phase — surfaced while scoping a phase +but with implications across the epic. These must be tracked here so +the epic's close-out catches them; filing as bd happens when the +relevant design work starts. + +- **Nav-config placement is inconsistent across features.** Surfaced + in Phase 2 scoping (see `2026-04-24-websites-phase-2.md` Decision 1 + & 6). Today: `navbar` reads from top-level document metadata, + `sidebar` reads from `website.sidebar`, and the per-page + sidebar-id override reads from top-level `site-sidebar`. Q1 has the + same split. For Q2 we should pick one placement — either + "everything top-level" or "everything under a nav namespace" — and + migrate all of navbar / sidebar / page-footer / page-navigation / + site-url / title-prefix / `site-sidebar` to it. The decision should + land before we commit to a docs-facing release, but is not a + blocker for the website epic to ship a working MVP. +- **Sidebar template placement.** Phase 2 puts the sidebar beside the + TOC on the right, which is the minimum-churn slot in the existing + full HTML template. Q1 renders sidebar-left, TOC-right. Moving to + the Q1 layout is a `FULL_HTML_TEMPLATE` restructuring task — not + sidebar-feature work — and is tracked as a separate follow-up so + Phase 2 stays scoped to feature implementation. +- **DocumentProfile should record its include set.** Surfaced while + merging the `IncludeExpansionStage` from `main` ahead of the + `DocumentProfile` checkpoint (`bd-xfwx`). After the merge, a + profile can reflect content spliced in from `{{< include … >}}` + children; the profile therefore *depends on* those child files + but carries no record of them. For Phase 8 (incremental + rebuilds) and for eventual `freeze`, the cache-key computation + needs to invalidate a parent's cached profile when any + (transitive) include changes. Tracked as `bd-r82e`; not a + blocker for Phases 4–7. +- **Page-navigation rules need user-facing docs.** Surfaced in + Phase 4 scoping (see `2026-04-24-websites-phase-4.md` Decision 9). + The flatten-the-sidebar / dedupe-by-href / separator-as-boundary / + section-header-as-neighbor rules are all non-obvious. Should land + in `bd-tr81`'s docs site. Not a blocker for the epic; user + explicitly flagged the need. +- ~~**`br` tool blocked on stale `k-02o9` JSONL entry.**~~ + *Resolved 2026-04-24.* `br` was upgraded from 0.1.28 → 0.1.45; + the newer release accepts the mixed `k-` / `bd-` prefix history + in `.beads/issues.jsonl` (611 legacy `k-*` IDs from before the + prefix migration co-exist with the newer `bd-*` IDs). Phase 4's + `bd-nwun` and its five follow-ups were filed under 0.1.45 + without incident. + +## Follow-up beads report (running log) + +Each phase will accumulate follow-up `bd` issues — deferred work +discovered while scoping or implementing that phase. To keep the +follow-up surface visible in one place, **the final close-out task +of the epic is to produce a single report** listing every `bd` issue +created in service of the website epic and its current status +(open / closed / reassigned). The report should link each issue to +its originating sub-plan so reviewers can trace why each was +deferred. + +Running log (update as phases close; cross-link from each sub-plan +when it files an issue): + +- **Phase 0 (`bd-f3jc`, closed).** No follow-ups filed at close-out. +- **Phase 1 (`bd-w5os`, closed).** Follow-ups filed at close-out: + - `bd-ee4z` — Pass-2 resumption from cached `AtProfile` + (optimization; v1 re-runs the head pipeline). + - `bd-7tvb` — `.quartoignore` support in file discovery. + - `bd-k9i1` — `project.resources` support for non-renderable + site resources. + - `bd-mlj6` — conditional render lists / `_quarto-<profile>.yml` + config profiles. + - `bd-xxul` — non-`.qmd` input extensions (.md / .ipynb / .Rmd) + in project discovery. + - `bd-pdwr` — parallel per-file rendering via rayon + + pollster-per-worker. +- **Phase 2 (`bd-9svl`, closed).** Follow-ups filed at close-out: + - `bd-6cme` — Sidebar search integration (depends on search epic). + - `bd-fod3` — Sidebar tools: reader-mode, dark-toggle, etc. + - `bd-ht0n` — Sidebar logo / subtitle / header / footer rendering. + - `bd-49ar` — Sidebar collapse/expand JS (rides with Phase 5). + - `bd-w0o9` — Draft-mode include/visible/exclude option. + - `bd-l6f0` — Honor explicit `expanded: true` through active + resolution. + - `bd-81x4` — Multi-sidebar ambiguity diagnostic. + - `bd-tfy0` — Deep-directory auto-sidebar grouping (N-level). + - `bd-2quy` — Audit `StageContext` ↔ `RenderContext` bridge + completeness. (Phase 2 surfaced a missing `project_index` + field; a structural guard would prevent recurrence.) + - `bd-n9dr` — *(epic-wide)* Unify nav config placement across + features (`navbar` vs `website.sidebar` vs `site-sidebar`). +- **Phase 3 (`bd-fqyg`, closed).** Follow-ups filed at close-out: + - `bd-jfyl` — Footer `Text`-region project-link rewriting (depends + on Phase 6's body-link rewriter contract). + - `bd-jbml` — Navbar index-forgiveness + (`about/` == `about/index.html`) if a real site hits it. + - `bd-bwwv` — Navbar sub-row (book-style secondary navbar, epic- + excluded for MVP). + - `bd-9m8p` — `navbar.pinned` JS (rides with Phase 5 `site_libs/`). + - `bd-15dw` — Navbar icon-only item enrichment tie-break. + - `bd-n9dr` reframed: Phase 3 replaced "unify everything under one + namespace" with "placement follows feature semantics." The only + remaining tension is `site-sidebar` at the doc-level override for + a website-scoped feature. Description updated 2026-04-24. + - *(no epic-wide follow-up for sidebar template placement; `bd-4g6g` + remains open from Phase 2 unchanged.)* + - `bd-4g6g` — *(epic-wide, from Phase 2)* Move sidebar to Q1 + template position (sidebar-left, TOC-right). +- **Phase 4 (`bd-nwun`, closed).** Follow-ups filed at close-out + (`br` was upgraded mid-close-out from 0.1.28 → 0.1.45, which + unblocked all `bd` operations): + - `bd-q1pe` — Emit `<link rel="prev/next">` meta tags for page-nav + (deferred Decision 7; touches the HTML render config and template + `<head>` slot). + - `bd-xwq8` — Suppress page-nav for `page-layout: custom` pages + (Q1 parity). + - `bd-q6ky` — Plain-text aria-label projection for rich titles + (rides with eventual rich-title support in `DocumentProfile`). + - `bd-bobp` — Index-forgiveness for page-source matching (mirrors + `bd-jbml` from Phase 3). + - `bd-nf50` — *(epic-wide, related to `bd-tr81`)* Page-navigation + rules need user-facing docs in the Q2 docs site. (Decision 9.) +- **Phase 5 (`bd-u5pr`, closed).** Follow-ups filed at close-out: + - `bd-b9za` — Extension-dep `site_libs/` dedup integration + test (Phase-5 plan tests 19 / 22 deferred; unit-level + coverage exists, integration fixture would close the gap). + - `bd-78ud` — Empty `{stem}_files/` cleanup for pages that + emit no Page-scoped artifacts. (Open question 5.) + - `bd-apvo` — `project.lib-dir:` user-config override. + `lib_dir()` returns owned `String` precisely to make this a + drop-in change. (Decision 4.) + - `bd-vdl8` — Retire `DEFAULT_CSS_ARTIFACT_PATH` once + hub-client (Phase 9) moves off synthetic VFS paths. +- **Phase 6 (`bd-v30t`, closed).** Follow-ups filed at close-out + (each `discovered-from:bd-v30t` and linked into the epic graph + via `parent-child:bd-0tr6` or `related:bd-0tr6`): + - `bd-p4sc` — Body-link draft-mode visibility (replace `<a>` + with inner content for draft targets when + `draft-mode != "visible"`). Requires draft-mode YAML config + surface first. P3. + - `bd-fo1r` — Body-link index-forgiveness (`docs/` → `docs/index.qmd`). + Mirrors Phase 3's `bd-jbml` and Phase 4's `bd-bobp`; consider + unifying. P3. + - `bd-nb32` — `data-noresolveinput` escape hatch for + user-controlled body links (Q1 parity). P4. + - `bd-j3a0` — Diagnostic dedup by (page, href). P3. + - `bd-gdrv` — Cross-format URL resolution (HTML→PDF). Out of + website-epic scope (`related` to `bd-0tr6`, not + parent-child); multi-format projects are a future epic. P4. + - `bd-td2a` — Footer Text-region project-link rewriting + using Phase 6's helper. Replaces / supersedes Phase 5's + `bd-jfyl`; the helper now exists, so this is "wire it in". + P3. +- **Phase 7 (`bd-b9mz`, closed).** Follow-ups filed at close-out + (each `discovered-from:bd-b9mz`, parent-child to `bd-0tr6`, + with extra `related` links where noted): + - `bd-7h6a` — Per-page favicon override (`meta.favicon` beats + `website.favicon`). User flagged 2026-04-27 as + expected-soon — the only follow-up the user explicitly + surfaced as likely to come up sooner rather than later. P3. + - `bd-pphv` — Sitemap incremental merge + (read-existing/update/write). Loops with Phase 8. P3. + - `bd-tyvt` — Open Graph / Twitter card / social meta tags + (Q1 `metadataHtmlPostProcessor` parity). P3. + - `bd-ochm` — Brand-aware favicon fallback (once Q2 brand + support lands). P4. + - `bd-4zdf` — Multi-format favicon variants (apple-touch-icon, + sizes). P4. + - `bd-1hdz` — Draft-mode interaction with sitemap. + Coordinate with `bd-p4sc` from Phase 6. P3. + - `bd-97yc` — Title-prefix home-page carve-out (Q1 + `stem == "index"` parity). P4. + - `bd-82dn` — Empty-`index.html` filter in sitemap. + Coordinate with `bd-r82e` (`DocumentProfile.includes` + enrichment is the natural place to add `is_empty`). P4. +- **Phase 8 (`bd-fegm`, closed).** Follow-ups filed at close-out + (each `discovered-from:bd-fegm`, parent-child to `bd-0tr6`): + - `bd-par3` — Smart Mode B nav-config-change detection. + When the nav-config-hash sentinel differs from the last + successful run, augment Mode B's render set with sidebar + members of the targets so their nav HTML stays fresh. P3. + - `bd-nv5c` — Opt-in Pass-2 cache for filter-pure projects. + User-asserts-purity opt-in surface (e.g. + `pass2-cache: trusted`). Out of website-epic scope. P4. + - `bd-pp89` — Native glob expansion for CLI render args. + Cross-platform parity (Windows / quoted args). Phase 1's + `discovery::expand_patterns` is the obvious reuse. P3. + - `bd-k8ol` — Mode B partial Pass-1 walk. Today Mode B does + full Pass-1 (cache makes it cheap on warm path); plan + originally called for partial walk, blocked by sidebar + `auto:` chicken-and-egg. Decoupling auto-resolver from + index unblocks. P3. + - `bd-nqcv` — Glob support in `project.nav-dependencies` + (`[posts/*.qmd]`). Open question 5. P4. + - `bd-3a0o` — Diagnostic for unresolved nav-dependency. + Decision 12 calls for it; graph builder currently silent. + Test 57 verifies render-proceeds half only. P3. + - `bd-o505` — Wire nav-config-hash file write at end of + project render (consumer is `bd-par3`). P4. +- Phase 9: TBD. diff --git a/claude-notes/plans/2026-04-23-websites-phase-0.md b/claude-notes/plans/2026-04-23-websites-phase-0.md new file mode 100644 index 000000000..195e64139 --- /dev/null +++ b/claude-notes/plans/2026-04-23-websites-phase-0.md @@ -0,0 +1,641 @@ +# Phase 0 — Foundations: DocumentProfile, Pipeline Checkpoint, Naming + +**Date:** 2026-04-23 +**Beads:** `bd-f3jc` (phase); parent `bd-0tr6` (website epic). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Status:** Draft — awaiting user review on open questions at the end. + +## Goal of this phase + +Lay the substrate that every subsequent website-epic phase depends on: + +1. A named, typed, serializable **static-document snapshot** type. +2. A named **pipeline checkpoint** between metadata merge and any AST + mutation, where the snapshot is extracted and from which pass 2 can + resume. +3. Round-trip serialization + clone-and-resume tests proving the + checkpoint does what we claim. +4. A short contract document recording **what a snapshot is guaranteed + to contain**, under what conditions, and what it is explicitly *not* + — so future work (sidebar, incremental rebuilds, freeze) builds on + a stable promise. + +**No user-visible behavior change.** This phase ships a pure refactor + +new types. A `quarto render` on a single document must produce +byte-identical output before and after, verified by the existing test +suite and by an explicit regression integration test. + +This phase does **not** implement: + +- The `ProjectType` trait (Phase 1). +- Two-pass orchestration (Phase 1). +- Any sidebar / navbar / footer project behavior (Phases 2–4). +- Any cross-doc index data structure beyond what the snapshot itself + already holds (Phase 1 introduces `ProjectIndex`). +- On-disk caching of snapshots (Phase 8). + +The naming choice must accommodate those later phases (see §Naming +decisions and open questions). + +## Reference material + +Read before starting implementation: + +- Parent plan: `claude-notes/plans/2026-04-23-website-project-epic.md` + (especially §"Pipeline with snapshot checkpoint" and + §"Open questions to resolve during phase 0"). +- `crates/quarto-core/src/stage/data.rs` — `PipelineData` enum and the + variant shapes we'll add to. +- `crates/quarto-core/src/stage/stages/mod.rs` — stage list. +- `crates/quarto-core/src/stage/stages/metadata_merge.rs` — the stage + we're inserting the checkpoint right after (tentatively). +- `crates/quarto-core/src/stage/stages/pre_engine_sugaring.rs` — the + next stage; snapshot lives at the boundary. +- `crates/quarto-core/src/pipeline.rs` — `build_html_pipeline_stages*`. +- `crates/quarto-core/src/crossref/index.rs` — reference pattern for a + serializable per-document artifact (`CrossrefIndex`) already living + in `quarto-core`. Follow its serde conventions. +- `crates/pampa/src/toc.rs` — `TocEntry` / `NavigationToc` (the + outline is already computed here for `toc: auto`; reuse). +- Q1 reference: `external-sources/quarto-cli/src/project/types.ts:315` + (`InputTargetIndex`) and `:322` (`InputTarget`) — the closest Q1 + equivalent, split across "raw" and "resolved". +- `.claude/rules/wasm.md`, `.claude/rules/cross-platform.md` — must + apply to any new code. +- `claude-notes/instructions/testing.md` and `coding.md`. + +## Naming decisions (confirmed 2026-04-23) + +| Concept | Name | +|---|---| +| Snapshot type | `DocumentProfile` | +| Pipeline variant | `PipelineData::AtProfile(DocumentAtProfile)` | +| `PipelineDataKind` tag | `PipelineDataKind::AtProfile` | +| Stage | `DocumentProfileStage` | +| Module (type) | `quarto_core::document_profile` | +| Module (stage) | `quarto_core::stage::stages::document_profile` | +| Trait (Phase 1, deferred) | `ProjectType` (parent plan) — confirmation deferred to Phase 1 | + +**Crate placement.** Keep `DocumentProfile` in `quarto-core` for +Phase 0; revisit `quarto-project` split at the start of Phase 1. + +## Checkpoint position + +Parent plan proposes the checkpoint live **after `MetadataMergeStage` +and before `PreEngineSugaringStage`**. My recommendation: stick with +that. Reasoning: + +1. After merge: metadata is fully resolved (project + directory + + document + runtime layers all flattened, format-specific keys + unwrapped), which is exactly what downstream project features need + to read `title`, `draft`, `categories`, `website.*`, etc. +2. Before sugar: the AST is still the raw parsed form. `outline` + extracted here reflects the author's headings, not synthetic ones + introduced by `TheoremSugar` / `FloatRefTargetSugar` / etc. The + parent plan's §"Open question — Snapshot location precisely" + identifies this as a judgment call; the cleaner cut is pre-sugar. +3. Before engine execution: the profile is static — it does not depend + on Python, R, or Julia running. This is the contract we want for + sidebars, incremental rebuilds, and (eventually) `freeze`. + +One subtlety: `ref_type_registry` is populated by +`PreEngineSugaringStage` (from `crossref.custom` metadata and +promised-id prefixes). It is not part of the snapshot — consumers of +the profile don't need it in Phase 0 — so no conflict today. + +**Forward note (user, 2026-04-23).** Eventually we should move +`ref_type_registry` construction *before* the profile checkpoint. That +would let project-level code validate custom-crossref-type +compatibility across a book or website without rendering every file — +the kind of static cross-document check DocumentProfile is meant to +enable. Not Phase 0 work, but a reminder that the checkpoint's +"pre-sugar" position is deliberately chosen to leave room for things +like this to move earlier in the pipeline. When that move happens, +the registry (or the subset of it needed for cross-file validation) +may need to be added as a profile field, with a `profile_version` +bump. + +## Type sketch + +```rust +// crates/quarto-core/src/document_profile.rs + +use std::path::PathBuf; +use serde::{Deserialize, Serialize}; +use pampa::toc::TocEntry; + +/// Version bumped when the serialized shape changes. Consumers reading +/// a cached profile from disk must check this and reject on mismatch. +pub const DOCUMENT_PROFILE_VERSION: u32 = 1; + +/// Static, engine-independent snapshot of a document extracted after +/// metadata merge and before any AST mutation. +/// +/// See `claude-notes/designs/document-profile-contract.md` for the +/// full contract (what is guaranteed, under what conditions). +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct DocumentProfile { + /// Version tag for serialized profiles. + pub profile_version: u32, + + /// Source path, **always project-relative**, forward-slash + /// separated. See §"Project root invariant" below: there is no + /// such thing as "no project" — a bare file is treated as a + /// single-file project rooted at the file's directory, and its + /// `source_path` is then just the file name. + pub source_path: PathBuf, + + /// Rendered-target href other pages should use to link to this + /// document (e.g. `"about.html"` or `"docs/api.html"`). + /// Forward-slash separated, relative to the project output + /// directory. + pub output_href: String, + + /// Which format-variant is being produced (e.g. `"html"`, + /// `"acm-html"`). Mirrors `ctx.format.target_format` at the + /// checkpoint. + pub format_id: String, + + /// Document title (plain text; inline formatting flattened for + /// cross-document use). `None` when the document has no title + /// and no first-heading fallback could be synthesized. + pub title: Option<String>, + + pub subtitle: Option<String>, + pub description: Option<String>, + + /// Authors, flattened to plain-text strings. One entry per + /// author. See open questions for the "structured authors" + /// trade-off. + pub authors: Vec<String>, + + pub date: Option<String>, + pub categories: Vec<String>, + pub keywords: Vec<String>, + pub image: Option<String>, + + pub draft: bool, + + /// Heading outline (id, text, level, nesting). Reuses + /// `pampa::toc::TocEntry`, which is already serde-serializable + /// and used by `TocGenerateTransform`. + /// + /// Always un-numbered: `TocEntry::number` is `None` for every + /// entry in the profile's outline. Section numbering is computed + /// later by `CrossrefIndexTransform`, which runs *after* the + /// profile checkpoint. Consumers that need numbered outlines must + /// read them from the post-render AST, not from the profile. + pub outline: Vec<TocEntry>, +} + +impl DocumentProfile { + pub const VERSION: u32 = DOCUMENT_PROFILE_VERSION; + + /// Extract a profile from a `DocumentAst` at the checkpoint. + /// This is pure: no I/O, no runtime calls. + pub fn extract( + ast: &Pandoc, + source_path: &Path, + output_href: &str, + format_id: &str, + ) -> Self { /* … */ } +} +``` + +### Pipeline data variant + +```rust +// crates/quarto-core/src/stage/data.rs (additions) + +pub enum PipelineDataKind { + // … existing variants … + AtProfile, +} + +pub enum PipelineData { + // … existing variants … + AtProfile(DocumentAtProfile), +} + +/// Pipeline state at the profile checkpoint. +/// +/// Holds the extracted `DocumentProfile` plus the `DocumentAst` from +/// which subsequent stages will resume. The AST is carried through +/// unchanged — this variant exists purely to expose the profile to +/// project orchestration while keeping the per-file pipeline +/// compositional. +#[derive(Debug, Clone)] +pub struct DocumentAtProfile { + pub profile: DocumentProfile, + pub ast: DocumentAst, +} +``` + +`DocumentAst` itself needs `#[derive(Clone)]` added so the outer +`DocumentAtProfile` can be cloned. All its fields are already Clone +(`Pandoc`, `pampa::pandoc::ASTContext`, `SourceContext`, +`Vec<DiagnosticMessage>` — verified). No serde for `DocumentAst` in +this phase; serialization of the whole checkpoint is a later concern +(freeze epic). + +### The stage + +`DocumentProfileStage` is a pass-through on the data plus an +extraction into `ctx` (or into a new variant — see open questions). +Two candidate shapes: + +**Option A: new pipeline variant (recommended).** + +- Input kind: `DocumentAst` +- Output kind: `AtProfile` +- Runs between `MetadataMergeStage` and `PreEngineSugaringStage`. +- Produces `PipelineData::AtProfile(DocumentAtProfile { profile, ast })`. +- `PreEngineSugaringStage` (and everything after it) changes its + input kind from `DocumentAst` to `AtProfile` and **unwraps** + internally, pulling the `DocumentAst` back out before proceeding. + +This keeps the checkpoint visible in the type system and makes pass 2 +resumability natural: pass 2 takes a `PipelineData::AtProfile` and runs +only the tail of the pipeline. + +**Option B: put the profile in `StageContext`.** + +- Stage input/output both `DocumentAst`. +- Stage writes `ctx.profile = Some(DocumentProfile::extract(...))`. +- No pipeline variant change, no downstream stage signature churn. + +Option B is smaller and lower-risk but does not represent the +checkpoint in the type system — it's just "metadata merge with a side +effect". Option A is more invasive but matches the parent plan's +design intent of a named checkpoint that pass 2 can resume *from*. + +**Decision (2026-04-23): Option A, with the unwrap-stage +implementation strategy** (see next subsection) to keep downstream +stage signatures unchanged. + +**User-flagged concern:** the Option A refactor touches every +downstream stage's input-kind declaration. The unwrap-stage approach +below keeps the diff small, but if something goes wrong during +implementation — e.g. the byte-identical regression test in +§Tests diverges for a reason we can't quickly diagnose — stop, +reassess, and consider falling back to Option B (profile in +`StageContext`, no pipeline-variant change). Option B is strictly +less informative in the type system but equivalent for Phase 0's +consumers. + +### Where the profile is stored for Phase-0 consumers + +In Phase 0 there are no project-orchestration consumers. The profile +is only used by: + +1. A round-trip serialization test. +2. A clone-and-resume integration test (see §Tests). + +For Phase 0 it's enough that the profile exists inside the pipeline +data. Phase 1 introduces `ProjectIndex` and adds it to `StageContext`. + +## Project root invariant (user directive, 2026-04-23) + +**There is no such thing as "no project root."** A bare `.qmd` file +with no `_quarto.yml` nearby is treated identically to a file sitting +next to an empty `_quarto.yml` in the same directory: project root is +the file's directory, `source_path` in the profile is just the file +name, and the output dir resolves relative to that same directory. + +This is a deliberate inversion of Q1, where "is there a project?" was +a branch point threaded through much of the rendering code and was a +repeated source of bugs. In Q2 we never branch on "project or +not" — the project context always exists, and single-file renders are +a degenerate case of the same code path. + +Concretely for Phase 0: + +- `DocumentProfile::extract` takes `project_dir: &Path` and computes + `source_path` as `input.strip_prefix(project_dir).unwrap_or(file_name)` + — never optional, never "absolute fallback". +- `output_href` likewise is always project-output-relative. For a + single-file render, project output dir == project dir == file's + dir, so the href is just `"<stem>.html"`. +- Tests 1–12 below must include a single-file case and a + multi-file-with-`_quarto.yml` case that exercise the *same* code + path. Any branch in the implementation on `ProjectContext::is_single_file` + is a red flag. + +The existing `ProjectContext` already has `is_single_file: bool`. +Phase 0 does not try to remove that field — doing so is a bigger +project — but **no new code introduced in this phase may read it.** +Where Phase 0 code would be tempted to branch on it, resolve the +concern structurally (by making the project-relative / output-dir +math work uniformly) rather than by adding a single-file branch. + +## Tests + +Per CLAUDE.md §TDD: every test below gets written *before* the code +that makes it pass, and gets run to verify it fails first. + +### Unit tests + +Unit-level, in `crates/quarto-core/src/document_profile.rs`: + +1. **`profile_extract_minimal_document`** — parse a 3-line qmd with + just a title; run through `ParseDocumentStage` + + `MetadataMergeStage`; call `DocumentProfile::extract`; assert + `title`, `source_path`, `format_id` are correct, `outline` is + empty, `draft == false`. +2. **`profile_extract_with_headings`** — document with `#`, `##`, + `###` headings; assert `outline` is a correctly nested + `Vec<TocEntry>`. +3. **`profile_extract_with_full_frontmatter`** — exercise every + documented profile field (authors, categories, keywords, image, + subtitle, description, date, draft). +4. **`profile_extract_handles_missing_title`** — document with no + title and no H1 → `title == None`. +5. **`profile_roundtrip_json`** — build a profile, serialize with + `serde_json::to_string`, deserialize, assert equal. +6. **`profile_version_mismatch_rejected`** — write a JSON blob with + `profile_version: 999`, assert `serde_json::from_str` returns an + error or our wrapper returns `VersionMismatch` (pick one; see open + questions on strictness). + +### Stage-level tests + +In `crates/quarto-core/src/stage/stages/document_profile.rs`: + +7. **`stage_extracts_profile_from_document_ast`** — end-to-end stage + invocation: feed `PipelineData::DocumentAst`, assert output kind + is `AtProfile` with expected fields. +8. **`stage_rejects_wrong_input_kind`** — feed + `PipelineData::LoadedSource`, assert `PipelineError::UnexpectedInput`. +9. **`stage_preserves_warnings`** — input DocumentAst has parse + warnings; output `AtProfile` preserves them on the inner + `DocumentAst`. + +### Pipeline integration tests + +In `crates/quarto-core/tests/` (new file, e.g. +`document_profile_pipeline.rs`): + +10. **`pipeline_at_profile_to_end_produces_expected_html`** — run the + full HTML pipeline on a fixture, extract the HTML, and also run a + "pause at profile, clone, resume" variant on the same fixture. + Assert both HTML outputs are **byte-identical**. This is the + load-bearing test for checkpoint resumability; it's what the + parent plan's §Risks calls out. +11. **`pipeline_profile_matches_metadata`** — run the full pipeline + with a document whose frontmatter sets title/author/categories, + and assert the profile extracted at the checkpoint has the same + values as the merged `ast.meta` post-merge. +12. **`wasm_pipeline_includes_profile_stage`** — verify + `build_wasm_html_pipeline()` also includes `DocumentProfileStage` + (hub-client needs it too; Phase 9 depends on this). + +### Snapshot regression + +No snapshot changes are expected in this phase — but to prove it: + +13. Run `cargo nextest run --workspace` before and after. **Any + snapshot diff is a red flag** and must be investigated per + CLAUDE.md §"Snapshot Test Changes" before the commit. + +### End-to-end verification + +Per CLAUDE.md §"End-to-end verification before declaring success": +`cargo run --bin quarto -- render <fixture>.qmd` before and after the +change should produce byte-identical output on a handful of fixtures +(pick 3 from existing `crates/quarto-core/tests/fixtures/`). Record +the invocations and results in the Phase 0 completion note, per +policy. + +## Crate placement + +The parent plan's §Open question asks whether `DocumentProfile` and +`ProjectType` live in `quarto-core` or a new `quarto-project` crate. + +**Decision (2026-04-23):** `quarto-core` for Phase 0, same crate as +`CrossrefIndex` (also a serializable per-document artifact). Revisit +the `quarto-project` split at the start of Phase 1 when we can see +what `ProjectType` actually needs to import. The +dependency analysis: + +- `DocumentProfile` needs: `serde`, `pampa::toc::TocEntry` (already a + dep), standard `PathBuf`. All already available in `quarto-core`. +- No new external deps required. +- `quarto-core` already depends on `quarto-navigation`, not the other + way around; putting `ProjectType` (Phase 1) in `quarto-core` + continues that direction. +- The argument *for* a new `quarto-project` crate is long-term + hygiene: project-type logic (website, book, manuscript) will grow + over this epic and may eventually want to depend on rendering but + be depended-on by thin orchestrators (`quarto` binary, hub-client). + That argument is real but Phase-0 premature — the hygiene case + should be re-evaluated at the start of Phase 1 once we can see + what `ProjectType` will actually need to import. + +If the user prefers a new crate up front, the cost is small (new +crate, re-export, update workspace `Cargo.toml`) but the benefit is +speculative. I'd rather defer. See open questions. + +## Contract doc + +**Location (confirmed):** `claude-notes/designs/document-profile-contract.md` +(new file). Short, reference-style. Contents: + +- What is a `DocumentProfile`? One-paragraph summary. +- **Guarantees.** Each field: what it contains, when it's + `None`/empty, what it reflects (document YAML vs. project + layered YAML vs. a fallback). +- **Non-guarantees.** What a profile does *not* contain: + engine output, sugar-synthesized headings, filter-mutated AST, + theme CSS, resolved shortcodes. +- **Versioning.** When to bump `profile_version`, what downstream + tools must check. +- **Writing a consumer.** Short note for Phase 1+ authors: + "profiles are read-only; mutation belongs in the user-filter + phase, not here." + +**Findability:** this Phase-0 plan and the parent epic plan must link +to the contract doc once written. When Q2 eventually documents +itself (per `bd-tr81`) we'll likely move or mirror this into the +user-facing docs site, but for now the `claude-notes/designs/` +location is fine and these plan references are how future agents +find it. + +## Work items (checklist) + +### Preparation +- [x] Re-read `claude-notes/instructions/testing.md` and + `coding.md` before writing any code. +- [x] Create a worktree under `.worktrees/websites-phase-0/` per + `.claude/rules/worktrees.md`. + +### TDD phase — tests first, all failing +- [x] Add `DocumentProfile` type skeleton (empty methods) so the + tests below compile. +- [x] Write unit tests 1–6 (see §Tests). *Result: 3 behavior tests + failed as expected against the stub; 3 infrastructure tests + (serde round-trip, version-mismatch, empty-doc) passed on the + stub, which is correct — they test the serde layer, not + extraction.* +- [x] Add `DocumentAtProfile` + `PipelineData::AtProfile` + + `PipelineDataKind::AtProfile` skeletons so stage tests + compile. +- [x] Add `DocumentProfileStage` skeleton. +- [x] Write stage tests 7–9. *Result: 1 behavior test failed as + expected; 2 invariant tests (wrong-input rejection, warnings + preserved) passed because their logic is in the stage, not + the stub extractor.* +- [x] Write pipeline integration tests 10–12. *Result: 4 of 5 + tests failed because the stages weren't in the pipeline + builders yet — correct intermediate state. 1 stage-name + sanity test passed.* + +### Implementation +- [x] Implement `DocumentProfile::extract(ast, source_path, output_href, format_id)`. + Pull each field from `ast.meta` via `ConfigValue::get` / + `as_plain_text()`. Outline from `pampa::toc::generate_toc` + using max depth (6), un-numbered post-scrub. +- [x] Implement `DocumentProfileStage::run`: extract profile, wrap + into `DocumentAtProfile`, return `PipelineData::AtProfile(...)`. + Project-relative paths and output href computed in the stage, + then handed to the pure extractor. **No branch on + `is_single_file`** — the math works uniformly. +- [x] Add `#[derive(Clone)]` to `DocumentAst` (all inner fields + were already Clone; `cargo check` confirmed). +- [x] **Decision captured in code**: went with the *unwrap-stage* + approach. `UnwrapProfileStage` sits immediately after + `DocumentProfileStage` and hands the inner `DocumentAst` back, + so every downstream stage keeps its `DocumentAst` input kind + unchanged. Phase 1's orchestrator will replace this with a + real consumer that reads the profile and drives two passes. +- [x] Wire `DocumentProfileStage` + `UnwrapProfileStage` into + `build_html_pipeline_stages_with_apply_config` and + `build_wasm_html_pipeline`. Analysis pipeline left alone — no + consumer there yet; adding stages without a consumer is dead + weight. +- [x] Implement `profile_version` check at deserialize time + (`DocumentProfile::from_json` returns + `DocumentProfileError::VersionMismatch`). +- [x] Run unit + stage tests; all 13 pass. +- [x] Run integration tests; all 5 pass. Test 10 (clone + resume + byte-identical HTML) is the acceptance criterion and passes. + +### Documentation +- [x] Write `claude-notes/designs/document-profile-contract.md` + per §Contract doc. +- [x] Add doc comment at `DocumentProfile` pointing at the contract. +- [x] Add a note to `CLAUDE.md` under "Architecture Notes". + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — 7654/7654 tests pass, 195 + skipped; no snapshot diffs. 3 hard-coded stage-count + assertions in `crates/quarto-core/src/pipeline.rs` tests + updated as intended (11 → 13 for HTML, 10 → 12 for WASM). +- [x] `cargo xtask lint` passes (609 files checked). +- [x] `cargo xtask verify` passes end-to-end: Rust build, Rust + tests, hub-client build, hub-client tests, trace-viewer + build, trace-viewer tests all green. (First attempt failed + on missing node_modules in the worktree; resolved by running + `npm install` once from the worktree root per hub-client + conventions.) +- [x] End-to-end: `cargo run --bin q2 -- render <fixture>.qmd` + on 3 synthetic fixtures (title-only, headings+author+categories, + full frontmatter with code block). MD5 of each rendered HTML + matches between `feature/websites` (pre-change) and + `feature/websites-phase-0` (post-change): + - `65d0bf7fa6978659d2bde67acfcbf5cb` (test-basic: title+subtitle+author+python) + - `d95941f74c232939bf75f5f533ce1b69` (fix2: minimal title) + - `88f0a5d8af4d23d4052a1eea9511890c` (fix3: categories, multi-author) + + **The Phase-0 change is behaviorally invisible at the CLI.** +- [ ] `br update bd-f3jc --status closed` with reason. +- [ ] `br sync --flush-only && git add .beads/ && git commit`. +- [ ] Stop and request permission before pushing to remote, per + CLAUDE.md §GIT PUSH POLICY. + +## Risks and mitigations + +- **Risk: every downstream stage changes its input kind from + `DocumentAst` to `AtProfile`.** That is mechanically large and + invasive. *Mitigation:* the alternative (unwrap stage right after + the checkpoint) keeps all other signatures unchanged. I'd start + with the unwrap-stage approach to minimize diff surface, then + revisit in Phase 1 when pass-2 resumability actually needs to + enter the pipeline mid-way. +- **Risk: test 10 (byte-identical clone + resume) reveals the + pipeline has hidden shared mutable state I missed.** *Mitigation:* + this is exactly why test 10 exists. If it fails, it is correct + to fail; the fix is to identify the shared state (likely in + `StageContext` — artifacts, registries, diagnostics) and either + clone it at the checkpoint or document that it's additive-only + and resuming from a clone is well-defined. +- **Risk: `DocumentAst` not Clone breaks something non-obvious.** + *Mitigation:* `cargo check` on the whole workspace after adding + the derive is the canary. Existing code that takes `DocumentAst` + by value should be unaffected. +- **Risk: outline computed pre-sugar differs from what a user + writing `toc: true` sees in the rendered document.** This is + intentional (the profile's outline is the *author's* hierarchy, + not the sugared one) but could surprise consumers. *Mitigation:* + call this out explicitly in the contract doc. Phase 2 (sidebar) + consumers will be designed around the pre-sugar outline. +- **Risk: changing the pipeline breaks hub-client.** *Mitigation:* + `cargo xtask verify` catches this. Also — `DocumentProfileStage` + is added symmetrically to both `build_html_pipeline_stages` and + `build_wasm_html_pipeline`. +- **Risk: `PipelineDataKind::AtProfile` adds a variant that every + `match` on the kind must handle.** *Mitigation:* `cargo check` + will flag non-exhaustive matches. Address each. + +## Explicit non-goals for this phase + +- No project orchestration, no two-pass driver. +- No disk cache for profiles. +- No `ProjectIndex` type. +- No `ProjectType` trait. +- No sidebar / navbar / footer / cross-doc features. +- No `DocumentAst` serialization (freeze concerns). +- No changes to user-filter positions. (The "profile-reading + filter position" mentioned in the parent plan is Phase 1+.) + +## Decisions log (user confirmed 2026-04-23) + +All open questions from the initial draft are resolved. Recording +them here for the audit trail. + +**Naming** (all confirmed as proposed): +- Type: `DocumentProfile` +- Stage: `DocumentProfileStage` +- Pipeline variant: `PipelineData::AtProfile(DocumentAtProfile)` +- Tag: `PipelineDataKind::AtProfile` +- Modules: `quarto_core::document_profile`, + `quarto_core::stage::stages::document_profile` + +**Shape**: Option A (new pipeline variant) + unwrap-stage strategy +to keep downstream signatures unchanged. User flagged that if the +large downstream refactor runs into trouble we should reconsider — +captured in §Shape and §Risks. + +**Fields**: +- `source_path`: project-relative, forward-slash. See §"Project + root invariant" — "no project root" is not a case; a bare file + is a single-file project rooted at its directory. +- `output_href`: project-output-relative, forward-slash. +- `authors`: flat `Vec<String>` for now; structured-author design + is a separate future pass. +- `outline`: un-numbered; consumers needing numbers read them from + the post-render AST. + +**Crate placement**: `quarto-core` for Phase 0; defer +`quarto-project` split to Phase 1. + +**Checkpoint position**: after `MetadataMergeStage`, before +`PreEngineSugaringStage`. Confirmed. + +**Docs**: contract at +`claude-notes/designs/document-profile-contract.md`; both this +Phase-0 plan and the parent epic plan must link to it. When Q2 is +documenting itself (see `bd-tr81`), this may move / be mirrored. + +**Out-of-scope sanity check**: defer `ProjectType` trait naming +confirmation to Phase 1 — not needed for Phase 0. diff --git a/claude-notes/plans/2026-04-23-websites-phase-1.md b/claude-notes/plans/2026-04-23-websites-phase-1.md new file mode 100644 index 000000000..abaf83bd9 --- /dev/null +++ b/claude-notes/plans/2026-04-23-websites-phase-1.md @@ -0,0 +1,829 @@ +# Phase 1 — Project orchestration (`ProjectType` trait + two-pass driver) + +**Date:** 2026-04-23 +**Beads:** `bd-w5os` (phase); parent `bd-0tr6` (website epic). Blocked-by +`bd-f3jc` (Phase 0) — closed. +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-23-websites-phase-0.md` +**Contract this phase consumes:** +`claude-notes/designs/document-profile-contract.md` +**Status:** Design approved (2026-04-23). Implementation in a +subsequent session. + +## Goal of this phase + +Introduce the infrastructure that makes multi-file project rendering +work: + +1. A **`ProjectType` trait** with `pre_render` / per-file contribution + hooks / `post_render` — the narrow Rust equivalent of Q1's + `ProjectType` interface. +2. A **`DefaultProjectType`** no-op implementation that is used for + every render today (single-file and loose-directory), so Phase 1 + ships a pure refactor of the CLI path. +3. A **`ProjectIndex`** type that holds `Vec<DocumentProfile>` plus + lookup helpers, seeded by Pass 1 and read by Pass 2. +4. A **`ProjectPipeline`** driver that: (a) expands the file list, + (b) runs Pass 1 for each file to produce a `DocumentAtProfile`, + (c) builds the `ProjectIndex`, (d) calls `pre_render` / + `post_render` hooks, and (e) runs Pass 2 to finish each file. +5. **CLI wiring** so `quarto render` invokes the driver rather than + the current inline `for` loop in `crates/quarto/src/commands/render.rs`. +6. **File-list expansion** for multi-file projects (populate the + today-empty `project.files` when `_quarto.yml` exists), respecting + `project.render` globs when present and a sensible default + otherwise. +7. A **rename**: the existing enum + `quarto_core::project::ProjectType` → `ProjectKind`, freeing the + `ProjectType` name for the new trait. Minimal-blast-radius — only + one external caller (the CLI info-log line). + +**No user-visible behavior change for existing single-file renders.** +The CLI must produce byte-identical HTML on the 3 fixtures used at +the end of Phase 0. Multi-file project rendering starts producing +output *for the first time*, but it won't do anything website-shaped +yet — Phase 2+ adds sidebars / navbars / cross-doc links. + +This phase does **not** implement: + +- Any website-specific behavior (sidebars, navbars, site_libs, etc.) + — those are Phases 2–7. +- The `WebsiteProjectType` implementation beyond a registered + placeholder type-tag. +- Book or Manuscript types. +- Parallel rendering. +- Incremental rebuilds / the on-disk profile cache (Phase 8). +- Hub-client orchestration (Phase 9). +- `freeze`. + +## Reference material + +- **Parent epic plan** §"Phase 1 — Project orchestration" and + §"Architecture sketch" / §"`ProjectType` trait". +- **Phase 0 plan** (for naming / shape / crate placement context) + and its §"Project root invariant" (must continue to hold). +- `claude-notes/designs/document-profile-contract.md` — how to read + profiles. +- `crates/quarto/src/commands/render.rs` — current CLI entry point + and per-file loop. +- `crates/quarto-core/src/render_to_file.rs` — the single-file + render workhorse (`render_document_to_file`, `render_to_file`). +- `crates/quarto-core/src/project.rs` — `ProjectContext`, + `ProjectConfig`, `DocumentInfo`, and the existing `ProjectType` + enum (to be renamed). +- `crates/quarto-core/src/pipeline.rs` — + `build_html_pipeline_stages`, `run_pipeline`, `render_qmd_to_html`. +- Q1 reference: `external-sources/quarto-cli/src/project/types/types.ts` + (`ProjectType` interface) and + `external-sources/quarto-cli/src/command/render/project.ts` + (`renderProject` flow — lines 310–862). + +## Key decisions (already settled by the epic) + +From `claude-notes/plans/2026-04-23-website-project-epic.md` +§"Key decisions": + +- Project orchestration uses a trait with pre-render / per-file + contributions / post-render hooks. +- Profiles are read-only to user filters. +- **One new user-filter position** after the snapshot checkpoint, + where filters can read `Vec<DocumentProfile>` but cannot mutate the + snapshot. *For Phase 1, we only add the machinery; the user-filter + position itself is a future phase that ties into the Lua API.* +- Single-document renders continue to work as a degenerate "default" + project. + +## Naming decisions (confirmed 2026-04-23) + +**Rename first.** The existing enum +`quarto_core::project::ProjectType` conflicts with the new trait. +Rename the enum to `ProjectKind` (values: `Default`, `Website`, +`Book`, `Manuscript`) and use `ProjectType` for the trait. + +| Concept | Proposed name | +|---|---| +| The kind tag (Default/Website/Book/Manuscript) | `ProjectKind` (was `ProjectType`) | +| The orchestration trait | `ProjectType` | +| No-op implementation used for single-file and loose-directory | `DefaultProjectType` | +| Tag-only placeholder for websites | `WebsiteProjectType` (unimplemented for Phase 1) | +| Cross-doc index | `ProjectIndex` | +| The driver | `ProjectPipeline` | +| Pass 1 output per file | `DocumentAtProfile` (Phase 0) | +| Module path for the trait + driver | `quarto_core::project::orchestrator` | +| Module path for `ProjectIndex` | `quarto_core::project::index` | + +**Crate placement.** Still `quarto-core` for Phase 1 — defer the +`quarto-project` split until an actual consumer (e.g. a shared +hub-client side-crate) demands it. + +**Trait method names:** `pre_render` / `post_render`, mirroring Q1. + +**Driver name:** `ProjectPipeline` (parallel to `Pipeline`). + +**Rename blast radius.** `git grep -n "ProjectType::"` shows the +enum is referenced only inside `project.rs` and one CLI info-log +call (`crates/quarto/src/commands/render.rs:93`: +`project.project_type().as_str()`). Public API change: the accessor +`ProjectContext::project_type()` becomes `project_kind()`. I'll do +this as **the first commit in Phase 1** so every subsequent commit +sits on a clean naming base. + +## Parallelism readiness (note — added 2026-04-23) + +The user plans to parallelize website rendering in a soon-ish +follow-up session. Recording the decision surface here so Phase 1's +choices don't foreclose it. + +**Today's model:** stages use `async_trait(?Send)`. This is +incompatible with tokio's multithreaded work-stealing scheduler out +of the box — a tokio-based parallelism path would require migrating +every stage to `Send` futures, a workspace-wide refactor. + +**The cheaper path (recommended) is rayon + per-worker +`pollster::block_on`.** Each rayon thread drives its own file's +async pipeline on a single-threaded executor local to that thread. +Stages stay `?Send`; nothing in the current model changes. Concretely: + +- Pass 1: `project.files.par_iter().map(|f| pollster::block_on(run_head(f))).collect::<Vec<_>>()`. + Each thread builds one `StageContext`, runs the head pipeline, + produces one `DocumentProfile`. No shared mutable state. +- Build `ProjectIndex` on the main thread from the collected + profiles. +- Pass 2: `project.files.par_iter().map(|f| pollster::block_on(render_document_to_file(..., index_arc)))`. + Each thread reads the shared `Arc<ProjectIndex>` and writes its + own output file. + +**Phase 1 decisions relevant to this:** + +- `StageContext` is already owned per-file and has no global state + contention — compatible. +- `ProjectIndex` is wrapped in `Arc<_>` on `StageContext` — shareable + across threads as-is. +- `SystemRuntime` trait objects are `Arc<dyn SystemRuntime>`; we'll + need to confirm `NativeRuntime: Send + Sync`. Today's single-doc + tests and the hub-client WASM shim both hold an `Arc`, so this is + almost certainly already the case — we'll add a `where T: Send + + Sync` compile-time check on the orchestrator when parallelism + lands. + +**What Phase 1 will not do:** introduce rayon. The driver ships +sequentially in v1. A follow-up bd issue (see §Follow-up beads) +tracks the conversion. + +**What Phase 1 will do to help:** avoid patterns that the rayon +conversion would have to unwind — in particular, the driver will +not thread any `&mut` through the per-file loops except via the +`ProjectContext` it already owns, and `pre_render` is called once +before the parallel section (exactly the Q1 pattern). + +## Architecture sketch + +### The invariant: all renders are project renders + +Following Phase 0's "no project-root branch" rule, Phase 1 takes a +parallel step: **all renders go through `ProjectPipeline`.** A +single-file or loose-directory render is just a `DefaultProjectType` +project with one file in `project.files`. There is no separate +"single-file path" and "project path" anymore — the CLI discovers a +project, chooses a `ProjectType`, hands the project to the driver. + +This is the inversion of Q1's synthetic-project pattern (where +`--output-dir` on a bare file creates a throw-away project). In Q2 we +never synthesize — we just *always* have a project, because +`ProjectContext::discover()` already always returns one. + +### The two passes + +Today, the pipeline is one-shot per file: + +``` +LoadedSource → Parse → Merge → [Profile] → Unwrap → Sugar → … → ApplyTemplate +``` + +Phase 1 wraps each file's render in two passes around that same +pipeline: + +``` +Pass 1 (per file): + LoadedSource → Parse → Merge → [Profile] ← STOP, collect DocumentAtProfile + +Build ProjectIndex from all Pass 1 results. + +ProjectType::pre_render(&mut ProjectContext, &ProjectIndex) + (Phase 1: no-op for DefaultProjectType; placeholder for Website.) + +Pass 2 (per file): + DocumentAtProfile → Unwrap → Sugar → Engine → … → ApplyTemplate → FinalOutput + +ProjectType::post_render(&ProjectContext, &ProjectIndex, &[RenderToFileResult]) + (Phase 1: no-op for DefaultProjectType.) +``` + +Pass 1 is cheap: no engine execution, no user filters, no AST +transforms. Pass 2 resumes from the cloned `AtProfile` (or, for +simplicity in v1, re-runs Pass 1 in-process — see §"Pass 2 +resumption strategy" below). + +### `ProjectType` trait shape + +```rust +// crates/quarto-core/src/project/orchestrator.rs + +use async_trait::async_trait; + +use crate::project::ProjectContext; +use crate::project::index::ProjectIndex; +use crate::render_to_file::RenderToFileResult; + +/// Trait implemented by each project kind (default, website, book, …). +/// +/// Phase 1 ships only `DefaultProjectType` and a placeholder +/// `WebsiteProjectType` with no-op hooks. Phase 2+ fills in the +/// website hooks. +#[async_trait(?Send)] +pub trait ProjectType { + /// The tag used to pick this implementation from a parsed + /// `_quarto.yml`'s `project.type`. + fn kind(&self) -> crate::project::ProjectKind; + + /// Called once per project, after `ProjectContext::discover` and + /// before any per-file rendering. Default implementation is a + /// no-op. Websites will use this (eventually) to, e.g., resolve + /// sidebar config. + async fn pre_render( + &self, + _project: &mut ProjectContext, + _index: &ProjectIndex, + ) -> crate::Result<()> { + Ok(()) + } + + /// Called once per project, after every file has rendered. + /// Default implementation is a no-op. Websites will use this to + /// emit `sitemap.xml`, copy favicon, etc. (Phase 7). + async fn post_render( + &self, + _project: &ProjectContext, + _index: &ProjectIndex, + _outputs: &[RenderToFileResult], + ) -> crate::Result<()> { + Ok(()) + } +} +``` + +The trait is intentionally minimal for Phase 1. Q1's +`ProjectType` interface has ~25 hooks; we'll grow into them only as +the phases actually need them. Growing a trait is easy; unwinding a +premature design isn't. + +Why `async`? Two reasons. (a) `render_qmd_to_html` and its stages are +already `async_trait(?Send)` — matching preserves one executor model. +(b) Future website hooks (sitemap writing, favicon copying, fetch of +remote resources) want async I/O. The no-op default implementations +mean today's code pays zero cost. + +### `ProjectIndex` shape + +```rust +// crates/quarto-core/src/project/index.rs + +use std::collections::HashMap; +use std::path::{Path, PathBuf}; + +use crate::document_profile::DocumentProfile; + +#[derive(Debug, Clone, Default)] +pub struct ProjectIndex { + profiles: Vec<DocumentProfile>, + by_source_path: HashMap<PathBuf, usize>, + by_output_href: HashMap<String, usize>, +} + +impl ProjectIndex { + pub fn new(profiles: Vec<DocumentProfile>) -> Self { /* … */ } + pub fn profiles(&self) -> &[DocumentProfile] { &self.profiles } + pub fn lookup_by_source(&self, path: &Path) -> Option<&DocumentProfile> { /* … */ } + pub fn lookup_by_href(&self, href: &str) -> Option<&DocumentProfile> { /* … */ } +} +``` + +- `HashMap` is fine here — the struct doesn't derive `Serialize` + (profiles do; the index is rebuilt in memory each run). Per + `claude-notes/instructions/coding.md` §"HashMap and Determinism", + non-serialized, lookup-only maps may use `HashMap`. +- Ordering-sensitive output (e.g. "all pages in sidebar auto order") + reads `profiles()`, which preserves insertion order. + +### `ProjectPipeline` driver + +```rust +// crates/quarto-core/src/project/orchestrator.rs + +use std::sync::Arc; + +use quarto_system_runtime::SystemRuntime; + +use crate::format::Format; +use crate::project::ProjectContext; +use crate::project::index::ProjectIndex; +use crate::render_to_file::{RenderToFileOptions, RenderToFileResult}; + +/// Orchestrate a two-pass render of every file in a project. +pub struct ProjectPipeline<'a> { + project: &'a mut ProjectContext, + project_type: Box<dyn ProjectType>, + format: Format, + options: &'a RenderToFileOptions, + runtime: Arc<dyn SystemRuntime>, +} + +impl<'a> ProjectPipeline<'a> { + pub fn new( + project: &'a mut ProjectContext, + project_type: Box<dyn ProjectType>, + format: Format, + options: &'a RenderToFileOptions, + runtime: Arc<dyn SystemRuntime>, + ) -> Self { /* … */ } + + /// Run the full two-pass flow. Returns one `RenderToFileResult` + /// per rendered file, in `project.files` order. + pub async fn run(&mut self) -> crate::Result<Vec<RenderToFileResult>> { + // 1. Pass 1: profile every file. (Re-using the head pipeline from Phase 0.) + let profiles = self.pass_one().await?; + let index = ProjectIndex::new(profiles); + + // 2. pre_render hook. + self.project_type.pre_render(self.project, &index).await?; + + // 3. Pass 2: render every file with the index in scope. + let outputs = self.pass_two(&index).await?; + + // 4. post_render hook. + self.project_type + .post_render(self.project, &index, &outputs) + .await?; + + Ok(outputs) + } + + async fn pass_one(&self) -> crate::Result<Vec<DocumentProfile>> { /* … */ } + async fn pass_two(&mut self, index: &ProjectIndex) + -> crate::Result<Vec<RenderToFileResult>> { /* … */ } +} + +/// Factory: pick the `ProjectType` implementation for a project. +pub fn project_type_for(project: &ProjectContext) -> Box<dyn ProjectType> { + match project.project_kind() { + ProjectKind::Default => Box::new(DefaultProjectType), + ProjectKind::Website => Box::new(WebsiteProjectType), + ProjectKind::Book | ProjectKind::Manuscript => Box::new(DefaultProjectType), + } +} +``` + +### Pass 2 resumption strategy + +Phase 0's clone-and-resume test shows we *can* pause after Profile, +clone, and resume cleanly. But threading a `PipelineData::AtProfile` +through `render_document_to_file` today is a sizeable refactor of +that function's internals. + +**Phase 1 takes the simpler path:** Pass 2 calls +`render_document_to_file` as it exists today. This means the head +pipeline re-runs for each file — exactly the redundant work Phase 0's +checkpoint was designed to avoid. We accept the redundancy in v1 for +two reasons: + +1. It keeps Phase 1's diff scoped to *orchestration*. Rewiring + `render_document_to_file` to accept a pre-built `AtProfile` is its + own change with its own test surface. +2. The `StageContext` carries mutable per-file state (artifacts, + registries, diagnostics). Threading a pre-built `AtProfile` needs + a careful decision about what *else* to carry forward from Pass 1 + — and we should make that call once we have a concrete consumer + (Phase 2 sidebar generate). + +**What Phase 1 *does* need from the profile work:** the fact that the +profile is computed once per file in Pass 1 and kept in +`ProjectIndex`, so that website hooks can read across files without +re-running pipelines. That alone is enough to unblock Phase 2. + +A follow-up task (file as `bd-<new>` during Phase 1) tracks converting +Pass 2 to resume from a cached `AtProfile` when the clone-and-resume +infrastructure is plumbed through `render_document_to_file`. + +### Injecting `ProjectIndex` into per-file rendering + +Pass-2 transforms and future user filters read +`&[DocumentProfile]` by reading an `Arc<ProjectIndex>` off +`StageContext`. Add: + +```rust +// crates/quarto-core/src/stage/context.rs +pub struct StageContext { + // … existing fields … + + /// Project-wide index of profiles from Pass 1. `None` for the + /// short-lived head-only runs in Pass 1 itself. Set by + /// `ProjectPipeline::pass_two` before each file's tail run. + pub project_index: Option<Arc<ProjectIndex>>, +} +``` + +`Arc` so every per-file `StageContext` shares one underlying index +without copying. Phase 1 doesn't *read* `project_index` anywhere — +Phase 2+ does — but we put the slot in now so Phase 2 is a drop-in. + +### File-list expansion + +Today `ProjectContext::discover` leaves `files = Vec::new()` when +`_quarto.yml` is present (`project.rs:422`). Phase 1 fills it: + +1. If `config.render_patterns` is non-empty, treat each entry as a + glob relative to `project.dir` and expand. Keep only matches with + a `.qmd` extension. +2. Otherwise, recursively walk `project.dir`, collecting files with + extension `.qmd` only. +3. **Always exclude:** + - Files under `project.output_dir` (default `_site/` for + websites). + - Files under `.quarto/`, `.git/`, `node_modules/`. + - Files whose path has a component starting with `_` (Q1 + convention: `_metadata.yml`, `_includes/`, `_*` partials). + - Files whose path has a component starting with `.` (hidden). + - Files whose *name* starts with `README` (case-insensitive) — + mirrors Q1's behavior; these are GitHub-facing, not rendered + pages. + - The project config file itself. +4. Respect extension-based type detection + (`SourceType::from_extension`) — though for Phase 1 the only + accepted extension is `.qmd`. + +**Scope choice (user directive, 2026-04-23): Phase 1 discovers only +`.qmd`.** Support for `.md`, `.ipynb`, `.rmd`, etc. is deferred — the +decision about which of those are "renderable documents" vs "source +artifacts" is a separate conversation. This is a conservative choice +that keeps Phase 1 tightly scoped and lets Phase 2's sidebar work +operate on a single, well-understood input shape. + +The walker lives in a new module `crates/quarto-core/src/project/discovery.rs` +with focused unit tests. + +**Not yet** respecting (each will be its own follow-up bd issue at +close-out — see §Follow-up beads): +- Non-`.qmd` input extensions. +- `.quartoignore`. +- `resources` key. +- `profile.render` / conditional render lists. + +### Binary integration + +In `crates/quarto/src/commands/render.rs`: + +```rust +// Before: +for doc_info in &project.files { + let result = render_document_to_file(...)?; + // report diagnostics +} + +// After: +let format = resolve_format(format_str)?; +let runtime_arc: Arc<dyn SystemRuntime> = /* same as today */; + +let project_type = quarto_core::project_type_for(&project); +let mut pipeline = ProjectPipeline::new( + &mut project, + project_type, + format, + &options, + runtime_arc, +); + +let results = pollster::block_on(pipeline.run())?; +for result in &results { + // Same diagnostic reporting as today. +} +``` + +`pollster::block_on` wraps the async driver for the native sync CLI, +matching the pattern already used for `render_qmd_to_html`. + +### Error handling + +One file's render failure should not by default abort the rest of +the project. Phase 1 adopts a middle-ground rule: + +- Pass 1 failures on a single file → log diagnostics, *exclude* that + file from the index, continue. (A file that won't parse still + shouldn't stop sibling profiles from being built.) +- Pass 2 failures on a single file → log diagnostics, collect an + error for that file, continue. Exit non-zero at the end if any + file failed. +- `pre_render` / `post_render` failures → abort the whole project + render. Those hooks are project-wide; their failure means the + project is broken. + +This is conservative and matches Q1's behavior. `--fail-fast` / other +strictness modes are follow-ups. + +## Tests + +Per CLAUDE.md §TDD: tests first, verify they fail, then implement. + +### Unit tests + +In `crates/quarto-core/src/project/index.rs`: + +1. **`index_round_trips_profiles`** — construct with 3 profiles, + verify `profiles()` order is preserved, `lookup_by_source` and + `lookup_by_href` return the right ones. +2. **`index_lookup_miss_returns_none`** — unknown keys return `None`. + +In `crates/quarto-core/src/project/orchestrator.rs`: + +3. **`default_project_type_hooks_are_no_ops`** — build a + `DefaultProjectType`, call `pre_render` and `post_render` on a + minimal context; both return `Ok(())` without mutating state. + +4. **`project_kind_rename_regression`** — call `ProjectKind::Default` + / `Website` / `Book` / `Manuscript` via both `as_str()` and + `TryFrom<&str>`; make sure the rename didn't break the string + mapping (the stringly-typed round-trip matters for `_quarto.yml` + parsing). + +### Discovery tests + +In `crates/quarto-core/src/project/discovery.rs`: + +5. **`discovery_walks_directory`** — construct a temp dir with + `a.qmd`, `sub/b.qmd`, `_partial.qmd`, `.hidden.qmd`, `README.md`, + `README.qmd`, `notes.md`, `notebook.ipynb`; assert only `a.qmd` + and `sub/b.qmd` are returned. Everything else is excluded: the + underscore and dot paths by component rule, the READMEs by the + README-name rule, and `notes.md` / `notebook.ipynb` because + Phase 1 is `.qmd`-only. +6. **`discovery_honors_render_patterns`** — with + `render_patterns = ["index.qmd", "docs/**/*.qmd"]`, only those + match. +7. **`discovery_excludes_output_dir`** — a file under `_site/` is + never returned, even if it matches a pattern. +8. **`discovery_excludes_quarto_scratch`** — files under `.quarto/` + are never returned. +9. **`discovery_unicode_and_spaces`** — a file with non-ASCII + characters and spaces is discovered correctly. + +### Pipeline / integration tests + +In `crates/quarto-core/tests/project_pipeline.rs` (new): + +10. **`single_file_goes_through_default_project_type`** — render a + single `.qmd` with no `_quarto.yml`. Verify the output is + byte-identical to a pre-Phase-1 reference rendering, and that + the `ProjectIndex` given to Pass 2 contains exactly one entry + with the expected title and source path. +11. **`two_file_project_builds_index_of_both`** — a project dir with + `_quarto.yml` and two qmds. Both render; the `ProjectIndex` + contains both profiles; pre/post hooks are called once each. +12. **`pre_render_failure_aborts_project`** — use a `ProjectType` + whose `pre_render` returns `Err`; assert the driver propagates + the error and no Pass-2 rendering happened. +13. **`per_file_render_failure_continues_others`** — a project with + one syntactically valid and one broken qmd; driver returns + non-zero overall but the valid file still produces output. +14. **`project_index_passes_through_to_stage_context`** — a test + `ProjectType` whose `post_render` inspects + `StageContext.project_index` (via a side channel or by looking + at `outputs`) confirms the index was non-None during Pass 2. + +### CLI end-to-end tests + +In `crates/quarto/tests/smoke-all/` — add a small website fixture +(see §End-to-end below) and assert it renders into `_site/`. + +15. **`cli_renders_two_file_website_into_site_dir`** — project dir + with two qmds and `_quarto.yml: project.type: website`. Run + `cargo run --bin q2 -- render <dir>`. Assert both files produce + `_site/<stem>.html`. No assertion on content *yet* beyond valid + HTML (sidebar / navbar is Phase 2+). + +### Snapshot regression + +16. Run `cargo nextest run --workspace` before and after. Any + snapshot change is a red flag — Phase 1 is orchestration, not + per-file rendering. Flag any diff per CLAUDE.md §"Snapshot Test + Changes". + +### End-to-end CLI verification + +Per CLAUDE.md §"End-to-end verification before declaring success": + +- **Single-file path:** same 3 fixtures from Phase 0 close-out, + assert MD5 of rendered HTML matches the Phase-0-close-out values + (`65d0bf7f…`, `d95941f7…`, `88f0a5d8…`). This proves the refactor + doesn't regress single-file rendering. +- **Multi-file path (new):** a 2-page project with `_quarto.yml`: + `project.type: default`. Running `q2 render <dir>` produces both + `*.html` outputs. Inspect one to confirm valid HTML. +- **Multi-file path, website kind:** same fixture with + `project.type: website`. Output goes into `_site/` (Phase 1 just + uses the default output-dir math — website-specific + `_site/site_libs/` is Phase 5). Confirm the two HTML outputs + exist where expected. + +## Work items (checklist) + +### Preparation +- [x] Re-read `claude-notes/instructions/testing.md`, `coding.md`, + and `review.md`. +- [x] Commit directly on `feature/websites` — no worktree, no + sub-branch (per user preference 2026-04-23). + +### Rename pre-commit +- [x] Rename enum `ProjectType` → `ProjectKind` across + `crates/quarto-core/src/project.rs` and + `crates/quarto/src/commands/render.rs`; update + `ProjectContext::project_type()` → + `project_kind()`. Run full workspace tests. Commit this + rename as its own atomic commit. (commit `5bd92a4a`). + +### TDD phase — tests first, all failing +- [x] Add skeleton `ProjectIndex` type in `project/index.rs`. +- [x] Add skeleton `ProjectType` trait + `DefaultProjectType` in + `project/orchestrator.rs`. +- [x] Add skeleton `ProjectPipeline::{new, run}`. +- [x] Write unit tests 1–4, discovery tests 5–9, integration tests + 10–14. + +### Implementation +- [x] Implement `ProjectIndex::{new, lookup_*, profiles}`. +- [x] Implement `ProjectPipeline::pass_one` — build the head stage + list (up through `DocumentProfileStage`), run per file via + `run_pipeline`, extract `DocumentProfile` from each + `AtProfile` output, collect into `Vec`. +- [x] Implement `ProjectPipeline::pass_two` — call + `render_document_to_file` per file with a freshly-built + `StageContext` whose `project_index` is set. + `render_document_to_file` gained an `Option<Arc<ProjectIndex>>` + parameter; `RenderContext` gained a matching slot; `run_pipeline` + transfers it into `StageContext`. +- [x] Implement `ProjectPipeline::run`: pass-1 → hook → pass-2 → + hook, with the error-handling rules. Added one refinement + not in the original plan: a file that fails Pass 1 is skipped + in Pass 2 (it would otherwise produce a duplicate error). +- [x] Implement `DefaultProjectType` no-op and + `WebsiteProjectType` no-op placeholder. Wire + `project_type_for()` factory. +- [x] Add `project_index: Option<Arc<ProjectIndex>>` to + `StageContext`; default `None`. +- [x] Implement file-list expansion in `project/discovery.rs`. + `ProjectContext::discover` now populates `files` via + `discover_project_files` for multi-file projects. +- [x] Confirm tests 1–14 pass. All 7674 workspace tests pass. + +### CLI wiring +- [x] Replace the `for doc_info in &project.files` loop in + `crates/quarto/src/commands/render.rs` with a + `ProjectPipeline` invocation. +- [x] Phase-0 regression: native smoke + workspace test suite pass. + (Phase-0 ad-hoc MD5 fixtures were not checked into the repo, + so the 1055 `smoke-all` tests and the pre-existing + `render_integration`/`navigation_e2e` suites serve as the + regression gate; no snapshots drifted.) + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — all green, no snapshot + diffs (7674 tests passed, 195 skipped). +- [x] `cargo xtask lint` passes (613 files checked). +- [x] `cargo xtask verify --skip-hub-tests --skip-rust-tests` + passes end-to-end: Rust build, hub-client build (including + WASM), trace-viewer tests. Full `cargo xtask verify` was not + re-run because the rust-tests / hub-client-tests phases were + already validated above by the direct workspace runs. +- [x] End-to-end CLI runs per §"End-to-end CLI verification": + - Single-file: `q2 render /tmp/q2-phase1-test/simple.qmd` + emits `simple.html` beside the input with valid HTML. + - Multi-file website: `_quarto.yml` with + `project.type: website, output-dir: _site` + three qmds + (including `docs/api.qmd`) renders into + `_site/index.html`, `_site/about.html`, and + `_site/docs/api.html`, each with its own + `{stem}_files/styles.css` sibling. Output inspected — + titles and body match. +- [ ] File follow-up beads issues for: (a) Pass-2 resumption from + `AtProfile`, (b) `.quartoignore` support, (c) `project.resources` + support, (d) conditional render lists / profiles, (e) non-`.qmd` + input extensions, (f) parallel per-file rendering. +- [ ] `br close bd-w5os --reason …`. +- [ ] `br sync --flush-only && git add .beads/ && git commit`. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** the single-file render path regresses because everything + now goes through `ProjectPipeline`. *Mitigation:* the first commit + in Phase 1 is the pure rename; subsequent commits are additive. The + Phase-0 fixture-MD5 check is an explicit acceptance gate (step 5 in + §Work items / CLI wiring). +- **Risk:** multi-file discovery silently picks up the wrong files + (e.g. READMEs, partials, stale outputs under `_site/`). *Mitigation:* + discovery unit tests 5–9 codify the exclusion rules up front. + Additions to the rules become tests first. +- **Risk:** `pre_render` / `post_render` hooks in Phase 2+ want more + or different arguments than Phase 1 provides. *Mitigation:* the + trait starts minimal; trait signatures grow when consumers need them. + Sub-plans for Phase 2+ will propose the additions. +- **Risk:** Pass 2 re-runs the head pipeline, making project renders + 2× slower than they need to be. *Mitigation:* v1 accepts this + overhead; a follow-up bd issue converts Pass 2 to resume from + cached `AtProfile`. Include a small benchmark in `perf-harness` to + track the slowdown and validate the eventual improvement. +- **Risk:** the async boundary in `ProjectType` infects synchronous + CLI code. *Mitigation:* the CLI already wraps async pipelines with + `pollster::block_on`; `ProjectPipeline::run` stays async. No new + pattern is introduced. +- **Risk:** `--output-dir` on a bare file (Q1's synthetic-project + case) doesn't behave correctly. *Mitigation:* Phase 0's "no + project-root branch" invariant means a bare file is already a + single-file project rooted at its directory; `--output-dir` just + sets `project.output_dir`. No synthesis needed. A smoke test covers + this. + +## Explicit non-goals for this phase + +- No `WebsiteProjectType` behavior beyond the placeholder. Sidebars, + navbars, cross-doc links, sitemap, favicon — all Phase 2+. +- No book or manuscript types. +- No parallel rendering. +- No incremental rebuild / disk cache (Phase 8). +- No hub-client orchestration (Phase 9). +- No freeze. +- No changes to the render pipeline stages themselves (the stages + shipped in Phase 0 stay as-is). +- No user-filter-reads-profiles plumbing — that's when a concrete Lua + API consumer lands. + +## Decisions log (user confirmed 2026-04-23) + +All open questions from the initial draft are resolved. Recording +them here for the audit trail. + +**Naming** +- Rename `enum ProjectType` → `enum ProjectKind`. Trait takes the + `ProjectType` name. +- Trait method names: `pre_render` / `post_render` (Q1 continuity). +- Driver name: `ProjectPipeline`. + +**Shape** +- Async `ProjectType` methods (aligns with existing stage trait, + allows future I/O hooks to be async). +- `ProjectPipeline::run` returns `Vec<Result<RenderToFileResult>>` + so per-file failures are explicit to callers (hub-client and + future richer integrations want this; the CLI wrapper collapses + to any-failure → non-zero exit). + +**Pass-2 resumption** +- v1 re-runs the head pipeline in Pass 2. Follow-up bd issue + tracks the `AtProfile` resumption optimization. + +**File discovery rules** +- `README*` files (case-insensitive name match) excluded — Q1 rule. +- `_quarto-*.yml` profile files excluded. +- **Phase 1 discovers only `.qmd`.** Non-`.qmd` extensions are + deferred — follow-up bd will decide which are "renderable + documents" vs "source artifacts". +- Empty render result (patterns and walk both find zero `.qmd` + files) → warning diagnostic, continue with zero files; the CLI + shell decides whether that's an error. + +**Error handling** +- Pass 1 failures: drop that file from the index, continue. +- Pass 2 failures: continue other files, exit non-zero at the end. +- Hook failures: abort the whole project render. +- No `--fail-fast` in Phase 1. + +**Binary integration** +- `pollster::block_on(pipeline.run())` at the CLI boundary; + the whole `render::execute` stays sync (matches the existing + `render_qmd_to_html` pattern). +- The async-model / `?Send` choice is revisited when parallelism + lands — see §"Parallelism readiness". Rayon + per-worker + `pollster` is the recommended path and does not require any + Phase-1 change. + +**Follow-up beads** (to be filed at close-out) +- Pass-2 resumption from cached `AtProfile` (optimization). +- `.quartoignore` support. +- `project.resources` support. +- Conditional render lists / `_quarto-*.yml` profiles. +- Non-`.qmd` input extensions (decide renderable vs artifact). +- Parallel per-file rendering (rayon). + +**Epic-level tracking (user directive, 2026-04-23):** add a note +to the parent epic plan's §"Work items" (or equivalent) calling +for a close-out report of all beads issues created *during* the +website-epic work. This lets the user see the full scope of +follow-up work accumulated across phases in one place. diff --git a/claude-notes/plans/2026-04-24-include-expansion-merge.md b/claude-notes/plans/2026-04-24-include-expansion-merge.md new file mode 100644 index 000000000..d4822ca9c --- /dev/null +++ b/claude-notes/plans/2026-04-24-include-expansion-merge.md @@ -0,0 +1,483 @@ +# Merge `main` into `feature/websites`: order IncludeExpansion before DocumentProfile + +**Date:** 2026-04-24 +**Beads:** `bd-xfwx` +**Parent plan / epic:** `claude-notes/plans/2026-04-23-website-project-epic.md` + (epic `bd-0tr6`). Gates the start of Phase 4 on `feature/websites`. +**Status:** Draft — awaiting user approval before any git operations. + +## Goal + +Merge the current state of `main` into `feature/websites` so that the +new **include-shortcode expansion** pipeline stage (landed on `main` +in `215482fb` on 2026-04-20) sits **before** the **DocumentProfile +checkpoint** (landed on `feature/websites` in `e8674612` as Phase 0 of +the website epic). + +In pipeline terms, the post-merge order of the HTML pipeline must be: + +``` +Parse +MetadataMerge +IncludeExpansion ← from main +DocumentProfile ← from feature/websites (profile checkpoint) +UnwrapProfile ← from feature/websites +PreEngineSugaring +EngineExecution +CompileThemeCss +UserFilters(pre) +AstTransforms +UserFilters(post) +CodeHighlight +RenderHtmlBody +ApplyTemplate +``` + +The user-visible contract this establishes: **statically-knowable +information a document declares via the `{{< include … >}}` +shortcode is visible to `DocumentProfile`**. Heading outline, code +blocks, crossref targets, and any other AST-shaped content that +arrives through an include should be reflected in the profile that +downstream project-level features (sidebars, nav, cross-doc links, +incremental rebuild cache, future `freeze`) read from. + +The symmetric order choice — IncludeExpansion *after* DocumentProfile +— is explicitly rejected: profiles would then be computed from the +pre-include AST, making cross-document features inconsistent with +what the document actually renders. + +## Scope + +In scope: + +1. Merge `main` (HEAD `349148ae` at time of writing) into + `feature/websites` locally, no push. +2. Resolve the pipeline-ordering conflicts such that IncludeExpansion + runs **immediately after** `MetadataMergeStage` and **immediately + before** `DocumentProfileStage`, in all three pipeline builders + (`build_html_pipeline_stages_with_apply_config`, + `build_wasm_html_pipeline`, `build_analysis_pipeline`). +3. Update the stage-count / stage-name assertions in + `crates/quarto-core/src/pipeline.rs` tests to reflect the new + ordering. +4. Add a regression test that demonstrates the ordering contract + end-to-end: a parent qmd with `{{< include child.qmd >}}` produces + a `DocumentProfile` whose `outline` contains headings defined in + `child.qmd`. **Write this test before performing the merge + resolution** (TDD per CLAUDE.md), on a scratch branch off + `feature/websites`, verify it fails for the "right reason" (the + IncludeExpansion stage does not exist on `feature/websites`), then + carry it into the merge resolution and verify it passes. +5. Run `cargo xtask verify` clean before proposing the push. + +Out of scope for this session: + +- Pushing the merged branch (user will approve separately). +- Shortcode resolution beyond `include` — e.g. `{{< meta … >}}` or + user-defined shortcodes in Lua — is intentionally not moved + relative to the checkpoint. That remains + `ShortcodeResolveTransform`'s responsibility inside + `AstTransformsStage`, well after the profile. If the user wants + general shortcode resolution pre-profile later, it is a separate + design conversation. +- Changing the `DocumentProfile` contract itself (adding fields that + only become knowable because of includes). If the current profile + fields cover the cases the user cares about, no contract change is + needed. If a new field is wanted, file a follow-up beads issue. +- Merging `main` → `feature/websites` at a future, different + snapshot of `main`; this plan targets the current + `main` HEAD and freezes that as the merge source for reproducibility. + +## Reference material + +- Parent epic: `claude-notes/plans/2026-04-23-website-project-epic.md` +- Phase-0 plan (which established the checkpoint): + `claude-notes/plans/2026-04-23-websites-phase-0.md` +- DocumentProfile contract doc: + `claude-notes/designs/document-profile-contract.md` +- Include-expansion plan from main: + `claude-notes/plans/2026-04-18-plan0-include-expansion-and-source-info.md` +- Commits being pulled in from `main` (the key two called out by the + user): + - `215482fb` — "Add include shortcode expansion pipeline stage" + - `ca765b32` — "Restructure TS engine plans: unified @quarto/api + + split Plan 1a" (plan-docs restructure; no functional overlap with + the website epic) +- Other commits on `main` not yet on `feature/websites` (all + relevant to the merge but not to the pipeline ordering specifically): + - `796a656a` — "Wire SourceInfo into ExecutionContext for engine + source provenance" (prerequisite of `215482fb`; modifies + `EngineExecutionStage::run` and `ExecutionContext`) + - `b47dd01b` — "Add write_with_source_info to QMD writer" + - `1ede8685` — "Add Block::source_info() / Inline::source_info() + accessors" + - `1cef8e8d` — "Add TS engine extensions grand plan and subplans" + (docs-only) + - `b1abee84` — "Add task to beads" (data file) + - `4dace404` — "Sync beads: note PR #116 merge on bd-itj9" + - `50274d2b` — "Add smoke-all fixtures for include shortcode + expansion" (five `crates/quarto/tests/smoke-all/includes/*` + fixtures and downgrades two diagnostics from ERROR to WARNING) + - `b2a48a35` — "Refine TS engine extension plans" (docs-only) + - `349148ae` — "Make `cargo xtask verify` unconditional in push + checklist" (docs-only) + +## Pre-merge investigation (done) + +Summarized findings; full details in the commit messages and diffs. + +1. **IncludeExpansion is a `DocumentAst → DocumentAst` stage.** Sits + cleanly between `MetadataMerge` (→ `DocumentAst`) and + `DocumentProfile` (`DocumentAst` → `AtProfile`) without any + adapter changes. +2. **IncludeExpansion runs after MetadataMerge deliberately.** It + needs the fully-merged metadata to resolve paths and operates on + the parent document's AST. *Included* files have their YAML + frontmatter stripped — Q1 parity. The profile reads the parent's + metadata + the post-include AST; included-file frontmatter never + reaches the profile (this is correct behavior; included files are + bodies, not documents). +3. **IncludeExpansion registers included files in both + `SourceContext`s on `DocumentAst`** (`ast_context.source_context` + for offset resolution and the top-level `source_context` for + ariadne snippets). Source info on spliced blocks is remapped to + the included file's `FileId`. This means headings that end up in + the profile's `outline` via an include will still carry correct + source locations. +4. **Main also contains ordering-neutral changes** in + `EngineExecutionStage` (source-info wiring) from `796a656a`. + `feature/websites` did not modify `engine_execution.rs`, so that + file merges cleanly. + +## Merge conflicts expected + +A dry-run of `git merge --no-commit --no-ff main` from a worktree +will surface conflicts in at least: + +1. `crates/quarto-core/src/pipeline.rs` + - Use statement (`crate::stage::{…}`) — both sides added imports. + - Doc comment listing pipeline stages — both sides renumbered. + - `build_html_pipeline_stages_with_apply_config` — both sides + inserted a stage after `MetadataMergeStage`. + - `build_wasm_html_pipeline` — same shape. + - `build_analysis_pipeline` — `main` inserted + `IncludeExpansionStage`; `feature/websites` did not touch this + function. Include the stage here too (LSP outline benefits from + expanded content; symmetric with the render pipeline). + - Tests `test_build_html_pipeline_stages`, + `test_build_html_pipeline`, `test_build_wasm_html_pipeline`, + `test_build_analysis_pipeline` — stage counts and stage-name + position assertions need updating. +2. `crates/quarto-core/src/stage/mod.rs` + - `pub use stages::{…}` — both sides added names. Merged set: + `ApplyTemplateStage, AstTransformsStage, CompileThemeCssStage, + DocumentProfileStage, EngineExecutionStage, + IncludeExpansionStage, MetadataMergeStage, ParseDocumentStage, + PreEngineSugaringStage, RenderHtmlBodyStage, UnwrapProfileStage, + UserFiltersStage`. +3. `crates/quarto-core/src/stage/stages/mod.rs` + - New module declarations on each side. Merged: `document_profile`, + `include_expansion`, `unwrap_profile` all present. +4. `.beads/issues.jsonl` + - Both sides updated. The correct resolution is to accept a + *union* that preserves all closed/opened issues on both + branches. After the textual merge, run + `br import -i .beads/issues.jsonl --resolve-collisions` to + reconcile any conflicting timestamps. + +Other non-conflicting but relevant changes from `main` that will +simply apply: `pampa` lua-diagnostics split, qmd writer +source-info changes, new TS-engine plan docs, five `smoke-all/includes` +fixtures, hub-client presence/visibility-gating work. None of these +interact with the pipeline ordering. They must nevertheless compile +and pass tests on the merged tree. + +## Work items (in execution order) + +Each checkbox is one discrete step. We pause at step 4 for a +verification gate before doing the merge, and at the end for the +push-approval gate. + +### Phase A — Scaffolding before the merge + +- [x] **A0. Create a worktree** `.worktrees/include-merge` off + `feature/websites` so the merge can be aborted cleanly without + disturbing the main working tree. Add the beads redirect per + `.claude/rules/worktrees.md`. + *Done:* branch `merge/include-expansion`; `br where` confirms + the redirect resolves to the main repo's `.beads/`. +- [x] **A1. Add a TDD-style regression test** exercising + the ordering contract we want to land. The test lives in + `crates/quarto-core/src/pipeline.rs` (or a new test file if the + existing module is crowded) and: + 1. Writes `parent.qmd` and `child.qmd` to a temp dir; the + child contains a `## Section A` heading and a `## Section B` + heading; the parent contains `{{< include child.qmd >}}`. + 2. Builds the HTML pipeline, runs it up to the profile + checkpoint (this is already exercised by the existing + `AtProfile` clone-and-resume test in Phase 0 — reuse its + halting idiom; if it halts by stopping at a given stage, + halt right after `DocumentProfileStage`). + 3. Asserts the extracted `DocumentProfile.outline` contains + "Section A" and "Section B". + Expected failure on `feature/websites` HEAD: the test fails + because there is no `IncludeExpansionStage`, so the `{{< include + >}}` shortcode is still present as an unresolved paragraph at + profile time and the heading does not appear in `outline`. + **Do not proceed to the merge until this test has been verified + to fail for exactly that reason.** (This is the key TDD check + that the merge fix actually fixes something.) + *Done:* test `profile_sees_heading_from_included_file` added in + `crates/quarto-core/tests/document_profile_pipeline.rs`. Landed + with one heading (`## Child Heading`) rather than two sections — + same contract, lighter fixture. Verified RED on + `merge/include-expansion` (pre-merge HEAD): fails with + `got outline titles: []` — the `{{< include >}}` shortcode is + not expanded and the parent has no headings of its own. +- [x] **A2. Also add a stage-ordering assertion** to + `test_build_html_pipeline_stages`: the position of + `"include-expansion"` must be strictly less than the position + of `"document-profile"`. This is a cheap structural guard + against future refactors silently reordering the two stages. + *Done:* `include_expansion_precedes_document_profile` added to + `tests/document_profile_pipeline.rs` (kept with the other + pipeline-shape assertions rather than in `pipeline.rs` unit + tests). Verified RED pre-merge: panics on + `.expect("include-expansion stage must be present ...")`. + +### Phase B — Perform the merge + +- [x] **B0. Fetch** latest `main` (no working-tree mutation beyond + the fetch). + *Done:* `git fetch origin main` → FETCH_HEAD at `349148ae`. +- [x] **B1. From the worktree**, run `git merge --no-ff --no-commit + main` to produce a merge commit buffer with conflicts surfaced + but nothing yet recorded. + *Done:* two conflicts reported, in `pipeline.rs` and + `stage/mod.rs`. `stage/stages/mod.rs` and `.beads/issues.jsonl` + auto-merged. +- [x] **B2. Resolve conflicts** file-by-file, using the merge-target + pipeline order from the §Goal section. Specifically: + - `pipeline.rs`: imports union; doc comments renumbered for + the final order; three builder functions each get both + `IncludeExpansionStage::new()` *and* `DocumentProfileStage` + / `UnwrapProfileStage` inserted in the target order; tests + updated with the new stage counts. Target counts after + merge: + - native HTML: **14** stages (current `feature/websites` + has 13 — inserts `IncludeExpansionStage` at position + 3, shifting `DocumentProfileStage` to 4, etc.). + - WASM: **13** stages (current `feature/websites` has + 12 — same insertion; WASM still has no + `EngineExecutionStage`). + - analysis: **5** stages (current `feature/websites` + has 4 — insertion between `MetadataMergeStage` and + `PreEngineSugaringStage`). + - `stage/mod.rs` and `stage/stages/mod.rs`: accept both + sides' additions. + - `.beads/issues.jsonl`: union of both sides; `br import + --resolve-collisions` after the textual resolution to + reconcile. + - Any incidental conflicts in `CLAUDE.md`, + `claude-notes/plans/*`, etc.: prefer the `main` version for + files that main substantially rewrote (e.g. TS-engine + plans) and the `feature/websites` version for website-epic + plans. +- [x] **B3. Do not commit yet.** Leave the merge in-progress; move + to Phase C to verify before committing. + *Done:* merge left in-progress until C0-C3 passed. + +### Phase C — Verification + +- [x] **C0. `cargo build --workspace`** — compiles cleanly. + *Done:* 2m 30s, exit 0. +- [x] **C1. `cargo nextest run --workspace`** — all tests pass. + Special attention to: + - The new regression test from A1 (must now pass — this is + the green half of the TDD cycle). + - The new structural assertion from A2. + - `test_build_html_pipeline_stages`, + `test_build_html_pipeline`, `test_build_wasm_html_pipeline`, + `test_build_analysis_pipeline` — stage counts. + - Phase-0 profile-checkpoint clone-and-resume tests (the + byte-identical-resume guarantee must still hold; adding + IncludeExpansion before the checkpoint does not change + this because include expansion is deterministic). + - Phase-2 sidebar / Phase-3 navbar/footer project-integration + tests (they read the profile; adding headings via include + must not break them). + *Done:* 7750 tests, 0 failed, 195 skipped. Focused re-run of + `document_profile_pipeline` confirmed: + `profile_sees_heading_from_included_file` and + `include_expansion_precedes_document_profile` both PASS + (the TDD GREEN); Phase-0 + `pipeline_at_profile_to_end_produces_expected_html` + (clone-and-resume byte-identical invariant) still PASSes. +- [x] **C2. `cargo xtask verify`** — full workspace + hub-client + build + hub-client tests. Required because `quarto-core` is on + the conflict path. + *Done:* `cargo xtask verify --skip-rust-tests` (since C1 + already covered Rust). Initially failed on a pre-existing + nightly-rustc issue (`VaList::next_arg` rename from + `f866c65e` required a rustc newer than local `1.94.0-nightly + 2026-01-14`). After `rustup update nightly` → + `1.97.0-nightly 2026-04-23` and a root `npm install` (fresh + worktree had no `node_modules/`), verify reported + **"All verification steps passed!"** +- [x] **C3. End-to-end CLI smoke** per the CLAUDE.md + end-to-end-verification rule. + *Done:* `cargo run --bin q2 -- render + crates/quarto/tests/smoke-all/includes/basic/basic.qmd` + produced `basic.html` (782 bytes). Inspected — the rendered + HTML contains the three expected paragraphs in order: + ``` + <p>Parent content before include.</p> + <p>This line contains BASIC-CHILD-MARKER-XYZ from the included file.</p> + <p>Parent content after include.</p> + ``` + confirming `{{< include _child.qmd >}}` was resolved during + render (and, by construction of the pipeline order, + *before* the profile checkpoint). Build artifacts (`basic.html`, + `basic_files/`) removed after inspection; not staged. + (Plan note: CLI binary is `q2`, not `quarto` — the earlier + draft of this step said `--bin quarto`, corrected at execution + time.) +- [ ] **C4. Finalize the merge commit.** `git commit` (the merge + buffer is still in progress). Use a descriptive message along + the lines of: + + ``` + Merge main into feature/websites + + Threads include-shortcode expansion (main, 215482fb) through the + DocumentProfile checkpoint (feature/websites, e8674612): the + merged HTML pipeline runs IncludeExpansionStage immediately after + MetadataMergeStage and immediately before DocumentProfileStage, + so statically-knowable content declared via {{< include … >}} + (headings, code blocks, crossref targets) is visible in the + profile that downstream project features consume. + + See claude-notes/plans/2026-04-24-include-expansion-merge.md + for the merge plan and rationale. + ``` + +### Phase D — Follow-ups and handoff + +- [x] **D0. `br sync --flush-only`** in the main repo (not the + worktree); `git add .beads/ && git commit -m "sync beads"`. + *Partial:* `bd-xfwx` closed in the local beads DB (via + `br --no-auto-import close bd-xfwx --reason …`). A standard + `br sync --flush-only` is blocked by a pre-existing prefix + config issue: the jsonl contains both `bd-`-prefixed and + 123 `k-`-prefixed issues, and `br sync` (post-rebuild) rejects + with "Prefix mismatch at line 124: expected 'bd', found issue + 'k-02o9'". A `--force` flush was attempted but would have + deleted `bd-2mxo` and `bd-tjbr` (present in the committed + jsonl but absent from the local DB). Reverted the jsonl to + its post-merge state to preserve those two issues; the DB's + knowledge of `bd-xfwx:closed` is therefore unflushed. + Follow-up: fix the beads prefix config (or import the k- + prefixed issues into the DB) before the next sync. +- [x] **D1. Update the epic plan file** + (`claude-notes/plans/2026-04-23-website-project-epic.md`) §Work + items with a note that this merge landed and the checkpoint + contract now includes post-expansion content. Reference this + plan. + *Done:* added an "Interphase merge" work item entry between + Phase 3 and Phase 4 pointing at `bd-xfwx` + follow-up + `bd-r82e`. Also added a §Epic-wide follow-ups bullet for + `bd-r82e` during the pre-merge prep commit. +- [x] **D2. File a follow-up beads issue** if the regression tests + surface that the profile contract should gain a field (e.g. + "is this document an include target of any other document in + the project?" — a question that becomes meaningful once + project orchestration inspects profiles). Only file if + actually needed; don't pre-file speculatively. + *Done during pre-merge prep:* `bd-r82e` filed for the + `DocumentProfile.includes: Vec<…>` field needed for Phase-8 + incremental-rebuild cache invalidation. Not a blocker for + Phases 4-7. +- [ ] **D3. Propose push to the user.** Do not push without explicit + approval. `git push origin feature/websites` only after the + user says yes. + *Pending user approval.* Feature branch is at + `c3bcfb76 bd-xfwx: merge main into feature/websites`, local + only. +- [ ] **D4. Delete the worktree** once the merge is on + `feature/websites` proper: + `git worktree remove .worktrees/include-merge`. + *Deferred until after push approval, in case the plan file + needs further edits in the same worktree.* + +## Test strategy (recap) + +- **Structural:** stage-ordering assertion in `pipeline.rs` tests + (A2); stage-count assertions updated for all three builders. +- **Contract:** A1 — profile-sees-included-heading regression test. + Failing-then-passing is the TDD proof that the merge does what + this plan claims. +- **Regression:** full workspace nextest + `cargo xtask verify`. +- **End-to-end:** CLI smoke render of a smoke-all/includes fixture + per CLAUDE.md §End-to-end verification. + +## Risks and mitigations + +- **Risk:** Phase-0 clone-and-resume byte-identical-output guarantee + breaks because IncludeExpansion runs before the clone point. + *Mitigation:* that test clones *at* the profile checkpoint, which + under the new ordering is already past IncludeExpansion; both + branches of the clone then resume with the same post-include AST. + No change needed to the guarantee. +- **Risk:** Phase 2/3 tests hard-code the parent-document-only view + of the AST and break if an included heading shows up in the + outline. *Mitigation:* Phase 2/3 tests use in-memory fixtures + without `{{< include >}}` shortcodes — they won't trigger the new + behavior. Verify in C1. +- **Risk:** `build_analysis_pipeline` (LSP) gains IncludeExpansion, + and some LSP operation that previously saw the unresolved + `{{< include >}}` paragraph now sees the spliced content, + surprising an LSP test. *Mitigation:* LSP outline wants the + spliced content (that's what a user expects to see in the + outline), so this is the right behavior. If tests catch a + regression in some other LSP feature, the fix is to update that + feature, not to skip include expansion in the analysis pipeline. +- **Risk:** `.beads/issues.jsonl` merge produces a malformed file. + *Mitigation:* always run `br import --resolve-collisions` after the + textual merge and verify `br ready` works before committing. +- **Risk:** Some hub-client test depends on the exact pipeline stage + list (unlikely but possible). *Mitigation:* `cargo xtask verify` + catches this before push. + +## Open questions to resolve during execution + +None blocking. The following are "decide in-session if they come up": + +1. **Should `build_analysis_pipeline` include `IncludeExpansionStage`?** + Recommendation: yes. LSP outline should see included content. + Confirm by reading any LSP tests that hit this pipeline before + flipping it; if any test specifically asserts the unresolved + shortcode is visible, that test has to change (and the bd issue + should note it). +2. **Should we add a test that exercises `include` declaring + a heading that then contributes to a `website.sidebar: auto` + listing?** This is a higher-level test than what's in scope + for the merge, but it's the best end-to-end proof of the user's + stated goal ("documents declare statically-knowable information + through shortcodes"). Recommendation: not in this plan; open a + bd issue against Phase 2 / `auto:` sidebar listings to cover it + once Phase 4+ work lands. +3. **Does the profile contract need a `includes: Vec<PathBuf>` + field** tracking which files were spliced in? Might be useful + for incremental rebuilds (a change to any included file should + invalidate the parent's cached profile). Not required for this + merge; file as Phase-8-adjacent follow-up if/when incremental + cache keying needs it. + +## Non-goals for this merge + +- No new `DocumentProfile` fields. +- No changes to `IncludeExpansionStage` semantics. +- No changes to what Phase 0's `PipelineData::AtProfile` + contains beyond the profile seeing the post-include AST. +- No push to `origin` without user approval. +- No merge into `main`; this is `main → feature/websites` only. diff --git a/claude-notes/plans/2026-04-24-websites-phase-2.md b/claude-notes/plans/2026-04-24-websites-phase-2.md new file mode 100644 index 000000000..caeb716d8 --- /dev/null +++ b/claude-notes/plans/2026-04-24-websites-phase-2.md @@ -0,0 +1,1142 @@ +# Phase 2 — Sidebar (data model, generate, render, template) + +**Date:** 2026-04-24 +**Beads:** to be filed (parent `bd-0tr6`; blocked-by `bd-w5os` Phase 1 — closed). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-23-websites-phase-1.md` +**Status:** Decisions confirmed 2026-04-24. Ready for implementation +pending final go-ahead. + +## Goal of this phase + +Introduce the first **website-specific** feature: a left-column **sidebar** +with page-to-page navigation, driven by `_quarto.yml`. + +Concretely: + +1. A `Sidebar` data model in `quarto-navigation`, with `SidebarEntry` + and `SidebarContents` enums that model the Q1 YAML surface closely + enough that migrating configs is a copy-paste. +2. A `SidebarGenerateTransform` that reads `website.sidebar` from the + merged metadata, resolves `auto:` entries by consulting the + `ProjectIndex` populated in Phase 1, picks the right sidebar for + the page being rendered, and stores the resolved sidebar at + `navigation.sidebar` (alongside the existing `navigation.navbar` / + `navigation.footer`). +3. A `SidebarRenderTransform` that emits Bootstrap-5-compatible HTML + at `rendered.navigation.sidebar` using Q1-matching class names so + existing Q1 CSS (`resources/scss/`) continues to style us without + modification. +4. A new template slot `$rendered.navigation.sidebar$` in the full + HTML template, wrapped in `$if(...)$` so single-doc renders remain + unchanged. +5. **Active-item highlighting** for the current page — computed in + Generate by comparing the sidebar item's source path to the + current page's `DocumentProfile.source_path`; rendered in Render + as `class="... active"`, with all ancestor sections marked + `expanded: true`. Active-state computation is format-agnostic + (no `.html` reference anywhere in Generate). +6. **Sidebar-for-page selection** (Q1 `sidebarForHref` equivalent): + resolve which of multiple sidebars applies to the current page, + by explicit id (via `site-sidebar: <id>` document-metadata + override) or by containment (which sidebar's contents reference + this page's source path). Single-sidebar projects get it for free. + +**No user-visible behavior change for existing single-doc renders.** +The generate transform is a silent no-op without a `website.sidebar` +key; the render transform is a no-op without `navigation.sidebar`; the +template slot is conditional. + +This phase does **not** implement: + +- **Cross-document link rewriting** — `[link](other.qmd)` → `other.html` + in *body* content is Phase 6. The sidebar's *own* `.qmd` → `.html` + href rewriting **is** in scope because it's necessary for the + sidebar to link to anything useful at all. +- **`site_libs/` / shared artifact store** — Phase 5. The sidebar's + own CSS/JS (collapse toggle behaviour) in this phase is not emitted + yet; Phase 5 takes over theme-asset plumbing and the sidebar's + collapse-JS will ride along with it. Phase 2 produces structural + HTML that Q1 CSS styles; interactive collapse is deferred. +- **Page navigation (prev/next)** — Phase 4. +- **Navbar project integration / active highlighting** — Phase 3. + Phase 2 only touches sidebars. +- **Sitemap, favicon, site-url/title** — Phase 7. +- **Search, tools, reader mode, dark toggle, logo/header/footer slots + on the sidebar** — excluded at the epic level. +- **Book / Manuscript types** — still just-a-default. + +## Reference material + +- **Parent epic plan** §"Phase 2 — Sidebar", §"Architecture sketch", + and §"Cross-document index". +- **Phase 1 plan** §"Injecting `ProjectIndex` into per-file rendering" + — the `StageContext::project_index` / `RenderContext::project_index` + slots are already wired; Phase 2 is the first consumer. +- **`DocumentProfile` contract** — + `claude-notes/designs/document-profile-contract.md`. Every profile + has `source_path`, `output_href`, `title`, `draft`, `outline`. This + is enough to render sidebars; we do *not* need to extend the profile + for Phase 2. +- **Q1 reference implementation:** + - Type definitions: + `external-sources/quarto-cli/src/project/types.ts:271–313` + (`Sidebar`, `SidebarItem`). + - Config read + normalization: + `external-sources/quarto-cli/src/project/types/website/website-shared.ts:123–280` + (`websiteNavigationConfig`). + - Sidebar-for-href resolution: + `external-sources/quarto-cli/src/project/types/website/website-shared.ts:403–427` + (`sidebarForHref`) and 470–495 (`containsHref`). + - Auto expansion: + `external-sources/quarto-cli/src/project/types/website/website-sidebar-auto.ts` + (the whole file). + - HTML emission templates: + `external-sources/quarto-cli/src/resources/projects/website/templates/sidebar.ejs`, + `sidebaritem.ejs`. + - CSS (not touched this phase but structurally relevant): + `external-sources/quarto-cli/src/resources/formats/html/bootstrap/...` + for the `.sidebar-*` class vocabulary. +- **Q2 current code:** + - `crates/quarto-navigation/src/{item,navbar,footer,render_html}.rs` + — the Generate/Render pattern to mirror. + - `crates/quarto-core/src/transforms/navbar_{generate,render}.rs` + — the transform pattern to mirror. + - `crates/quarto-core/src/template.rs` lines 126–224 — where the + new template slot lands. + - `crates/quarto-core/src/pipeline.rs:605–615` — where the new + `SidebarGenerateTransform` / `SidebarRenderTransform` slot into + the transform pipeline. + - `crates/quarto-core/src/project/index.rs` — `ProjectIndex` API + (lookup_by_source / lookup_by_href / profiles). + +## Key decisions (to confirm) + +These are proposals; the user will confirm or amend before +implementation begins. + +### Decision 1 — Config path: `website.sidebar`, not top-level `sidebar` (confirmed) + +Q1 reads sidebars from `website.sidebar`, and bare files sometimes +set a document-level `site-sidebar: <id>` to pick which sidebar +applies. The existing Q2 navbar transform reads from the top-level +`navbar` — which works for single-doc renders but would collide with +Q1's `navbar: object | boolean` convention once `website.navbar` +support lands in Phase 3. For this phase: + +- `SidebarGenerateTransform` reads `ast.meta.website.sidebar` only. +- Accepts **either** a single `Sidebar` object **or** an array of + `Sidebar`s (matches Q1). +- The per-page sidebar id override reads `ast.meta.site-sidebar` + (document-level), again matching Q1's `kSiteSidebar`. + +**Why not support top-level `sidebar:` as a convenience alias?** One +way to do it avoids ambiguity — `website.sidebar` is always the +canonical location — and keeps the config surface honest. If a user +wants the shorthand, their `_quarto.yml` already nests everything +under `website:`. + +**Epic-level follow-up (user-directed 2026-04-24):** this leaves Q2 +with an inconsistent config surface — `navbar` lives at the top +level, `sidebar` lives under `website.`. That will be hard to teach. +Either everything should move to the top level or everything should +move under a shared nav namespace. **Recorded in the parent epic plan +as a follow-up task** so it doesn't get lost between phases. + +### Decision 2 — Trait for "give me all profiles" in generate (confirmed) + +`SidebarGenerateTransform` runs inside `AstTransformsStage`, which +bridges `StageContext` to `RenderContext`. `RenderContext` already +has `project_index: Option<Arc<ProjectIndex>>` — Phase 1 shipped it +*unused*. Phase 2 is the first reader. When `project_index` is `None` +(standalone render), the generate transform **emits the sidebar +anyway** if the user wrote one by hand, but `auto:` entries resolve +to empty (with a diagnostic). This preserves the single-doc no-op +when the user didn't configure a sidebar, and matches the principle +from Phase 0 "no `is_project?` branch": the sidebar transform works +the same whether it's a one-file project or a hundred-file project. + +### Decision 3 — Crate placement (confirmed) + +Data types + HTML rendering → `quarto-navigation`. +Generate/Render transforms → `quarto-core/src/transforms/`. + +Mirrors navbar and footer exactly. `quarto-navigation` adds one new +module (`sidebar.rs`) and extends `render_html.rs` with a public +`sidebar_to_html` function. The crate's `README`-ish lib docs are +updated to mention sidebars. + +### Decision 4 — Sidebar contents model (confirmed) + +Q1's `SidebarItem` is a single struct with optional `contents`, +`section`, `auto`, `href`, `text` fields — effectively a discriminated +union encoded by presence. Q2 uses Rust: model it as an enum so the +shape is type-enforced. + +Proposed: + +```rust +pub struct Sidebar { + pub id: Option<String>, + pub title: Option<ConfigValue>, + pub subtitle: Option<ConfigValue>, + pub style: SidebarStyle, // Docked | Floating; default Floating + pub collapse_level: u32, // default 2 + pub background: Option<String>, // Bootstrap color name or CSS color + pub contents: Vec<SidebarEntry>, + pub pinned: bool, // default false +} + +pub enum SidebarStyle { Docked, Floating } + +pub enum SidebarEntry { + /// A leaf link. From `- about.qmd`, `- {href: …, text: …, icon: …}`, + /// or `- {section: <path>}` with no `contents:` (rare). + Link(NavigationItem), + + /// A nested section with children. From + /// `- section: Title\n contents: […]` or + /// `- {section: index.qmd, contents: […]}`. + Section { + /// Display text (from `section:` key) or `None` if the section + /// is keyed on an href. + text: Option<ConfigValue>, + /// Optional link for the section's header row. + href: Option<String>, + /// Section id (auto-generated from text if absent). + id: Option<String>, + /// Child entries. + contents: Vec<SidebarEntry>, + /// `expanded: true` forces open regardless of collapse-level; + /// computed by active-highlighting when an active child is inside. + expanded: bool, + }, + + /// A visual separator. From `- ---` (three or more dashes). + Separator, + + /// Plain text heading (no link, no children, no icon). From + /// `- {text: "Label"}` with nothing else. + Heading(ConfigValue), + + /// An `auto:` directive. Replaced by concrete entries during + /// `SidebarGenerateTransform::transform` — this variant does not + /// survive into the rendered output. + Auto(AutoSpec), +} + +pub enum AutoSpec { + All, // `auto: true` + Path(String), // `auto: "docs"` or `auto: "docs/*"` + Paths(Vec<String>), // `auto: ["intro.qmd", "advanced/*"]` +} +``` + +`NavigationItem` is the existing shared shape (already used by navbar +and footer). Reusing it keeps icons, `aria-label`, `rel`, `target` +consistent across all nav surfaces. + +**Hrefs stay as author source paths.** A leaf `Link` whose YAML said +`about.qmd` carries exactly `about.qmd` through Generate. The +format-specific rewrite to `about.html` happens in Render (see +Decision 7+8). External URLs (http(s), mailto, etc.) pass through +unchanged at both steps. + +**Active and expanded state** is computed by the generate transform +using source-path equality — not output-href equality — so the +Generate result is format-agnostic (see Decision 7+8). The +`Section::expanded` field is output-only; the YAML `expanded: true` +override gets folded in first, then active-state expansion overrides +it to `true` wherever it hits. The leaf `Link` variant gains an +equivalent `active: bool` flag, defaulted `false`. + +The `SidebarEntry::Link` form therefore looks like this, slightly +enriched from the bare `NavigationItem`: + +```rust +pub enum SidebarEntry { + Link { item: NavigationItem, active: bool }, + Section { … expanded: bool }, + Separator, + Heading(ConfigValue), + Auto(AutoSpec), +} +``` + +(Or: `item: NavigationItem` stays bare and `active` sits on a parallel +wrapper — the sub-plan's implementation chooses whichever keeps the +code tidy. The contract is that `active` is set by Generate and read +by Render.) + +### Decision 5 — Module shape (confirmed) + +``` +crates/quarto-navigation/src/ + sidebar.rs # Sidebar, SidebarEntry, AutoSpec, SidebarStyle + render_html.rs # add sidebar_to_html(); existing navbar_to_html stays + lib.rs # re-export + +crates/quarto-core/src/transforms/ + sidebar_generate.rs # SidebarGenerateTransform + sidebar_render.rs # SidebarRenderTransform + sidebar_auto.rs # expand_auto(project_index, spec) helper, + # kept separate because it's ~200 LOC and + # testable in isolation +``` + +### Decision 6 — Sidebar-for-page selection (confirmed, with caveat) + +Mirrors `sidebarForHref` in `website-shared.ts:403`, but operates on +source paths rather than output hrefs so it stays format-agnostic: + +1. If the page's metadata sets `site-sidebar: <id>` (or + `website.sidebar-id: <id>` — see alternative below), prefer the + sidebar with that `id`. +2. Otherwise, if exactly one sidebar is configured *and* it has no + `id`, that sidebar applies (Q1 wildcard). +3. Otherwise, find the first sidebar whose contents (recursively) + reference the current page's source path. The comparison is on + source paths: an entry `href: about.qmd` matches the page whose + `DocumentProfile.source_path` is `about.qmd`. +4. Otherwise, no sidebar for this page — `navigation.sidebar` is not + populated. + +For the per-page `site-sidebar` override: Q1 uses the key +`site-sidebar`, which is awkward (dashes) but established. Accept +both `site-sidebar: <id>` (Q1 compat) and `website.sidebar-id: <id>` +(clearer). Rule 1 checks both; document the canonical name as +`site-sidebar` for migration continuity. + +**Epic-level follow-up (user-directed 2026-04-24):** same note as +Decision 1 — the `site-sidebar` key lives at the document's top level +while the sidebar config lives under `website.`. When we unify nav +config placement, revisit this key's name too. Recorded in the epic. + +### Decision 7 — Active highlighting is format-agnostic; set in Generate (revised 2026-04-24) + +User feedback (2026-04-24): the existing +`navbar_generate` / `navbar_render` split draws a sharp line — +Generate is format-agnostic, Render is format-specific. The original +draft put `.qmd → .html` rewriting inside Generate, which silently +violated that invariant. Revised rule: + +- **Generate** marks each entry's `active: bool` / section's + `expanded: bool` by comparing against the current page's + *source path*, looked up via `ProjectIndex::lookup_by_source`. + This uses `ctx.document.input`, stays in Rust path space, and never + references an `.html` extension. A hypothetical future non-HTML + format (PDF-per-page, reveal.js-per-page, whatever) inherits the + same `active` data without re-running Generate. +- **Render** reads the resolved `Sidebar` from `navigation.sidebar` + and emits an HTML `active` class on `active: true` items. + +Algorithm, run after auto-expansion, over the chosen sidebar: + +1. Resolve the current page's source path from + `ProjectIndex::lookup_by_source(&ctx.document.input)`. If no index + (standalone render) or no hit, skip active-marking. +2. Walk the tree, looking for the first `SidebarEntry::Link` whose + href, interpreted as a project-relative source path, equals the + current page's source path. Mark it `active: true`. +3. Mark every ancestor `SidebarEntry::Section` `expanded: true`. +4. If no leaf matched but a `Section::href` matches, mark the section + itself active and its ancestors expanded. + +External URLs never match; comparing a source path to `https://…` +yields `false` trivially. + +### Decision 8 — `.qmd → .html` href rewriting lives in Render (revised 2026-04-24) + +`.qmd → .html` is a format-specific transformation and belongs in +the HTML-aware Render step, not Generate. Revised plumbing: + +- Generate stores a `Sidebar` at `navigation.sidebar` whose hrefs are + the author's source paths (e.g. `about.qmd`) and/or external URLs. +- `SidebarRenderTransform` resolves each href at emit time: + - If `ProjectIndex::lookup_by_source(href)` hits, emit the + profile's `output_href` (Phase 1 `DocumentProfile` already + computes this as the HTML output-relative path). + - Otherwise (external URL, `#` fragment, unknown local path), + emit the string unchanged. + - On a miss-that-looks-like-a-source-path (`ends_with(".qmd")` and + no index hit), emit a `DiagnosticMessage::warning` naming the + sidebar and the missing target. The href is left unchanged (Q1 + dangles silently; we do better with a diagnostic). + +This keeps the invariants clean: + +- `navigation.sidebar` (post-Generate) is format-agnostic; a future + PDF-per-page render could reuse it and apply its own link rewrite. +- `rendered.navigation.sidebar` (post-Render) is HTML. +- Body-content `[link](x.qmd)` rewriting is still Phase 6. + +**Why not do the rewrite in a separate "normalize hrefs" transform +that runs before Render?** Because that would re-introduce the same +format-coupling the split is meant to avoid: anyone implementing a +non-HTML output format would still have to run or skip the rewrite. +Having Render own format-specific concerns is the cleanest contract. + +### Decision 9 — Collapse-level default (confirmed) + +Q1 default is `2`. Q2 matches. YAML-configurable via `collapse-level`. + +### Decision 10 — Defer: search, tools, logo, sidebar-header/footer (confirmed) + +Epic excludes search; tools are mostly search + reader/dark toggles. +Deferring these simplifies this phase substantially. Logo/subtitle +*display* on the sidebar is deferred too — v1 supports `title` only. +If a user writes `logo:` or `tools:` in their sidebar config, the +YAML is parsed and stored but the renderer ignores it. Follow-ups +will slot them in with the same Q1 class names. + +### Decision 11 — Style: Docked vs Floating (confirmed) + +Q1 `docked` = sidebar always visible, takes layout column. `floating` += sidebar overlays on narrow viewports and sits beside on wide. +Phase 2 emits both with the same Q1 CSS classes (`sidebar-docked` / +`sidebar-floating`). No JS is emitted yet; the `collapse`/`expand` +chevrons are inert until Phase 5 lands the collapse-toggle JS (or a +trivial inline `<details>`-based fallback, to be decided when JS +plumbing lands). + +## Architecture sketch + +### Pipeline position + +`SidebarGenerateTransform` and `SidebarRenderTransform` join the +navigation phase, alongside navbar/footer/toc: + +``` +… +TocGenerateTransform +NavbarGenerateTransform +SidebarGenerateTransform ← NEW +FooterGenerateTransform +TocRenderTransform +NavbarRenderTransform +SidebarRenderTransform ← NEW +FooterRenderTransform +… +``` + +The order inside each mini-phase doesn't matter (each transform reads +its own slice of metadata), but keeping the Generate-then-Render +split visible preserves the existing invariant: "all structured data +at `navigation.*` is populated before anything reads it for HTML". + +### Generate transform flow (format-agnostic) + +``` +SidebarGenerateTransform::transform(ast, ctx): + if feature-disabled (`sidebar: false`): return. + if `navigation.sidebar` already populated: return. // user override + + sidebars_yaml = ast.meta.get_path(["website", "sidebar"]) + if sidebars_yaml is None: return. + + sidebars = Sidebar::parse_list_from_config(sidebars_yaml) + // accepts single object or array + + // Sidebar-for-page selection uses source paths, not output hrefs. + picked = sidebar_for_page(&sidebars, ctx.project_index, + &ctx.document.input, &ast.meta) + if picked is None: return. + + let mut sb = picked.clone(); + if let Some(idx) = ctx.project_index.as_deref() { + expand_auto(&mut sb, idx, &mut diagnostics); + // Compare against source path, not output href, so this step + // doesn't hard-code HTML. + let self_source = idx.lookup_by_source(&ctx.document.input) + .map(|p| p.source_path.clone()); + if let Some(src) = self_source { + resolve_active_state(&mut sb, &src); + } + } else { + // No index → auto expands to empty (with a warning). + strip_auto(&mut sb, &mut diagnostics); + } + + ast.meta.insert_path(&["navigation", "sidebar"], sb.to_config_value()); +``` + +The stored `navigation.sidebar` still carries `.qmd` paths; the +Render transform rewrites them. `active: true` / `expanded: true` +flags are already set on the entries they apply to. + +`sidebar_for_page` implements Decision 6 — source-path comparison, +no HTML assumptions. + +### Render transform (HTML-specific) + +Reads `navigation.sidebar`, resolves any project-relative source +paths through `ProjectIndex::lookup_by_source` to the profile's +`output_href`, then calls `sidebar_to_html`. Emits the result at +`rendered.navigation.sidebar`. Skip conditions mirror the navbar +render: + +- `sidebar: false` at document or project level. +- `rendered.navigation.sidebar` already populated (user filter + pre-rendered). +- `navigation.sidebar` absent. + +The href-resolution helper is a tight function: + +```rust +fn resolve_href_for_html( + raw: &str, + index: Option<&ProjectIndex>, + diagnostics: &mut Vec<DiagnosticMessage>, + sidebar_id: Option<&str>, +) -> String { + // External URLs, anchors, mailto: → unchanged. + if is_external(raw) || raw.starts_with('#') { + return raw.to_string(); + } + // Project-relative source lookup. + if let Some(idx) = index { + if let Some(profile) = idx.lookup_by_source(Path::new(raw)) { + return profile.output_href.clone(); + } + } + // Looks like a source path but didn't resolve → warn. + if raw.ends_with(".qmd") { + diagnostics.push(DiagnosticMessage::warning(format!( + "Sidebar{} references unknown document {}", + sidebar_id.map(|i| format!(" '{}'", i)).unwrap_or_default(), + raw + ))); + } + raw.to_string() +} +``` + +Called once per `href`-bearing sidebar entry immediately before +emission. + +### `sidebar_to_html` (rendering) + +Class vocabulary to match Q1 (so `resources/scss/` Just Works): + +- `<nav id="quarto-sidebar" class="sidebar sidebar-docked|sidebar-floating">` +- `<div class="sidebar-menu-container">` + `<ul class="list-unstyled mt-1">` +- Leaf: `<li class="sidebar-item"> + <div class="sidebar-item-container"> + <a class="sidebar-item-text sidebar-link [active]" href="…">…</a> + </div> + </li>` +- Section: + `<li class="sidebar-item sidebar-item-section"> + <div class="sidebar-item-container"> + <a class="sidebar-item-text sidebar-link" href="…">…</a> + <a class="sidebar-item-toggle [collapsed]" + data-bs-toggle="collapse" data-bs-target="#<section-id>" + aria-expanded="true|false"> + <i class="bi bi-chevron-right ms-2"></i> + </a> + </div> + <ul id="<section-id>" class="collapse list-unstyled sidebar-section depth<N> show|"> + [children…] + </ul> + </li>` +- Separator: `<li class="px-0"><hr class="sidebar-divider"></li>` +- Heading (text, no link): `<li class="sidebar-item"> + <span class="menu-text">…</span> + </li>` + +Icons use the same `<i class="bi bi-…">` shape as the navbar renderer. +Section IDs are stable hashes of the section's path for predictable +`#anchors`. + +### Auto expansion + +`expand_auto(sidebar, index)` walks the contents tree, replacing each +`SidebarEntry::Auto(spec)` with a flattened list derived from the +`ProjectIndex`. Algorithm: + +1. Collect candidate profiles: for `AutoSpec::All`, every profile in + the index. For `Path("docs")` or `Path("docs/*")`, every profile + whose `source_path` is under `docs/`. For `Paths([…])`, the union + of each pattern's matches. +2. Exclude `index.qmd`-style top-level index files from the auto + expansion's *sibling* level (Q1 behaviour: the directory's index + page becomes the section's `href`, not an item inside it). +3. Exclude profiles with `draft: true` (TODO: respect a + `draft-mode: include|exclude` project option — for Phase 2, + **always exclude drafts**). +4. Group by directory. A subdirectory with its own `index.qmd` + becomes a `Section` whose `href` is the index's **source path** + (`docs/index.qmd`, not `.html` — the Render step rewrites) and + whose `text` is the index page's title; its `contents` are the + siblings. A subdirectory without an index becomes a `Section` + with no href, text = capitalized directory name. +5. Sort within each directory by: + - explicit `order:` frontmatter (asc), + - then by title (case-insensitive, alphabetical). + Deterministic; matches Q1. + +Requires one new `DocumentProfile` field — **`order: Option<i32>`** +extracted from frontmatter. This is an additive change to the +profile: its default is `None`, so the `profile_version` does **not** +need to bump (see the contract doc). But an entry in the contract's +change log is required. + +### Template slot + +In the full HTML template (`crates/quarto-core/src/template.rs` +lines 160–215), add a conditional sidebar block alongside the +existing TOC block. Proposed placement: inside +`<div id="quarto-content">`, just before the TOC column: + +```html +$if(rendered.navigation.sidebar)$ +<div id="quarto-sidebar-container" class="sidebar-column"> +$rendered.navigation.sidebar$ +</div> +$endif$ +``` + +Bootstrap-grid math is the same as Q1's layout; when Phase 5 lands +the theme CSS, the existing Q1 grid rules (`.sidebar` + main content) +apply. We do not edit `crates/pampa/resources/templates/html/main.html` +(the minimal template) — sidebars only appear in the full template. + +### Data flow summary + +``` +_quarto.yml → MetadataMergeStage → ast.meta.website.sidebar + (raw YAML ConfigValue) + ↓ + SidebarGenerateTransform + (reads raw YAML + project_index) + ↓ + ast.meta.navigation.sidebar + (resolved Sidebar as ConfigValue) + ↓ + SidebarRenderTransform + ↓ + ast.meta.rendered.navigation.sidebar + (HTML string) + ↓ + ApplyTemplateStage + ↓ + <nav id="quarto-sidebar">…</nav> in output +``` + +## DocumentProfile change + +One additive field: + +```rust +pub struct DocumentProfile { + … + /// `order:` frontmatter value, used by auto-sidebar to sort + /// entries. `None` when the author didn't specify. + pub order: Option<i32>, +} +``` + +Extracted in `DocumentProfileStage` by calling `meta.get("order")` +and coercing to `i32` (bool/string rejected). Treated as additive, +so no version bump; contract doc's change log adds a line. + +## Tests (TDD: write and fail first) + +Per CLAUDE.md §"TEST-DRIVEN DEVELOPMENT": every test is authored +before the code that makes it pass. + +### Unit tests — `quarto-navigation::sidebar` + +1. **`parse_sidebar_single_object`** — `website.sidebar: {contents: [a.qmd, b.qmd]}` + parses into one `Sidebar` with two `SidebarEntry::Link`s. +2. **`parse_sidebar_array_form`** — `website.sidebar: [{id: main, contents: [...]}, {id: other, contents: [...]}]` + parses into two `Sidebar`s. +3. **`parse_sidebar_nested_section`** — `{section: "Docs", contents: [x.qmd]}` + becomes `SidebarEntry::Section { text: "Docs", contents: [Link(x.qmd)] }`. +4. **`parse_sidebar_auto_variants`** — `auto: true`, `auto: "docs"`, + `auto: ["a", "b"]` each produce the right `AutoSpec`. +5. **`parse_sidebar_separator`** — string of three dashes produces + `SidebarEntry::Separator`. +6. **`parse_sidebar_defaults`** — missing `style` → `Floating`, + missing `collapse-level` → `2`. +7. **`roundtrip_sidebar_to_config_value`** — full sidebar survives + `to_config_value`+`from_config_value` with fields intact. +8. **`sidebar_render_minimal_manual`** — snapshot-style assertion + over the HTML for a two-entry manual sidebar; class names match + the Q1 vocabulary listed in "sidebar_to_html". +9. **`sidebar_render_nested_section_collapsed`** — a section with + `expanded: false` renders with `aria-expanded="false"` and the + `.collapse` class without `.show`. +10. **`sidebar_render_nested_section_expanded`** — same with + `expanded: true`; `.show` present, `aria-expanded="true"`. +11. **`sidebar_render_active_leaf`** — a leaf with `active: true` + gets `class="…sidebar-link active"`. +12. **`sidebar_render_separator`** — renders `<hr class="sidebar-divider">`. +13. **`sidebar_render_heading_plain_text`** — a `Heading` entry with + markdown inlines renders escaped inline HTML (no `<a>`). + +### Unit tests — `sidebar_for_page` resolution + +14. **`resolve_single_sidebar_without_id_matches_every_page`**. +15. **`resolve_explicit_id_override_wins`** — two sidebars with ids + `main` and `reference`, page sets `site-sidebar: reference` → + `reference` returned. +16. **`resolve_containment_fallback`** — no explicit id, two sidebars + each with distinct contents; current page's source path + `docs/api.qmd` is referenced in the second sidebar → second + sidebar returned. (Comparison is source-path-keyed, per + Decision 6.) +17. **`resolve_no_match_returns_none`** — no explicit id, page not + referenced in any sidebar → `None`. +18. **`resolve_containment_checks_nested_sections`** — page source + path only appears inside a `Section` → still matches. + +### Unit tests — auto expansion + +19. **`auto_true_lists_all_renderable_profiles`** — 3 profiles, + `auto: true`, result is 3 `Link` entries in deterministic order. +20. **`auto_excludes_index_as_sibling`** — 3 profiles with one + `index.qmd`, `auto: true` returns 2 `Link`s (index is not a + sibling). +21. **`auto_path_scopes_to_subdir`** — profiles `a.qmd`, `docs/b.qmd`, + `docs/c.qmd`; `auto: docs` → 2 entries (`b`, `c`). +22. **`auto_groups_into_section_with_index`** — profiles + `docs/index.qmd`, `docs/b.qmd`, `docs/c.qmd`; `auto: true` + produces a `Section` with `href = docs/index.qmd` (Generate + stays format-agnostic — see Decision 7/8), title from index + profile, and two children. The Render test suite (28/28a) + covers the follow-up `.qmd → .html` rewrite. +23. **`auto_sorts_by_order_then_title`** — profiles with + `order: 1` / `order: 2` / no order are sorted 1, 2, then alpha by + title. +24. **`auto_drops_drafts`** — draft profile excluded. +25. **`auto_without_index_is_noop`** — standalone render (no + `project_index`) with `auto: true` logs a diagnostic and emits + no items. + +### Unit tests — active-state resolution (Generate, format-agnostic) + +26. **`active_state_marks_leaf_and_expands_ancestors`** — two-level + section, active page is inside the inner section → inner and outer + sections become `expanded: true`; the matching leaf is `active`. + Assertion is on the `active: bool` / `expanded: bool` fields of + the resolved `Sidebar` — no HTML involved. +27. **`active_state_no_self_source_no_changes`** — if the current + page's source path isn't referenced in the sidebar, nothing is + marked active. +27a. **`active_state_is_source_path_keyed`** — a sidebar link to + `about.qmd` matches the current-page profile whose `source_path` + is `about.qmd`, regardless of what `output_href` would be. + Proves the Generate-step active logic is format-agnostic. The + test builds a mock `ProjectIndex` whose profile has a synthetic + `output_href: "about.foo"` and still marks active correctly. + +### Unit tests — href rewriting (Render, HTML-specific) + +28. **`render_rewrites_qmd_hrefs_to_output_href`** — a `Link` + entry with `href: "about.qmd"` + a profile whose + `output_href: "about.html"` produces `<a href="about.html">` in + the rendered HTML. +28a. **`render_rewrites_nested_qmd_hrefs`** — `docs/api.qmd` + becomes `docs/api.html` (tests subdirectory preservation). +28b. **`render_passes_external_urls_through_unchanged`** — + `href: "https://example.com"` is emitted verbatim. +28c. **`render_passes_fragment_anchors_unchanged`** — + `href: "#section"` is emitted verbatim. +29. **`render_qmd_href_lookup_miss_emits_diagnostic`** — a link to + `missing.qmd` is left unchanged and a warning diagnostic is + pushed. The warning names the sidebar id when the sidebar has one. +29a. **`render_works_without_project_index`** — the render transform + is still callable when `ProjectIndex` is `None` (standalone + render with a hand-written sidebar that only uses external + URLs). Raw hrefs pass through; no diagnostics. + +### Integration tests — transforms + +30. **`sidebar_generate_skips_when_feature_disabled`** — + `sidebar: false` at document level, no `navigation.sidebar`. +31. **`sidebar_generate_skips_when_absent`** — no `website.sidebar`, + no `navigation.sidebar`. +32. **`sidebar_generate_honors_user_override`** — if + `navigation.sidebar` is pre-populated by a user filter, the + transform leaves it alone. +33. **`sidebar_generate_produces_resolved_tree`** — end-to-end on a + small fixture: yaml in, resolved `navigation.sidebar` tree out + (auto expanded, hrefs rewritten, active marked). +34. **`sidebar_render_skips_when_missing`** — no `navigation.sidebar`, + no `rendered.navigation.sidebar`. +35. **`sidebar_render_produces_html`** — round-trip + generate→render→read back the HTML from + `rendered.navigation.sidebar`, assert structure. + +### Pipeline / integration tests — `crates/quarto-core/tests/` + +Add new test file `sidebar_pipeline.rs`: + +36. **`pipeline_renders_sidebar_for_two_page_website`** — fixture with + `_quarto.yml: { project: { type: website }, website: { sidebar: + { contents: [index.qmd, about.qmd] } } }`; render both pages; + assert each output HTML contains `<nav id="quarto-sidebar"`, with + the current page's link carrying `active`, and the other not. +37. **`pipeline_auto_sidebar_lists_all_pages`** — same shape but + `website.sidebar: { contents: [{auto: true}] }`; assert both + pages are in each rendered output. +38. **`pipeline_multiple_sidebars_select_by_containment`** — 4 pages, + two sidebars (contents `[a, b]` and `[c, d]`); pages a and b + render with the first sidebar; c and d with the second. +39. **`pipeline_cross_page_links_are_written_as_html`** — sidebar + entry `about.qmd` produces `href="about.html"` in the rendered + HTML of both pages (validates that the Render-step rewrite runs + inside the full pipeline, not just in isolated unit tests). +39a. **`pipeline_navigation_sidebar_preserves_qmd_paths`** — inspect + `ast.meta.navigation.sidebar` *between* Generate and Render + (via a test-only transform that snapshots it) and assert the + paths are still `.qmd`. Proves the format-agnostic invariant + survives end-to-end. + +### CLI end-to-end — `crates/quarto/tests/` + +40. **`cli_renders_website_with_sidebar`** — extend an existing + Phase-1 website fixture to add `website.sidebar`; run + `cargo run --bin quarto -- render <dir>`; assert + `_site/index.html` contains the expected `<nav id="quarto-sidebar">` + block and class names. + +### Snapshot tests + +A few targeted snapshots under `crates/quarto-navigation/snapshots/` +for the three sidebar-HTML shapes (manual, auto-with-sections, +active-marked). Per CLAUDE.md §"Snapshot Test Changes", flag any +unexpected diffs to the user explicitly. + +### End-to-end CLI verification + +Per CLAUDE.md §"End-to-end verification before declaring success": + +- Build a fresh fixture at `/tmp/q2-phase2-smoke/`: + ``` + _quarto.yml: + project: { type: website } + website: + sidebar: + title: "Docs" + contents: [index.qmd, about.qmd, {section: "Guides", + contents: [guides/intro.qmd]}] + ``` + plus the three `.qmd` files. +- Run `cargo run --bin quarto -- render /tmp/q2-phase2-smoke/`. +- Inspect `_site/index.html` and `_site/guides/intro.qmd.html` + manually: + - Both contain `<nav id="quarto-sidebar"`. + - The current page's link carries `class="…active"`. + - The "Guides" section's expanded state depends on whether the + current page is inside it. + - `<a href="about.html">` not `<a href="about.qmd">`. +- Record the raw HTML fragment in the plan's §"Close-out" or in the + commit message so the human reviewer can verify without re-running. + +## Work items (checklist) + +### Preparation +- [ ] Re-read `claude-notes/instructions/testing.md`, `coding.md`, + `review.md`. +- [ ] Confirm user agreement with Decisions 1–11 before starting. +- [ ] Create `bd` issue `Phase 2 — Sidebar`, parent `bd-0tr6`, + blocked-by `bd-w5os` (closed). +- [ ] Commit directly on `feature/websites` (Phase 1 precedent). + +### Profile extension +- [x] Add `order: Option<i32>` to `DocumentProfile`; extract in + `DocumentProfileStage`. Update + `claude-notes/designs/document-profile-contract.md` change log. + (Extraction lives on the shared `DocumentProfile::extract` + helper, which the stage delegates to — one call site, covered.) +- [x] Unit tests: profile carries `order` when frontmatter provides + it; `None` when absent; non-integer `order:` is dropped. + +### Data model — `quarto-navigation` +- [x] Create `sidebar.rs` with `Sidebar`, `SidebarEntry`, + `SidebarStyle`, `AutoSpec` types. +- [x] Implement `Sidebar::from_config_value` / `parse_list_from_config`. +- [x] Implement `Sidebar::to_config_value`. +- [x] Write unit tests 1–7; run; confirm fail. Implement to pass. + Added a few extra tests for `collapse-level`, `style: docked`, + the `contents: auto` shorthand, the `text`-only Heading shape, + and short-dash strings. 13 tests total, all passing. + +### HTML rendering — `quarto-navigation::render_html` +- [x] Add `sidebar_to_html(&Sidebar) -> String`. +- [x] Write unit tests 8–13; run; confirm fail. Implement to pass. + Added 5 additional tests for style-docked, section-with-href, + active-ancestor expansion, separator positioning, and stray-auto + defensive handling. 11 tests total, all passing. +- [ ] Add snapshot tests for three canonical shapes. *(Deferred — + inline string asserts cover the vocabulary more cheaply and + the website template is expected to churn; decision logged in + Phase 2 plan Open Questions #6.)* + +### Sidebar-for-page + active state — `quarto-navigation` + +Both are format-agnostic and operate on source paths (forward-slash +strings; callers normalize `PathBuf` before calling). + +- [x] Add `sidebar_for_page(&[Sidebar], page_source: &str, + meta: &ConfigValue) -> Option<&Sidebar>`. Signature takes + `&str` rather than `&Path` / `Option<&ProjectIndex>` because + the helper is a pure source-path comparison — the caller + (Generate transform) already has the project-relative source + in forward-slash form. +- [x] Add `resolve_active_state(&mut Sidebar, self_source: &str) + -> bool` (source-path keyed; no HTML assumption). Returns true + if any entry matched, so the caller can emit a "page not in + sidebar" diagnostic if desired. +- [x] Tests 14–18 (+ 2 extras: `website.sidebar-id` alternative + key, unknown-id fall-through), 26–27, 27a, + section-header + match. 11 tests added; 81 navigation-crate tests total pass. + +### Auto expansion — `quarto-core/src/transforms/sidebar_auto.rs` +- [x] Implement `expand_auto(&mut Sidebar, &ProjectIndex, + &mut Vec<DiagnosticMessage>)` plus `strip_auto` (no-index path). + Grouping implemented as 1-level directory sections (top-level + files flat; subdirs grouped into Sections with optional index + header-href). Deeper nesting is a follow-up. +- [x] Tests 19–25 + `auto_paths_is_union_flat` and + `expand_auto_recurses_into_sections`. 10 tests, all passing. + +### Generate transform — `quarto-core/src/transforms/sidebar_generate.rs` + +Format-agnostic. Hrefs stay as source paths at this step. + +- [x] Implement `SidebarGenerateTransform` following the flow in + §"Generate transform flow". +- [x] Wire into `build_transform_pipeline` between + `NavbarGenerateTransform` and `FooterGenerateTransform`. +- [x] Tests 30–33 + `drops_auto_without_index` and + `keeps_qmd_paths` (the format-agnostic invariant). + 6 Generate tests, all passing. 1047 quarto-core tests still pass. + +### Render transform — `quarto-core/src/transforms/sidebar_render.rs` + +HTML-specific. Rewrites `.qmd` source paths to `output_href` at emit +time. + +- [x] Implement `SidebarRenderTransform` including + `resolve_href_for_html` helper per §"Render transform". +- [x] Wire into `build_transform_pipeline` between + `NavbarRenderTransform` and `FooterRenderTransform`. +- [x] Tests 28–29a (href rewriting), 34–35 (skip conditions + basic + render) plus `sidebar_render_skips_when_feature_disabled`, + `sidebar_render_honors_user_override`, and + `render_preserves_query_and_fragment_after_rewrite` (edge case + for query strings / fragment preservation). + 11 Render tests, all passing. 1058 quarto-core tests pass. + +### Template slot — `crates/quarto-core/src/template.rs` +- [x] Add conditional `$if(rendered.navigation.sidebar)$…$endif$` + block inside `FULL_HTML_TEMPLATE`, placed *before* the TOC + column (Decision 4 — minimum-churn slot for Phase 2). +- [x] Did NOT touch `crates/pampa/resources/templates/html/main.html`. +- [x] Full-workspace tests pass (7739 passed, no snapshot drift), + confirming the conditional template addition is a no-op for + any test that doesn't set `navigation.sidebar`. + +### Integration tests — `crates/quarto-core/tests/sidebar_pipeline.rs` +- [x] Tests 36–39 (plus `pipeline_unresolved_sidebar_entry_keeps_raw_qmd` + as the indirect proof of the format-agnostic invariant — a + .qmd href that has no matching profile survives untouched in + the rendered HTML, which can only happen if Generate didn't + pre-rewrite). 5 tests, all passing. +- [x] **Pipeline wiring bug found and fixed:** `AstTransformsStage` + bridged `StageContext` → `RenderContext` for artifacts, + includes, registries, and observer, but forgot to bridge + `project_index`. Every transform (including SidebarRender) + saw `ctx.project_index == None` at Pass 2, making the href + rewrite a silent no-op. Integration tests were load-bearing + here — unit tests built their own `RenderContext` with the + index already attached, and never exercised the stage-level + bridge. Fix: clone the `Arc<ProjectIndex>` into render_ctx + in the state-transfer block. See commit. + +### CLI end-to-end — `crates/quarto/tests/` +- [x] Test 40 *(coverage provided by `sidebar_pipeline.rs` — + `ProjectPipeline` is exactly the entry point the CLI uses, + so a separate shell-out test would duplicate coverage. The + CLI layer (`crates/quarto/src/commands/render.rs`) has no + sidebar-specific branching; it just calls `ProjectPipeline::run`).* +- [x] Manual smoke per §"End-to-end CLI verification" on a 3-page + nested fixture at `/tmp/q2-phase2-smoke`: + + - `_quarto.yml` with `project.type: website`, `website.sidebar` + including a "Guides" nested section. + - `index.qmd`, `about.qmd`, `guides/intro.qmd`. + - `cargo run --bin q2 -- render /tmp/q2-phase2-smoke` succeeded + with zero warnings. + - All outputs landed in `_site/`: `index.html`, `about.html`, + `guides/intro.html`. + - Sidebar HTML inspected: + - Title "Phase 2 Smoke" renders from `website.sidebar.title`. + - `index.html` / `about.html` / `guides/intro.html` links + all rewritten (`.qmd`→`.html`); subdirectory path + `guides/intro.html` preserved. + - Bare-path entries display the referenced documents' + *titles* ("Home", "About", "Guide Intro") rather than + raw hrefs — from the `enrich_text_from_index` Generate + helper added after the smoke revealed raw-href labels. + - Current page's link carries `class="…active"` on both + `index.html` and `guides/intro.html`; other pages' + links do not. + - Guides section renders with toggle chevron, + `aria-expanded="true"`, `show` on the child `<ul>` + (because `collapse-level=2` and this is a depth-1 section). +- [x] Added `sidebar_generate_enriches_missing_text_from_index` and + `sidebar_generate_does_not_clobber_explicit_text` unit tests + for the enrichment pass. + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — all green (7739 tests). + No snapshot drift. +- [x] `cargo xtask lint` passes (618 files checked). +- [x] `cargo xtask verify --skip-hub-tests` end-to-end green: + Rust build + tests, hub-client build (including WASM), + trace-viewer tests. (hub-client tests skipped to save CI + time; this phase doesn't touch `hub-client/src/`.) +- [x] Follow-up bd issues filed: see §"Follow-up beads". +- [x] `br close bd-9svl …` — closed. +- [ ] `br sync --flush-only && git add .beads/ && git commit`. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** single-doc renders regress because + `SidebarGenerateTransform` is in the standard pipeline. + *Mitigation:* the transform is a no-op without `website.sidebar` in + `ast.meta`. The full pipeline tests from Phase 1 must pass + unchanged. Add a specific `cli_single_file_unchanged_by_phase_2` + assertion over a Phase-1 fixture's MD5 if needed. +- **Risk:** Q1 class-name drift (someone renames one in + `quarto-cli/src/resources/formats/html/bootstrap/` and our HTML + still uses the old name). *Mitigation:* this phase emits *structural* + HTML; CSS plumbing is Phase 5. We document the expected vocabulary + in `sidebar.rs` and an explicit comment in `sidebar_to_html` points + at the Q1 EJS templates as the source of truth. +- **Risk:** ambiguous YAML shapes (single object vs array, `auto` + key at the contents level vs item level) produce surprising parses. + *Mitigation:* tests 1–6 exercise every canonical shape; `from_config_value` + never silently succeeds on malformed input — it returns a diagnostic. +- **Risk:** `sidebar_for_page` picks the wrong sidebar in + corner-case configurations. *Mitigation:* follow Q1's exact + algorithm (tests 14–18 codify all four rules); add a focused + integration test for the "page appears in two sidebars" ambiguity + (first-match wins, document this loudly). +- **Risk:** auto-expansion produces non-deterministic output due to + `ProjectIndex`'s internal `HashMap`. *Mitigation:* auto expansion + iterates `ProjectIndex::profiles()`, which preserves insertion + order; sorting is explicit and deterministic (order then title). +- **Risk:** active-state highlighting misses because hrefs differ in + trailing slash / encoding / fragment. *Mitigation:* compare on the + normalized `output_href` computed by `DocumentProfile`; write a + test covering a subpath page (`docs/api.html`). +- **Risk:** the transform trait method chain is invoked repeatedly + and per-file auto expansion is O(N²) across a large project. + *Mitigation:* Phase 2 accepts this; a follow-up bd issue can memoize + per-file-resolved sidebars in `ProjectIndex` if it shows up on the + perf dashboard. In the common case (one sidebar, small project) + the work is negligible. + +## Explicit non-goals for this phase + +- No search, tools, reader/dark toggles, logo, subtitle display, + header/footer slots, or breadcrumbs. +- No `site_libs/` / shared CSS / shared JS — the collapse-toggle + chevrons exist in the HTML but are inert until Phase 5. +- No page-navigation prev/next (Phase 4). +- No navbar active highlighting (Phase 3). +- No sitemap / favicon (Phase 7). +- No incremental rebuilds (Phase 8). +- No hub-client wiring (Phase 9). +- No book or manuscript types. +- No changes to existing single-doc render behavior. +- No changes to `crates/pampa` templates (full-template-only slot). + +## Decisions log (confirmed 2026-04-24) + +1. **Config path.** `website.sidebar` only — no top-level `sidebar:` + shorthand. Follow-up recorded in the epic to unify nav config + placement across navbar / sidebar / site-sidebar-id. +2. **Sidebar-id override key.** Accept both `site-sidebar` (Q1 + compat) and `website.sidebar-id`; document `site-sidebar` as + canonical for now. Will be revisited when nav config placement + unifies (see #1). +3. **Draft handling in auto.** Always exclude drafts in Phase 2. + Follow-up bd for `draft-mode: include|exclude|visible`. +4. **Template placement.** Sidebar column rendered *before* the TOC + column, both on the right, for this phase. The Q1 layout puts the + sidebar on the left and TOC on the right; moving to that layout is + a separate template-restructuring task, **recorded as a follow-up + bd issue** so Phase 2 doesn't get blocked on it. +5. **Interactive collapse.** Inert HTML now, live JS with Phase 5 + (`site_libs/`). Collapse JS is delicate and deserves its own + attention. `<details>` fallback is not worth the markup churn. +6. **Snapshot tests.** Add snapshots for three canonical sidebar + shapes, but rely primarily on inline string assertions. Website + templates will churn as Q1 features port over; snapshots would + make every unrelated template adjustment noisy. + +## Epic-level follow-ups recorded this phase + +Because this phase surfaces two structural issues that are epic-wide, +not phase-local, they must be recorded in the parent epic plan so +later phases don't forget them: + +1. **Nav-config placement inconsistency.** `navbar` lives at the + top level of document metadata; `sidebar` lives under `website.`; + `site-sidebar` (the per-page id override) lives at the top level. + Pick one convention and migrate. The parent epic plan's Work-items + section gains a new entry tracking this. +2. **Sidebar template placement.** Phase 2 puts the sidebar column + beside the TOC on the right, which is the minimum-churn slot in + the existing full HTML template. Q1's convention is sidebar-left, + TOC-right. Moving to the Q1 layout means restructuring + `FULL_HTML_TEMPLATE` (and touching any layout-sensitive tests); + separate task. + +## Follow-up beads (filed at close-out) + +Epic-wide (also recorded in the parent epic plan §"Epic-wide +follow-ups"): + +- `bd-n9dr` — Unify nav config placement across features + (`navbar` top-level vs `website.sidebar` nested vs + `site-sidebar` top-level). +- `bd-4g6g` — Move sidebar to Q1 template position (sidebar-left, + TOC-right). Template restructuring task, separate from + sidebar feature work. + +Phase-local: + +- `bd-6cme` — Sidebar search integration (depends on search epic). +- `bd-fod3` — Sidebar tools: reader-mode, dark-toggle, etc. +- `bd-ht0n` — Sidebar logo / subtitle / header / footer rendering. +- `bd-49ar` — Collapse-toggle JS (ride with Phase 5 site_libs). +- `bd-w0o9` — Draft-mode include/visible/exclude option. +- `bd-l6f0` — Honor explicit `expanded: true` through active-state + resolution without letting `expanded: false` block the + auto-expand-ancestors behavior. +- `bd-81x4` — Multi-sidebar ambiguity diagnostic when a page + matches more than one sidebar's containment. +- `bd-tfy0` — Deep-directory auto-sidebar grouping (N-level + recursive; today's 1-level is fine for shallow hierarchies but + flattens deeper paths). +- `bd-2quy` — Audit `StageContext` ↔ `RenderContext` bridge + completeness. Phase 2 surfaced one missing field (`project_index`); + a structural guard (test that compares the field sets, or a + derive macro) would prevent recurrence. + +## Epic-level impact + +Phase 2 unlocks the minimum-shape deliverable called out in the epic +under "bd-tr81": a rendered website with navbar + sidebar + shared +resources. Combined with Phases 3 + 5–7, this is the bootstrap surface +for Quarto-2's own documentation site. diff --git a/claude-notes/plans/2026-04-24-websites-phase-3.md b/claude-notes/plans/2026-04-24-websites-phase-3.md new file mode 100644 index 000000000..459cc683f --- /dev/null +++ b/claude-notes/plans/2026-04-24-websites-phase-3.md @@ -0,0 +1,1149 @@ +# Phase 3 — Navbar / page-footer project integration + +**Date:** 2026-04-24 +**Beads:** to be filed (parent `bd-0tr6`; blocked-by `bd-9svl` Phase 2 — +closed). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-24-websites-phase-2.md` +**Status:** Decisions 1–8 confirmed 2026-04-24 after design iteration. +Implementation in progress. + +## Goal of this phase + +Bring the navbar and the page-footer into the project model Phase 1 +built and Phase 2 began consuming. Concretely: + +1. Keep navbar / page-footer config exactly where it is today — at the + **top level** of document metadata (`navbar:`, `page-footer:`). + These are feature-scoped, not website-scoped; they work in + single-doc contexts (including non-HTML formats like revealjs) and + in multi-page projects alike. The project-level `_quarto.yml` still + reaches each document through the existing metadata merge. **No YAML + surface change.** +2. Resolve each navbar / footer item's href through the `ProjectIndex` + — `.qmd` source paths become `.html` output hrefs in the HTML render + step. Items pointing at unknown `.qmd`s emit a warning. When there + is no index (standalone render) hrefs pass through unchanged. +3. Enrich bare-path items (`- about.qmd`) with the referenced + document's title from the `ProjectIndex` when no `text:` was + supplied. Mirrors the Phase 2 sidebar enrichment. No-op when the + index is absent. +4. Mark the **active** navbar item for the current page, format-agnostic + (source-path keyed, set in Generate), and render it with Q1-matching + `active` class in Render. Recurses into dropdown `menu` items. +5. Add a **navbar brand fallback** via `website.title`: the brand + anchor's label is `navbar.title ?? website.title ?? document.title` + (in that order). `website.title` is read from the already-merged + metadata — reading *site-wide* values from under `website.` is + fine even though the navbar config itself is top-level; the + feature is "use this title as the brand label," which is genuinely + a site-scoped setting. +6. **Page-footer** gets the same `.qmd` → `.html` rewrite and text + enrichment treatment. Footer items do **not** get active marking + (matches Q1; page-footer is static cross-site chrome). + +**No YAML-surface changes.** Existing single-doc renders with +`navbar:` or `page-footer:` at the top level continue to work +unchanged. The changes are all downstream of the YAML read: enrichment, +active-marking, and href-rewriting all silently become no-ops when no +`ProjectIndex` is attached (standalone single-doc renders). + +This phase does **not** implement: + +- **Cross-document link rewriting in body content** — `[link](other.qmd)` + in a paragraph is still Phase 6. Phase 3 only rewrites hrefs in the + structured `navigation.{navbar,footer}` subtree. +- **`site_libs/`, shared CSS/JS** — Phase 5. The navbar emits Bootstrap + classes as before; theme plumbing is separate. +- **Sitemap, favicon, `<title>` prefix** — Phase 7. The navbar brand + reads `website.title` but `<title>` tag prefixing is Phase 7. +- **Navbar tools, reader-mode, dark-toggle, search** — excluded from + the epic MVP. +- **Sub-navbar (book chapter row), breadcrumbs, repo-actions** — + excluded from the epic MVP. + +## Reference material + +- **Parent epic plan** §"Phase 3 — Navbar / footer project integration". +- **Phase 2 plan** — the Generate/Render split (§Decision 7/8) and the + format-agnostic active-state algorithm (§"Generate transform flow") + are the templates this phase copies. `resolve_href_for_html` in + `sidebar_render.rs` is the helper this phase extracts and reuses. +- **Phase 2 close-out follow-ups**: + - `bd-n9dr` (nav-config placement unification) — Phase 3 **refines + the framing** of this follow-up rather than closing it. The + original direction was "unify everything under one namespace." The + new direction: *placement follows feature semantics*. Features that + only make sense for a website (sidebar, site-url, favicon, title + prefix) live under `website.`; features that work in single-doc + and multi-doc contexts alike (navbar, page-footer) live at the top + level. The dangling inconsistency becomes narrower: `site-sidebar` + (the per-doc override selecting *which* sidebar applies) lives at + the doc top level while the sidebar configs themselves live under + `website.`. Update `bd-n9dr`'s description to match this revised + framing when the phase lands. + - `bd-2quy` (`StageContext` ↔ `RenderContext` bridge completeness) — + Phase 3 is the second consumer of `ctx.project_index` in the + Generate step, so will surface any remaining gaps if they exist. +- **Q2 current code:** + - `crates/quarto-navigation/src/{item.rs,navbar.rs,footer.rs, + render_html.rs}` — data shapes, YAML parsing, HTML emission. + - `crates/quarto-core/src/transforms/{navbar_generate.rs, + navbar_render.rs,footer_generate.rs,footer_render.rs}` — current + transforms that Phase 3 rewires. + - `crates/quarto-core/src/transforms/sidebar_render.rs:135-181` + (`resolve_href_for_html`, `is_external`) — the helper to extract. + - `crates/quarto-core/src/transforms/sidebar_generate.rs:125-171` + (`enrich_text_from_index`) — the enrichment helper to extract. + - `crates/quarto-core/src/pipeline.rs:607-619` — navigation phase + ordering (no change needed — the existing slot works). + - `crates/quarto-core/src/project/index.rs` — `ProjectIndex` API. +- **Q1 reference:** + - `external-sources/quarto-cli/src/project/types/website/ + website-shared.ts:123-150` — `websiteNavigationConfig()`: navbar + read from `website.navbar` via `websiteConfig(kSiteNavbar, ...)`. + - `external-sources/quarto-cli/src/project/types/website/ + website-shared.ts:489-492` — `itemHasNavTarget()`: exact href + equality, plus a `/index.html` → `/` forgiveness. + - `external-sources/quarto-cli/src/project/types/website/ + website-navigation.ts:1161-1170` — per-page active-marking pass. + - `external-sources/quarto-cli/src/resources/projects/website/ + templates/navitem.ejs` — class vocabulary (`nav-link`, with `active` + appended when `item.active`). + - `external-sources/quarto-cli/src/resources/types/schema-types.ts: + 336-344` — `PageFooter` schema (left/center/right each + `string | NavigationItem[]`). + +## Key decisions (confirmed 2026-04-24) + +All decisions below were confirmed by the user on 2026-04-24 after +iteration on Decision 1. Decisions 2–8 approved as drafted; Decision 1 +was rewritten in response to user feedback (see revision note below). + +### Decision 1 — Keep navbar / page-footer config at the top level + +User feedback (2026-04-24): the initial draft proposed moving both +under `website.` to mirror Q1 and Phase 2's sidebar. Rejected. The +argument: navbar and page-footer are **feature-scoped, not +website-scoped**. A revealjs deck with a `page-footer:` is a perfectly +reasonable single-doc use case; forcing the user to write + +```yaml +website: + page-footer: ... +``` + +for a document that has nothing to do with a website is bad UX. The +same argument applies to navbar (single-doc HTML with a navbar is +unusual but coherent). + +The design principle this locks in: **placement follows feature +semantics**. Features that only make sense in a multi-page website +(sidebar, sitemap/site-url, favicon, title prefix) live under +`website.`. Features that are per-document chrome — whether the doc +lives alone or in a project — live at the top level. Project-level +`_quarto.yml` still configures them via the existing metadata merge: +setting `navbar: {...}` in `_quarto.yml` flows to each document's +`ast.meta.navbar` as it does today. + +Concretely for Phase 3: + +- `NavbarGenerateTransform` continues to read `ast.meta.navbar` (no + change). +- `FooterGenerateTransform` continues to read `ast.meta.page-footer` + (no change). +- `SidebarGenerateTransform` continues to read `ast.meta.website.sidebar` + (Phase 2, unchanged). +- **Site-scoped values that navbar/footer care about** — + `website.title` for brand fallback, potentially `website.site-url` + later — are read from `ast.meta.website.<key>` at the specific + render point where they matter. A renderer reading values from two + namespaces is fine when the two namespaces describe genuinely + different concepts. + +**Compat note.** No existing Q2 tests break; no migration required. +Phase 3 is YAML-surface-compatible with Phase 2. Q1-compatibility +(reading `website.navbar` as an alias) is **not** attempted in this +phase — if real-world Q1 migration shows users stuck on that spelling +we can add a deprecation-warning alias in a follow-up. + +### Decision 2 — Active marking: add `active: bool` to `NavigationItem` + +Currently, sidebar's `SidebarEntry::Link { item: NavigationItem, +active: bool }` keeps `active` outside `NavigationItem`. Adding the +same flag separately for navbar would be a second parallel-wrapper +pattern. Cleaner to move `active` onto `NavigationItem` once: + +```rust +pub struct NavigationItem { + pub href: Option<String>, + pub text: Option<ConfigValue>, + pub icon: Option<String>, + pub aria_label: Option<String>, + pub rel: Option<String>, + pub target: Option<String>, + pub menu: Vec<NavigationItem>, + pub active: bool, // NEW — defaults to false +} +``` + +Default is `false`; every existing call site uses `..Default::default()` +or field-by-field init. `SidebarEntry::Link` loses its `active` field, +reads `item.active` instead. Sidebar tests assert against `item.active`; +the existing surface churn is small (one struct field, one match arm +simplification). + +**Why add the field rather than compute in Render?** Phase 2 Decision 7 +locked in "Generate is format-agnostic, Render is format-specific." +Active-marking is source-path-keyed comparison; that's format-agnostic +data. Computing it in Render duplicates the comparison logic per format +and breaks the contract for hypothetical non-HTML outputs. + +**Alternative considered:** keep `active` out of `NavigationItem` and +introduce a `NavbarItem` wrapper mirroring `SidebarEntry::Link`. I'm +recommending against it: navbar has `menu` (recursive) and left/right +(flat) — wrapping doubles the type count with no new semantics. + +### Decision 3 — Extract `resolve_href_for_html` and `is_external` into a shared module + +Phase 2 put these two helpers inside `sidebar_render.rs`. Phase 3 +needs the same logic for navbar and footer render. Extract to a new +module: + +``` +crates/quarto-core/src/transforms/navigation_href.rs + pub fn resolve_href_for_html( + raw: &str, + index: Option<&ProjectIndex>, + source_label: Option<&str>, // e.g. "Sidebar 'docs'" or "Navbar" or "Page footer" + diagnostics: &mut Vec<DiagnosticMessage>, + ) -> String; + pub(crate) fn is_external(href: &str) -> bool; +``` + +`source_label` replaces the Phase 2 `sidebar_id` parameter with a more +general "who's asking" string so the warning diagnostics can name the +context uniformly. The module has no other dependencies. + +Phase 2 callers in `sidebar_render.rs` migrate to the new location in +the same phase-3 commit. Their test behavior is unchanged (the +diagnostic wording shifts slightly — explicit in the migration note). + +### Decision 4 — Extract `enrich_text_from_index` for navbar/footer reuse + +Phase 2 put sidebar's text enrichment inside `sidebar_generate.rs`. +Navbar and footer need the same "bare `- about.qmd` pulls its label +from the index" behavior. + +Two ways to share: + +- **A.** Extract a generic `enrich_navigation_items(&mut [NavigationItem], + &ProjectIndex)` that walks navbar `left`/`right` (and recursively + into `menu`) and footer `Items` regions. Because sidebar items are + also `NavigationItem`-under-an-enum-wrapper, sidebar's enrichment + could delegate to this helper for the `Link` case. +- **B.** Keep each transform's enrichment inlined. + +A is cleaner and removes the duplication; B is less disruption to +Phase 2 code. Propose **A**, in the shared module: + +``` +crates/quarto-core/src/transforms/navigation_enrich.rs + pub fn enrich_navigation_items( + items: &mut [NavigationItem], + index: &ProjectIndex, + ); +``` + +Sidebar's `enrich_text_from_index` becomes a thin wrapper that calls +this for each `SidebarEntry::Link` and recurses into `SidebarEntry::Section`. + +### Decision 5 — Active marking algorithm (navbar) + +Mirrors sidebar Decision 7. In `NavbarGenerateTransform::transform`: + +1. Compute `page_source`: the current doc's project-relative source + path (forward-slash form). Same helper as sidebar — lift into a + shared utility (`project_relative_source(ctx)` in a new + `transforms::navigation_context` module, or just as a free fn). +2. For each navbar item (left, right, recurse into `menu`): + - If `item.href` is an external URL or a `#`-anchor, leave `active` + as `false`. + - Else if `item.href` (interpreted as source path) equals + `page_source`, mark `item.active = true`. +3. No "expand ancestors" step — navbar has no expansion semantics. + Dropdown menus just have one active leaf at most. + +Unknown-href items (`foo.qmd` with no matching profile) are **not** +marked active; they'll emit the unknown-doc warning at Render time. + +Index-forgiveness. Q1's `itemHasNavTarget` also treats +`about/index.html` as matching `about/`. In Q2's source-path space, +that means: an item whose href is `about/index.qmd` matches the page +whose source path is `about/index.qmd`. No ambiguity — we compare +source-to-source, and Q1's slash-forgiveness was about output-href +normalization that the Render step handles. + +### Decision 6 — Navbar brand title fallback chain + +Current behavior: `Navbar.title == NavbarTitle::Default` falls back to +`ast.meta.title` (the document's title). For a project, each page has +its own title, so each page's navbar shows a different brand label — +wrong. + +New chain (in priority order), computed in `NavbarRenderTransform`: + +1. `navbar.title == NavbarTitle::Text(cv)` → use `cv`. +2. `navbar.title == NavbarTitle::Default`: + - If `ast.meta.website.title` exists, use that. + - Else fall back to `ast.meta.title` (document title). +3. `navbar.title == NavbarTitle::Hidden` → no title. + +Reads `website.title` from the already-merged metadata — no new +profile field needed. Single-doc renders without `website.title` +continue to fall through to the document title (no regression). + +**Why touch this in Phase 3 rather than Phase 7?** Because it's a +navbar-rendering concern, not a sitemap concern. Phase 7 owns the +HTML `<title>` tag ("page — site" prefix), which is a distinct +concern. Calling `website.title` at render time doesn't prejudge how +Phase 7 emits it. + +### Decision 7 — Navbar Generate takes ProjectIndex; Footer Generate does too + +Today, `NavbarGenerateTransform::transform` takes `_ctx: +&mut RenderContext` (ignored). Phase 3 actually uses `ctx` for: + +- `ctx.project_index` to enrich text and mark active. +- `ctx.project.dir` + `ctx.document.input` to compute `page_source`. +- `ctx.diagnostics` to push unknown-index warnings (rare — Generate + mostly defers warnings to Render). + +Footer Generate takes the same dependency, minus active-marking: + +- `ctx.project_index` to enrich text in `FooterRegion::Items`. + +The `RenderContext::project_index` plumbing is already in place +(Phase 2 fix `bd-9svl`). Nothing new to wire. + +### Decision 8 — Footer items get href rewrite but NOT active marking + +Footer items (icons, social links, "copyright" rows) aren't page- +scoped nav. Q1 doesn't mark them active. Phase 3 matches: `FooterRender` +rewrites `.qmd` → `.html` in `FooterRegion::Items`, but doesn't call +the active-state algorithm. + +Footer `Text` regions (string values that may include markdown) are +**not** scanned for `.qmd` links in Phase 3 — that's body-content +link rewriting, which is Phase 6's territory. + +## Architecture sketch + +### Pipeline position — unchanged + +The transforms already sit in the right order +(`pipeline.rs:612-619`): + +``` +TocGenerateTransform +NavbarGenerateTransform ← Phase 3 rewires internals +SidebarGenerateTransform +FooterGenerateTransform ← Phase 3 rewires internals +TocRenderTransform +NavbarRenderTransform ← Phase 3 rewires internals +SidebarRenderTransform +FooterRenderTransform ← Phase 3 rewires internals +``` + +No changes to `pipeline.rs`. Phase 3 is internal-only. + +### NavbarGenerateTransform (new flow) + +``` +NavbarGenerateTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "navbar"): return. + if navigation.navbar already populated: return. + + let Some(mut navbar) = resolve_navbar(&ast.meta) else { return }; + // ^^^ unchanged — reads top-level ast.meta.navbar as today. + + if let Some(index) = ctx.project_index.as_deref() { + enrich_navigation_items(&mut navbar.left, index); + enrich_navigation_items(&mut navbar.right, index); + let page_source = page_relative_source(ctx); + mark_active(&mut navbar.left, &page_source); + mark_active(&mut navbar.right, &page_source); + } + // Standalone render (no index): no enrichment, no active marking. + // The navbar YAML is still honored as-is; hrefs remain as authored. + + ast.meta.insert_path(&["navigation", "navbar"], + navbar.to_config_value()); +``` + +`resolve_navbar` stays as-is in `quarto-navigation::navbar` — no +rename, no signature change. Phase 3's work is purely the +ProjectIndex-aware post-processing between resolve and store. + +Hrefs in `navigation.navbar` are still source paths (format-agnostic, +per Phase 2 Decision 7). Render rewrites. + +### NavbarRenderTransform (new flow) + +``` +NavbarRenderTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "navbar"): return. + if rendered.navigation.navbar already populated: return. + + let navbar_cv = ast.meta.get_path(["navigation", "navbar"])?; + let mut navbar = Navbar::from_config_value(navbar_cv); + + // Rewrite hrefs on all items (left, right, and recursively menu). + let mut local_diags = std::mem::take(&mut ctx.diagnostics); + rewrite_navigation_item_hrefs(&mut navbar.left, + ctx.project_index.as_deref(), + "Navbar", + &mut local_diags); + rewrite_navigation_item_hrefs(&mut navbar.right, + ctx.project_index.as_deref(), + "Navbar", + &mut local_diags); + ctx.diagnostics = local_diags; + + // Brand fallback chain: navbar.title → website.title → document.title. + let fallback = brand_title_fallback(&ast.meta); + let html = navbar_to_html(&navbar, fallback.as_deref()); + + ast.meta.insert_path(&["rendered", "navigation", "navbar"], + ConfigValue::new_string(&html, SourceInfo::default())); +``` + +`rewrite_navigation_item_hrefs` walks left/right and recurses into +`menu`. Each item's `href` is passed through `resolve_href_for_html`. + +### navbar_to_html changes + +- Emit `active` class on `<a class="nav-link ...">` when + `item.active == true`. +- Dropdown leaves: emit `active` on dropdown-item anchor too (Q1 does + this for sidebar; we extend to navbar dropdowns for consistency). +- Brand fallback: renderer already accepts `document_title_fallback`; + the Render transform now computes this via `brand_title_fallback` + which consults `website.title` first. + +### FooterGenerateTransform (new flow) + +``` +FooterGenerateTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "page-footer"): return. + if navigation.footer already populated: return. + + let Some(mut footer) = resolve_page_footer(&ast.meta) else { return }; + // ^^^ unchanged — reads top-level ast.meta["page-footer"] as today. + + if let Some(index) = ctx.project_index.as_deref() { + enrich_footer_region(&mut footer.left, index); + enrich_footer_region(&mut footer.center, index); + enrich_footer_region(&mut footer.right, index); + } + + ast.meta.insert_path(&["navigation", "footer"], footer.to_config_value()); +``` + +`enrich_footer_region` inspects the region: if `FooterRegion::Items`, +calls `enrich_navigation_items`; else no-op. + +### FooterRenderTransform (new flow) + +``` +FooterRenderTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "page-footer"): return. + if rendered.navigation.footer already populated: return. + + let footer_cv = ast.meta.get_path(["navigation", "footer"])?; + let mut footer = PageFooter::from_config_value(footer_cv); + + let mut local_diags = std::mem::take(&mut ctx.diagnostics); + for region in [&mut footer.left, &mut footer.center, &mut footer.right] { + if let FooterRegion::Items(items) = region { + rewrite_navigation_item_hrefs(items, + ctx.project_index.as_deref(), + "Page footer", + &mut local_diags); + } + } + ctx.diagnostics = local_diags; + + let html = page_footer_to_html(&footer); + ast.meta.insert_path(&["rendered", "navigation", "footer"], + ConfigValue::new_string(&html, SourceInfo::default())); +``` + +### Module shape + +``` +crates/quarto-navigation/src/ + item.rs # add `active: bool` to NavigationItem + navbar.rs # unchanged — `resolve_navbar` still reads + # top-level `navbar:` as today + footer.rs # unchanged — `resolve_page_footer` still + # reads top-level `page-footer:` + render_html.rs # `navbar_to_html` emits `active` class; + # dropdown active handling + sidebar.rs # SidebarEntry::Link loses `active` field; + # reads `item.active` via NavigationItem + # (Phase 2 tests migrate) + +crates/quarto-core/src/transforms/ + navigation_href.rs # NEW — resolve_href_for_html + is_external + # (moved from sidebar_render.rs) + navigation_enrich.rs # NEW — enrich_navigation_items + text-enrich + # helper (consumed by navbar/footer/sidebar) + navigation_active.rs # NEW — mark_active(&mut [NavigationItem], + # &page_source) + recurse-into-menu logic + navbar_generate.rs # rewrite — uses ProjectIndex, marks active + navbar_render.rs # rewrite — rewrites hrefs, brand fallback + footer_generate.rs # rewrite — uses ProjectIndex + footer_render.rs # rewrite — rewrites hrefs in Items regions + sidebar_render.rs # migrate to navigation_href::resolve_… + sidebar_generate.rs # migrate to navigation_enrich +``` + +### Data flow summary + +``` +_quarto.yml → MetadataMergeStage → ast.meta.navbar +or doc frontmatter ast.meta.page-footer + (raw YAML ConfigValue, + top-level as today) + ↓ + NavbarGenerateTransform / FooterGenerateTransform + (read raw YAML + ProjectIndex for post-processing) + ↓ + ast.meta.navigation.{navbar,footer} + (resolved structure as ConfigValue; + hrefs still in source-path space; + active: bool already set on items) + ↓ + NavbarRenderTransform / FooterRenderTransform + (rewrite hrefs via ProjectIndex; + read ast.meta.website.title for brand fallback) + ↓ + ast.meta.rendered.navigation.{navbar,footer} + (HTML strings) + ↓ + ApplyTemplateStage + ↓ + navbar/footer injected into output HTML +``` + +### Template slots — unchanged + +`template.rs:162-164` (navbar) and `225-227` (footer) stay as-is. +Phase 3 doesn't restructure the template. + +## DocumentProfile change + +**None.** Phase 3 reads `source_path`, `title`, and `output_href` — +all present since Phase 1. No profile-version bump. + +## Tests (TDD: write and fail first) + +Every test authored before the code that makes it pass. Failing baseline +captured before implementation. + +### Unit tests — `quarto-navigation::item` + +1. **`navigation_item_default_has_inactive`** — the `active` field + defaults to `false` for every factory path (bare string, object + form, menu). +2. **`navigation_item_roundtrip_preserves_active`** — `to_config_value` + emits `active: true` when set; `from_config_value` reads it back. + (Active state *needs* to roundtrip so the Generate → Render handoff + via `navigation.navbar` ConfigValue preserves it.) + +### Unit tests — `quarto-navigation::navbar` / `footer` + +No new tests here. The existing `resolve_navbar` / +`resolve_page_footer` tests already cover the top-level-YAML +parsing contract, and Phase 3 doesn't change that contract. (A +regression guard — "top-level `navbar:` still resolves" — is covered +implicitly by the un-modified Phase 2 tests that exercise these +resolvers.) + +### Unit tests — `quarto-navigation::render_html` (navbar) + +9. **`navbar_render_emits_active_class_on_leaf`** — navbar with a + leaf item whose `active: true` emits `class="nav-link active"`. +10. **`navbar_render_no_active_class_when_inactive`** — no `active` + substring in the emitted `class` attribute. +11. **`navbar_render_active_propagates_into_dropdown_leaves`** — + a dropdown menu containing an `active` leaf emits the leaf's + anchor with `class="dropdown-item active"`. +12. **`navbar_render_brand_uses_fallback_string`** — existing test + `falls_back_to_document_title` continues to pass after the + fallback helper is extracted. + +### Unit tests — `quarto-core::transforms::navigation_href` + +13. **Migrated from `sidebar_render.rs`:** the six existing tests + (`render_passes_external_urls_through_unchanged`, etc.) move to + `navigation_href.rs` and are renamed to test the extracted helper + directly. Behavior unchanged. +14. **`resolve_href_source_label_appears_in_diagnostic`** — warning + for a miss carries the `source_label` string verbatim (e.g. + `"Navbar"`, `"Page footer"`). + +### Unit tests — `quarto-core::transforms::navigation_enrich` + +15. **`enrich_fills_missing_text_from_profile_title`** — `[{href: + "about.qmd"}]` + profile with `title: "About"` → `text: "About"`. +16. **`enrich_does_not_clobber_explicit_text`** — existing `text` + survives. +17. **`enrich_recurses_into_menu`** — nested dropdown items enriched. +18. **`enrich_skips_external_urls`** — `href: "https://…"` never gets + `text` filled from index. + +### Unit tests — `quarto-core::transforms::navigation_active` + +19. **`mark_active_matches_by_source_path`** — an item whose href is + `about.qmd` gets `active: true` when `page_source == "about.qmd"`. +20. **`mark_active_does_not_match_other_pages`** — + `page_source == "index.qmd"` leaves `about.qmd` item inactive. +21. **`mark_active_recurses_into_menu`** — an item inside a dropdown + whose href matches `page_source` becomes active. +22. **`mark_active_skips_external_urls`** — external href never + matches. + +### Unit tests — `navbar_generate` (extended; existing tests preserved) + +The existing skip tests (`skips_when_absent`, `skips_when_false`, +`skips_when_bare_true`, `skips_when_navigation_navbar_already_set`, +`populates_navigation_navbar_from_full_config`) remain and continue to +pass unchanged — Phase 3 is additive. New tests: + +23. **`navbar_generate_marks_active_item_for_current_page`** — + two-item navbar (`index.qmd`, `about.qmd`); rendering `about.qmd` + marks the second item active. +24. **`navbar_generate_does_not_mark_active_without_index`** — + standalone render (no `ProjectIndex`): active stays `false` + everywhere. +25. **`navbar_generate_enriches_item_text_from_index`** — bare-path + item `- about.qmd` gets `text: "About"` from the profile. +26. **`navbar_generate_keeps_qmd_paths`** — the resolved + `navigation.navbar` still carries `.qmd` hrefs (format-agnostic + invariant check). +27. **`navbar_generate_no_index_passes_through_unchanged`** — no + enrichment, no active marking, no diagnostics; navbar structure + is stored verbatim (regression guard for single-doc, non-website + formats like revealjs). + +### Unit tests — `navbar_render` (extended) + +Existing tests (`skips_when_navigation_navbar_missing`, +`skips_when_navbar_false`, `skips_when_prerendered`, +`renders_navbar_html`, `falls_back_to_document_title`) stay. New: + +28. **`navbar_render_rewrites_qmd_hrefs_to_output_href`** — leaf items + `about.qmd` → `href="about.html"` in the emitted HTML. +29. **`navbar_render_rewrites_dropdown_hrefs`** — same in dropdown menu. +30. **`navbar_render_passes_external_urls_through`**. +31. **`navbar_render_emits_diagnostic_for_unknown_qmd`** — `source_label` + is `"Navbar"`. +32. **`navbar_render_preserves_active_class_on_rewritten_href`** — + after href rewrite, `class="nav-link active"` is still there (the + rewrite doesn't clobber `active`). +33. **`navbar_render_brand_uses_website_title_fallback`** — + `{website: {title: "My Site"}}` with a default navbar title shows + "My Site" in the brand. +34. **`navbar_render_brand_prefers_navbar_title_over_website_title`** + — explicit `navbar.title` wins. +35. **`navbar_render_brand_falls_back_to_document_title_when_no_website_title`** + — regression guard for single-doc renders (existing + `falls_back_to_document_title` covers part of this; make the + ordering explicit). +36. **`navbar_render_no_index_passes_hrefs_through_unchanged`** — + standalone render, no `ProjectIndex`; a navbar entry `about.qmd` + is emitted verbatim (no rewrite, no diagnostic). + +### Unit tests — `footer_generate` (extended) + +Existing tests (`skips_when_absent`, `skips_when_false`, +`string_shortcut_populates_center`, `object_form_populates_regions`, +`skips_when_navigation_footer_already_set`) stay. New: + +37. **`footer_generate_enriches_items_in_regions`** — bare + `- about.qmd` in a footer `left` region gets its text enriched + from index. +38. **`footer_generate_does_not_enrich_text_regions`** — a string + region survives untouched. +39. **`footer_generate_keeps_qmd_paths`** — format-agnostic invariant. +40. **`footer_generate_no_index_passes_through_unchanged`** — + standalone render: no enrichment. + +### Unit tests — `footer_render` (new) + +`footer_render` has no existing Rust tests (the transform is thin and +delegates to `page_footer_to_html`). Phase 3 adds: + +41. **`footer_render_rewrites_qmd_hrefs_in_items_region`** — leaf + `about.qmd` → `about.html`. +42. **`footer_render_leaves_text_regions_unchanged`** — markdown-like + text in `center` survives. +43. **`footer_render_emits_diagnostic_for_unknown_qmd`** — + `source_label` is `"Page footer"`. +44. **`footer_render_no_index_passes_hrefs_through`** — standalone + render: `about.qmd` stays as-is, no diagnostic. + +### Integration tests — `crates/quarto-core/tests/` + +New file `navbar_footer_pipeline.rs` mirroring `sidebar_pipeline.rs`: + +45. **`pipeline_renders_navbar_for_two_page_website`** — fixture + `_quarto.yml`: + ``` + project: { type: website } + navbar: { title: "Site", left: [index.qmd, about.qmd] } + ``` + Render both pages; each output HTML contains `<nav class="navbar...`, + with the current page's `nav-link` carrying `active`. +46. **`pipeline_navbar_dropdown_href_rewriting`** — navbar with a menu + containing `about.qmd` becomes `about.html` in both pages' HTML. +47. **`pipeline_renders_page_footer_for_two_page_website`** — fixture + with top-level `page-footer: { left: "© 2026", right: [about.qmd] }` + in `_quarto.yml`; assert both pages' HTML contains + `<footer class="footer"` and the `about.qmd` href rewritten to + `.html`. +48. **`pipeline_navbar_active_never_cross_contaminates`** — rendering + `index.qmd` does not mark the `about.qmd` item active in + `index.html` output (regression against stateful transform bugs). +49. **`pipeline_navigation_subtree_is_format_agnostic`** — inspect + `ast.meta.navigation.navbar` between Generate and Render via a + test-only snapshot transform; assert `.qmd` paths intact, `active` + booleans present. +50. **`pipeline_single_doc_navbar_unchanged`** — regression: render a + standalone `doc.qmd` (no `_quarto.yml`) with a top-level `navbar:` + in its frontmatter; assert the resulting navbar HTML is + byte-identical to the pre-Phase-3 output (or close to it, modulo + the new `active` class being absent). Protects the single-doc UX + story from silent breakage. + +### CLI end-to-end + +51. **Manual smoke** (per CLAUDE.md §"End-to-end verification"): extend + `/tmp/q2-phase3-smoke/` fixture: + - `_quarto.yml`: + ``` + project: { type: website } + website: + title: "Q2 Phase 3 Smoke" + navbar: + left: + - index.qmd + - text: About + href: about.qmd + - text: Docs + menu: + - guides/intro.qmd + page-footer: + left: "© 2026 Quarto" + right: + - { icon: github, href: "https://github.com/quarto-dev/quarto" } + ``` + (`website.title` stays under `website.` because it *is* a + site-scoped concept; `navbar` and `page-footer` are at the top + level.) + - Three `.qmd` files. + - `cargo run --bin q2 -- render /tmp/q2-phase3-smoke/`. + - Inspect each rendered HTML: + - `<nav class="navbar ...">` with `nav-link` entries pointing at + `.html` files. + - Current page's `nav-link` has `active`. + - Dropdown menu renders with `dropdown-item` entries, rewriting + `guides/intro.qmd` → `guides/intro.html`. + - `<footer class="footer">` present; `© 2026 Quarto` in left + region; github icon link in right region. + - No warnings for known `.qmd` references; missing ones produce + diagnostics (test by introducing a `- missing.qmd` temporarily). + - Record the observed HTML snippet in the commit message or plan + close-out so reviewers don't need to re-run. +52. **Regression:** run Phase 2 fixtures (`/tmp/q2-phase2-smoke/`) + unchanged; assert sidebar output is pixel-identical (the sidebar + Generate/Render migration to shared helpers shouldn't alter output). +53. **Single-doc revealjs smoke:** render a standalone `deck.qmd` + with `format: revealjs` and a top-level `page-footer: "© 2026"`. + Confirm the footer renders without any `website.` namespacing + being required. (Belt-and-suspenders on the UX story the user + raised when rejecting the original Decision 1.) + +### Snapshot tests + +None in Phase 3 — the inline asserts listed above cover the vocabulary, +and sidebar Phase 2 chose explicit-asserts over snapshots for the same +reasons (see Phase 2 Decision 6). + +## Work items (checklist) + +### Preparation +- [x] Re-read `claude-notes/instructions/testing.md`, `coding.md`, + `review.md`. +- [x] Confirm user agreement with Decisions 1–8 before starting. +- [x] Create `bd` issue `Phase 3 — Navbar / footer project integration` + (`bd-fqyg`), parent `bd-0tr6`, parent-child dependency linked. +- [x] Commit directly on `feature/websites` (Phase 1 + 2 precedent). + +### `NavigationItem` adds `active: bool` +- [x] Add `active: bool` to `NavigationItem` struct (defaults to + `false`; documented as a Generate→Render handoff field). +- [x] Update `from_config_value` / `to_config_value` roundtrip. + `active: true` roundtrips; `active: false` is omitted from the + emitted map (omit-default convention). `active: true` alone no + longer triggers the all-fields-empty rejection. +- [x] Update `roundtrip_preserves_basic_fields` test to use + `..NavigationItem::default()`; all other callsites already used + the default-spread pattern. +- [x] Tests 1 and 2 (+ an additional + `navigation_item_inactive_omits_active_key` guard on the + omit-default convention). 84 quarto-navigation tests pass; + workspace build clean. + +### `SidebarEntry::Link` sheds its `active` field +- [x] Remove `active: bool` from `SidebarEntry::Link`; variant is now + `Link { item: NavigationItem }`. +- [x] `SidebarEntry::from_config_value` no longer extracts `active` + separately; `NavigationItem::from_config_value` handles it. +- [x] `SidebarEntry::to_config_value` for Link delegates directly to + `item.to_config_value()` (was a custom re-packaging path). +- [x] Migrate all pattern matches — sidebar.rs (9 sites incl. tests), + render_html.rs (1 renderer + 2 test helpers), sidebar_auto.rs + (2 sites), sidebar_render.rs (1 rewriter + 2 tests), + sidebar_generate.rs (1 enrichment site). +- [x] All 1149 quarto-navigation + quarto-core tests pass. Behavior + unchanged — the `active` bit lives on `item` now, the path + through `ConfigValue` roundtrip is identical. + +### Extract shared `navigation_href` module +- [x] Created `crates/quarto-core/src/transforms/navigation_href.rs` + with `resolve_href_for_html(raw, index, source_label, diags)` + and `is_external(href)`. `source_label` generalizes Phase 2's + `sidebar_id` parameter. +- [x] Migrated `sidebar_render.rs` to call the shared helper; dropped + the local copies. Sidebar builds `source_label` as + `"Sidebar '<id>'"` when it has an id, else `"Sidebar"`. +- [x] Tests 13–14 (plus edge-case tests: + `no_index_passes_raw_href_through`, `non_qmd_miss_does_not_emit_diagnostic`, + `is_external_classification`, query/fragment preservation). +- [x] **Contract shift from Phase 2**: when `index` is `None`, the + resolver no longer emits a warning for `.qmd`-shaped misses. + Rationale: standalone single-doc renders (including revealjs) + don't have project context, so the renderer can't tell if the + user's `.qmd` href is broken or intentionally literal. This + keeps the non-website use case quiet. All 1074 quarto-core + tests pass (Phase 2 test `render_works_without_project_index` + used external-only hrefs, so the shift is behaviorally safe). + +### Extract shared `navigation_enrich` module +- [x] Created `crates/quarto-core/src/transforms/navigation_enrich.rs` + with `enrich_navigation_items(&mut [NavigationItem], &ProjectIndex)` + and a crate-internal `enrich_one(item, index)` delegator. + Recurses into `menu` for dropdown items. +- [x] Migrated `sidebar_generate.rs::enrich_text_from_index`: + `SidebarEntry::Link` now delegates to `enrich_one`; `Section` + retains its section-specific enrichment path (title from + section href profile) and recurses. +- [x] Tests 15–18 (+ 2 edge cases: + `enrich_noop_for_item_without_href`, `enrich_noop_when_index_miss`). + 1080 quarto-core tests pass. + +### Create `navigation_active` shared module +- [x] Created `crates/quarto-core/src/transforms/navigation_active.rs` + with `mark_active(&mut [NavigationItem], page_source)`. + Source-path equality only; no HTML assumptions; no expand- + ancestors semantic (navbar/footer convention per Decision 5). + Recurses into `menu`. +- [x] Tests 19–22 (+ 2 edge cases: hrefless-item descent, duplicate- + href multi-match). 6 new tests, all passing. +- [x] Dead-code warnings on `mark_active` + `enrich_navigation_items` + are expected — they resolve when Tasks 7 (navbar_generate) and + 9 (footer_generate) consume the helpers. + +### `SidebarEntry::Link` sheds its `active` field +- [ ] Remove the field; read `item.active` instead. +- [ ] Update sidebar unit tests and integration tests to read + `item.active` (~7 tests in Phase 2 touched this). +- [ ] Re-run Phase 2 sidebar tests; confirm no behavior change. + +### Extract shared helpers +- [ ] Create `crates/quarto-core/src/transforms/navigation_href.rs`. + Move `resolve_href_for_html` + `is_external` from + `sidebar_render.rs`; rename `sidebar_id` parameter to + `source_label: Option<&str>`. +- [ ] Update all existing sidebar tests (13 in `sidebar_render.rs`) + to point at the new module or to use the new API; assert + behavior unchanged. +- [ ] Create `crates/quarto-core/src/transforms/navigation_enrich.rs` + with `enrich_navigation_items`. Sidebar's `enrich_text_from_index` + becomes a thin wrapper that recurses and delegates. +- [ ] Create `crates/quarto-core/src/transforms/navigation_active.rs` + with `mark_active(&mut [NavigationItem], &page_source)`. +- [ ] Tests 13–22. + +### Navbar YAML source — no change +- [ ] No work. `resolve_navbar` continues to read top-level + `navbar:` as today. Confirm Phase 2 tests for `resolve_navbar` + still pass after the `NavigationItem` shape change. + +### Footer YAML source — no change +- [ ] No work. `resolve_page_footer` continues to read top-level + `page-footer:`. Same confirmation. + +### NavbarGenerateTransform extension +- [x] Signature changed from `_ctx` to `ctx`; consume + `ctx.project_index` when present. +- [x] Added `enrich_navigation_items` + `mark_active` passes over + `left` and `right`. +- [x] `page_relative_source(ctx)` lifted from `sidebar_generate.rs` + into `navigation_active` so both transforms share it. + sidebar_generate delegates through the new location. +- [x] Tests 23–27. Existing Phase 2 skip-tests preserved (5). 10 + navbar_generate tests total, all passing. 1091 quarto-core + tests pass workspace-wide. + +### NavbarRenderTransform extension +- [x] `navbar_to_html` / `render_navbar_item` / `render_dropdown_item` + updated to emit `active` class on `nav-link` and `dropdown-item` + anchors when `item.active == true`. +- [x] Tests 9–11 (navbar active class rendering). 87 quarto-navigation + tests pass. +- [x] `rewrite_navigation_item_hrefs` walks left/right (recursing + into `menu`) and rewrites hrefs via the shared + `resolve_href_for_html`. `source_label = "Navbar"` for + diagnostics. +- [x] `brand_title_fallback(meta)` extracted; returns + `website.title ?? meta.title` (the `navbar.title` level is + already consumed by `navbar_to_html`'s own fallback handling + since it passes the fallback only when the navbar title is + `Default`). +- [x] Tests 28–36 in navbar_render.rs. 14 navbar_render tests, + all passing. 1100 quarto-core tests pass workspace-wide. + +### FooterGenerateTransform extension +- [x] `_ctx` → `ctx`; consume `ctx.project_index`. +- [x] `enrich_footer_region(region, index)` helper walks each of + left/center/right and delegates to `enrich_navigation_items` + when the region is `FooterRegion::Items`. `Text` and `Empty` + regions are skipped (Phase 6's territory). +- [x] Tests 37–40. 9 footer_generate tests total (5 preserved Phase 2 + + 4 new), all passing. + +### FooterRenderTransform extension +- [x] `_ctx` → `ctx`; `rewrite_region_hrefs` applies the shared + `resolve_href_for_html` across items inside `FooterRegion::Items` + in each of left/center/right. `source_label = "Page footer"`. +- [x] `rewrite_items_hrefs` is symmetric with navbar — recurses into + `menu` for safety (footers rarely nest menus, but the type + allows it). +- [x] Tests 41–44 plus the 4 preserved Phase 2 tests. 8 footer_render + tests total, all passing. 1108 quarto-core tests pass + workspace-wide. + +### Integration tests +- [x] `navbar_footer_pipeline.rs` created with tests 45–50. + 6 tests, all passing on first run. Drives the real + `ProjectPipeline` end-to-end via the same helper shape as + `sidebar_pipeline.rs` (temp dir, `ProjectContext::discover`, + `ProjectPipeline::run`). Covers: + * navbar rendering + active-item highlighting per page + * dropdown menu href rewriting + dropdown active class + * page-footer rendering + footer-item href rewriting + * active-class cross-contamination guard + * format-agnostic invariant spot check (`.qmd` paths survive + Generate, Render rewrites them, active class survives) + * single-doc-in-project regression (doc-level frontmatter + navbar still works; doesn't spill into siblings) + +### CLI end-to-end + regression +- [x] Smoke fixture at `/tmp/q2-phase3-smoke/` with three pages, + top-level `navbar:` (with dropdown) and `page-footer:` (with + icon + copyright), and `website.title` set. Rendered clean. + Observed HTML per page (quoted here for close-out review, + per CLAUDE.md §End-to-end verification): + * **index.html**: + - Brand uses site title: `<a class="navbar-brand" href="/">Q2 Phase 3 Smoke</a>` + - `<a href="index.html" class="nav-link active">Home</a>` (active) + - `<a href="about.html" class="nav-link">About</a>` (rewritten, not active) + - Dropdown `Docs` with `<a href="guides/intro.html" class="dropdown-item">Guide Intro</a>` (enriched text from profile) + - `<footer class="footer">` with left `© 2026 Quarto`, right github icon link (`<i class="bi bi-github">`) + * **about.html**: same navbar structure, active class flipped + to `About` only (`href="about.html" class="nav-link active"`). + * **guides/intro.html**: dropdown leaf active + (`<a href="guides/intro.html" class="dropdown-item active">`); + dropdown ancestor stays inactive (Decision 5 — matches Q1). +- [x] Revealjs/standalone single-doc smoke at + `/tmp/q2-phase3-revealjs-smoke/deck.qmd` with top-level + `page-footer: "© 2026 Standalone"`. Rendered clean without any + `website:` namespacing; the UX story Decision 1 hinged on is + intact. Footer HTML contains the literal copyright text in + `nav-footer-center`. +- [x] Phase 2 sidebar smoke re-run at `/tmp/q2-phase2-smoke/`. Output + includes `<nav id="quarto-sidebar">`, active class on the + current page's `sidebar-link`, nested-section expansion. No + regression from the Phase 2/Phase 3 refactor. + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — 7801 tests pass, 195 skipped + (gained 6 integration + 30 unit tests over the 7795 Phase 2 + baseline). +- [x] `cargo xtask lint` passes (622 files checked). +- [x] `cargo xtask verify --skip-hub-tests` end-to-end green — Rust + build + tests, hub-client build (including WASM), trace-viewer + tests. +- [x] Filed follow-ups: `bd-jfyl`, `bd-jbml`, `bd-bwwv`, `bd-9m8p`, + `bd-15dw`. Description of epic-wide `bd-n9dr` refreshed. +- [x] `br close bd-fqyg`. +- [x] `br sync --flush-only && git add .beads/ claude-notes/ crates/ && git commit`. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** adding `active: bool` to `NavigationItem` ripples through + navbar and sidebar tests en masse. *Mitigation:* the default is + `false`, so most construction sites that use `..Default::default()` + compile unchanged. Sidebar's `Link { item, active }` loses its + local `active` field in one atomic commit. + +- **Risk:** single-doc users in non-HTML formats (revealjs, + beamer) unexpectedly see their `page-footer:` stop rendering because + the transform takes a different branch without `ProjectIndex`. + *Mitigation:* Phase 3's non-index branch is explicitly a pass-through + — the resolver runs, the structure lands at `navigation.footer`, the + render emits it verbatim. Integration test 50 + smoke test 53 lock + this in. + +- **Risk:** extracting the href / enrich / active helpers into three + new modules fragments a small codebase. *Mitigation:* three small + modules is cheaper than three duplicated in-transform + implementations; each module owns one concept and one pub fn. + +- **Risk:** active-marking performance is O(N_items × 1) per-file, so + O(N_files × N_items) for a project sweep. For a 100-file site with + a 10-item navbar, 1,000 comparisons — negligible. + +- **Risk:** dropdown-active propagation introduces a surprising "nav + looks active when current page is deep inside a submenu" behavior. + *Mitigation:* only the matching leaf is marked; the dropdown + ancestor carries no `active` class (matches Q1's behavior; also a + simpler contract). Test 11 locks this in. + +- **Risk:** the brand-title fallback via `website.title` conflicts + with Phase 7's ownership of the site-title concept. *Mitigation:* + Phase 3 only *reads* `website.title`; Phase 7 adds the `<title>`-tag + prefixing as a separate concern. No overlap in state. + +- **Risk:** `enrich_navigation_items` + `mark_active` duplicate tree + walks across the navbar items. *Mitigation:* if the profile- + dashboard shows this up, merge into a single walk — but v1 keeps + them separate for readability. + +- **Risk:** footer `Text` regions may contain `.qmd` links inline — + e.g. `"See [our docs](docs.qmd)"`. Phase 3 doesn't rewrite those. + *Mitigation:* Phase 6 is the body-link-rewrite phase; call out + in the Phase 3 docs that footer `Text` regions are not project- + link-aware, and surface `bd-<new>` for "footer-text link + rewriting" as a follow-up if users hit this. + +## Explicit non-goals for this phase + +- No `site_libs/`, no shared CSS/JS (Phase 5). +- No sitemap, favicon, `<title>` prefix (Phase 7). +- No breadcrumbs, no repo-actions, no search, no reader/dark toggles, + no announcements (epic-excluded). +- No body-content `[link](x.qmd)` rewriting (Phase 6). +- No changes to the pipeline ordering or the template slots. +- No changes to sidebar behavior beyond the `active: bool` location + refactor and migration to the shared helpers. +- No book or manuscript types. +- No navbar "search" button wired up — stays a stub. + +## Follow-up beads (filed at close-out) + +- `bd-jfyl` — Footer `Text` region project-link rewriting (depends on + body-link Phase 6's contract). +- `bd-jbml` — `itemHasNavTarget`-style index-forgiveness (Q1 treats + `about/` and `about/index.html` as equivalent). Phase 3 uses strict + source-path equality; revisit if a real site hits the edge case. +- `bd-bwwv` — Navbar sub-row (book-style sub-navbar), epic-excluded + for MVP. +- `bd-9m8p` — `navbar.pinned` behavior (sticky-on-scroll JS); rides + with Phase 5 (`site_libs/` ships the JS). +- `bd-15dw` — Text-enrichment tie-breaker: if an item supplies `icon` + but no `text`, should we still enrich `text` from the profile title? + Phase 3 says no (`icon`-only items are intentional); confirmed. + +Epic-wide follow-up (description refreshed in Phase 3): + +- `bd-n9dr` reframed: placement follows feature semantics, not + uniformity. Remaining tension: `site-sidebar` at doc-level for a + website-scoped feature. See the bead for migration options. + +## Decisions log (confirmed 2026-04-24) + +1. **Navbar / page-footer config placement.** Stays at the top level + (no YAML surface change). Originally proposed to move under + `website.` to match Q1; rejected after user feedback pointing out + that non-HTML formats like revealjs can reasonably set + `page-footer:` without any website context. Principle established: + *placement follows feature semantics*. See Decision 1 for detail. +2. **`active: bool` on `NavigationItem`.** Added as a field with + default `false`. Sidebar's `SidebarEntry::Link { item, active }` + loses its local `active` and reads `item.active`. Unifies the nav + model across navbar / sidebar / footer. +3. **Shared `navigation_href` module.** `resolve_href_for_html` and + `is_external` move from `sidebar_render.rs` into a new + `crates/quarto-core/src/transforms/navigation_href.rs`. Phase 2 + callers migrate in the same commit. The `sidebar_id` parameter + generalizes to `source_label: Option<&str>`. +4. **Shared `navigation_enrich` module.** Title-enrichment logic + extracted into `enrich_navigation_items(&mut [NavigationItem], + &ProjectIndex)`; sidebar's wrapper delegates. Navbar + footer are + new consumers. +5. **Active-marking algorithm.** Format-agnostic, source-path keyed, + set in Generate. Recurses into dropdown `menu` items. No "expand + ancestors" semantics for navbar (unlike sidebar). Dropdown + ancestors stay inactive even when a leaf is active. +6. **Navbar brand fallback chain.** `navbar.title → website.title → + document.title`. Phase 3 reads `website.title` from merged + metadata; Phase 7 still owns the `<title>` tag prefixing. +7. **Navbar and footer Generate take `ProjectIndex`.** Both transforms + switch their `_ctx` signature to `ctx` and consume + `ctx.project_index` for enrichment and active-marking. No-index + branch silently skips post-processing. +8. **Footer items get href rewrite, no active marking.** Matches Q1. + Footer `Text` regions are not scanned for `.qmd` links in Phase 3 + — that's Phase 6's body-link-rewrite territory. + +## Epic-level impact + +Phase 3 completes the project-aware navigation surface for websites: +navbar + sidebar + page-footer all participate in project rendering, +all link across documents, all highlight the current page. Together +with Phases 5+7, this is the minimum-shape deliverable for `bd-tr81` +(the Q2 docs site bootstrap). + +After Phase 3: + +- A website with a navbar, a sidebar, and a footer renders correctly + on a cold project. +- Every internal `.qmd` link in navigation surfaces becomes an `.html` + link in the output HTML. +- The "you are here" cue is present in both sidebar (already shipped) + and navbar (this phase). +- Single-doc renders — including non-HTML formats like revealjs — keep + working with the same top-level `navbar:` / `page-footer:` YAML + surface they had before. +- The epic's "where does nav config live?" question has a principled + answer: **placement follows feature semantics**. Site-scoped + features (sidebar, sitemap, favicon, site title) live under + `website.`; document-level chrome (navbar, page-footer) lives at + the top level. diff --git a/claude-notes/plans/2026-04-24-websites-phase-4.md b/claude-notes/plans/2026-04-24-websites-phase-4.md new file mode 100644 index 000000000..04b1ef418 --- /dev/null +++ b/claude-notes/plans/2026-04-24-websites-phase-4.md @@ -0,0 +1,877 @@ +# Phase 4 — Page navigation (prev / next) + +**Date:** 2026-04-24 +**Beads:** `bd-nwun` (closed; parent `bd-0tr6`). +Follow-ups: `bd-q1pe`, `bd-xwq8`, `bd-q6ky`, `bd-bobp`, `bd-nf50`. +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-24-websites-phase-3.md` +**Status:** Closed 2026-04-24. Decisions 1–9 confirmed; implementation +shipped on `feature/websites` in commit `4a59a9dd`. + +## Goal of this phase + +Emit the bottom-of-page **prev / next** navigation strip that Q1 +produces on website pages, driven by the current page's already- +resolved sidebar. Concretely: + +1. Add a `PageNavigation { prev: Option<NavigationItem>, next: + Option<NavigationItem> }` data type in `quarto-navigation`. +2. Add `PageNavGenerateTransform` (runs right after + `SidebarGenerateTransform`). Reads the already-picked sidebar from + `navigation.sidebar`, flattens it per Q1's `flattenItems` + + `nextAndPrevious` rules, finds the current page, and stores the + resulting `PageNavigation` at `navigation.page_navigation`. Hrefs + remain in source-path space (format-agnostic, per Phase 2 + Decision 7). +3. Add `PageNavRenderTransform` (runs right after + `SidebarRenderTransform`). Rewrites `prev`/`next` hrefs via the + shared `navigation_href::resolve_href_for_html`, emits Q1-matching + HTML, stores at `rendered.navigation.page_navigation`. +4. Add template slot `$rendered.navigation.page_navigation$` inside + `<main class="content">`, after `$body$`, before `</main>`. +5. Honor top-level `page-navigation: false` via the existing + `is_feature_disabled` helper. Default-on when a sidebar applies and + at least one neighbor exists; silent no-op otherwise. + +**No YAML-surface changes** beyond the top-level `page-navigation: bool` +key that Q1 already uses. Phase 3's "placement follows feature +semantics" principle is preserved: per-document chrome at the top +level, not under `website.`. + +This phase does **not** implement: + +- **`<link rel="prev">` / `<link rel="next">` meta tags** in `<head>`. + Q1 emits these; Q2 defers as follow-up — see close-out beads. +- **`usesCustomLayout` suppression**. Q1 hides page-nav when a user + page opts into a custom layout. Defer until real content hits the + edge case. +- **Rich-text `aria-label` stripping**. `DocumentProfile.title` is + `String` today; when titles grow inline markup support, we'll revisit. +- **"Remove chapter number" post-render patch**. Book-specific; out of + epic scope. +- **`site_libs/` / theme CSS for the nav strip**. Phase 4 emits the + HTML with the exact Q1 class vocabulary + (`nav-page-previous`/`nav-page-next`/`pagination-link`) so Phase 5's + shared-assets work will light up the Q1 CSS without re-markup. + +## Reference material + +- **Parent epic plan** §"Phase 4 — Page navigation (prev/next)". +- **Phase 2 plan** — sidebar Generate/Render split, sidebar data model. + `resolve_active_state` / `sidebar_for_page` live in + `crates/quarto-navigation/src/sidebar.rs`. +- **Phase 3 plan** — the shared navigation helpers + (`navigation_href`, `navigation_enrich`, `navigation_active`) that + Phase 4 reuses for href rewriting. `NavigationItem::active` is + irrelevant here (page-nav targets are *not* the current page by + construction), but `text` / `href` / `aria_label` all apply. +- **Q2 current code:** + - `crates/quarto-navigation/src/sidebar.rs` — `Sidebar`, + `SidebarEntry`, `sidebar_for_page`, `resolve_active_state`, + `contains_source_path`. + - `crates/quarto-navigation/src/item.rs` — `NavigationItem`. + - `crates/quarto-navigation/src/render_html.rs` — place to add + `page_navigation_to_html`. + - `crates/quarto-core/src/transforms/navigation_href.rs` — + `resolve_href_for_html`, `is_external`. + - `crates/quarto-core/src/transforms/sidebar_generate.rs` — pattern + Phase 4 mirrors for Generate. + - `crates/quarto-core/src/transforms/sidebar_render.rs` — pattern + Phase 4 mirrors for Render. + - `crates/quarto-core/src/pipeline.rs:623-630` — navigation-phase + ordering (insert two new entries). + - `crates/quarto-core/src/template.rs:161-220` — `FULL_HTML_TEMPLATE`, + place to add the new slot inside `<main>`. +- **Q1 reference:** + - `external-sources/quarto-cli/src/project/types/website/website-navigation.ts:1188-1227` + — `nextAndPrevious` (the flatten + dedupe + neighbor algorithm + Phase 4 mirrors). + - `external-sources/quarto-cli/src/project/types/website/website-shared.ts:339-354` + — `flattenItems` (the depth-first walk). + - `external-sources/quarto-cli/src/resources/projects/website/templates/nav-after-body-postamble.ejs` + — the target HTML shape. + - `external-sources/quarto-cli/src/resources/projects/website/navigation/quarto-nav.scss:740+` + — Q1 `.page-navigation` CSS (informational; Phase 5 ships it). + +## Key decisions (confirmed 2026-04-24) + +All decisions below were confirmed by the user on 2026-04-24 after the +design sketch. Decision 1 was tempered by a user note that "single-doc +articles probably won't have prev-next navigation" — ergonomics review +left for a follow-up once the feature is in. + +### Decision 1 — Config placement: top level `page-navigation: bool` + +`page-navigation: true|false` lives at the top level of document +metadata. Not under `website.`. Matches Q1's YAML shape and Phase 3's +principle that per-document chrome stays top-level. + +Flows through the existing metadata merge: setting +`page-navigation: false` in `_quarto.yml` disables for all docs in the +project; a per-doc override in frontmatter wins over that. + +Reading code uses the shared `is_feature_disabled(&ast.meta, +"page-navigation")` helper — same pattern as navbar / sidebar / footer +/ toc. No new helper needed. + +### Decision 2 — Pipeline position: after sidebar Generate / Render + +``` +TocGenerateTransform +NavbarGenerateTransform +SidebarGenerateTransform +PageNavGenerateTransform ← NEW — depends on navigation.sidebar +FooterGenerateTransform +TocRenderTransform +NavbarRenderTransform +SidebarRenderTransform +PageNavRenderTransform ← NEW +FooterRenderTransform +``` + +`PageNavGenerateTransform` runs after `SidebarGenerateTransform` so it +reads the already-resolved `navigation.sidebar` rather than re-picking +the sidebar itself. That's the single source of truth: whatever sidebar +the user sees, page-nav neighbors come from that same sidebar. + +### Decision 3 — Data model: `PageNavigation { prev, next }` in `quarto-navigation` + +```rust +#[derive(Debug, Clone, PartialEq, Default)] +pub struct PageNavigation { + pub prev: Option<NavigationItem>, + pub next: Option<NavigationItem>, +} + +impl PageNavigation { + pub fn from_config_value(cv: &ConfigValue) -> Self { … } + pub fn to_config_value(&self) -> ConfigValue { … } + pub fn is_empty(&self) -> bool { self.prev.is_none() && self.next.is_none() } +} +``` + +Reuses `NavigationItem` (href, text, aria_label, …) so the Phase 3 +shared `resolve_href_for_html` helper drops in without a wrapper. The +`active`, `icon`, `menu`, `target`, `rel` fields on `NavigationItem` +are not meaningful for page-nav but are carried along harmlessly by +the roundtrip (omit-default keeps them out of the emitted map). + +### Decision 4 — Flatten algorithm (mirror Q1 `nextAndPrevious`) + +Given the already-resolved `Sidebar` for the current page: + +1. **Depth-first walk** (`flatten_sidebar_entries`) collecting entries + that qualify for prev/next positioning: + - `SidebarEntry::Link { item }`: include if `item.href` is + `Some(_)` and **not** `is_external(href)`. + - `SidebarEntry::Section { href, contents, … }`: include the + section header as a positional entry if `href` is `Some(_)` and + not external. **Always** recurse into `contents` regardless of + whether the header itself was included. + - `SidebarEntry::Separator`: include as a `Separator` marker. Q1 + uses these as hard boundaries. + - `SidebarEntry::Heading(_)`: skip (label only, no position). + - `SidebarEntry::Auto(_)`: skip defensively (should have been + expanded by this point; a stray `Auto` at Phase 4 is a bug + elsewhere — emit nothing rather than panic). + +2. **De-duplicate** by `href`, keeping the **first** occurrence. Q1 + does the same. Rationale: if a section-header href matches one of + its child-link hrefs (common idiom), we want a single entry in + the prev/next ring. Separators are never deduped (they have no + href). + +3. **Find current-page index**: linear scan for the flat-list entry + whose `href` equals `page_source` (the current doc's project- + relative source path, forward-slash form — same helper + `page_relative_source(ctx)` used by sidebar/navbar Generate). + +4. **Pick neighbors**: + - `prev = index > 0 && !is_separator(list[index-1]) ? list[index-1] : None` + - `next = index+1 < list.len() && !is_separator(list[index+1]) ? list[index+1] : None` + - If the current page is not in the flat list (e.g. a page the + sidebar doesn't list at all, but which still gets picked as its + sidebar via a wildcard containment match), produce `{prev: None, + next: None}`. + +5. The flattened list is intermediate; only the final `PageNavigation` + leaves the transform. + +### Decision 5 — Default behavior: on when sidebar + neighbor exist + +Transform runs unconditionally, subject to `is_feature_disabled`. + +- If `page-navigation: false` at any merge level: skip. +- If `navigation.page_navigation` already populated (user override or + repeat run): skip. +- If `navigation.sidebar` absent: skip. +- If the current page is not found in the flat list: skip (no prev/ + next, no insertion). +- If the current page *is* found and at least one neighbor exists: + insert `navigation.page_navigation = PageNavigation { prev, next }`. +- If both neighbors are `None` (current page is the only non-separator + entry): also skip — no point emitting an empty strip. + +Silent in every skip case. No diagnostic — absent page-nav is not an +error. + +### Decision 6 — Render output (Q1-matching HTML) + +`page_navigation_to_html(&PageNavigation) -> String` in +`quarto-navigation::render_html`. Emits exactly Q1's postamble markup: + +```html +<nav class="page-navigation"> + <div class="nav-page nav-page-previous"> + <a href="{prev.href}" class="pagination-link" aria-label="{prev.text}"> + <i class="bi bi-arrow-left-short"></i> + <span class="nav-page-text">{prev.text}</span> + </a> + </div> + <div class="nav-page nav-page-next"> + <a href="{next.href}" class="pagination-link" aria-label="{next.text}"> + <span class="nav-page-text">{next.text}</span> + <i class="bi bi-arrow-right-short"></i> + </a> + </div> +</nav> +``` + +When `prev` is `None`, the `<div class="nav-page nav-page-previous">` +wrapper is still emitted (empty). Same for `next`. Matches Q1 +(templates always render both divs; the CSS layout relies on the +two-column symmetry). When *both* are None we skip the entire block — +the Generate transform already guards this, so Render only sees +populated structures. + +`text` defaults to the item's `href` when `text` is missing (defensive; +enrichment in Generate should have filled this). `aria-label` uses the +same `text` value (MVP — the Q1 `plainText` stripping is out of scope +per Phase 4 non-goals). + +HTML escaping matches `navbar_to_html` — `escape_html` for node text, +`escape_attr` for attribute values. + +### Decision 7 — No `<link rel="prev/next">` in `<head>` (deferred) + +Q1 emits `<link rel="prev" href="…">` / `<link rel="next" href="…">` +inside `<head>` alongside the visible strip (for SEO hints + browser +preload). Phase 4 **defers**: wiring into `<head>` touches the +template's `<link>` plumbing and the HTML render config, which is +tangential to the page-nav feature itself. + +Follow-up: file `bd-<new>` at close-out — "Emit `<link rel="prev">` / +`<link rel="next">` when page-navigation is active". + +### Decision 8 — Template slot inside `<main>`, after `$body$` + +Add a new slot inside the existing `FULL_HTML_TEMPLATE`: + +``` +<main class="content" id="quarto-document-content"> +$if(title)$ +<header id="title-block-header" …>…</header> +$endif$ + +$body$ + +$if(rendered.navigation.page_navigation)$ ← NEW +$rendered.navigation.page_navigation$ +$endif$ +</main> +``` + +Placement note: Q1 emits the strip inside the content region just +before the footer, via the `nav-after-body-postamble.ejs` partial. +Placing it inside `<main>` after `$body$` gives semantically correct +nesting (the nav belongs to the article) and keeps all changes inside +the template. We can revisit placement once we see the whole feature +holistically (epic note). + +Template comment in the doc block lists the new slot alongside the +others (`$rendered.navigation.page_navigation$`). + +### Decision 9 — Documentation note carry-forward + +User flagged that the flatten + dedupe + separator-boundary rules are +"fairly complicated behavior." The Q2 docs site (`bd-tr81`) is the +reason we're doing websites, and this feature needs proper user- +facing documentation once the epic lands. Add to the epic plan's +close-out checklist: **"Phase 4 prev/next rules need a dedicated +docs section"**, linked to `bd-tr81`. + +## Architecture sketch + +### Generate-transform flow + +``` +PageNavGenerateTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "page-navigation"): return. + if navigation.page_navigation already populated: return. + + let Some(sidebar_cv) = ast.meta.get_path(["navigation", "sidebar"]) else { return }; + let sidebar = Sidebar::from_config_value(sidebar_cv); + + let page_source = page_relative_source(ctx); + let flat = flatten_for_page_nav(&sidebar.contents); // Vec<FlatEntry> + let Some(idx) = flat.iter().position(|e| e.is_link_with_href(&page_source)) else { + return; // current page not in sidebar flat list + }; + + let prev = neighbor(&flat, idx, Direction::Prev); + let next = neighbor(&flat, idx, Direction::Next); + + if prev.is_none() && next.is_none(): return; // lonely page + + let page_nav = PageNavigation { prev, next }; + ast.meta.insert_path(&["navigation", "page_navigation"], + page_nav.to_config_value()); +``` + +`flatten_for_page_nav` lives in `crates/quarto-navigation/src/sidebar.rs` +next to `flatten_items_for_containment` (if we have one — otherwise a +new pub helper). It returns a `Vec<FlatEntry>` where: + +```rust +enum FlatEntry { + Item(NavigationItem), + Separator, +} +``` + +`Separator` is private to the algorithm; only `NavigationItem`s leave +the transform wrapped in `Option<_>`. + +`neighbor(flat, idx, direction)` walks one step in the given direction +and returns `Some(NavigationItem)` if the step lands on an `Item`, +`None` if it lands on a `Separator` or runs off the end. + +### Render-transform flow + +``` +PageNavRenderTransform::transform(ast, ctx): + if is_feature_disabled(&ast.meta, "page-navigation"): return. + if rendered.navigation.page_navigation already populated: return. + + let Some(cv) = ast.meta.get_path(["navigation", "page_navigation"]) else { return }; + let mut page_nav = PageNavigation::from_config_value(cv); + + let mut local_diags = std::mem::take(&mut ctx.diagnostics); + if let Some(ref mut item) = page_nav.prev { + if let Some(href) = item.href.as_mut() { + *href = resolve_href_for_html(href, ctx.project_index.as_deref(), + Some("Page navigation"), &mut local_diags); + } + } + if let Some(ref mut item) = page_nav.next { + // same as above + } + ctx.diagnostics = local_diags; + + let html = page_navigation_to_html(&page_nav); + ast.meta.insert_path(&["rendered", "navigation", "page_navigation"], + ConfigValue::new_string(&html, SourceInfo::default())); +``` + +### Module shape + +``` +crates/quarto-navigation/src/ + sidebar.rs # add `flatten_for_page_nav` (pub fn) + + # pub enum FlatEntry (or keep FlatEntry + # crate-private and expose a narrower API) + page_nav.rs # NEW — PageNavigation struct, + # from_config_value / to_config_value + render_html.rs # add page_navigation_to_html + lib.rs # re-export PageNavigation + +crates/quarto-core/src/transforms/ + page_nav_generate.rs # NEW — PageNavGenerateTransform + page_nav_render.rs # NEW — PageNavRenderTransform + mod.rs # wire up the two new modules + re-exports + +crates/quarto-core/src/ + pipeline.rs # insert 2 lines (after sidebar Generate, + # after sidebar Render) + template.rs # add $rendered.navigation.page_navigation$ + # slot + comment in the doc block +``` + +### Data flow summary + +``` +_quarto.yml / frontmatter → MetadataMergeStage → ast.meta.website.sidebar + ast.meta["page-navigation"] (bool) + ↓ + SidebarGenerateTransform + ↓ + ast.meta.navigation.sidebar (resolved, format-agnostic) + ↓ + PageNavGenerateTransform + (flatten + find current + neighbors) + ↓ + ast.meta.navigation.page_navigation (format-agnostic) + ↓ + PageNavRenderTransform + (href rewrite via ProjectIndex + emit HTML) + ↓ + ast.meta.rendered.navigation.page_navigation (HTML) + ↓ + ApplyTemplateStage → slot in <main> +``` + +## DocumentProfile change + +**None.** Phase 4 reads `source_path` and `title` (through sidebar +enrichment done in Phase 2/3) — all present since Phase 1. No +profile-version bump. + +## Tests (TDD: write and fail first) + +Every test authored before the code that makes it pass. Failing baseline +captured before implementation. + +### Unit tests — `quarto-navigation::page_nav` + +1. **`page_navigation_default_is_empty`** — `PageNavigation::default()` + has `prev: None` and `next: None`; `is_empty()` returns true. +2. **`page_navigation_roundtrip_preserves_prev_next`** — populate with + items bearing `href` + `text`; roundtrip through + `to_config_value` / `from_config_value` preserves both sides. +3. **`page_navigation_roundtrip_empty_side_omits_key`** — only `next` + set; the emitted map has no `prev` key; `from_config_value` on + that map yields `prev: None`. + +### Unit tests — `quarto-navigation::sidebar::flatten_for_page_nav` + +4. **`flatten_includes_internal_links_only`** — sidebar with one + internal `Link` and one external `Link` (`https://…`); the flat + list contains only the internal one. +5. **`flatten_includes_section_header_with_href`** — section carrying + `href: "index.qmd"` appears as a flat entry; its children also + appear, in depth-first order. +6. **`flatten_skips_section_header_without_href`** — section with + text + contents but no header href: header omitted, children + walked. +7. **`flatten_includes_separators_as_markers`** — `Separator` entries + appear in the flat list (used downstream to break adjacency). +8. **`flatten_skips_headings`** — `Heading(_)` omitted. +9. **`flatten_skips_stray_auto`** — `Auto(_)` omitted (defensive; + should never reach this point). +10. **`flatten_dedupes_by_href_keeping_first`** — section `href: + "docs.qmd"` followed by a child `Link { href: "docs.qmd" }`: only + the section appears in the flat list. +11. **`flatten_dedupe_does_not_collapse_separators`** — two separators + surrounding a link stay as three flat entries. +12. **`flatten_depth_first_order_matches_q1`** — regression guard: a + handcrafted sidebar with two levels of nesting produces exactly + the Q1-expected order. (Fixture included verbatim in the test for + reviewer eyeballing.) + +### Unit tests — `quarto-navigation::render_html::page_navigation_to_html` + +13. **`page_nav_html_emits_prev_and_next_divs`** — both sides filled: + output contains both `nav-page-previous` and `nav-page-next` + wrappers with `pagination-link` anchors. +14. **`page_nav_html_empty_prev_wrapper_when_missing`** — + `prev: None, next: Some(_)`: previous `<div>` is emitted but has + no `<a>` inside. +15. **`page_nav_html_uses_text_in_aria_label`** — item with + `text: "About"` produces `aria-label="About"` on the anchor. +16. **`page_nav_html_escapes_text_and_attributes`** — text with + `<` / `&` / `"` is HTML-escaped in the `<span>` and attribute- + escaped in `aria-label` / `href`. +17. **`page_nav_html_falls_back_to_href_when_text_missing`** — item + with `href: "a.qmd"` and `text: None` renders `a.qmd` in the + visible span. +18. **`page_nav_html_emits_q1_bootstrap_icons`** — output contains + `<i class="bi bi-arrow-left-short"></i>` on prev and + `<i class="bi bi-arrow-right-short"></i>` on next. + +### Unit tests — `page_nav_generate` + +19. **`page_nav_generate_skips_when_feature_disabled`** — + `page-navigation: false` at doc level: no + `navigation.page_navigation` written. +20. **`page_nav_generate_skips_when_sidebar_absent`** — no + `navigation.sidebar` on the meta: skip. +21. **`page_nav_generate_skips_when_already_populated`** — a + pre-set `navigation.page_navigation` survives verbatim. +22. **`page_nav_generate_skips_when_page_not_in_sidebar`** — current + page has a sidebar assigned but its source path doesn't appear in + the flat list: no insertion. +23. **`page_nav_generate_skips_when_lonely_page`** — current page is + the only non-separator entry in a single-item sidebar: no + insertion (both neighbors would be None). +24. **`page_nav_generate_middle_page_has_both_neighbors`** — three- + page linear sidebar, rendering page 2: prev = page 1, next = + page 3. +25. **`page_nav_generate_first_page_only_has_next`** — three-page + sidebar, rendering page 1: prev = None, next = page 2. +26. **`page_nav_generate_last_page_only_has_prev`** — three-page + sidebar, rendering page 3: prev = page 2, next = None. +27. **`page_nav_generate_separator_breaks_adjacency`** — sidebar: + `[a.qmd, ---, b.qmd]`. Rendering `a.qmd`: next = None (separator + is next). Rendering `b.qmd`: prev = None. +28. **`page_nav_generate_keeps_qmd_hrefs`** — format-agnostic + invariant: stored prev/next hrefs end in `.qmd`. +29. **`page_nav_generate_carries_enriched_text_from_sidebar`** — a + bare-path sidebar entry `- about.qmd` was enriched by + `SidebarGenerateTransform` (Phase 2). Page-nav picks that entry + as a neighbor; the `text` field comes along on the + `NavigationItem`. +30. **`page_nav_generate_respects_section_header_as_neighbor`** — + sidebar contains a section with an href; that section can be a + prev or next neighbor of a leaf sibling. + +### Unit tests — `page_nav_render` + +31. **`page_nav_render_skips_when_absent`** — no + `navigation.page_navigation` → no `rendered.navigation.page_navigation`. +32. **`page_nav_render_skips_when_feature_disabled`**. +33. **`page_nav_render_skips_when_already_prerendered`**. +34. **`page_nav_render_rewrites_qmd_hrefs_to_html`** — prev.href + `about.qmd` becomes `about.html` in the emitted HTML (via + ProjectIndex). +35. **`page_nav_render_passes_external_urls_through`** (defensive — + Generate filters externals, but Render must be robust if a user + filter inserts one). +36. **`page_nav_render_emits_diagnostic_for_unknown_qmd`** — + `source_label = "Page navigation"` in the diagnostic. +37. **`page_nav_render_no_index_passes_hrefs_through`** — standalone + render, no project index: hrefs stored verbatim, no diagnostic. +38. **`page_nav_render_populates_rendered_slot`** — happy path: HTML + string lands at `rendered.navigation.page_navigation`. + +### Integration tests — `crates/quarto-core/tests/` + +New file `page_navigation_pipeline.rs` modeled on +`sidebar_pipeline.rs` / `navbar_footer_pipeline.rs`: + +39. **`pipeline_page_nav_three_page_website`** — fixture with + `_quarto.yml` declaring a sidebar `[index.qmd, about.qmd, + docs.qmd]`. Assertions: + - `index.html`: contains `nav-page-next` pointing at + `about.html`; `nav-page-previous` div is empty. + - `about.html`: both prev (`index.html`) and next (`docs.html`) + populated. + - `docs.html`: `nav-page-previous` pointing at `about.html`; next + div empty. +40. **`pipeline_page_nav_disabled_at_doc_level`** — same fixture, + `about.qmd` frontmatter sets `page-navigation: false`. Assertions: + - `about.html`: no `<nav class="page-navigation">`. + - `index.html` / `docs.html`: page-nav present (doc-level disable + does not spill across documents). +41. **`pipeline_page_nav_disabled_at_project_level`** — fixture + declares `page-navigation: false` at the top of `_quarto.yml`. No + page emits `page-navigation`. +42. **`pipeline_page_nav_honors_separator_boundary`** — sidebar + `[a.qmd, ---, b.qmd]`. `a.html`: next empty. `b.html`: prev empty. +43. **`pipeline_page_nav_cross_contamination_guard`** — rendering + `index.qmd` does not mark or leak neighbors into the other two + pages' output (regression against stateful-transform bugs, same + shape as the navbar cross-contamination test from Phase 3). +44. **`pipeline_single_doc_no_page_nav`** — a bare `doc.qmd` with no + `_quarto.yml`, top-level `page-navigation: true`: no + `<nav class="page-navigation">` in the output (no sidebar → no + page-nav, matches default-on semantics). + +### CLI end-to-end (per CLAUDE.md §End-to-end verification) + +45. **Manual smoke** at `/tmp/q2-phase4-smoke/`: + ``` + _quarto.yml: + project: { type: website } + website: + title: "Q2 Phase 4 Smoke" + sidebar: + contents: [index.qmd, about.qmd, docs.qmd] + index.qmd, about.qmd, docs.qmd: (three minimal pages) + ``` + - `cargo run --bin q2 -- render /tmp/q2-phase4-smoke/`. + - Inspect each rendered HTML: + - `index.html`: `<nav class="page-navigation">` present; left + div empty; right div `<a href="about.html" …>About</a>` with + the right-arrow icon. + - `about.html`: left points at `index.html`, right at + `docs.html`. + - `docs.html`: left at `about.html`; right div empty. + - Record the observed HTML snippet in the plan close-out. +46. **Separator variant** at `/tmp/q2-phase4-separator-smoke/`: + sidebar `[a.qmd, "---", b.qmd, c.qmd]`. Confirm `a.html` has no + next, `b.html` has no prev, `b.html`→`c.html` and back. +47. **Regression:** Phase 2 / Phase 3 smokes (`/tmp/q2-phase2-smoke/`, + `/tmp/q2-phase3-smoke/`) unchanged — now also carry a + `page-navigation` strip when appropriate, but sidebar/navbar + output is otherwise pixel-identical. + +### Snapshot tests + +None in Phase 4 — inline asserts cover the vocabulary (same choice +Phase 2 and Phase 3 made). + +## Work items (checklist) + +### Preparation +- [ ] Re-read `claude-notes/instructions/testing.md`, `coding.md`, + `review.md`. +- [ ] Confirm user agreement with Decisions 1–9. **DONE 2026-04-24.** +- [ ] Create `bd` issue `Phase 4 — Page navigation (prev/next)` + (new id), parent `bd-0tr6`, parent-child dependency linked. +- [ ] Commit directly on `feature/websites` (Phase 1/2/3 precedent). + +### `PageNavigation` data model (`quarto-navigation/src/page_nav.rs`) +- [x] New module `page_nav.rs` with struct + `from_config_value` / + `to_config_value` / `is_empty`. +- [x] `lib.rs` re-exports `PageNavigation`. +- [x] Tests 1–3 (all 3 passing). + +### Sidebar flattening (`quarto-navigation/src/sidebar.rs`) +- [x] Added `pub enum FlatEntry { Item(NavigationItem), Separator }` + with `is_link_with_href` helper. +- [x] `pub fn flatten_for_page_nav(&[SidebarEntry]) -> Vec<FlatEntry>` + depth-first + dedupe-by-href + separator preservation per + Decision 4. Local `is_external_href` keeps `quarto-navigation` + free of `quarto-core` dep; semantics match the shared helper. +- [x] Tests 4–12 (+ 1 bonus `is_link_with_href` sanity test). All 100 + quarto-navigation tests pass. + +### HTML renderer (`quarto-navigation/src/render_html.rs`) +- [x] `pub fn page_navigation_to_html(&PageNavigation) -> String` + emitting Q1-matching markup per Decision 6. Empty-side wrappers + always emitted; aria-label falls back to href when text is + empty. +- [x] Tests 13–18 (all 6 passing). 106/106 quarto-navigation tests + pass. + +### `PageNavGenerateTransform` (`quarto-core/src/transforms/page_nav_generate.rs`) +- [x] New module. Skip conditions per Decision 5. +- [x] Reads `navigation.sidebar` via `Sidebar::from_config_value`, + applies `flatten_for_page_nav`, finds current page, picks + neighbors via `neighbor_before` / `neighbor_after` (Separator + → None). +- [x] `mod.rs` re-export. Pipeline registration deferred to Task 7. +- [x] Tests 19–30 (12 from plan + 1 bonus separator variant covering + "neighbor remains on the unblocked side"). 13 passing. + +### `PageNavRenderTransform` (`quarto-core/src/transforms/page_nav_render.rs`) +- [x] New module. Skip conditions symmetric to Generate. +- [x] Rewrites hrefs via shared `resolve_href_for_html` with + `source_label = "Page navigation"`. +- [x] Stores HTML at `rendered.navigation.page_navigation`. +- [x] `mod.rs` re-export. +- [x] Tests 31–38 (8 from plan + 1 bonus visible-span text check). + All 9 passing. + +### Pipeline wiring (`quarto-core/src/pipeline.rs`) +- [x] Inserted `PageNavGenerateTransform::new()` immediately after + `SidebarGenerateTransform` (with comment explaining the ordering + dependency). +- [x] Inserted `PageNavRenderTransform::new()` immediately after + `SidebarRenderTransform`. + +### Template slot (`quarto-core/src/template.rs`) +- [x] Added `$if(rendered.navigation.page_navigation)$ …$endif$` block + inside `<main>`, after `$body$`, before `</main>`. +- [x] Updated template doc-block listing. +- [x] `cargo build --workspace` clean; all 1156 quarto-core tests + pass after wiring (no regressions). + +### Integration tests (`quarto-core/tests/page_navigation_pipeline.rs`) +- [x] Tests 39–44 written and passing on first run. Use the same + `ProjectContext::discover` / `ProjectPipeline::run` helper + shape as `sidebar_pipeline.rs`. 6/6 tests pass. + +### CLI end-to-end + regression +- [x] Smoke fixture `/tmp/q2-phase4-smoke/` — three-page sidebar. + Observed HTML on each page (per CLAUDE.md §End-to-end + verification): + * **index.html** (first page): empty `nav-page-previous` div, + next `<a href="about.html" … aria-label="About">About</a>` + with right-arrow icon. + * **about.html** (middle): prev → + `<a href="index.html" … aria-label="Home">Home</a>` with + left-arrow; next → `<a href="docs.html" … aria-label="Documentation">Documentation</a>` + with right-arrow. + * **docs.html** (last): prev → + `<a href="about.html" … aria-label="About">About</a>` with + left-arrow, empty `nav-page-next` div. + * Bare-path entries enriched with profile titles ("Home", + "About", "Documentation") via Phase 2 / shared + `enrich_navigation_items` machinery. +- [x] Smoke fixture `/tmp/q2-phase4-separator-smoke/` — separator + boundary `[a, ---, b, c]`. Observed: + * **a.html**: separator-as-next, no prev → strip skipped + entirely (lonely page). + * **b.html**: prev empty (separator), next → `c.html`. + * **c.html**: prev → `b.html`, next empty. + Confirms Decision 4 separator semantics end-to-end. +- [x] Re-ran `/tmp/q2-phase2-smoke/` + `/tmp/q2-phase3-smoke/` after + Phase 4 wiring. Sidebar (5 navbar elements + 1 footer) and + Phase 3 active-class behavior unchanged. Page-nav now appears + on Phase-2-smoke pages because they have a sidebar — matches + the default-on contract. + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — 7797 tests pass, 195 skipped. + New tests added in Phase 4: 3 (PageNavigation roundtrip) + 11 + (sidebar flatten + FlatEntry sanity) + 6 (page-nav HTML render) + + 13 (page-nav generate) + 9 (page-nav render) + 6 (integration) + = **48 new tests**, all passing. +- [x] `cargo xtask lint` passes (628 files checked). +- [x] `cargo xtask verify --skip-hub-tests` end-to-end green — + Rust build + tests + fmt + clippy + lint + hub-client build + (incl. WASM) + trace-viewer build + trace-viewer tests, all 9 + steps clean. +- [x] **`br` upgrade to 0.1.45 unblocked bead operations.** The + newer release accepts the mixed `k-` / `bd-` prefix history + that the project's JSONL contains, so the v0.1.28 prefix- + enforcement error is gone. Phase 4 issue `bd-nwun` filed, + linked parent-child to `bd-0tr6`, marked `in_progress`, then + closed with a reason citing commit `4a59a9dd` and the + follow-up bead IDs. +- [x] **Follow-ups filed** (each `discovered-from:bd-nwun`): + * `bd-q1pe` — Emit `<link rel="prev/next">` meta tags for + page-navigation (Decision 7 defer). + * `bd-xwq8` — Suppress page-nav for `page-layout: custom` + pages (Q1 parity). + * `bd-q6ky` — Plain-text aria-label projection for rich + titles (rides with rich-title support in + `DocumentProfile`). + * `bd-bobp` — Index-forgiveness for page-source matching + (mirrors Phase 3's `bd-jbml`). + * `bd-nf50` — *(epic-wide, related to `bd-tr81`)* Page- + navigation rules need user-facing docs in the Q2 docs + site (Decision 9). +- [x] Updated the epic plan's "Work items" checklist — Phase 4 marked + done, sub-plan linked, `bd-nwun` referenced. +- [x] Added the documentation reminder to the epic plan's + "Epic-wide follow-ups surfaced by sub-plans" section. +- [x] `br close bd-nwun` — closed with reason citing `4a59a9dd`. +- [x] `.beads/issues.jsonl` updated by `br`; ready to commit. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** re-picking the sidebar in `PageNavGenerateTransform` + would duplicate logic and risk drift from the sidebar the user + sees. *Mitigation:* read `navigation.sidebar` (resolved, post-pick) + only. Zero re-picking. + +- **Risk:** flatten-order mismatch with Q1 would produce "wrong next + page" for sections with multi-level nesting. *Mitigation:* Test 12 + pins depth-first order against a handcrafted fixture reviewers can + eyeball; `flatten_items` in Q1 is also depth-first so the match is + natural. + +- **Risk:** dedupe-by-href drops a legitimately distinct entry when + two sidebar entries share an href with different `text`. + *Mitigation:* Q1 accepts the same risk; keeping first-occurrence + matches user expectations ("the top of the sidebar is the canonical + entry"). Revisit if a real site complains. + +- **Risk:** separators used as visual-only dividers (not intended as + hard boundaries) will surprise users. *Mitigation:* Q1 users have + lived with this semantics for years; matching is safer than + inventing. Document the boundary behavior in the docs site (epic + follow-up tied to Decision 9). + +- **Risk:** a stray `Auto` entry reaching Phase 4 after Phase 2/3 + expansion would be silent (per Decision 4). *Mitigation:* it + shouldn't happen (Auto expansion lives in + `SidebarGenerateTransform`, and `strip_auto` removes anything that + couldn't expand). Test 9 documents the defensive skip. An + assertion-failure alternative was considered and rejected — + Phase 4 shouldn't panic on upstream bugs, just not-render. + +- **Risk:** `page-navigation: false` at the project level not + flowing to doc-level via metadata merge. *Mitigation:* uses the + same `is_feature_disabled` path as sidebar/navbar/footer/toc — + already tested in Phase 2/3; Test 41 locks in the project-level + disable path. + +- **Risk:** single-doc users with no sidebar setting + `page-navigation: true` expecting *something* to appear. + *Mitigation:* Test 44 pins the no-sidebar-no-navigation contract; + surface in docs that page-navigation requires a sidebar. + +- **Risk:** HTML markup drift from Q1 breaks Q1 CSS reuse in Phase 5. + *Mitigation:* Test 18 pins the icon class names; Test 13/14 pin + the wrapper div / link classes; integration Test 39 inspects the + rendered strings for the exact Q1 class vocabulary. + +## Explicit non-goals for this phase + +- No `<link rel="prev">` / `<link rel="next">` in `<head>` (follow-up). +- No `usesCustomLayout` suppression (follow-up if a real page needs it). +- No `plainText` aria-label stripping (requires rich-title support). +- No changes to sidebar/navbar/footer transforms. Their outputs are + inputs to page-nav, not the other way around. +- No changes to `ProjectIndex`, `DocumentProfile`, or `ProjectType`. +- No book/manuscript-specific page-nav semantics (chapter numbering, + appendix handling). +- No CSS / JS (Phase 5). +- No sitemap / favicon / title prefix (Phase 7). +- No `quarto preview`-side behavior (separate epic). + +## Follow-up beads (to file at close-out) + +- **Head `<link rel>` for page-nav** — emit `<link rel="prev">` / + `<link rel="next">` in `<head>` when page-nav is active. Q1 does + this for SEO + browser preload. +- **`usesCustomLayout` suppression** — mirror Q1's check that hides + page-nav when a user page opts into `page-layout: custom`. +- **`aria-label` plain-text stripping** — once `DocumentProfile.title` + supports inline markup, add a plain-text projection for ARIA + labels. +- **Index-forgiveness for page source matching** — today page-nav + looks for `page_source == entry.href` (exact). If real content + hits `about/` vs `about/index.qmd` path-normalization drift, add + the same forgiveness Phase 3 filed as `bd-jbml` for navbar. +- *(epic-wide, cross-phase)* **Prev/next rules need dedicated user- + facing docs in the Q2 docs site** — dedupe, separator, section- + header-as-neighbor are all non-obvious. Tie to `bd-tr81`. + +## Decisions log (confirmed 2026-04-24) + +1. **Config placement** stays top-level (`page-navigation: bool`). Not + under `website.`. Matches Q1 and Phase 3 "per-doc chrome at top". +2. **Pipeline position**: Generate after `SidebarGenerateTransform`; + Render after `SidebarRenderTransform`. No other ordering changes. +3. **Data model**: `PageNavigation { prev, next: Option<NavigationItem> }` + in `quarto-navigation`. Reuses existing item type + Phase 3 + helpers. +4. **Flatten algorithm**: depth-first; include internal Links / + Sections-with-href / Separators; skip Heading / Auto / externals; + dedupe by href; separators break adjacency. Matches Q1. +5. **Default behavior**: on whenever a sidebar applies and at least + one neighbor exists. Silent no-op otherwise. Top-level + `page-navigation: false` disables. +6. **Render output**: Q1-matching HTML (`nav-page-previous`, + `nav-page-next`, `pagination-link`, Bootstrap icons). Empty-side + wrappers still emitted. +7. **`<link rel>` meta tags**: deferred to follow-up. +8. **Template slot**: `$rendered.navigation.page_navigation$` inside + `<main>`, after `$body$`. +9. **Documentation note**: the flatten+dedupe+separator rules need a + dedicated docs section in `bd-tr81` work; carry as an epic-wide + follow-up reminder. + +## Epic-level impact + +Phase 4 completes the **user-visible** navigation surface for websites: + +- navbar (top) — Phase 3 +- sidebar (column) — Phase 2 +- prev/next strip (page bottom) — Phase 4 +- page-footer (site bottom) — Phase 3 + +After Phase 4, the **information architecture** for a website is +complete. What's left in the epic is **production plumbing**: shared +CSS/JS via `site_libs/` (Phase 5), cross-document body-link rewriting +(Phase 6), post-render artifacts like sitemap and favicon (Phase 7), +incremental rebuilds (Phase 8), and hub-client live preview (Phase 9). + +Phase 4 is the last "structural feature" phase; everything afterwards +is about making the structure ship-quality. diff --git a/claude-notes/plans/2026-04-24-websites-phase-5.md b/claude-notes/plans/2026-04-24-websites-phase-5.md new file mode 100644 index 000000000..478ba8f15 --- /dev/null +++ b/claude-notes/plans/2026-04-24-websites-phase-5.md @@ -0,0 +1,1190 @@ +# Phase 5 — Scoped artifact store + `site_libs/` + +**Date:** 2026-04-24 +**Beads:** `bd-u5pr` (closed). Follow-ups TBD at close-out. +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-24-websites-phase-4.md` +**Status:** Implementation complete 2026-04-24. All 7827 workspace +tests pass; `cargo xtask verify` (full, incl. WASM) green. + +## Goal of this phase + +Give `ArtifactStore` entries a **scope** (per-page vs. +project-shared) and teach the output writer to route them +accordingly. In a website project, project-scoped artifacts go to a +single `_site/site_libs/` tree, deduplicated across pages; in a +single-doc project, everything continues to resolve under +`{stem}_files/` so nothing about today's single-doc behavior changes. + +Concretely: + +1. Add `ArtifactScope { Page, Project }` and attach it to every + `Artifact`. Default = `Page`. Every existing producer gets + `Page` on day one — **pure refactor**, no user-visible change. +2. Introduce a **project-level artifact store** on `ProjectContext` + (`project_artifacts: ArtifactStore`). Between Pass-2 per-doc + renders, the orchestrator **drains** `Project`-scoped artifacts + from the per-doc `StageContext.artifacts` into the project store + (with dedup / consistency check). +3. Introduce a **resolver** that turns `(scope, artifact_path, + current_page)` into an HTML-side URL. This is the piece + `ApplyTemplateStage` and the final writer consume. The resolver + knows the project layout (site root, lib dir, per-page output + path) and computes the right `../site_libs/...` prefix. +4. Flip producers to the right scope: + - `CompileThemeCssStage` → `Project` scope (theme CSS is shared + across pages in a website; identical on a single-doc render, + which treats Project = Page). + - `store_html_dependencies()` (extension CSS/JS from Lua filters + / shortcodes) → `Project` scope. + - Any *future* engine-generated image / plot → `Page` scope + (none exist yet; note the contract in code). +5. Wire it through `WebsiteProjectType::post_render` so the + project-scoped artifacts flush once to `_site/site_libs/`. +6. Keep single-doc / default-project behavior **byte-identical** — + the scope machinery resolves `Project` to the same + `{stem}_files/` layout when there's only one page. + +This phase does **not** implement: + +- **Vendoring of Bootstrap / `quarto-html` JS / `quarto-nav.js`** + as standalone assets. Theme CSS (our SCSS pipeline output) is the + only CSS artifact today, and there are no JS producers beyond + extension dependencies. Bootstrap is embedded in the compiled + theme CSS via the existing theme pipeline. If a later phase adds + JS bundles (e.g. navbar collapse JS from `bd-9m8p`), they slot + into the scope machinery built here. +- **Cross-document link rewriting** in body content — that's + Phase 6. Phase 5 only touches `<link>` and `<script>` tags in + `<head>` (which are template substitutions, not body transforms). +- **Incremental re-use of `site_libs/` artifacts across project + runs** — that's Phase 8. Phase 5 rewrites the directory on every + build. +- **Per-page resource scope for engine outputs** (figures, cached + plots). The contract exists from day one, but there's no + producer to verify it until an engine phase fills that seat. +- **`project.lib-dir:` config override.** Phase 5 hardcodes the + name via `ProjectType::lib_dir()` (`"site_libs"` for website, + `"{stem}_files"` for default). Exposing the override is a + follow-up. + +## Reference material + +- **Parent epic plan** §"Phase 5 — Scoped artifact store and + `site_libs/`" and §"Architecture sketch / Artifact store scoping + and relocation". +- **Q2 current code:** + - `crates/quarto-core/src/artifact.rs` — `Artifact`, + `ArtifactStore` today. Path is `Option<PathBuf>` relative to + the per-page resource dir; we'll add `scope` alongside. + - `crates/quarto-core/src/stage/stages/compile_theme_css.rs` — + the only non-Lua producer of `css:default`. Stores with + `.with_path(DEFAULT_CSS_ARTIFACT_PATH)`. + - `crates/quarto-core/src/dependency.rs` + (`store_html_dependencies`) — producer for extension CSS/JS + artifacts keyed `css:<name>:<file>` / `js:<name>:<file>`. + - `crates/quarto-core/src/stage/stages/apply_template.rs:154-183` + — **consumer**. Builds `css_paths` / `script_paths` for the + template by iterating `get_by_prefix("css:")` / `("js:")` and + prepending `self.config.resource_prefix`. This is the main + integration point. + - `crates/quarto-core/src/render_to_file.rs:219-279` — + **writer**. Computes `resource_prefix = format!("{}_files/", + output_stem)`, calls `prepare_html_resources` (which creates + `{stem}_files/`), writes `css:default` to + `{stem}_files/styles.css`, then iterates remaining `css:*` / + `js:*` artifacts and writes each to + `resource_paths.resource_dir.join(path)`. + - `crates/quarto-core/src/project/mod.rs:49-54` — + `default_output_dir`: website → `dir.join("_site")`, others + → `dir`. + - `crates/quarto-core/src/project/orchestrator.rs:78-155` — + `ProjectType` trait (no `lib_dir` yet), `DefaultProjectType`, + `WebsiteProjectType`, `project_type_for`. Trait methods are + already `async_trait(?Send)`. + - `crates/quarto-core/src/project/orchestrator.rs:229-361` — + `ProjectPipeline::run` / `pass_one` / `pass_two`. The place + to thread the per-doc → project artifact drain. + - `crates/quarto-core/src/pipeline.rs:83-100` — + `HtmlRenderConfig { css_paths, resource_prefix }`. Phase 5 + replaces the single-string `resource_prefix` with a richer + resolver context. + - `crates/quarto-core/src/resources.rs` — + `prepare_html_resources`, `resource_dir_name(stem) = + "{stem}_files"`. Centralized today. +- **Q1 reference:** + - `external-sources/quarto-cli/src/project/types/website/website.ts:111` + — `libDir: "site_libs"`. + - `external-sources/quarto-cli/src/project/types/book/book.ts:114` + and `.../manuscript/manuscript.ts:136` — same `libDir`. + - `external-sources/quarto-cli/src/project/project-context.ts:292-297` + — project-type `libDir` default flows into `projectConfig.project[kProjectLibDir]`. + - Observed Q1 output shape for a rendered website: + ``` + _site/ + index.html + about.html + docs/api.html + site_libs/ + quarto-html/ + quarto.min.css + quarto.min.js + quarto-html.css (theme CSS lives here) + bootstrap/ + bootstrap.min.css bootstrap-icons.css … + quarto-nav/ + quarto-nav.js + clipboard/ + clipboard.min.js + docs/api_files/ ← per-page engine outputs only + ``` + Our MVP produces a subset of this tree: Phase 5 only emits the + artifacts that our producers actually generate today — theme + CSS (landing at `site_libs/quarto/styles.css`, see Decision 5) + and extension deps (at `site_libs/libs/{name}/{file}`). + +## Key decisions (to confirm with user) + +These are proposed — please push back on anything that looks wrong +before we start. + +### Decision 1 — `ArtifactScope` is a field on `Artifact` + +Add `pub scope: ArtifactScope` to `Artifact` with `Default == +ArtifactScope::Page`: + +```rust +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum ArtifactScope { + #[default] + Page, + Project, +} +``` + +Producers tag at creation (`.with_scope(ArtifactScope::Project)`). +Consumers / writers branch on scope. + +**Rationale.** One field, one place to decide. Alternative +considered: two separate stores (`ArtifactStore` per scope). +Rejected because every consumer (ApplyTemplate, writer) would need +to traverse both, and the keys collide semantically (same namespace +`css:*`). One store + scope tag keeps the API flat. + +### Decision 2 — Per-doc render returns its drained store; orchestrator merges sequentially + +The orchestrator (`ProjectPipeline`) owns a project-wide artifact +store, distinct from the per-document `StageContext.artifacts`: + +```rust +pub struct ProjectPipeline<'a> { + // existing fields … + project_artifacts: ArtifactStore, // NEW +} +``` + +**Implementation note (added during implementation):** an earlier +draft put this field on `ProjectContext`. That would force a +mechanical refactor of ~130 struct-literal sites across the +workspace. Putting it on `ProjectPipeline` is strictly better: +- Workers (Pass-2 per-doc renders) never see the field, so they + can't accidentally touch it. Reinforces Decision 2's + parallelism contract. +- `ProjectContext` stays "what's needed to render a doc" — stable + across Pass-2. Project-level *transient* state (artifact + accumulator, output summaries) lives on the orchestrator. +- Test fixtures that build `ProjectContext` literals are + unchanged. + +**Parallelism contract** (locked in now to avoid a foreseeable +redesign): each Pass-2 render is **stateless** with respect to the +project artifact store. A worker rendering `intro.qmd` produces a +per-doc `StageContext.artifacts` that already separates Page from +Project scope (via the scope tag). When that worker finishes, it +returns its **drained Project-scoped artifacts** as a value +alongside the `RenderToFileResult`: + +```rust +fn render_document_to_file(…) -> Result<(RenderToFileResult, ArtifactStore)> +// ^^^^^^^^^^^^^^^ +// drained Project-scoped artifacts +``` + +The orchestrator merges these returned stores into +`project.project_artifacts` **after** the worker returns, in the +single-threaded join section. No worker ever touches +`project.project_artifacts` directly. + +This shape: + +- Composes cleanly with sequential Pass-2 today. +- Composes cleanly with `rayon` / `pollster-per-worker` parallelism + tomorrow — each worker writes only to its own stack, the merge + is a sequential reduce. +- Keeps the byte-equality check (D3) in the merge step, where + there's no contention and no lock. + +Drain operation (in the merge step): + +```rust +fn merge_into_project( + drained: ArtifactStore, + project: &mut ArtifactStore, +) -> Result<()> { + for (key, artifact) in drained.into_iter() { + if let Some(existing) = project.get(&key) { + // Two docs produced the same project-scoped key; + // require byte-equality. Mismatch = hard error. + if existing.content != artifact.content { + return Err(…); // Decision 3 + } + } else { + project.store(key, artifact); + } + } + Ok(()) +} +``` + +**Rejected alternatives:** + +- `Arc<Mutex<ArtifactStore>>` shared across workers. Lock + contention is low in practice, but introduces a synchronization + point on what should be an embarrassingly-parallel render. +- Each worker writes its `site_libs/` contributions directly to + disk. Defeats dedup, races on write, and ties Pass-2 to a + filesystem (bad for the hub-client VFS path). + +**Memory bound.** Drain happens immediately as each Pass-2 render +returns — peak extra memory ≈ (max parallelism) × (one doc's +Project-scoped artifact bytes). For a website with a 200 KB theme +CSS and 8 workers, that's ~1.6 MB held during the wave. Trivial. + +### Decision 3 — Dedupe policy: byte-equal content wins, mismatch is an error + +When two docs emit the same key with different bytes (say, two +versions of `css:libs:kbd:kbd.css`), we fail the render with a +clear diagnostic naming both docs. No "last-writer-wins" silent +overwrites. + +**Why this is safe under the keying scheme (Decision 9 below):** +keys identify the asset (`css:theme:<fingerprint>`, +`css:libs:<extension>:<file>`), not just the role. Two docs using +identical theme inputs produce identical fingerprints → identical +keys → identical bytes → byte-equality check passes → one entry +kept. Two docs using *different* themes produce different keys → +both coexist. A byte mismatch under the same key means the same +asset name is being produced from different inputs, which is +genuinely a user-visible bug (e.g. an extension vendoring two +incompatible versions of the same file under the same name). + +**Performance cost.** The check is a `Vec<u8>` `==` per drained +Project artifact per doc. For a 100-doc website with a 200 KB +theme CSS plus a few extension deps, worst case is ~100 × ~250 KB += ~25 MB of byte comparisons total across the entire build, all +against already-hot cache lines. This is negligible relative to +the engine execution and SCSS compilation that dominate render +time. No pre-optimization warranted. + +**If profiling later shows the equality dominates** (unlikely), +we can add a content-hash field to `Artifact` populated at +producer time and compare hashes only. Drop-in replacement; not +worth doing now. + +### Decision 4 — Add `fn lib_dir(&self) -> String` to `ProjectType` + +Owned `String` return — not `&'static str` — because the +follow-up `project.lib-dir:` user-config override (already filed +as a follow-up bead in §"Follow-up beads") will read the value +out of `ProjectContext.config`. A `'static` return would force a +later API change; owned `String` lets us swap implementations +without touching callers. + +```rust +pub trait ProjectType { + fn kind(&self) -> ProjectKind; + fn lib_dir(&self) -> String; // NEW (owned) + // existing async hooks … +} + +impl ProjectType for DefaultProjectType { + fn lib_dir(&self) -> String { String::new() } +} + +impl ProjectType for WebsiteProjectType { + fn lib_dir(&self) -> String { "site_libs".to_string() } +} +``` + +The cost of an extra heap allocation per project render is +irrelevant — `lib_dir()` is called O(docs) times per build, and +the resolver caches the result anyway. When the override lands, +the implementation reads `config.metadata.get("project.lib-dir")` +without touching the trait signature. + +`DefaultProjectType::lib_dir()` returns the empty string — +default projects have no separate lib dir; everything resolves +under `{stem}_files/` via the resolver's single-doc shortcut. +The trait method is only consulted when a project actually has a +multi-doc shared layout (Website, eventually Book / Manuscript). + +### Decision 5 — `site_libs/` subdirectory layout (MVP subset) + +Artifacts resolve under `site_libs/` like this: + +| Artifact key | MVP on-disk path | +|------------------------------|----------------------------------------------------| +| `css:default` | `site_libs/quarto/styles.css` | +| `css:<name>:<file>` | `site_libs/libs/<name>/<file>` | +| `js:<name>:<file>` | `site_libs/libs/<name>/<file>` | + +Rationale: + +- **`site_libs/quarto/styles.css`**: keeps the theme CSS bundled + under a namespace we control. Q1 uses + `site_libs/quarto-html/quarto-html.css`; we're not splitting + `quarto-html/quarto.min.css` out of the theme anyway, so a + single `quarto/styles.css` is cleaner. If future phases vendor + `quarto.min.js`, add `site_libs/quarto/quarto.min.js` next to + it. (The exact subdirectory name is the least-load-bearing bit + of this plan — happy to pick whatever name the user prefers.) +- **`site_libs/libs/<name>/<file>`**: the extension-deps subtree + mirrors Q1's layout and preserves the artifact's existing + `path` shape (`libs/<name>/<file>`). We just re-root it under + `site_libs/` instead of `{stem}_files/`. + +Single-doc / default project: both resolve to `{stem}_files/` per +today's layout. No visible change. + +### Decision 6 — Replace `HtmlRenderConfig.resource_prefix: &str` with a resolver context + +Today `resource_prefix` is a single string like `"test_files/"` +that `ApplyTemplateStage` prepends to every artifact path. This +assumption breaks as soon as a page lives at `docs/api.html` and +needs `../site_libs/...`. + +Proposed replacement: + +```rust +pub struct ResourceResolverContext { + /// Absolute output path of the current page (e.g. "_site/docs/api.html"). + pub page_output: PathBuf, + /// Site root (e.g. "_site/"), i.e. where `site_libs/` lives. + pub site_root: PathBuf, + /// Name of the project lib dir (from `ProjectType::lib_dir()`). + pub lib_dir: &'static str, + /// Per-page fallback (e.g. "api_files"), used for Page-scoped artifacts. + pub page_files_dir: String, +} + +impl ResourceResolverContext { + pub fn html_url_for(&self, scope: ArtifactScope, artifact_path: &Path) -> String { … } + pub fn on_disk_path_for(&self, scope: ArtifactScope, artifact_path: &Path) -> PathBuf { … } +} +``` + +`ApplyTemplateStage` takes this instead of the bare `resource_prefix` +string. The final writer in `render_to_file.rs` (well, what's left +of it after Phase 5) consults `on_disk_path_for` for per-doc write, +or defers the write to the project orchestrator for `Project` scope. + +Backwards compat for callers that don't care about the +single-string shortcut: we keep a small convenience +`ResourceResolverContext::single_doc(output_path)` helper that +reproduces today's behavior. + +### Decision 7 — URL resolution at template-apply time; disk write split per-scope + +This decision is the most subtle one in the phase, so it spells +out two separable concerns explicitly: + +| Concern | Where it happens | Reads from | +|---------|-----------------|------------| +| `<link>` / `<script>` URL in rendered HTML | `ApplyTemplateStage` (per-doc, in-pipeline) | per-doc `StageContext.artifacts` (still has scope tags) | +| File at `_site/site_libs/...` on disk | `WebsiteProjectType::post_render` (once per project) | `project.project_artifacts` (drained from per-doc) | + +**No HTML inspection or post-render path-fixing is required.** The +risk you'd worry about — needing a Deno-dom-style HTML walker to +fix `<link>` paths after the fact — is avoided by construction: +when `ApplyTemplateStage` runs, the per-doc store still carries +all of that doc's artifacts with their scope tags attached. The +resolver translates `(scope, artifact_path, page_output_path)` into +the correct relative URL **before any HTML is emitted**: + +- Project-scoped `quarto/cosmo.css` for a page at `_site/index.html` + → `<link href="site_libs/quarto/cosmo.css">`. +- Project-scoped `quarto/cosmo.css` for a page at + `_site/docs/api.html` → `<link href="../site_libs/quarto/cosmo.css">`. +- Page-scoped `figure-html/fig-1.png` for any page → relative path + to that page's `{stem}_files/`. + +The drain into `project.project_artifacts` happens *after* +`ApplyTemplateStage` has already produced correct URLs. The drain +is purely about **on-disk write coordination** ("which file gets +written where, once"), not URL computation. + +**Concretely:** + +- After each Pass-2 doc's pipeline returns, + `render_document_to_file` writes the HTML and all **Page-scoped** + artifacts to `{stem}_files/` — same as today. +- **Project-scoped** artifacts are drained out of the per-doc + store and returned to the orchestrator (Decision 2), which + merges them into `project.project_artifacts`. +- `WebsiteProjectType::post_render` walks the project-level store + and writes everything under `_site/site_libs/`. Runs exactly + once per project render. Phase 7 hooks (sitemap, favicon) plug + in here too. +- For a `DefaultProjectType` single-doc render (the + `is_single_file` path), the drain still runs mechanically — but + the resolver, when constructed for a default project, has been + told `lib_dir == ""` so Project scope resolves under + `{stem}_files/`. The drained artifacts then have nowhere + project-shared to go; the per-doc writer treats them as if they + were Page-scoped (or, equivalently, the orchestrator flushes + the project store into `{stem}_files/` because that's what the + resolver says). Either implementation is fine; the user-visible + output is identical to today. + +**Format-specificity caveat (acknowledged):** `post_render` is +HTML-specific in that the asset layout it writes (`site_libs/...`) +only makes sense for HTML output. For non-HTML formats (PDF, +docx) the website epic doesn't yet have a story; when it does, +each format's `post_render` writes the layout that format needs. +But because URL rewriting happens at template-apply time (when +the producer's scope tag is still attached to the artifact), no +format ever needs to re-inspect its own output to fix paths. The +contract holds across formats. + +### Decision 8 — Diagnostic path: resolver vs. `source_label` + +When the resolver can't compute a relative path (malformed input +path, project not discovered), emit a diagnostic with +`source_label = "Resource resolver"` — mirrors +Phase 3's `"Sidebar"` / Phase 4's `"Page navigation"` convention +for `navigation_href::resolve_href_for_html`. This is for the +Phase 6 link-rewriter to share later. + +### Decision 9 — Theme CSS keyed by content fingerprint; retire `css:default` + +`css:default` was a singleton key, which works for one-doc-one- +theme but breaks the moment a website mixes themes (e.g. doc A +`theme: cosmo`, doc B `theme: darkly`). Q1 hit this exact issue +and resolved it by hash-suffixing CSS dependency names; we adopt +the same pattern from the start. + +`CompileThemeCssStage` produces: + +- **Key**: `css:theme:<fingerprint>` where `<fingerprint>` is a + short hash of all SCSS-compilation **inputs** for that doc: + - the resolved theme name(s) (`cosmo`, `darkly`, …), + - any user-added SCSS layers / files declared in metadata + (Q1 supports `theme: [cosmo, custom.scss]` and additional + SCSS via `format.html.theme.brand` / `theme.scss`; Q2 will + eventually too), + - the Bootstrap version baked into our pipeline, + - any theme-affecting variables resolved from merged metadata. +- **Path**: `quarto/quarto-theme-<fingerprint>.css`. +- **Scope**: `Project`. + +Behavior under your three-doc example: + +| Doc | Theme inputs | Fingerprint | Outcome | +|-----|--------------|-------------|---------| +| `intro.qmd` | `cosmo` | `abc123` | First sighting; stored. | +| `methods.qmd` | `cosmo` | `abc123` | Same key + same bytes; dedup, one entry. | +| `appendix.qmd` | `darkly` | `def456` | Different key; coexists. | + +Output: +``` +_site/site_libs/quarto/quarto-theme-abc123.css ← cosmo +_site/site_libs/quarto/quarto-theme-def456.css ← darkly +``` + +Each doc's `<link>` resolves to its own fingerprint at template- +apply time (because `ApplyTemplateStage` sees only its own +artifact during its pipeline run). + +**The `css:default` constant goes away.** Its sole role was as a +sentinel for "the doc's theme CSS"; now there's no sentinel — +the doc has a themed CSS artifact with a real, content-derived +key, and the writer treats it identically to any other Project- +scoped CSS artifact. + +**Hash inputs must be stable.** The fingerprint is a hash over a +canonical serialization of the inputs (sorted, normalized +whitespace where applicable). Implementation will pick a concrete +hash (likely `xxh3` or `blake3`) and a serialization scheme. +Stable across Quarto versions is *not* required (CSS bundling can +change between releases); stable across runs of the same Quarto +version *is* required (same inputs → same fingerprint → dedup +works). + +**WASM impact.** `DEFAULT_CSS_ARTIFACT_PATH` is the synthetic URL +the WASM path uses for the in-memory theme CSS. With `css:default` +gone, WASM consumers need to: (a) iterate `css:theme:*` artifacts +to find the doc's theme CSS, or (b) keep the synthetic URL as a +hub-client-side convention pointing at "whatever theme CSS this +doc has". The audit task in §"Work items / WASM impact check" +covers the migration. + +### Decision 10 — Single-doc behavior is locked to byte-identical + +A **regression test in Phase 5** renders a single-doc fixture end- +to-end (same fixture used in Phase 2/3/4 smokes) and asserts +every byte of the generated HTML / CSS / extension-dep file is +identical to a pre-Phase-5 baseline snapshot. We capture the +baseline first, commit it, then refactor underneath. + +**Rationale.** The #1 risk the epic plan calls out for Phase 5 is +that the refactor regresses single-doc rendering. A pixel-identity +test is cheaper than a review and more durable than a unit test. + +## Architecture sketch + +### Producer changes + +```diff + // CompileThemeCssStage ++let fingerprint = theme_fingerprint(&theme_inputs); // see Decision 9 ++let key = format!("css:theme:{fingerprint}"); ++let path = format!("quarto/quarto-theme-{fingerprint}.css"); + ctx.artifacts.store( +- "css:default", ++ key, + Artifact::from_string(theme_css, "text/css") +- .with_path(PathBuf::from(DEFAULT_CSS_ARTIFACT_PATH)), ++ .with_path(PathBuf::from(path)) ++ .with_scope(ArtifactScope::Project), + ); +``` + +```diff + // store_html_dependencies + ctx.artifacts.store( + format!("css:{name}:{filename}"), + Artifact::from_bytes(content, "text/css") +- .with_path(PathBuf::from(format!("libs/{name}/{filename}"))), ++ .with_path(PathBuf::from(format!("libs/{name}/{filename}"))) ++ .with_scope(ArtifactScope::Project), + ); +``` + +Everything else stays `ArtifactScope::Page` by default. + +### Consumer changes (ApplyTemplateStage) + +```diff +-let prefix = &self.config.resource_prefix; + for (key, artifact) in ctx.artifacts.get_by_prefix("css:") { +- if key == "css:default" { continue; } + if let Some(path) = &artifact.path { +- css_paths.push(format!("{}{}", prefix, path.to_string_lossy())); ++ css_paths.push(resolver.html_url_for(artifact.scope, path)); + } + } +``` + +Note that the `css:default` skip goes away with the +fingerprinted-theme keying (Decision 9): every CSS artifact — +including the doc's own theme CSS — flows through the same +resolver path. The CSS-paths list output by `ApplyTemplateStage` +no longer needs a synthetic "default" placeholder. + +(Resolver stored on `StageContext` or passed via `ApplyTemplateConfig`.) + +### Writer changes (render_to_file) + +```diff +-// Write extension CSS/JS dependency artifacts (e.g., libs/kbd/kbd.css) +-for (key, artifact) in ctx.artifacts.iter() { +- if key == "css:default" { continue; } +- … +- let output_path = resource_paths.resource_dir.join(path); +- … +-} ++// Write Page-scoped artifacts per-doc. Project-scoped artifacts ++// are drained into project_artifacts (see orchestrator) and ++// flushed once in post_render. ++for (key, artifact) in ctx.artifacts.iter() { ++ if artifact.scope == ArtifactScope::Project { continue; } ++ if !(key.starts_with("css:") || key.starts_with("js:")) { continue; } ++ let Some(path) = &artifact.path else { continue; }; ++ let output_path = resolver.on_disk_path_for(ArtifactScope::Page, path); ++ runtime.file_write(…, &artifact.content)?; ++} +``` + +### Orchestrator changes + +```diff + // ProjectPipeline::pass_two + for doc_info in &self.project.files { + match render_document_to_file(…) { +- Ok(result) => outputs.push(result), ++ Ok((result, drained)) => { ++ // Sequential merge — workers never touch project state. ++ // Composes with future rayon-per-worker parallelism: each ++ // worker's `drained` is private until merge. ++ merge_into_project( ++ drained, ++ &mut self.project.project_artifacts, ++ )?; ++ outputs.push(result); ++ } + … + } + } +``` + +`render_document_to_file` returns +`Result<(RenderToFileResult, ArtifactStore)>`. The second element +is the doc's drained Project-scoped artifacts; the orchestrator +merges them sequentially. The merge step is the *only* place that +holds `&mut self.project.project_artifacts`, satisfying the +parallelism contract from D2. + +### `WebsiteProjectType::post_render` body + +```rust +async fn post_render( + &self, + project: &ProjectContext, + _index: &ProjectIndex, + _outputs: &[RenderToFileResult], +) -> Result<()> { + let lib_root = project.output_dir.join(self.lib_dir()); + for (_key, artifact) in project.project_artifacts.iter() { + let Some(path) = &artifact.path else { continue; }; + let out_path = lib_root.join(path); + if let Some(parent) = out_path.parent() { + runtime.dir_create(parent, true)?; + } + runtime.file_write(&out_path, &artifact.content)?; + } + Ok(()) +} +``` + +Phase-7 hooks (sitemap, favicon) slot into this same method later. + +### Data flow summary + +``` +Per-doc pipeline ──► StageContext.artifacts (mixed scopes) + │ + ├── Page-scoped ──► writer emits + │ to {stem}_files/ + │ per-doc + │ + └── Project-scoped ──► drained into + ProjectContext + .project_artifacts + +After Pass 2 ──► WebsiteProjectType::post_render ──► walk project_artifacts + write each under _site/site_libs/… +``` + +## DocumentProfile change + +**None.** Phase 5 reshapes machinery beneath the pipeline stages; +the profile is unaffected. No `profile_version` bump. + +## Tests (TDD: write and fail first) + +### Unit tests — `ArtifactScope` + `Artifact.scope` + +1. `artifact_default_scope_is_page` — `Artifact::from_string(…).scope + == ArtifactScope::Page`. +2. `artifact_with_scope_builder` — `.with_scope(Project)` sets scope + without touching content/path. +3. `artifact_scope_round_trips_through_store` — store/get preserves + scope. + +### Unit tests — `ResourceResolverContext` + +4. `resolver_single_doc_html_url_matches_today` — with + `site_root == page_output.parent()` and + `page_files_dir == "doc_files"`, resolving `Page`-scoped + `libs/kbd/kbd.css` returns `"doc_files/libs/kbd/kbd.css"`. +5. `resolver_single_doc_project_scope_falls_back_to_page_files` — + Project scope in a `DefaultProjectType` also resolves under + `{stem}_files/` (the "single-doc = no separation" invariant). +6. `resolver_website_root_page_project_scope` — page at + `_site/index.html`, Project-scope `quarto/styles.css` → URL + `"site_libs/quarto/styles.css"`. +7. `resolver_website_nested_page_project_scope` — page at + `_site/docs/api.html`, Project-scope `quarto/styles.css` → URL + `"../site_libs/quarto/styles.css"`. +8. `resolver_website_deeply_nested_page` — `_site/a/b/c/d.html` → + `"../../../site_libs/quarto/styles.css"`. +9. `resolver_on_disk_path_project_scope` — Project-scope + `libs/kbd/kbd.css` resolves on disk to + `<site_root>/site_libs/libs/kbd/kbd.css`. +10. `resolver_on_disk_path_page_scope` — Page-scope + `figure-1.png` resolves to + `<site_root>/<page_files_dir>/figure-1.png`. + +### Unit tests — drain + merge + +11. `drain_returns_only_project_scoped` — per-doc store with 1 + Page + 1 Project entry: drain returns the Project one, + leaves the Page in the per-doc store. +12. `merge_dedupes_byte_equal_keys` — merge two drained stores + with same key + same bytes: project store has one entry; + second merge is a no-op. +13. `merge_errors_on_byte_mismatch` — merge two drained stores + with same key + different bytes: returns `Err(…)` naming the + key. +14. `drain_preserves_artifact_metadata_path` — roundtrip through + drain + merge keeps `path`, `content_type`, `metadata`. + +### Unit tests — theme fingerprint + +15a. `fingerprint_stable_for_identical_inputs` — same theme name + + same SCSS layers → same fingerprint across runs. +15b. `fingerprint_differs_for_different_themes` — `cosmo` vs. + `darkly` → different fingerprints. +15c. `fingerprint_differs_for_added_scss_layer` — `cosmo` alone + vs. `cosmo` + custom user SCSS → different fingerprints. +15d. `fingerprint_input_canonicalization` — list ordering / + whitespace differences in the input metadata that *should* + produce the same theme produce the same fingerprint. + +### Unit tests — `ProjectType::lib_dir` + +15. `website_project_type_lib_dir_is_site_libs` — owned `String`, + value `"site_libs"`. +16. `default_project_type_lib_dir_is_empty` — owned `String`, + empty value. + +### Integration tests — `crates/quarto-core/tests/` + +New file `artifact_scoping_pipeline.rs`: + +17. `single_doc_render_unchanged_under_scope_refactor` — + regression snapshot. Render `phase5-single-doc-fixture/doc.qmd` + and diff every generated file byte-for-byte against a + pre-refactor baseline captured into the test fixture. **This + is the single most important test in Phase 5.** +18. `website_render_emits_site_libs_dir` — three-page website; + after render, `_site/site_libs/quarto/quarto-theme-<hash>.css` + exists with the expected theme CSS content. +19. `website_render_deduplicates_extension_css` — two pages each + reference an extension providing `libs/kbd/kbd.css`. Output has + exactly one file at `_site/site_libs/libs/kbd/kbd.css` with + that extension's bytes. +19b. `website_render_emits_two_themes_when_docs_differ` — three- + page website where `intro.qmd` and `methods.qmd` use + `theme: cosmo` and `appendix.qmd` uses `theme: darkly`. + Output has exactly two themed CSS files under + `_site/site_libs/quarto/` (one per fingerprint), each doc + links to the right one. Direct test of the + fingerprint-based dedup. +20. `website_nested_page_links_css_with_relative_path` — render a + website with `docs/api.qmd` → `_site/docs/api.html`. Inspect + the emitted HTML: `<link rel="stylesheet" + href="../site_libs/quarto/quarto-theme-<hash>.css">`. +21. `website_root_page_links_css_with_direct_path` — `index.qmd` → + `_site/index.html` with + `href="site_libs/quarto/quarto-theme-<hash>.css"`. +22. `website_merge_byte_mismatch_is_hard_error` — construct a + fixture where two docs would generate the *same* artifact key + with *different* bytes (e.g. via a custom transform). Render + fails with a diagnostic naming the key and both source docs. + (Note: under the fingerprint scheme this is hard to trigger + organically with theme CSS — different inputs produce + different keys, so the byte-equality check only fires on + genuinely-identical-key/different-bytes bugs. A focused + fixture is needed.) +23. `website_no_per_page_files_dir_when_no_page_artifacts` — + MVP contract: if a page has no Page-scoped artifacts, we do + not create an empty `{stem}_files/` for it (today's behavior + is "always create"; this is a small cleanup we can ship here, + or defer — see Open question 5). + +### CLI end-to-end (per CLAUDE.md §End-to-end verification) + +24. **Baseline capture** at `/tmp/q2-phase5-baseline/`: before any + code change, render Phase-4 smoke fixtures to disk, capture + `find /tmp/q2-phase5-baseline/ -type f` + sha256 of each + generated file. Store as a snapshot inside the test fixture. +25. **Post-refactor smoke** at `/tmp/q2-phase5-smoke/`: after the + refactor, re-render, diff against baseline. Expected diff for + the website fixture: files have moved from + `{stem}_files/styles.css` to `site_libs/quarto/styles.css`, + and `<link>` hrefs in HTML reflect that. Expected diff for the + single-doc fixture: zero — byte identical. +26. **Extension dep smoke**: render a website fixture whose + `_quarto.yml` loads a shortcode / Lua filter that pulls in an + HTML dependency (`kbd` is the canonical existing test + extension). Verify `_site/site_libs/libs/kbd/kbd.css` exists + and pages link to it via correct relative paths. +27. **Regression:** re-run `/tmp/q2-phase2-smoke/`, + `/tmp/q2-phase3-smoke/`, `/tmp/q2-phase4-smoke/`. Website + fixtures now emit `site_libs/`; sidebar / navbar / footer / + page-nav behavior is otherwise unchanged (snapshot the HTML + body content, ignore `<link>` hrefs in the diff). + +### Snapshot tests + +One new insta snapshot (or inline assertion) covering the exact +rendered `<link>` / `<script>` block for a nested-page website +render. This pins the relative-path computation against +regressions. + +## Work items (checklist) + +### Preparation +- [x] Re-read `claude-notes/instructions/testing.md`, `coding.md`, + `review.md`. +- [x] Confirm user agreement with Decisions 1–10. **DONE + 2026-04-24** — D2/D3/D4/D7/D9 revised mid-conversation + based on user feedback; user approved revisions. +- [x] Create `bd` issue `Phase 5 — Scoped artifact store + + site_libs/`, parent `bd-0tr6`, parent-child dependency + linked. (`bd-u5pr`.) +- [x] Commit directly on `feature/websites` (Phase 1/2/3/4 + precedent). + +### Baseline capture (before any code change) +- [x] Add single-doc fixture under + `crates/quarto-core/tests/fixtures/phase5-single-doc-baseline/` + + `expected_hashes.txt` capturing the pre-refactor sha256s + (commit `7881178e`). +- [x] Add website fixture + `crates/quarto-core/tests/fixtures/phase5-website-baseline/` + with `_quarto.yml` + 3 pages + `PRE_PHASE5_OUTPUT.md` + documenting the pre-/post-refactor layout shift. + +### Data model (`quarto-core/src/artifact.rs`) +- [x] `pub enum ArtifactScope { Page, Project }` + `Default`. +- [x] `Artifact.scope: ArtifactScope` field + `with_scope()` + builder. +- [x] `ArtifactStore` helpers: `project_scoped_keys()`, + `page_scoped_keys()`, `drain_project_scoped() -> ArtifactStore`, + `merge_into_project(other) -> Result<MergeStats, ArtifactMergeConflict>`. +- [x] Tests 1–3, 11–14 (all 7 passing). + +### Resource resolver (`quarto-core/src/resource_resolver.rs` — NEW) +- [x] `ResourceResolverContext` struct + `html_url_for` / + `on_disk_path_for` methods. +- [x] `single_doc(output_path, stem)` convenience constructor. +- [x] `website(site_root, page_output, lib_dir, page_stem)` + constructor. +- [x] **Bonus** `vfs_root(root)` constructor for the WASM + hub-client's synthetic-VFS-path convention (added during + task #13). +- [x] Tests 4–10 + 2 vfs_root tests (11 passing). + +### ProjectType extension (`quarto-core/src/project/orchestrator.rs`) +- [x] Add `fn lib_dir(&self) -> String` to trait (Decision 4). + Owned `String` per D4 revision (so the future user-config + override doesn't churn the trait signature). +- [x] `WebsiteProjectType::lib_dir` returns `"site_libs"`. +- [x] `DefaultProjectType::lib_dir` returns `""`. +- [x] Tests 15–16 (passing). + +### Project artifact store ownership +- [x] Add `project_artifacts: ArtifactStore` field on + `ProjectPipeline` (revised during implementation — + originally planned for `ProjectContext` but moved to the + orchestrator to keep `ProjectContext` immutable across + Pass-2 and avoid a 130-site mechanical refactor of struct + literals; matches D2's parallelism contract). +- [x] Drain from per-doc into project store in `pass_two`. The + per-doc `render_document_to_file` accepts an + `Option<&mut ArtifactStore>` argument: when `Some` AND the + project type has a non-empty `lib_dir()`, it merges drained + Project-scoped artifacts into the orchestrator's + accumulator; otherwise it flushes them via the resolver + (default-project / standalone-call paths). + +### Producer flips +- [x] `CompileThemeCssStage`: switch to fingerprinted key + `css:theme:<fingerprint>` (16-hex truncation of SHA-256 + over the compiled CSS bytes), scope `Project`. Path is + `quarto/quarto-theme-<fingerprint>.css` for multi-doc + projects and bare `styles.css` for single-doc (per + Decision 10's byte-identity requirement). +- [x] Hash function: SHA-256 (already a workspace dep via + `sha2`); 16 hex char truncation. No xxh3/blake3 needed. +- [x] `store_html_dependencies`: scope `Project`, path + unchanged (`libs/<name>/<file>`). Keys retain the + `css:<name>:<file>` / `js:<name>:<file>` shape from + Phase 4 — Phase 5 didn't need to renamespace them since + they don't collide with theme keys. +- [x] `DEFAULT_CSS_ARTIFACT_PATH` constant — kept (still used + by hub-client's vfs_root resolver argument). Retiring it + entirely would force a hub-client convention break that + isn't worth Phase-5 scope. + +### Consumer flip (`ApplyTemplateStage`) +- [x] Replaced `config.resource_prefix: String` / + `config.css_paths: Vec<String>` with + `config.resolver: Option<ResourceResolverContext>`. +- [x] Iterate artifacts, call `resolver.html_url_for(artifact.scope, + path)` for each. No `css:default` skip — the only theme + CSS keys are `css:theme:*` and they flow through the same + resolver path. +- [x] Sorted-key iteration so `<link>` / `<script>` order is + deterministic across runs. + +### Writer refactor (`render_to_file.rs`) +- [x] Dropped the special-case write of `css:default` (subsumed + into the general artifact loop via `write_artifacts`). +- [x] Per-doc render writes only Page-scoped artifacts via the + resolver. +- [x] Project-scoped artifacts are drained out of the per-doc + store and either: (a) merged into the orchestrator's + accumulator (real multi-doc projects), or (b) flushed + in-place via the resolver (default project / standalone + call). Branch chosen by `project_type.lib_dir().is_empty()`. + +### Orchestrator plumbing (`project/orchestrator.rs`) +- [x] After each per-doc Pass-2 render, the orchestrator's + accumulator receives the drained store via + `render_document_to_file`'s `Option<&mut ArtifactStore>` + parameter (cleaner than tuple-return; same effect). +- [x] Byte-mismatch produces an error naming the conflicting + key + lengths via `ArtifactMergeConflict`. The error + message is composed at the orchestrator boundary so the + user sees `"Project-scoped artifact merge failed for + <doc>: ..."`. +- [x] Sequential merge confirmed: no `Mutex`, no `Arc`, no + shared mutable state during Pass-2 — ready for future + rayon-per-worker (D2 contract holds). + +### Website post_render +- [x] `WebsiteProjectType::post_render` walks + `project_artifacts`, writes each to + `{output_dir}/{lib_dir}/{artifact.path}` via + `SystemRuntime::file_write`. Sorted-key iteration so the + on-disk write order is deterministic. +- [x] `DefaultProjectType::post_render` stays no-op. The + branching in `render_document_to_file` (driven by + `lib_dir().is_empty()`) ensures Project-scoped artifacts + get flushed via the resolver per-doc when no shared lib + dir exists, so post_render has nothing to do for default + projects. (Confirmed by `single_doc_render_unchanged...` + regression test.) + +### WASM / hub-client impact check +- [x] Audited `crates/wasm-quarto-hub-client/src/lib.rs` (two + callsites of `render_qmd_to_html`) and + `hub-client/src/services/wasmRenderer.ts` (the only + JavaScript consumer of `/.quarto/project-artifacts/styles.css`). +- [x] Hub-client now constructs `ResourceResolverContext::vfs_root("/.quarto/project-artifacts")` + and passes it via `HtmlRenderConfig::with_resolver`. The + browser-side TypeScript continues to read from + `/.quarto/project-artifacts/styles.css` because the WASM + writer routes every artifact through the same resolver + (path-on-disk == URL-in-HTML). +- [x] `cargo xtask verify` full (Rust build + tests + fmt + + clippy + lint + hub-client build incl. WASM + hub-client + tests + trace-viewer build/tests) — all 9 steps green. + +### Integration tests (`quarto-core/tests/artifact_scoping_pipeline.rs`) +- [x] Tests 17, 18, 19b, 20, 21 written and passing on first + run. Test 19 (extension-dep dedup) deferred — needs an + extension fixture that emits `css:libs:*` artifacts; + shape covered by the producer flip + drain unit tests. + Tests 22 (byte-mismatch hard error) and 23 (empty + `{stem}_files/` cleanup) deferred to follow-ups (see + §"Follow-up beads"). + +### CLI end-to-end + regression +- [x] Single-doc smoke at `/tmp/q2-phase5-singledoc-test/` + against the captured baseline: + * `doc.html` sha256 = `7026c8c5...` ✓ (matches baseline) + * `doc_files/styles.css` sha256 = `3536a93e...` ✓ (matches + baseline) +- [x] Website smoke at `/tmp/q2-phase5-website-test/` + (3-page fixture, root + 1 nested): + * Single shared `_site/site_libs/quarto/quarto-theme-3536a93eba680c9b.css` + (no per-page duplicates). + * `<link>` hrefs: + - `index.html` → `site_libs/quarto/quarto-theme-….css` + - `about.html` → `site_libs/quarto/quarto-theme-….css` + - `docs/api.html` → `../site_libs/quarto/quarto-theme-….css` + (correct relative depth) +- [x] Regression smokes: Phase 2 (`/tmp/q2-phase2-smoke/`), + Phase 3 (`/tmp/q2-phase3-smoke/`), Phase 4 + (`/tmp/q2-phase4-smoke/`) — sidebar / navbar / page-nav + output preserved; only the `<link>` href moved from + `<page>_files/styles.css` to + `site_libs/quarto/quarto-theme-….css`, exactly as + planned. + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — **7827 tests pass** (up + from 7820 pre-Phase-5; net +7 from Phase-5 work). +- [x] `cargo xtask lint` passes (part of `cargo xtask verify`). +- [x] `cargo xtask verify` (full, incl. WASM) — all 9 steps + green. +- [x] No snapshot files added or modified. +- [x] **Follow-ups filed** (each `discovered-from:bd-u5pr`): + * `bd-b9za` — Extension-dep `site_libs/` dedup + integration test (Phase-5 plan tests 19 / 22 deferred). + * `bd-78ud` — Empty `{stem}_files/` cleanup for pages + with no Page-scoped artifacts (Open question 5). + * `bd-apvo` — `project.lib-dir:` user-config override + (Decision 4 future-proofing pays off). + * `bd-vdl8` — Retire `DEFAULT_CSS_ARTIFACT_PATH` once + hub-client (Phase 9) moves off synthetic VFS paths. +- [x] Updated the epic plan's "Work items" checklist — + Phase 5 marked done, sub-plan linked, `bd-u5pr` + referenced; follow-up beads logged in the running + report section. +- [x] `br close bd-u5pr` with reason citing the commit + (commit hash to be filled in at commit time). +- [ ] `br sync --flush-only && git add .beads/ && git commit`. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** Single-doc render regresses silently. *Mitigation:* + Decision 10 — baseline snapshot + byte-diff test (test 17 / 24). + This is the #1 risk the epic calls out. + +- **Risk:** WASM / hub-client uses a `resource_prefix` string + somewhere we haven't found, and the resolver refactor breaks + in-browser rendering. *Mitigation:* full `cargo xtask verify` + gate before declaring done; explicit audit task above. The + DEFAULT_CSS_ARTIFACT_PATH synthetic URL is a red flag — that + code path needs specific attention. + +- **Risk:** Nested-page relative-path math is wrong, producing + 404s in `<link>`. *Mitigation:* tests 7 / 8 / 20 / snapshot + pin the math; integration test renders actual nested fixture + and the test assertion reads the emitted HTML. + +- **Risk:** Project artifact drain loses data (e.g. Page-scoped + artifacts accidentally dropped, or Project-scoped written twice). + *Mitigation:* tests 11–14 pin the drain semantics; integration + test 19 verifies dedup end-to-end. + +- **Risk:** Byte-mismatch-is-an-error (Decision 3) trips on a + legitimate case we haven't anticipated. *Mitigation:* the + diagnostic names both sources so the user can pick a fix; + we can relax to "first-writer-wins + diagnostic" in a follow-up + if real content hits this. + +- **Risk:** Scope-aware resolver adds latency / complexity to a + hot path (`ApplyTemplateStage` runs per-doc). *Mitigation:* + resolver is a tiny struct with two pure methods; no allocation + beyond the returned `String` (same as today's + `format!("{prefix}{path}")`). + +- **Risk:** Retiring `css:default` (Decision 9) breaks WASM + consumers reading by the `DEFAULT_CSS_ARTIFACT_PATH` constant + or by the literal `"css:default"` key. *Mitigation:* explicit + audit task; the migration is "iterate `css:theme:*` and pick + the one this doc produced" or keep a hub-client-side alias. + +- **Risk:** Theme fingerprint hashes inputs the user expects to + not affect the output (e.g. ordering of an unordered list), + causing spurious duplicate `site_libs/quarto/quarto-theme-*.css` + files. *Mitigation:* canonicalize inputs before hashing + (sort lists, normalize whitespace where applicable); test + 15d covers this. + +- **Risk:** Theme fingerprint omits an input that does affect the + compiled CSS, causing two different SCSS outputs to share a + key and fail the byte-equality merge check. *Mitigation:* the + failing merge is the diagnostic — better than silently + producing wrong CSS. Phase-5 implementation pins the input + set against `CompileThemeCssStage`'s actual reads. + +## Explicit non-goals for this phase + +- No Bootstrap / quarto-html / quarto-nav JS vendoring. +- No changes to the SCSS compile pipeline (beyond the output + path). +- No changes to the sidebar / navbar / footer / page-nav + transforms. Their HTML output is downstream of Phase 5's + reshaping only via the template substitution layer. +- No changes to `ProjectIndex` or `DocumentProfile`. +- No cross-document link rewriting (Phase 6). +- No sitemap / favicon / title-prefix (Phase 7). +- No incremental re-use of `site_libs/` (Phase 8). +- No `project.lib-dir:` config override — `ProjectType::lib_dir()` + is the sole source. +- No parallelism. + +## Follow-up beads (to file at close-out) + +- **`project.lib-dir:` override** — expose the Q1 YAML option that + lets users rename `site_libs/`. +- **`lib-dir` name collision with page stems** — if someone has + a `site_libs.qmd`, today's discovery doesn't exclude it. File + once the exclusion contract is designed. +- **Dedup strategy: warn instead of error** — collect real-world + cases where byte-mismatch is legitimate (likely: extension + version skew) and consider relaxing Decision 3. +- **Vendor Bootstrap / quarto-nav JS / quarto.min.js** — once + navigation-feature JS lands (`bd-9m8p`, `bd-49ar`), those + producers populate `site_libs/bootstrap/`, + `site_libs/quarto-nav/`, `site_libs/quarto/quarto.min.js`. +- **Empty `{stem}_files/` cleanup** — today we create the dir + unconditionally; if a page has no Page-scoped artifacts we could + skip creation. Low-priority. + +## Open questions (resolve during implementation) + +Most of the original open questions were collapsed into the +revised decisions above. What remains: + +1. **Theme fingerprint hash function** — `xxh3` (faster, non- + cryptographic) vs. `blake3` (slower but already in the + workspace?). Decide based on what's already a dep. +2. **Theme fingerprint input set** — exactly which fields of the + merged metadata feed into the fingerprint. Probably: + `format.html.theme` (string, list, or map), any + `format.html.theme.brand`, any `theme.scss` user files, plus + Bootstrap version constant. Pin the list during + implementation by reading `CompileThemeCssStage`. +3. **Where does the per-doc artifact drain happen** — inside + `render_document_to_file` (returns drained store as second + tuple element), or as a step in the orchestrator after the + call returns? Proposal: inside `render_document_to_file` + returning the drained store, so the function signature + remains `Result<(RenderToFileResult, ArtifactStore)>`. Locks + in the parallelism contract from D2. +4. **WASM `DEFAULT_CSS_ARTIFACT_PATH` migration** — depends on + what hub-client actually reads. Audit before deciding whether + the constant survives or gets replaced. +5. **Test 23 scope** — should we also clean up empty + `{stem}_files/` dirs in Phase 5, or defer? + +## Decisions log (to fill in after user confirmation) + +1. _TBD_ +2. _TBD_ +… (mirror the numbered decisions above once confirmed) + +## Epic-level impact + +Phase 5 completes the **shared-asset substrate** that every later +phase leans on: + +- **Phase 6** (cross-document link rewriting) needs to rewrite + body-level `href`s alongside the `<link>` / `<script>` + rewrites Phase 5 ships. The resolver built here is the shared + tool. +- **Phase 7** (`post_render`: sitemap, favicon) plugs into the + same `WebsiteProjectType::post_render` hook Phase 5 opens. +- **Phase 8** (incremental rebuilds) gets a clean contract: the + project-level artifact store is the unit of cache-check. +- **Phase 9** (hub-client project rendering) can reuse the + `ProjectContext.project_artifacts` as the in-memory shared + asset pool between browser-side page renders. + +After Phase 5, the website epic has: + +- complete information architecture (Phases 1–4), +- a working shared-assets pipeline (Phase 5), + +and the remaining phases (6–9) are about **connecting** +documents to each other and to their runtime environment. diff --git a/claude-notes/plans/2026-04-24-websites-phase-6.md b/claude-notes/plans/2026-04-24-websites-phase-6.md new file mode 100644 index 000000000..038c8f352 --- /dev/null +++ b/claude-notes/plans/2026-04-24-websites-phase-6.md @@ -0,0 +1,1154 @@ +# Phase 6 — Cross-document link rewriting + +**Date:** 2026-04-24 +**Beads:** `bd-v30t` (parent `bd-0tr6`). Follow-ups TBD at close-out. +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-24-websites-phase-5.md` +**Status:** Draft — pending user review. + +## Goal of this phase + +Rewrite **body-content** `[link](other.qmd)` references so they +resolve to the right output URL on disk, with a relative path that +accounts for the current page's depth in the site tree. Concretely: + +- `[About](about.qmd)` in `index.qmd` → `<a href="about.html">About</a>` +- `[About](../about.qmd)` in `docs/api.qmd` → `<a href="../about.html">About</a>` +- `[API](docs/api.qmd)` in `index.qmd` → `<a href="docs/api.html">API</a>` +- `[Section](other.qmd#sec)` → `<a href="other.html#sec">Section</a>` +- `[Search](other.qmd?q=x)` → `<a href="other.html?q=x">Search</a>` +- `[Site root](/about.qmd)` in `docs/api.qmd` → `<a href="../about.html">Site root</a>` + +Today the navigation transforms (sidebar, navbar, page-footer, +page-nav) already rewrite `.qmd` hrefs through the shared +`navigation_href::resolve_href_for_html`. Phase 6 extends this rewrite +to **body content** — the inline `Link` nodes that come from the +markdown source itself. + +This phase adds: + +1. A new `LinkRewriteTransform` that walks the AST body, finds every + `Inline::Link`, and rewrites its `target.0` URL when it points at + another project document. +2. A new helper (working name `resolve_doc_relative_href`) that + handles the **source-doc-relative** path math the existing + `resolve_href_for_html` doesn't cover. Body links are written + relative to the current source file's directory; navigation links + live in `_quarto.yml` and are project-root-relative. The two helpers + share the lookup + diagnostics path but differ in their input + normalization. +3. A new `page_url_for(target_output_href: &str) -> String` method on + `ResourceResolverContext` that turns a target page's project- + relative output href into a relative URL from the current page, + using the same `pathdiff` + `rel_to_url` machinery Phase 5 uses + for shared assets. +4. A small additive change to `RenderContext`: a + `resource_resolver: Option<ResourceResolverContext>` field so the + new transform can read the resolver Phase 5 already builds in + `render_to_file.rs`. Populated alongside `project_index`. + +This phase does **not** implement: + +- **Draft handling.** Q1 hides links to draft pages (replacing the + `<a>` with its inner content) when `draftMode != "visible"`. Q2's + `DocumentProfile.draft` field exists, but draft-mode config doesn't. + Defer the visibility-mode behavior to a follow-up bead. Phase 6 still + rewrites href targets that happen to be draft pages — they just + remain reachable through the link. Filing as `bd-<draft-mode>`. +- **Index-forgiveness** (`docs/` matching `docs/index.qmd`). Same + deferral as Phase 3's `bd-jbml` and Phase 4's `bd-bobp` — file as + a single follow-up that covers nav + body uniformly. +- **`.md` / `.ipynb` extension recognition.** Q1 warns on + unresolvable links to all "engine valid" extensions; Q2 currently + only renders `.qmd` (per `bd-xxul`). Match: warn on `.qmd` only. + When `bd-xxul` lands, that work extends Phase 6's heuristic at the + same time. +- **Cross-format link awareness.** A `[link](other.qmd)` from an + HTML page targeting a doc with `format: pdf` should produce a + `.pdf` URL. MVP assumes single-format projects (HTML); cross- + format URL resolution is out of epic scope. +- **Image rewriting.** `Image.target.0` is left unchanged. Images + point at static resources, not project documents; Q1 doesn't + rewrite them either. +- **`<base href>` / `offset`-prefix output.** Q1 emits relative URLs + from the current page; Q2 matches. No `/`-rooted URLs. +- **Footer Text-region link rewriting.** Phase 5's follow-up + `bd-jfyl` is the right bead to consume the helper this phase adds. + Tracked separately. +- **Custom-node body links.** Walking is recursive (mirrors + `crossref_render`'s `render_inlines` pattern), so any `Inline::Link` + reachable through `Inline::Custom`'s `Slot` content is rewritten too. + No special-case work, but no proactive design for novel custom-node + shapes that bypass Inlines. + +## Reference material + +- **Parent epic plan** §"Phase 6 — Cross-document link rewriting" + and §"Cross-document index". +- **Phase 5 sub-plan** §Decision 6 (`ResourceResolverContext`) and + §Decision 7 (URL resolution at template-apply time). +- **Phase 3 sub-plan** §Decision 3 (shared `navigation_href` helper) + and the resulting `crates/quarto-core/src/transforms/navigation_href.rs`. +- **Q2 current code:** + - `crates/quarto-core/src/transforms/navigation_href.rs` — + `resolve_href_for_html`, `is_external`. Project-root-relative + input, project-root-relative output. Phase 6 wraps / extends. + - `crates/quarto-core/src/transforms/resource_collector.rs` — + template for the recursive AST walk (block / inline / custom + slots). + - `crates/quarto-core/src/transforms/crossref_render.rs:177-214` — + `render_inline` recursive walk pattern. Phase 6 mirrors. + - `crates/quarto-core/src/resource_resolver.rs` — Phase 5 resolver. + Phase 6 adds one method (`page_url_for`). + - `crates/quarto-core/src/render.rs:134` — `RenderContext.project_index` + field. Phase 6 adds a sibling `resource_resolver` field. + - `crates/quarto-core/src/render_to_file.rs:217-235` — where the + project index and resolver are constructed. Phase 6 wires the + resolver into `RenderContext` here. + - `crates/quarto-core/src/pipeline.rs:622-645` — `build_transform_pipeline`. + Phase 6 inserts one new transform near the end. + - `crates/quarto-core/src/project/index.rs` — `ProjectIndex` and + `lookup_by_source`. Already used by `resolve_href_for_html`. + - `crates/quarto-pandoc-types/src/inline.rs:191-199` — `Link` + struct. `target: Target = (String, String)`; `target.0` is the URL. + - `crates/quarto-core/src/transforms/navigation_active.rs:36-49` — + `page_relative_source(ctx)`. Phase 6 reuses to know "what doc am + I in?" for resolving doc-relative hrefs. +- **Q1 reference:** + - `external-sources/quarto-cli/src/project/types/website/website-utils.ts:61-122` + — `resolveProjectInputLinks`. The Deno-DOM-based body-link + rewriter. Phase 6 mirrors its semantics in AST-space: + - leading-`/` strips to project-relative + - else `join(dirname(sourceRelative), linkHref)` resolves + relative to source-doc dir + - hash split / re-append + - `resolveInputTarget` lookup → `outputHref` + - `offset + outputHref + hash` to produce the final href + - `external-sources/quarto-cli/src/project/types/website/website-navigation.ts:218` + and `:577` — call sites. Q1 invokes the rewriter post-render + (Deno-DOM walk over the emitted HTML); Q2 does it pre-render + (AST walk before the format renderer runs). + +## Key decisions (to confirm with user) + +These are proposed — please push back on anything that looks wrong +before we start. + +### Decision 1 — Rewrite at AST level, not post-HTML + +Walk `Inline::Link` nodes in the AST body, mutate `target.0` in +place. Do **not** add an HTML post-processor. + +**Rationale.** +- Format-agnostic by construction. Today only HTML cares; tomorrow a + PDF-ish renderer can consume the same AST and choose to ignore / + use the rewritten hrefs. +- No new dependency on a DOM library. Q1's Deno DOM round-trip is + expensive (parse → walk → serialize); the AST already has + structured `Link` nodes. +- Composes with the existing `resolve_href_for_html` helper used by + navigation transforms (sidebar / navbar / page-nav / footer). + Same lookup, same diagnostics shape, same source label + convention. + +**Trade-off.** A Lua filter that *generates* `.qmd` hrefs after Phase +6 would not get its hrefs rewritten. Phase 6 sits in the Finalization +Phase, after most filters have run; specifically users get one chance +to rewrite hrefs *before* Phase 6 (in pre-engine / engine / generic +AstTransforms) but not after. Q1 has an analogous limitation (any +post-rewrite Lua filter rewriting hrefs would bypass Q1's HTML +post-processor too). If a real workflow surfaces filter-emitted .qmd +hrefs, we add a second-pass transform and document the ordering +contract. + +### Decision 2 — Pipeline placement: first transform in Finalization Phase + +Insert `LinkRewriteTransform` between the navigation Render +transforms and `AppendixStructureTransform`: + +``` +TocRenderTransform +NavbarRenderTransform +SidebarRenderTransform +PageNavRenderTransform +FooterRenderTransform + ← end of Navigation Phase +LinkRewriteTransform ← NEW (start of Finalization Phase) +AppendixStructureTransform +CrossrefRenderTransform +ResourceCollectorTransform +``` + +**Rationale for this slot:** +- After all transforms that *generate* navigation HTML — those + rewrite hrefs in their own subtrees, not in body content, so they + don't conflict. +- After `CrossrefResolveTransform` — crossref rewrites turn `@fig-1` + into `Inline::Link` nodes pointing at intra-doc fragments + (`#fig-1`). Those have empty path / fragment-only hrefs, so the + `is_external | starts_with('#')` shortcut in the helper skips + them. Verified by reading `crossref_render.rs:704+`. +- Before `AppendixStructureTransform` — appendix consolidation + doesn't touch link hrefs, but moving the transform afterwards would + give it body-link inlines reorganized into the appendix container, + which doesn't change behavior. Either ordering works; we pick the + earlier slot for predictability ("rewrite finishes before any + reshuffle starts"). +- Before `CrossrefRenderTransform` — actually, this is when crossref + custom-node Inlines become `Inline::Link`. Does that matter? Read: + `crossref_render.rs` produces `Inline::Link` for resolved refs, + but those have `#`-anchored hrefs (`#fig-1`), which Phase 6 skips + via the fragment-anchor short-circuit. So order doesn't matter for + intra-doc crossrefs. **Cross-document crossrefs** (e.g. + `@chapter-2` resolving to `chapter-2.qmd#sec`) would matter, but + that's `bd-xxxx` / book scope, out of this epic. + +If the ordering reveals a corner case during implementation +(e.g. some Finalization-phase transform that *does* emit +`.qmd` hrefs after Phase 6), we'll move the transform. Easy to +reorder in `pipeline.rs`. + +### Decision 3 — New helper `resolve_doc_relative_href` + +Add to `crates/quarto-core/src/transforms/navigation_href.rs` +alongside the existing `resolve_href_for_html`: + +```rust +/// Resolve a body-content href to a relative URL. +/// +/// `raw` is the link href as written by the user (e.g. +/// `"../about.qmd#bio"`, `"docs/api.qmd"`, `"/about.qmd"`). +/// `source_relative` is the current document's project-relative +/// source path (forward-slash form), used to resolve doc-relative +/// references. +/// `resolver` is the per-page resource resolver (Phase 5) used to +/// turn a target output href into a page-relative URL. +/// `index` is the project's `ProjectIndex`; the function is a no-op +/// (returns `raw.to_string()`) when `None`. +pub fn resolve_doc_relative_href( + raw: &str, + source_relative: &str, + resolver: Option<&ResourceResolverContext>, + index: Option<&ProjectIndex>, + source_label: Option<&str>, + diagnostics: &mut Vec<DiagnosticMessage>, +) -> String { … } +``` + +Algorithm: +1. **External / fragment-only short-circuit** — same as + `resolve_href_for_html`. Pass through. +2. **Split path / tail** — `path_part = raw[..i]`, `tail = raw[i..]` + where `i` is the first `#` or `?`. Same as today. +3. **Source-relative resolution** — compute + `project_relative_path`: + - If `path_part.starts_with('/')`: strip leading `/`. (Q1 parity.) + - Else: join with `dirname(source_relative)` and **normalize** + `.` / `..` components. (`PathBuf::join` doesn't normalize, so + a small helper does the walk-and-pop.) Forward-slash result. +4. **Lookup** — `index.lookup_by_source(project_relative_path)`. +5. **Hit:** + - `target_output_href = profile.output_href` (project-relative, + forward-slash, e.g. `"docs/api.html"`). + - `relative_url = resolver.page_url_for(target_output_href)` + when a resolver is available; falls back to + `target_output_href` verbatim otherwise (no relative-depth + math). + - Return `relative_url + tail`. +6. **Miss:** + - If `path_part.ends_with(".qmd")` and `index.is_some()`: + emit a warning diagnostic `"<source_label> references unknown + document '<path_part>'"`. (Mirrors `resolve_href_for_html`.) + - Return `raw.to_string()` so the dangling link renders visibly. +7. **No `index`:** return `raw.to_string()` verbatim, no diagnostic. + (Mirrors today's standalone-render behavior.) + +**Why a separate helper, not extend `resolve_href_for_html`:** +- Different input normalization: navigation hrefs are project-root- + relative as written (`about.qmd`, `docs/api.qmd`); body hrefs are + source-relative (`../about.qmd`, `subdir/foo.qmd`). Conflating the + two would silently mis-route nav configs that happen to start with + `..`. +- Different output: navigation produces project-root URLs (consumed + by `<a href="about.html">` where the template's `<base>` or static + assumptions make root-relative work); body links need page-relative + URLs that account for the current page's depth. +- Same lookup + diagnostics infrastructure though, so the two + helpers share `is_external`, the `path_part` / `tail` split, and + the diagnostic shape. + +**Naming alternatives considered:** +- `resolve_body_link_href` — possibly too narrow if a future caller + wants to use the helper outside of body content. +- `resolve_relative_qmd_href` — too tied to the `.qmd` extension. +- `resolve_doc_relative_href` — picked. Matches Q1's + `resolveProjectInputLinks` semantics (the "input" name in Q1 means + "input to the renderer" = source doc). + +### Decision 4 — New `page_url_for` method on `ResourceResolverContext` + +Add to `crates/quarto-core/src/resource_resolver.rs`: + +```rust +impl ResourceResolverContext { + /// Compute a relative URL from the current page to another + /// page in the project, given the target's project-relative + /// output href (e.g. `"docs/api.html"`). + /// + /// In VFS-root mode returns `{vfs_root}/{target_output_href}`. + /// In single-doc mode returns `target_output_href` verbatim + /// (no project structure to relate against). + /// Otherwise returns the relative URL from the current page's + /// directory to `{site_root}/{target_output_href}`. + pub fn page_url_for(&self, target_output_href: &str) -> String { + if let Some(root) = &self.vfs_root_mode { + return rel_to_url(&root.join(target_output_href)); + } + let target_abs = self.site_root.join(target_output_href); + let page_dir = self.page_output.parent().unwrap_or_else(|| Path::new(".")); + let rel = pathdiff::diff_paths(&target_abs, page_dir) + .unwrap_or_else(|| target_abs.clone()); + rel_to_url(&rel) + } +} +``` + +Same shape as `html_url_for`, except the input is a project-relative +output href (a `String`) rather than an `(ArtifactScope, &Path)` +pair. Reuses the private `rel_to_url` helper Phase 5 introduced. + +**Single-doc fallback rationale:** in `single_doc` mode `site_root == +page_output.parent()`, so the math collapses to `target_output_href` +itself — which is correct for the (uncommon) case where a single-doc +render somehow has an index. In practice the transform's standalone- +render branch returns early before it ever calls `page_url_for`, so +this branch is defensive, not load-bearing. + +### Decision 5 — `RenderContext.resource_resolver: Option<ResourceResolverContext>` + +The Phase 5 resolver is constructed in `render_to_file.rs:229` and +passed to `HtmlRenderConfig::with_resolver`. AST transforms today +have no way to read it. + +Add a field to `RenderContext`: + +```rust +pub struct RenderContext<'a> { + // existing fields … + pub resource_resolver: Option<ResourceResolverContext>, // NEW +} +``` + +Populate it in `render_to_file.rs` immediately after `project_index`: + +```rust +let resolver = ResourceResolverContext::website(…); +ctx.project_index = Some(index); +ctx.resource_resolver = Some(resolver.clone()); // NEW +let config = HtmlRenderConfig::with_resolver(resolver); +``` + +Bridge it through `pipeline.rs:415` the same way `project_index` is +threaded into `StageContext` for stages that need it. (For Phase 6, +only the AST transform reads it via `RenderContext`; no stage +plumbing needed beyond the existing `RenderContext` field.) + +**Why on `RenderContext` and not a transform-constructor argument:** +- Symmetric with `project_index` (already on `RenderContext`). +- Lets the helper signature stay narrow — the transform passes + `ctx.resource_resolver.as_ref()` and `ctx.project_index.as_deref()` + in a single call site. +- Future consumers (Phase 5 follow-up `bd-jfyl` for footer text- + region links, Phase 7's site-url qualifier) can read it without + re-plumbing. + +**Risk.** `RenderContext` already has a lot of fields; adding another +ratchets the struct size and `RenderContext::new`. Mitigation: the +field has a `None` default and is purely additive — no caller +literal needs to change (verified by grep of `RenderContext { … +}` literals). The `.with_*` builder pattern stays. + +### Decision 6 — `LinkRewriteTransform` walks blocks + inlines, including custom slots + +Mirror the recursive pattern in +`crates/quarto-core/src/transforms/crossref_render.rs:171-214`. The +transform owns the walk; `resolve_doc_relative_href` is the +per-link helper. + +```rust +pub struct LinkRewriteTransform; + +#[async_trait::async_trait(?Send)] +impl AstTransform for LinkRewriteTransform { + fn name(&self) -> &str { "link-rewrite" } + + async fn transform(&self, ast: &mut Pandoc, ctx: &mut RenderContext) -> Result<()> { + let Some(index) = ctx.project_index.as_deref() else { + // Standalone render: no project context, no rewrites. + return Ok(()); + }; + let resolver = ctx.resource_resolver.as_ref(); + let source = page_relative_source(ctx); + let mut local_diags = std::mem::take(&mut ctx.diagnostics); + let mut rewriter = LinkRewriter { + source: &source, + index, + resolver, + diagnostics: &mut local_diags, + }; + for block in &mut ast.blocks { + rewriter.visit_block(block); + } + ctx.diagnostics = local_diags; + Ok(()) + } +} + +struct LinkRewriter<'a> { … } +impl<'a> LinkRewriter<'a> { + fn visit_block(&mut self, block: &mut Block) { … } + fn visit_inline(&mut self, inline: &mut Inline) { + match inline { + Inline::Link(link) => { + // Recurse into content first (in case nested + // Inline::Link or Inline::Custom contains rewritable + // children — uncommon but possible). + for child in link.content.iter_mut() { + self.visit_inline(child); + } + // Rewrite target.0 (URL); target.1 (title) untouched. + let new_url = resolve_doc_relative_href( + &link.target.0, + self.source, + self.resolver, + Some(self.index), + Some("Body link"), + self.diagnostics, + ); + link.target.0 = new_url; + } + // … recurse through other Inline variants (Emph, Strong, + // Span, Custom, Image content, Note content, …) per the + // resource_collector pattern. + } + } +} +``` + +**Image targets are not rewritten.** Image content (alt text / +captions) is walked recursively in case it contains `Inline::Link`, +but `Image::target.0` (the image URL) is left as-is — Q1 doesn't +rewrite it either; images point at static resources, not project +documents. + +**Custom nodes** are walked through their `Slot`s, mirroring +`resource_collector.rs:191-213`. + +### Decision 7 — Standalone render = no-op + +When `ctx.project_index` is `None`, the transform returns +immediately without touching the AST. Body links pass through +verbatim (no rewriting, no diagnostics). + +This matches the existing single-doc-render contract for sidebar / +navbar / page-nav / footer (Phase 2/3/4 Decision 1). A revealjs slide +deck or a one-off `.qmd` file with `[link](other.qmd)` keeps its +literal href. + +Cost: a body-link author who *expects* their `[link](other.qmd)` to +become `other.html` in a standalone render gets surprised. Mitigation: +docs note + the diagnostic is silent (no warning to ignore). Q1 is +the same here: it only runs `resolveProjectInputLinks` inside +`renderForPrint` when a project context exists. + +### Decision 8 — Diagnostic shape + +`source_label = "Body link"`. Matches Phase 3's `"Sidebar"` / +`"Navbar"` / `"Page footer"` and Phase 4's `"Page navigation"` +convention. Diagnostic title: + +``` +Body link references unknown document 'docs/missing.qmd' +``` + +Same warning-level severity as the navigation diagnostics. The href +is preserved so the broken link is visibly broken at render time. + +**No diagnostic is emitted** for non-`.qmd` misses (e.g. +`assets/foo.png`, `mailto:`, …). External URLs and fragment-only +anchors short-circuit before the lookup. Non-qmd-shaped misses are +indistinguishable from intentional static-resource references — Q1 +takes the same stance. + +**Future:** when `bd-xxul` lands `.md` / `.ipynb` support, the same +diagnostic fires for those extensions. The decision of "which +extensions warrant a warning" lives with the renderable-extensions +list, not in this helper. + +### Decision 9 — Path normalization helper + +Body hrefs can contain `..` and `.` components. `PathBuf::join` +doesn't resolve these: +- `Path::new("docs").join("../about.qmd")` produces `docs/../about.qmd`, + not `about.qmd`. + +We need a lossless walk-and-pop normalizer. Two options: + +1. **Inline helper in `navigation_href.rs`** that walks + `Path::components()`, pushing `Normal` components onto a stack + and popping on `ParentDir`. Returns a `String` (forward-slash). +2. **Reuse a crate.** `path-clean` or `pathdiff` (already in + workspace) — `pathdiff` doesn't normalize, only diffs; + `path-clean` would be a new dep. + +Recommendation: **inline helper**, ~15 lines. Minimal dependency +footprint, exact semantics we control, easy to test. + +```rust +/// Join `linkHref` (a forward-slash, doc-relative or absolute path +/// expression) against `source_relative`'s directory, normalize +/// `.` / `..` components, and return a project-relative +/// forward-slash path. +/// +/// - `link_href` starting with `/` strips the leading slash. +/// - Otherwise joins with `dirname(source_relative)`. +/// - Components that walk above the project root are clamped at +/// the root (matches `Path::canonicalize` behavior, no error). +fn resolve_to_project_root(source_relative: &str, link_href: &str) -> String { … } +``` + +Tests cover: leading `/`, `..` to parent dir, multiple `..`, walking +above root (clamp), `.` no-op, mixed-case forward slashes. + +### Decision 10 — Final URL is page-relative + +Q1 uses `offset + outputHref + hash` where `offset` is the relative +prefix from current page's depth. Q2 uses `pathdiff::diff_paths` from +current page dir to target page abs path. Equivalent result. + +Examples (pages in `_site/…`): + +| Source page | Target output href | Result URL | +|-------------|---------------------|------------| +| `index.html` | `about.html` | `about.html` | +| `index.html` | `docs/api.html` | `docs/api.html` | +| `docs/api.html` | `about.html` | `../about.html` | +| `docs/api.html` | `docs/intro.html` | `intro.html` | +| `a/b/c/d.html` | `e/f.html` | `../../../e/f.html` | + +**Trailing-tail re-attach:** `resolver.page_url_for("docs/api.html") ++ "#sec"` → `"docs/api.html#sec"`. The `+` is plain string +concatenation; the helper doesn't insert any extra `/`. + +## Architecture sketch + +### Data flow + +``` +ast.blocks (after navigation Render transforms) + │ + ▼ +LinkRewriteTransform + │ + ├── for each Inline::Link in body: + │ ├── resolve_doc_relative_href( + │ │ link.target.0, + │ │ page_relative_source(ctx), + │ │ ctx.resource_resolver.as_ref(), + │ │ ctx.project_index.as_deref(), + │ │ Some("Body link"), + │ │ &mut local_diags, + │ │ ) + │ └── link.target.0 = new_url + │ + └── ctx.diagnostics absorbs warnings for missing docs +``` + +### Module shape + +``` +crates/quarto-core/src/ + resource_resolver.rs # add `page_url_for` method + render.rs # add `resource_resolver` field + render_to_file.rs # populate `ctx.resource_resolver` + pipeline.rs # insert LinkRewriteTransform + +crates/quarto-core/src/transforms/ + navigation_href.rs # add `resolve_doc_relative_href` + + # private `resolve_to_project_root` + # path-normalization helper + link_rewrite.rs # NEW — LinkRewriteTransform + mod.rs # re-export LinkRewriteTransform +``` + +### Single-doc behavior (regression check) + +For a default project (single-file or directory without +`_quarto.yml`), `ctx.project_index` is `None`. The transform's first +line returns `Ok(())` and the AST is untouched. `[link](other.qmd)` +in body content keeps its `.qmd` href verbatim — same as +pre-Phase-6. + +### Multi-doc website behavior + +For a website project, every Pass-2 doc receives a populated +`project_index` and `resource_resolver`. The transform walks every +`Inline::Link`, rewrites internal `.qmd` hrefs, and leaves +external/fragment/non-qmd hrefs untouched. The downstream HTML +renderer emits `<a href="…">` from `link.target.0` without further +processing. + +## DocumentProfile change + +**None.** Phase 6 reads only `output_href`, `source_path`, and +`draft` (the last not yet — drafts deferred). All three are +profile-version 1 fields. No bump. + +## Tests (TDD: write and fail first) + +Every test authored before the code that makes it pass. Failing +baseline captured before implementation. + +### Unit tests — `resource_resolver::page_url_for` + +1. `page_url_for_root_page_root_target` — page at + `_site/index.html`, target `about.html` → `"about.html"`. +2. `page_url_for_root_page_nested_target` — page at + `_site/index.html`, target `docs/api.html` → + `"docs/api.html"`. +3. `page_url_for_nested_page_root_target` — page at + `_site/docs/api.html`, target `about.html` → + `"../about.html"`. +4. `page_url_for_nested_page_sibling_target` — page at + `_site/docs/api.html`, target `docs/intro.html` → + `"intro.html"`. +5. `page_url_for_deep_nesting` — page at `_site/a/b/c/d.html`, + target `e/f.html` → `"../../../e/f.html"`. +6. `page_url_for_vfs_root_mode` — `vfs_root("/.quarto/proj")`, + target `about.html` → `"/.quarto/proj/about.html"` (matches + `html_url_for` VFS conventions). +7. `page_url_for_single_doc_returns_target_verbatim` — + `single_doc("/tmp/doc.html", "doc")`, target `about.html` → + `"about.html"` (single-doc fallback). + +### Unit tests — `resolve_to_project_root` (path normalization) + +8. `path_normalize_leading_slash_strips` — `"/about.qmd"` from any + source → `"about.qmd"`. +9. `path_normalize_doc_relative_no_dotdot` — `"foo.qmd"` from + `docs/api.qmd` → `"docs/foo.qmd"`. +10. `path_normalize_dotdot_to_parent` — `"../about.qmd"` from + `docs/api.qmd` → `"about.qmd"`. +11. `path_normalize_multiple_dotdot` — `"../../about.qmd"` from + `a/b/c.qmd` → `"about.qmd"`. +12. `path_normalize_dot_no_op` — `"./foo.qmd"` from `docs/api.qmd` + → `"docs/foo.qmd"`. +13. `path_normalize_clamp_above_root` — `"../../../foo.qmd"` from + `a/b.qmd` → `"foo.qmd"` (clamp at root, no error). +14. `path_normalize_subdir` — `"sub/foo.qmd"` from `docs/api.qmd` + → `"docs/sub/foo.qmd"`. +15. `path_normalize_root_source` — `"about.qmd"` from `index.qmd` + → `"about.qmd"`. + +### Unit tests — `resolve_doc_relative_href` + +16. `body_href_external_passes_through` — `"https://example.com"` + from any source → `"https://example.com"`. +17. `body_href_fragment_only_passes_through` — `"#section"` from + any source → `"#section"`. +18. `body_href_qmd_hits_index` — `"about.qmd"` from `index.qmd`, + project has `about.qmd → about.html` → `"about.html"`. +19. `body_href_doc_relative_qmd_hits_index` — `"../about.qmd"` + from `docs/api.qmd`, project has `about.qmd → about.html`, + resolver page at `_site/docs/api.html`, site root `_site` → + `"../about.html"`. +20. `body_href_absolute_qmd_hits_index` — `"/about.qmd"` from + `docs/api.qmd` → `"../about.html"`. +21. `body_href_subdir_qmd` — `"docs/api.qmd"` from `index.qmd` → + `"docs/api.html"`. +22. `body_href_preserves_fragment` — `"about.qmd#bio"` from + `index.qmd` → `"about.html#bio"`. +23. `body_href_preserves_query` — `"about.qmd?x=1"` → + `"about.html?x=1"`. +24. `body_href_preserves_query_and_fragment` — + `"about.qmd?x=1#bio"` → `"about.html?x=1#bio"`. +25. `body_href_qmd_miss_emits_diagnostic` — `"missing.qmd"` with + `source_label = "Body link"`: diagnostic title starts with + `"Body link"` and contains `"missing.qmd"`. Returned href is + `"missing.qmd"` (verbatim — broken link visible). +26. `body_href_non_qmd_miss_no_diagnostic` — + `"assets/logo.png"` with no matching profile: returned + verbatim, no diagnostic. +27. `body_href_no_index_passes_through` — `"about.qmd"` with + `index = None`: returned verbatim, no diagnostic. +28. `body_href_no_resolver_falls_back_to_output_href` — + `"about.qmd"` from `index.qmd` with `index` set but + `resolver = None`: returns the bare `output_href` + (`"about.html"`) — no relative-depth math, but no panic. + +### Unit tests — `LinkRewriteTransform` + +29. `link_rewrite_skips_when_no_index` — single-doc render + (`project_index = None`): every `Inline::Link.target.0` + survives unchanged. +30. `link_rewrite_walks_paragraph_inlines` — `Para [Link …, Link + …]`: both rewritten. +31. `link_rewrite_walks_nested_emph_link` — `Para [Emph [Link …]]`: + rewritten. +32. `link_rewrite_walks_div_blocks` — `Div [Para [Link …]]`: + rewritten. +33. `link_rewrite_walks_lists` — `BulletList [[Para [Link …]]]`: + rewritten. +34. `link_rewrite_walks_custom_node_slots` — `Custom { slots: [ + Inlines [Link …]] }`: rewritten. +35. `link_rewrite_external_pass_through` — link with + `target.0 = "https://example.com"` survives unchanged. +36. `link_rewrite_fragment_pass_through` — `target.0 = "#sec"` + survives unchanged. +37. `link_rewrite_image_url_unchanged` — paragraph with `Image` + pointing at `"img.png"`: image target unchanged. Image's alt- + text content is walked (so a `Link` *inside* the alt would + be rewritten); the image's own URL is not. +38. `link_rewrite_diagnostic_uses_body_link_label` — broken + `.qmd` link in body produces diagnostic starting with + `"Body link"`. + +### Integration tests — `crates/quarto-core/tests/` + +New file `link_rewriting_pipeline.rs`: + +39. `pipeline_body_link_rewrites_simple_qmd` — three-page website + `[index, about, docs/api]`. `index.qmd` body has + `[About](about.qmd)`. After render, `index.html` contains + `<a href="about.html">About</a>`. +40. `pipeline_body_link_rewrites_doc_relative` — `docs/api.qmd` + body has `[About](../about.qmd)`. After render, + `docs/api.html` contains `<a href="../about.html">About</a>`. +41. `pipeline_body_link_rewrites_subdir` — `index.qmd` body has + `[API](docs/api.qmd)`. After render, `index.html` contains + `<a href="docs/api.html">API</a>`. +42. `pipeline_body_link_preserves_fragment` — `index.qmd` body has + `[Bio](about.qmd#bio)`. After render, `index.html` contains + `<a href="about.html#bio">Bio</a>`. +43. `pipeline_body_link_preserves_query_string` — body has + `[Search](search.qmd?q=foo)`. Output href contains + `"search.html?q=foo"`. +44. `pipeline_body_link_external_unchanged` — body has + `[GitHub](https://github.com)`. Output href is + `https://github.com`, no diagnostic. +45. `pipeline_body_link_broken_qmd_emits_diagnostic` — body has + `[Missing](nope.qmd)`. After render, output href is `nope.qmd` + verbatim, and the render result's diagnostics list contains + a "Body link" warning naming `nope.qmd`. +46. `pipeline_body_link_single_doc_unchanged` — bare `.qmd` + rendered without a `_quarto.yml`. Body has `[X](other.qmd)`. + Output href is `other.qmd` verbatim. No diagnostic. Confirms + the standalone-render no-op contract. +47. `pipeline_body_link_absolute_path` — body has + `[Home](/index.qmd)` from `docs/api.qmd`. Output href is + `../index.html`. +48. `pipeline_body_link_in_list` — body has a bullet list with + a `.qmd` link. Output href is rewritten. +49. `pipeline_body_link_no_cross_contamination` — rendering + `index.qmd` does not affect `about.qmd`'s body links + (regression guard, mirrors Phase 3's navbar + cross-contamination test). + +### CLI end-to-end (per CLAUDE.md §End-to-end verification) + +50. **Body-link smoke** at `/tmp/q2-phase6-smoke/`: + ``` + _quarto.yml: + project: { type: website } + website: + title: "Phase 6 Smoke" + index.qmd: "[About me](about.qmd) — see also [API](docs/api.qmd)." + about.qmd: "Back to the [home page](index.qmd)." + docs/api.qmd: "See [the about page](../about.qmd) or [home](/index.qmd)." + ``` + Run `cargo run --bin q2 -- render /tmp/q2-phase6-smoke/` and + inspect each rendered HTML: + - `_site/index.html`: `<a href="about.html">About me</a>` and + `<a href="docs/api.html">API</a>`. + - `_site/about.html`: `<a href="index.html">home page</a>`. + - `_site/docs/api.html`: `<a href="../about.html">…</a>` and + `<a href="../index.html">home</a>`. + Record observed snippets in the close-out. +51. **Broken-link smoke** at `/tmp/q2-phase6-broken-smoke/`: + `index.qmd` body has `[X](missing.qmd)`. Verify diagnostic + `"Body link references unknown document 'missing.qmd'"` + appears in stderr; rendered HTML has `<a href="missing.qmd">`. +52. **Regression smokes**: re-run + `/tmp/q2-phase2-smoke/`, `/tmp/q2-phase3-smoke/`, + `/tmp/q2-phase4-smoke/`, `/tmp/q2-phase5-website-test/`. + Sidebar / navbar / page-nav / `site_libs` behavior unchanged. + Body-link rewriting now active — pages with `.qmd` body links + (if any in those fixtures) get them rewritten. + +### Snapshot tests + +None — inline asserts over the emitted HTML cover the vocabulary +(consistent with Phase 2 / 3 / 4 / 5 choices). + +## Work items (checklist) + +### Preparation + +- [x] Re-read `claude-notes/instructions/testing.md`, + `coding.md`, `review.md`. +- [x] Confirm user agreement with Decisions 1–10. **DONE 2026-04-27.** +- [x] Create `bd` issue `Phase 6 — Cross-document link rewriting`, + parent `bd-0tr6`, parent-child dependency linked. (`bd-v30t`.) +- [x] Commit directly on `feature/websites` (Phase 1–5 precedent). + +### Resolver extension (`quarto-core/src/resource_resolver.rs`) + +- [x] Add `page_url_for(target_output_href: &str) -> String` + method (Decision 4). +- [x] Tests 1–7 (all passing). + +### `RenderContext` extension (`quarto-core/src/render.rs`) + +- [x] Add `resource_resolver: Option<ResourceResolverContext>` + field (Decision 5). +- [x] Default to `None` in `RenderContext::new`. +- [x] Verified no `RenderContext { ... }` struct-literal callers + exist (only `CslRenderContext` literals, which is a different + type). All construction goes through `RenderContext::new`. + +### Resolver wiring (`quarto-core/src/render_to_file.rs`) + +- [x] Populate `ctx.resource_resolver = Some(resolver.clone())` + immediately after the existing `ctx.project_index` assignment. +- [x] Hub-client / WASM `render_qmd_with_options` and + `render_qmd_with_resources` also wire `ctx.resource_resolver + = Some(resolver.clone())` for the VFS-root resolver. Two + callsites in `crates/wasm-quarto-hub-client/src/lib.rs` + updated (lines 977 and 1089). + +### Helper module (`quarto-core/src/transforms/navigation_href.rs`) + +- [x] Add `pub fn resolve_doc_relative_href(...)` per Decision 3. +- [x] Add private `fn resolve_to_project_root(...)` path + normalizer per Decision 9. Implementation walks + forward-slash segments (not `Path::components`) to dodge + Windows-specific path surprises (drive prefixes, backslash + separators) — URL paths are forward-slash by convention. +- [x] Tests 8–28 (all 21 passing). + +### `LinkRewriteTransform` + (`quarto-core/src/transforms/link_rewrite.rs` — NEW) + +- [x] New module. Standalone-render skip per Decision 7. +- [x] Recursive `LinkRewriter` visitor mirroring + `crossref_render::render_inline` and + `resource_collector::ResourceVisitor` (Decision 6). Walks + Block / Inline / `Inline::Custom` slots with full coverage + of body-bearing variants (Lists, Tables, Figures, Notes, + Captions, etc.). +- [x] Use `page_relative_source(ctx)` for the source-relative + basis. +- [x] `mod.rs` re-export. +- [x] Tests 29–38 (all 10 passing). + +### Pipeline wiring (`quarto-core/src/pipeline.rs`) + +- [x] Insert `LinkRewriteTransform::new()` as the first + transform in the Finalization Phase, before + `AppendixStructureTransform` (Decision 2). Comment + explains the placement contract and links to the sub-plan. +- [x] Update the doc-block enumerating Finalization Phase + transforms (now lists Link rewrite, Appendix, Crossref, + Resource collector). +- [x] Full quarto-core test suite green (1230 tests pass) — no + regressions in existing transforms or integration tests. + +### Integration tests + (`quarto-core/tests/link_rewriting_pipeline.rs`) + +- [x] Tests 39–49 written following the `sidebar_pipeline.rs` + pattern (11 tests, all passing). Test 46's + strictly-standalone "no `_quarto.yml`" contract was + reframed: `ProjectPipeline::run` always builds a + `ProjectIndex`, so the no-index branch is exclusively + exercised by the unit tests + (`link_rewrite_skips_when_no_index`, + `body_href_no_index_passes_through`). The integration test + that replaces it (`pipeline_body_link_unresolvable_in_website_warns`) + covers the user-visible "broken link in a website project" + case. + +### Discovered during integration: bridge resolver through stages + +- [x] Adding the resolver to `RenderContext` was not enough — + `AstTransformsStage` rebuilds a fresh `RenderContext` from + `StageContext` data, so the resolver had to live on + `StageContext` too and be re-bridged. Adds: + * `StageContext.resource_resolver: Option<ResourceResolverContext>` + with the same docstring contract as on `RenderContext`. + * `run_pipeline` clones `ctx.resource_resolver` into + `stage_ctx.resource_resolver` next to `project_index`. + * `AstTransformsStage::run` clones it back into + `render_ctx.resource_resolver` next to `project_index`. + Without this bridge, `LinkRewriteTransform` saw + `ctx.resource_resolver = None` and emitted bare + `output_href` strings instead of page-relative URLs. + Caught by integration test + `pipeline_body_link_rewrites_doc_relative` failing. + +### CLI end-to-end + regression + +- [x] Smoke fixture at `/tmp/q2-phase6-smoke/` (3 pages, root + + nested + 2-level mix). Observed rendered HTML body links: + * `index.html`: `href="about.html"`, `href="docs/api.html"` + * `about.html`: `href="index.html"` + * `docs/api.html`: `href="../about.html"`, + `href="../index.html"` + Matches the plan's example table 1:1. +- [x] Smoke fixture at `/tmp/q2-phase6-broken-smoke/` exercises + the broken-link path. Rendered HTML body has + `href="missing.qmd"` (verbatim); stderr contains + `Warning: Body link references unknown document 'missing.qmd'`. +- [x] Re-rendered `/tmp/q2-phase2-smoke/`, `/tmp/q2-phase3-smoke/`, + `/tmp/q2-phase4-smoke/`, `/tmp/q2-phase5-website-test/` + under Phase 6 wiring. Sidebar / page-nav HTML structure + unchanged in all of them (the existing fixtures don't have + body-`.qmd` links to rewrite, so the only diff would be in + navigation regions which Phase 6 doesn't touch). All 4 + regression fixtures render cleanly. + +### Hub-client / WASM impact check + +- [x] Audited `crates/wasm-quarto-hub-client/src/lib.rs`. Two + callsites of `render_qmd_to_html` exist (in + `render_qmd_with_options` and `render_qmd_with_resources`); + both now wire + `ctx.resource_resolver = Some(resolver.clone())` next to the + VFS-root resolver creation. `hub-client/src/services/wasmRenderer.ts` + is consumer-side only; it doesn't need changes. +- [x] `cargo xtask verify` (full, including WASM build, hub-client + test suite, and trace-viewer build/tests) — all 9 steps + green on a clean run. The verify-failed-but-fresh-run-passes + transient was a vitest race in a parallel test (likely a + pre-existing flake unrelated to Phase 6); the full re-run + passes 562/562. + +### Verification and close-out + +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — **7876 tests pass** (up + from 7827 pre-Phase-6; net +49 tests covering resolver + `page_url_for`, path normalization, `resolve_doc_relative_href`, + `LinkRewriteTransform` walker, and integration plumbing). +- [x] `cargo xtask lint` passes (632 files checked). +- [x] `cargo fmt --check` clean. +- [x] `cargo xtask verify` (full, including WASM build, + hub-client `npm run build:all`, hub-client tests, and + trace-viewer build/tests) — all 9 steps green. +- [x] No snapshot files added or modified. +- [x] Follow-ups filed (each `discovered-from:bd-v30t`, + verified via `br dep tree`): + * `bd-p4sc` — Body-link draft-mode visibility (priority 3, + epic-scoped via parent-child to bd-0tr6). + * `bd-fo1r` — Body-link index-forgiveness (priority 3, + epic-scoped — could be unified with `bd-jbml` / + `bd-bobp` from Phases 3 / 4). + * `bd-nb32` — `data-noresolveinput` escape hatch + (priority 4, epic-scoped — Q1 parity). + * `bd-j3a0` — Diagnostic dedup by (page, href) (priority 3, + epic-scoped — UX polish). + * `bd-gdrv` — Cross-format URL resolution (priority 4, + `related` to epic — out of website-epic scope, multi- + format projects are a future epic). + * `bd-td2a` — Footer Text-region project-link rewriting + (priority 3, epic-scoped — `related` to `bd-jfyl` from + Phase 5; replaces it once both are reconciled). +- [x] Updated the epic plan's "Work items" checklist — Phase 6 + marked done, sub-plan linked, `bd-v30t` referenced; + follow-up beads logged in the running report section. +- [ ] `br close bd-v30t` with reason citing commit hash + (deferred to commit time). +- [ ] `br sync --flush-only && git add .beads/ && git commit` + (deferred to commit time). +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** A Lua filter that emits `.qmd` hrefs after Phase 6 + bypasses rewriting. *Mitigation:* documented limitation; if real + workflows need this, file a second-pass transform after + AstTransforms. Q1 has the same gap. + +- **Risk:** Body-link rewriting affects standalone (single-doc) + renders. *Mitigation:* Decision 7 standalone no-op; Test 29 + Test + 46 lock it in. + +- **Risk:** Path normalization (`..` / `.`) mishandles edge cases + (Windows paths, trailing slashes, empty segments). + *Mitigation:* Tests 8–15 cover the main cases; cross-platform + rule (CLAUDE.md): forward-slash everywhere on the URL side, even + on Windows. The `Path::components()` walk is inherently OS-aware. + +- **Risk:** `ctx.resource_resolver` not populated in some + `RenderContext` construction site, causing transforms to fall + back to the no-resolver path silently. *Mitigation:* the helper's + no-resolver fallback is correct behavior (returns bare + `output_href` — same as Phase 3's `resolve_href_for_html` does + today). Audit task at close-out. + +- **Risk:** Diagnostic spam — every internal misspelled `.qmd` + link produces a warning, and a real site might have hundreds. + *Mitigation:* matches Q1 behavior. Users can fix the typo. If + this proves loud, file a follow-up to dedupe diagnostics by + href. + +- **Risk:** Cross-format hrefs (HTML page linking to a doc that + outputs PDF) get rewritten as `.html` regardless. *Mitigation:* + out of scope (non-goals). Single-format projects work; multi- + format is a future epic. + +- **Risk:** Rewriting custom-node body-link targets affects a + custom-node consumer that expected source-relative hrefs. + *Mitigation:* by the Finalization Phase placement, the only + custom nodes still in the AST are the post-resolve crossref + nodes (which use fragment hrefs, skipped) and engine outputs + (which don't typically carry `.qmd` links). If a real + custom-node user surfaces an issue, add a `data-noresolveinput` + attribute escape hatch (Q1 has one). + +- **Risk:** Phase 6 affects body links inside callouts / + theorems / proof / footnotes (custom-node Slots). + *Mitigation:* this is the *intended* behavior — body links + inside any wrapper should rewrite. Test 34 locks this in. + +- **Risk:** Performance — walking every `Inline::Link` adds a + per-link helper call. *Mitigation:* the walk is O(N) over + Inlines, the helper is cheap (string ops + one HashMap lookup + via `ProjectIndex`). Compared to the engine + theme-CSS + compilation that dominates render time, negligible. + +## Explicit non-goals for this phase + +- No draft-mode visibility handling (link removal for drafts). +- No index-forgiveness (`docs/` matching `docs/index.qmd`). +- No `.md` / `.ipynb` / `.Rmd` extension support (rides with + `bd-xxul`). +- No cross-format link awareness (HTML→PDF resolution). +- No `Image::target.0` rewriting. +- No HTML post-processing path. AST-side only. +- No `data-noresolveinput` escape hatch (Q1 feature). +- No diagnostic deduplication. +- No `<base href>` / root-relative URL output. +- No incremental-rebuild interaction (Phase 8). + +## Follow-up beads (to file at close-out) + +- **Draft-mode visibility for body links** — when + `DocumentProfile.draft && draftMode != "visible"`, replace the + `<a>` with its inner content. Needs draft-mode YAML config first + (currently no Q2 surface for it). +- **Index-forgiveness for body links** — `docs/` matches + `docs/index.qmd`. Mirrors Phase 3's `bd-jbml` and Phase 4's + `bd-bobp`. Consider unifying as a single epic-wide bead. +- **`data-noresolveinput` escape hatch** — Q1 lets a Lua filter or + hand-authored HTML opt out of rewriting via this attribute. + Phase 6 doesn't honor it; file once a real workflow surfaces. +- **Diagnostic deduplication** — if a site has many broken `.qmd` + links, the warning list grows fast. A simple "first occurrence + wins" dedupe per (page, href) would tame the output. +- **Cross-format link resolution** — once Q2 supports per-doc + `format:` overrides in the project, body links targeting a + PDF-output doc should produce `.pdf` hrefs. +- **Rich-source link rewriting** — the helper assumes + `link.target.0` is a plain forward-slash string. If + `Inlines`-bearing link targets ever land (Pandoc has talked + about it), audit the rewriter. + +## Open questions (resolved during implementation) + +1. **Active custom nodes at Phase 6's slot — do any wrap body + links?** *Resolved 2026-04-27.* By the start of Finalization + Phase, `CalloutResolveTransform` and `CrossrefResolveTransform` + have run; `FloatRefTargetSugarTransform`, `EquationLabelTransform`, + `TheoremSugarTransform`, `ProofSugarTransform`, and shortcode + outputs *can* leave `Inline::Custom` / `Block::Custom` nodes + live in the AST. Those slots may carry `Inlines` containing + `Link`s. The recursive walk handles them correctly; the unit + test `link_rewrite_walks_custom_node_slots` locks this in. + No trimming, no special-case test added — the contract holds. +2. **Hub-client behavior.** *Resolved 2026-04-27.* The two + WASM callsites (`render_qmd_with_options`, + `render_qmd_with_resources`) wire + `ResourceResolverContext::vfs_root("/.quarto/project-artifacts")` + into `ctx.resource_resolver`; the `page_url_for` VFS branch + returns absolute `/.quarto/project-artifacts/<output_href>` + URLs (test `page_url_for_vfs_root_mode` confirms the shape). + The actual hub-client multi-doc preview flow doesn't yet pass + a `project_index`, so body-link rewriting is a no-op in the + browser today — Phase 9 lights it up. +3. **Diagnostic source-info.** Deferred. Today the helper still + produces a plain `DiagnosticMessage::warning(text)` (matches + the navigation helpers' shape from Phases 2/3/4). When source + info is plumbed through, both helpers should switch together + to keep diagnostic shape consistent across navigation / + body links. Not blocking Phase 6. +4. **Per-page output href format.** `DocumentProfile.output_href` + is forward-slash, project-relative, non-empty for renderable + docs (verified by reading the profile contract doc and + inspecting `DocumentProfileStage`'s output). The resolver's + `page_url_for` and the helper both treat it as a string and + pass it through `pathdiff` / segment-walks — no path + reinterpretation needed. + +## Decisions log (confirmed 2026-04-27) + +1. **AST-side rewrite** (not HTML post-processing). Walk + `Inline::Link` nodes; mutate `target.0` in place. +2. **Pipeline placement**: start of Finalization Phase, between + Navigation Render transforms and `AppendixStructureTransform`. +3. **New helper** `resolve_doc_relative_href` in + `navigation_href.rs`, alongside `resolve_href_for_html`. +4. **`page_url_for` method** added to `ResourceResolverContext` + for page-relative URL math (mirrors `html_url_for`). +5. **`resource_resolver` field** added to `RenderContext` (and, + discovered during integration testing, also to `StageContext` + with bridging in `run_pipeline` and `AstTransformsStage`). +6. **`LinkRewriteTransform`** walks blocks / inlines / custom + slots recursively, mirroring `crossref_render` and + `resource_collector` traversal patterns. +7. **Standalone (no `project_index`) render** is a no-op. +8. **Diagnostic shape**: `source_label = "Body link"`, message + matches `<label> references unknown document '<path>'`. +9. **Inline path-normalization helper** (~30 lines) instead of + adding a `path-clean` crate dep. Walks forward-slash segments + to dodge OS-specific path surprises. +10. **Page-relative output URLs** (Q1 parity); the resolver + handles depth via `pathdiff::diff_paths`. + +## Epic-level impact + +Phase 6 closes the **link-resolution surface** for websites: + +- Navigation hrefs (sidebar / navbar / footer / page-nav) — Phase 2/3/4 +- Shared-asset URLs (`<link>` / `<script>`) — Phase 5 +- Body-content links — Phase 6 + +After Phase 6, every `.qmd` reference in a website project — config- +sourced or content-sourced — resolves to the correct rendered URL +on every page, regardless of nesting depth. + +The shared resolver (`ResourceResolverContext::page_url_for`) is the +**third consumer** of the relative-URL math Phase 5 introduced +(after `html_url_for` for assets and the on-disk-path side). When +Phase 7 lands `<link rel="canonical">` and sitemap URLs, those will +likely become a fourth consumer using `site_url + output_href`. + +Phase 5's follow-up `bd-jfyl` (footer Text-region project-link +rewriting) was deferred precisely because Phase 6's helper is its +natural home: once Phase 6 ships, `bd-jfyl` is "call +`resolve_doc_relative_href` from the footer renderer's text walker". + +Phase 6 also unblocks a real Q2 docs-site authoring loop: until body +links rewrite, every `[See chapter X](chapter-x.qmd)` would be a +broken link in the rendered output, blocking the docs epic +(`bd-tr81`). diff --git a/claude-notes/plans/2026-04-27-websites-phase-7.md b/claude-notes/plans/2026-04-27-websites-phase-7.md new file mode 100644 index 000000000..0cd286d9b --- /dev/null +++ b/claude-notes/plans/2026-04-27-websites-phase-7.md @@ -0,0 +1,1145 @@ +# Phase 7 — Post-render (sitemap, favicon, site-url / title-prefix) + +**Date:** 2026-04-27 +**Beads:** `bd-b9mz` (parent `bd-0tr6`). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-24-websites-phase-6.md` +**Status:** Draft — pending user review. + +## Goal of this phase + +Phase 7 closes the **site-shape surface** for websites — the four +features that turn a folder of rendered pages into a site that knows +its own identity: + +1. **Title prefix.** A page with `title: "Getting Started"` in a + project where `website.title: "Quarto Docs"` should render as + `<title>Getting Started – Quarto Docs`. +2. **Favicon.** `website.favicon: favicon.ico` results in (a) the file + copied to `_site/favicon.ico` and (b) `` injected into every page's ``, with + the href page-relative. +3. **Sitemap.** When `website.site-url` is set, emit + `_site/sitemap.xml` listing every rendered page with its `` + (absolute URL based on `site-url`) and `` (input file + mtime). +4. **robots.txt.** If `/robots.txt` exists, copy it. Else, if + `website.site-url` is set, emit a one-line robots.txt pointing at + the sitemap. + +Three of the four (favicon link, title prefix) are **per-page** +contributions made during Pass 2; favicon copy, sitemap, and +robots.txt are **project-level** writes done in +`WebsiteProjectType::post_render` after Pass 2 finishes. + +This phase does **not** implement: + +- **Open Graph / Twitter card / social meta tags.** Q1 has these via + `metadataHtmlPostProcessor`. Out of MVP — file as a follow-up bead + when there's a real consumer. +- **Brand-aware favicon fallback.** Q1's favicon falls back to + `brand.light.favicon`. Q2 doesn't have brand support yet; defer. +- **Multi-format favicon variants** (apple-touch-icon, multi-size). + Single `` with a single href is the MVP. Q1 also + emits one entry. +- **Empty-`index.html` filtering in the sitemap.** Q1 skips + `index.html` files whose source `qmd` has no body. Q2 emits all + pages; defer the filter once `DocumentProfile` carries an + is-empty signal. +- **Draft-mode interaction with the sitemap.** Q1 omits drafts (or + writes them with `` markers depending on `draft-mode`). Q2 + has `DocumentProfile.draft` but no draft-mode YAML config — defer + the visibility logic, and for Phase 7 just emit every profiled + page (drafts included). The eventual draft-mode bead will gate + this in the same place Phase 6's body-link rewriter does. +- **Incremental sitemap merge.** Q1 reads the existing `sitemap.xml`, + patches changed entries, writes back. Q2 today renders every page + every time, so a fresh-write each run produces the same on-disk + result as a read-merge-write. Phase 8's incremental rebuild will + add the merge logic; Phase 7 ships fresh-write only. **The epic + plan calls out "Incremental-aware: read existing, update, write" — + we propose deferring that to Phase 8 because without incremental + rebuilds there is no behavioral difference. User sign-off needed + on this scope cut.** +- **`canonical-url`.** The full template already has a + `$canonical-url$` slot (`template.rs:146-148`); Phase 7 could + populate it from `website.site-url + output_href`. Recommend + including this — it's a 5-line addition once site-url is read. +- **``.** Already populated by the template + engine (`template.rs:133`). No work. +- **Repo-actions / source links / `edit-on-github` `` + contributions.** Out of epic scope per parent plan. +- **Browser tab detection of HTML changes via meta refresh / cache + headers.** Out of scope. +- **Per-page `` overrides for favicon.** A document that sets + its own `favicon` field doesn't override the website's. Confirmed + with user 2026-04-27 to leave out of Phase 7 *but* track as an + explicit follow-up bead — the user expects this to come up + sooner rather than later. Filed as `bd-` + at close-out (see §Follow-up beads). + +## Reference material + +- **Parent epic plan** §"Phase 7 — Post-render". +- **Phase 1 sub-plan** §"`ProjectType` trait shape" (the trait + signature; `post_render` already accepts everything Phase 7 + needs). +- **Phase 5 sub-plan** §"`ResourceResolverContext`" (page_url_for + used for the favicon `` href). +- **Phase 6 sub-plan** §Decision 4 (`page_url_for` works for any + project-relative output href, not just page hrefs — favicon path + qualifies). +- **Q2 current code:** + - `crates/quarto-core/src/project/orchestrator.rs:170-229` — + `WebsiteProjectType::post_render`. Today flushes `site_libs/`; + Phase 7 grows it. + - `crates/quarto-core/src/transforms/metadata_normalize.rs` — + `MetadataNormalizeTransform`. Phase 7's title-prefix transform + sits adjacent and is the closest analogue. + - `crates/quarto-core/src/transforms/navbar_render.rs:134-142` — + `brand_title_fallback`: reads `meta.get_path(&["website", + "title"])`. Phase 7's transforms reuse this access pattern. + - `crates/quarto-core/src/template.rs:128-235` — + `FULL_HTML_TEMPLATE`. Slots Phase 7 writes into: + `$pagetitle$` (line 149), `$header-includes$` (line 158), + `$canonical-url$` (line 146). + - `crates/quarto-core/src/template.rs:330-365` — + `set_includes_list`: how `header-includes` is currently + populated from metadata. Phase 7's favicon transform appends to + the same list. + - `crates/quarto-core/src/document_profile.rs:46-94` — + `DocumentProfile`. Phase 7 reads `output_href`, `source_path`, + `title`. No new profile fields needed. + - `crates/quarto-core/src/project/index.rs` — `ProjectIndex`. + Phase 7 reads `profiles()` for the sitemap walk. + - `crates/quarto-core/src/resource_resolver.rs:176-186` — + `page_url_for`. Phase 7 calls it for the favicon `` href. + - `crates/quarto-core/src/project/mod.rs:294-336` — + `ProjectConfig`. `metadata: Option` is where the + project-level `website.*` keys live; readable from + `post_render` via `project.config.metadata`. + - `crates/quarto-system-runtime/src/traits.rs` — `SystemRuntime` + methods Phase 7 uses: `file_write`, `file_copy`, `path_exists`, + `path_metadata` (for mtime). +- **Q1 reference:** + - `external-sources/quarto-cli/src/project/types/website/website-sitemap.ts` + lines 32–193 — full sitemap + robots.txt logic. Phase 7 ports + to Rust in idiomatic style. + - `external-sources/quarto-cli/src/project/types/website/website.ts` + lines 175–216 — title-prefix and favicon plumbing. + - `external-sources/quarto-cli/src/project/types/website/website-shared.ts` + lines 90–115 — `computePageTitle` semantics. Phase 7 mirrors. + - `external-sources/quarto-cli/src/project/types/website/website-config.ts` + lines 170–188 — `websiteTitle`, `websiteBaseurl`, `websiteImage`. + - `external-sources/quarto-cli/src/resources/projects/website/templates/sitemap.ejs.xml` + — sitemap XML shape (urlset / url / loc / lastmod). + - `external-sources/quarto-cli/src/project/types/website/website-constants.ts` + — canonical key names: `kSiteUrl = "site-url"`, + `kSiteFavicon = "favicon"`, `kSiteTitle = "title"`. + +## Key decisions (to confirm with user) + +These are proposed — please push back on anything that looks wrong +before we start. + +### Decision 1 — Phase 7 splits cleanly into per-page Pass-2 transforms and post-render writes + +| Concern | Where it runs | Reads | Writes | +|---|---|---|---| +| Title prefix | Pass 2, AST transform | `ast.meta.website.title`, `ast.meta.title`, `ast.meta.pagetitle` | `ast.meta.pagetitle` | +| Favicon `` | Pass 2, AST transform | `ast.meta.website.favicon`, `RenderContext.resource_resolver` | `ast.meta.header-includes` (append) | +| Canonical URL (proposed inclusion) | Pass 2, AST transform | `ast.meta.website.site-url`, `RenderContext` (current page's output_href via `RenderContext.document.output`) | `ast.meta.canonical-url` | +| Favicon file copy | post_render | `project.config.metadata.website.favicon` | `/` | +| Sitemap | post_render | `project.config.metadata.website.site-url`, `ProjectIndex.profiles()`, input mtimes | `/sitemap.xml` | +| robots.txt | post_render | `project.dir/robots.txt` (if exists), `website.site-url` | `/robots.txt` | + +**Rationale.** The two halves consume different state. Per-page +transforms have access to `ast.meta` and the per-page resolver but +don't see the full `ProjectIndex` walk; post_render has the index and +direct `SystemRuntime` access but doesn't touch any individual page's +AST. The split mirrors Phase 5 (per-page artifact emission + +post-render flush). + +### Decision 2 — Three small AST transforms, not one omnibus + +Three separate transforms in `crates/quarto-core/src/transforms/`: + +1. `WebsiteTitlePrefixTransform` — modifies `pagetitle`. +2. `WebsiteFaviconTransform` — appends a `` to `header-includes`. +3. `WebsiteCanonicalUrlTransform` — sets `canonical-url`. + +**Rationale.** Each is ~30–50 lines, has a single responsibility, +and tests independently. Bundling them would force "if any +website.* key is set" branching for shared work that doesn't exist +— each transform reads a different config key. Also keeps Phase 7 +easy to extend in follow-ups (Open Graph tags would be a fourth +transform of identical shape; analytics a fifth). + +**Naming.** `Website*Transform` is the prefix; matches existing +`WebsiteProjectType` and is searchable. Alternative `Site*` was +rejected because Q1 uses `kSite*` for keys and `website*` for +helpers — Q1's naming is the authoritative reference. + +**Trade-off.** Three name slots in `transforms/mod.rs` instead of +one. Acceptable — `transforms/` already has 25+ entries and search +discovers `Website*` cleanly. + +### Decision 3 — Pipeline placement: right after `MetadataNormalizeTransform` + +`MetadataNormalizeTransform` produces `pagetitle` from `title` if +absent. The website transforms read `pagetitle` *after* that +derivation, so they must run later. Placement: + +``` +MetadataNormalizeTransform +WebsiteTitlePrefixTransform ← NEW +WebsiteFaviconTransform ← NEW +WebsiteCanonicalUrlTransform ← NEW +… (existing pre-engine and engine stages) +``` + +These are pure metadata transforms — they touch only `ast.meta`, +not blocks/inlines — so their relative ordering with respect to +later AST transforms (`Sugar`, `Engine`, navigation generate/render, +link-rewrite, crossref) is irrelevant. The latest-binding +constraint is just "after `pagetitle` is derived, before +`ApplyTemplate` reads it". + +**Standalone-render no-op contract.** Each transform reads its +config key under `meta.website.*`. If no `website.*` namespace +exists (single-doc render with no project), all three are no-ops. +Same shape as Phases 2–6's "no `project_index` → no-op" pattern. + +### Decision 4 — Title prefix algorithm mirrors Q1 `computePageTitle` + +Pseudocode: + +``` +let website_title = meta.website.title.as_plain_text()?; +let title = meta.title.as_plain_text(); +let pagetitle = meta.pagetitle.as_plain_text(); + +// Already explicit? Don't touch. +if pagetitle.is_some() && pagetitle != Some(title.unwrap_or("")) { + return; // user / earlier transform set it +} + +let new_pagetitle = match (title, website_title) { + (Some(t), wt) if t == wt => t, // page == site + (Some(t), wt) => format!("{t} – {wt}"), // both, distinct + (None, wt) => wt, // home page fallback +}; +meta.pagetitle = new_pagetitle; +``` + +Notes: +- Uses an **en-dash** (`–`, U+2013) to match Q1 line 108. +- The "pagetitle already set" check distinguishes + *MetadataNormalize-derived* `pagetitle` (always equals `title`) + from *user-or-earlier-transform-set* `pagetitle` (which we + preserve). Concretely: if `pagetitle == title`, treat it as + derived and rewrite; otherwise leave it. This is a small heuristic + that's robust because both Q1 and Q2 only auto-derive + `pagetitle = title`, never `pagetitle = something-else`. +- Home page handling: Q1 has a dedicated "if `stem == 'index'` and + no title at all, use `website.title` as pagetitle". Our + algorithm subsumes this via the `(None, wt) => wt` branch — any + page with no title uses the website title. The Q1 `stem == index` + guard exists to avoid clobbering pages that *intentionally* lack + a title with the website title; Q2 v1 takes the simpler + always-use-website-title-as-fallback rule. **Recommend going with + the simple rule and revisiting if a real fixture surfaces a + problem.** + +### Decision 5 — Favicon `` is appended to `header-includes` + +The full HTML template already loops over `header-includes` (lines +158–160 of `template.rs`). Phase 7's favicon transform produces a +`` string and appends it to that list. + +**Why not a dedicated `$favicon$` template slot?** Two reasons: +1. The template would gain a Phase-7-specific slot for a + one-line contribution. `header-includes` is the existing + "additional `` content" channel; using it scales as we + add more head contributions (canonical, OG, analytics, …) + without churning the template. +2. The template engine renders `header-includes` as raw HTML + already (see `template.rs:88-91, 158-160`), so no new template + plumbing needed. + +**MIME-type detection.** Trivial extension map: + +| extension | type | +|---|---| +| `.ico` | `image/x-icon` | +| `.png` | `image/png` | +| `.svg` | `image/svg+xml` | +| `.gif` | `image/gif` | +| `.jpg` / `.jpeg` | `image/jpeg` | +| else | `omit type="..." attribute` | + +~10-line helper in the favicon transform module. No external dep. + +**HTML emitted.** + +```html + +``` + +When `mime` is unknown, omit the `type` attribute. Q1 emits `type` +unconditionally via `contentType(favicon)`; we degrade gracefully. + +**`href` computation.** Use +`ResourceResolverContext::page_url_for(favicon_path)`. The favicon's +project-relative path (e.g. `favicon.ico`, `assets/favicon.png`) is +the same in source and output dirs because Phase 7 copies it +verbatim — so `page_url_for` (which expects a project-relative +output href) gives the right relative URL from any page. + +**No-resolver fallback.** If `ctx.resource_resolver` is `None` (a +scenario that shouldn't happen in Pass 2 of a website project but +is possible in tests), emit the favicon path verbatim. Same +defensive shape as Phase 6. + +### Decision 6 — Canonical URL transform (proposed inclusion) + +Phase 7 also populates the existing `$canonical-url$` slot +(`template.rs:146-148`): + +```html +$if(canonical-url)$ + +$endif$ +``` + +Algorithm: + +``` +let site_url = meta.website.site-url.as_plain_text()?; +let output_href = ctx.document.output_href()?; // doc's own project-rel output +let canonical = format!("{}/{}", site_url.trim_end_matches('/'), output_href); +meta.canonical-url = canonical; +``` + +**Why include this?** Marginal cost (~30 lines + 3 tests), and +without it `site-url` is only useful for the sitemap — a half-done +feature. Q1 does not (yet) emit canonical-url either, so this is a +small Q2-only win. **User decides: include in Phase 7 or defer to +its own follow-up bead?** Recommend include. + +If the user defers it, drop §Decision 6, drop the `WebsiteCanonicalUrlTransform` +from §Module shape, drop tests 16–19, and remove the +`canonical-url` row from §Decision 1's table. + +### Decision 7 — Reading website.* config + +Add a small helper module +`crates/quarto-core/src/project/website_config.rs`: + +```rust +/// Read `website.title` from a merged metadata value. +pub fn website_title(meta: &ConfigValue) -> Option { … } +/// Read `website.site-url`. Trailing slash NOT stripped — callers +/// strip if they need to (sitemap does, link emission can leave it). +pub fn website_site_url(meta: &ConfigValue) -> Option { … } +/// Read `website.favicon`. Forward-slash, project-relative path. +pub fn website_favicon(meta: &ConfigValue) -> Option { … } +``` + +All three accept a `&ConfigValue` so they work for both +`ast.meta` (per-page transforms) and +`project.config.metadata.as_ref()?` (post_render). + +**Why a dedicated module?** Three reads, three transforms, one +post_render hook → six call sites. Centralizing avoids drift if +Q2 ever moves the keys (the epic-wide nav-config-placement +follow-up `bd-n9dr` could rename `website.title` to e.g. +`title-prefix` at top-level; a single helper is one edit). + +**Module placement.** `quarto-core/src/project/website_config.rs`, +re-exported from `project/mod.rs`. Adjacent to `ProjectContext` +which owns the on-disk `_quarto.yml`. Other crates can import +`quarto_core::project::website_config::{…}`. + +### Decision 8 — Favicon copy in post_render + +Algorithm: + +``` +let Some(favicon_path) = website_favicon(&project.config.metadata?) else { return }; +let src = project.dir.join(&favicon_path); +if !runtime.path_exists(&src) { + diagnose("website.favicon refers to missing file '{}'", favicon_path); + return; +} +let dst = project.output_dir.join(&favicon_path); +if let Some(parent) = dst.parent() { runtime.dir_create(parent, true)?; } +runtime.file_copy(&src, &dst)?; +``` + +Notes: +- **Copy, don't symlink** — `_site/` is meant to be standalone. +- **Missing source.** Diagnose, do not error. `` tag is still + emitted; if the user packages `_site/` with a missing favicon, + browsers fall back to no icon. Q1 silently skips; Q2's + diagnostic is mildly more helpful. +- **Idempotent.** `file_copy` overwrites. No staleness check — + Phase 8 incremental will gate this. + +### Decision 9 — Sitemap algorithm (fresh-write only in Phase 7) + +``` +let Some(site_url) = website_site_url(&project.config.metadata?) else { + return; // no site-url → no sitemap +}; +let base = site_url.trim_end_matches('/'); +let mut entries = Vec::with_capacity(index.profiles().len()); +for profile in index.profiles() { + let loc = format!("{}/{}", base, profile.output_href); + let lastmod = file_mtime_iso8601(&profile.source_path, runtime); + entries.push(SitemapEntry { loc, lastmod }); +} +let xml = render_sitemap_xml(&entries); +runtime.file_write(&project.output_dir.join("sitemap.xml"), xml.as_bytes())?; +``` + +Notes: +- **Encoding.** XML-escape `loc` (`&`, `<`, `>`, `"`, `'`). Q1 uses + `lodash.escape`. Inline our own ~10-line escaper — same tactic + Phase 6 used for path normalization (no new crate dep). +- **lastmod.** ISO-8601 timestamp from input file mtime. + `runtime.path_metadata(&profile.source_path)?.mtime()`. If + unreadable, omit `` (Q1 falls back to "1970"; we omit, + cleaner XML). +- **Drafts.** Phase 7 includes drafts. The "skip drafts unless + visible" filter is the same as Phase 6's deferred draft-mode + handling — file as the same follow-up bead, don't fork the + decision. +- **Output path.** `/sitemap.xml`. Always at + the site root. +- **Deterministic order.** Iterate `index.profiles()` directly — + `ProjectIndex` preserves Pass-1 insertion order. Phase 8's + incremental rebuild will need to preserve that ordering after + partial updates; for Phase 7 it's just-in-time correct. + +**Sitemap XML shape.** + +```xml + + + + https://example.com/index.html + 2026-04-27T14:32:11Z + + … + +``` + +Hand-written formatter, ~25 lines. No XML library dep. + +**Open question (§Open questions): trailing-slash policy on +``.** Q1 emits `https://example.com/index.html` (file URL). +Some sites prefer `https://example.com/` for the home page. We +follow Q1. + +### Decision 10 — robots.txt + +``` +let dst = project.output_dir.join("robots.txt"); +let src = project.dir.join("robots.txt"); +if runtime.path_exists(&src) { + runtime.file_copy(&src, &dst)?; + return; +} +let Some(site_url) = website_site_url(&project.config.metadata?) else { + return; +}; +let base = site_url.trim_end_matches('/'); +let body = format!("Sitemap: {base}/sitemap.xml\n"); +runtime.file_write(&dst, body.as_bytes())?; +``` + +Notes: +- User's `robots.txt` wins (Q1 parity). +- Auto-generated robots.txt only when `site-url` is set — + otherwise it'd reference a non-existent sitemap. +- No idempotence check — overwrite each render. Phase 8 + incremental will skip if unchanged. + +### Decision 11 — `post_render` ordering + +```rust +async fn post_render(...) -> Result<()> { + flush_site_libs(...)?; // existing (Phase 5) + copy_favicon(...)?; // new (Phase 7) + write_sitemap(...)?; // new (Phase 7) + write_robots_txt(...)?; // new (Phase 7) + Ok(()) +} +``` + +**Why this order.** No real dependencies between the four — each +writes to a different output file. The grouping is "shared assets +first (site_libs, favicon), discovery files last (sitemap, +robots)" for readability. Failures in any one short-circuit the +rest (matches Phase 1's `?` propagation; Phase 5 already does +this). + +**Refactor proposed.** The current `post_render` body in +`orchestrator.rs:186-228` is inlined site_libs flushing. Phase 7 +extracts it to a private fn `flush_site_libs(...)` and adds three +sibling fns `copy_favicon`, `write_sitemap`, `write_robots_txt` — +all in `orchestrator.rs` (or in a new +`crates/quarto-core/src/project/website_post_render.rs` if the +file gets too long). Recommend **extract into +`website_post_render.rs`** to keep `orchestrator.rs` focused on +orchestration mechanics; `WebsiteProjectType::post_render` becomes +a four-line composition. + +### Decision 12 — DocumentProfile change + +**None.** Phase 7's reads (`output_href`, `source_path`, `title`) +are all profile-version-1 fields. No bump. + +## Architecture sketch + +### Module shape + +``` +crates/quarto-core/src/project/ + website_config.rs # NEW — website_title / website_site_url / website_favicon + website_post_render.rs # NEW — flush_site_libs / copy_favicon / write_sitemap / write_robots_txt + orchestrator.rs # WebsiteProjectType::post_render → 4-line composition + mod.rs # re-export website_config + +crates/quarto-core/src/transforms/ + website_title_prefix.rs # NEW — WebsiteTitlePrefixTransform + website_favicon.rs # NEW — WebsiteFaviconTransform + website_canonical_url.rs # NEW — WebsiteCanonicalUrlTransform (if Decision 6 confirmed) + mod.rs # re-exports + +crates/quarto-core/src/pipeline.rs # insert the three new transforms after MetadataNormalizeTransform +``` + +### Data flow + +**Per-page (Pass 2):** + +``` +ast.meta (post-MetadataMergeStage, has website.*) + │ + ▼ +MetadataNormalizeTransform (sets pagetitle = title if absent) + │ + ▼ +WebsiteTitlePrefixTransform (rewrites pagetitle if website.title) + │ + ▼ +WebsiteFaviconTransform (appends to header-includes) + │ + ▼ +WebsiteCanonicalUrlTransform (sets canonical-url) + │ + ▼ (existing engine + transforms) + ▼ +ApplyTemplate reads pagetitle, header-includes, canonical-url +``` + +**Project-level (after Pass 2):** + +``` +ProjectIndex.profiles() ──┐ +project.config.metadata ──┼──> WebsiteProjectType::post_render +project.dir, output_dir ──┤ ├── flush_site_libs (Phase 5) +SystemRuntime ────────────┘ ├── copy_favicon + ├── write_sitemap + └── write_robots_txt +``` + +### Single-doc behavior (regression) + +For a default project (no `_quarto.yml`, or `project.type: +default`): +- Per-page transforms read `meta.get_path(&["website", "title"])` + etc., which return `None`. Each transform returns early — no AST + mutation, no diagnostics. +- post_render is `DefaultProjectType`'s no-op default. Nothing + written. + +A standalone `.qmd` file with no website context produces +byte-identical output to pre-Phase-7. Locked by regression tests. + +## Tests (TDD: write and fail first) + +Every test authored before the code that makes it pass. + +### Unit tests — `website_config` helpers + +1. `website_title_reads_string` — `website: { title: "Site" }` → + `Some("Site")`. +2. `website_title_reads_inlines_as_plain_text` — + `website: { title: [Str "S", Space, Str "T"] }` → `Some("S T")`. +3. `website_title_missing_returns_none` — no `website` key. +4. `website_site_url_reads_string` — `website: { site-url: "https://example.com/" }`. +5. `website_favicon_reads_string` — `website: { favicon: "favicon.ico" }`. +6. `website_helpers_handle_non_map_meta` — `meta` is a scalar: + all three return `None` without panic. + +### Unit tests — `WebsiteTitlePrefixTransform` + +7. `title_prefix_no_op_without_website_title` — no `website.title` + → `pagetitle` unchanged. +8. `title_prefix_combines_doc_and_site_titles` — + doc title `"Getting Started"`, website title `"Quarto Docs"` → + `pagetitle = "Getting Started – Quarto Docs"`. +9. `title_prefix_skips_when_titles_equal` — + doc title == website title → `pagetitle = "Quarto Docs"` (no + `– Quarto Docs`). +10. `title_prefix_uses_website_title_for_untitled_page` — + no doc title, website title `"Quarto Docs"` → + `pagetitle = "Quarto Docs"`. +11. `title_prefix_preserves_explicit_pagetitle` — + `pagetitle: "Explicit"`, doc title `"Doc"`, website + title `"Site"` → `pagetitle = "Explicit"` (untouched, because + `pagetitle != title`). +12. `title_prefix_overrides_normalize_derived_pagetitle` — + `MetadataNormalize` set `pagetitle = title = "Doc"`, + website title `"Site"` → `pagetitle = "Doc – Site"`. + +### Unit tests — `WebsiteFaviconTransform` + +13. `favicon_no_op_without_website_favicon` — + `header-includes` unchanged. +14. `favicon_appends_link_with_resolved_href` — + `website.favicon = "favicon.ico"`, resolver returns + `"../favicon.ico"` → `header-includes` ends with + ``. +15. `favicon_appends_without_type_for_unknown_extension` — + `website.favicon = "favicon.foo"` → `` omits `type` + attribute. +16. `favicon_falls_back_to_path_verbatim_without_resolver` — + no `ctx.resource_resolver` → href is `"favicon.ico"`. +17. `favicon_handles_subdirectory_path` — + `website.favicon = "assets/favicon.svg"`, resolver returns + `"../assets/favicon.svg"` → `` has that href and + `type="image/svg+xml"`. +18. `favicon_appends_to_existing_header_includes` — existing + `header-includes: [""]` is preserved; new + `` appended. + +### Unit tests — `WebsiteCanonicalUrlTransform` (if Decision 6 confirmed) + +19. `canonical_url_no_op_without_site_url` — + `canonical-url` unchanged. +20. `canonical_url_composes_site_url_and_output_href` — + `website.site-url: "https://example.com/"`, + `output_href: "docs/api.html"` → + `canonical-url = "https://example.com/docs/api.html"`. +21. `canonical_url_handles_trailing_slash_on_site_url` — + same with no trailing slash on site-url. +22. `canonical_url_skips_when_no_output_href` — defensive: an AST + used in tests without a populated render context. + +### Unit tests — sitemap generator + +23. `sitemap_xml_empty_urlset` — zero entries → valid empty + ``. +24. `sitemap_xml_single_entry` — one entry → conformant XML with + `` + ``. +25. `sitemap_xml_escapes_special_chars` — entry with `loc` + containing `&` → `&` in output. +26. `sitemap_xml_omits_lastmod_when_unknown` — entry with no mtime + → no `` element. +27. `sitemap_url_join_strips_trailing_slash` — + site-url `"https://example.com/"` + `output_href "x.html"` → + `"https://example.com/x.html"`. + +### Unit tests — robots.txt generator + +28. `robots_txt_default_body` — site-url `"https://example.com"` + → `"Sitemap: https://example.com/sitemap.xml\n"`. +29. `robots_txt_strips_trailing_slash_in_sitemap_url` — + site-url `"https://example.com/"` → same as test 28. + +### Integration tests — `crates/quarto-core/tests/website_post_render.rs` (new) + +30. `pipeline_title_prefix_combines_titles` — two-page website + with `website.title: "Site"`. After render, + `_site/index.html` has `Index – Site`, + `_site/about.html` has `About – Site`. +31. `pipeline_favicon_link_emitted_per_page` — website with + `website.favicon: "favicon.ico"`. After render, every page's + `` contains a ``. Nested page's href + starts with `../`; root page's does not. +32. `pipeline_favicon_file_copied_to_output_dir` — same fixture: + `_site/favicon.ico` exists. +33. `pipeline_canonical_url_per_page` (if Decision 6) — + `website.site-url: "https://example.com"`. `_site/index.html` + has ``. +34. `pipeline_sitemap_emitted_with_site_url` — sitemap has both + pages' URLs based on site-url. +35. `pipeline_sitemap_omitted_without_site_url` — fixture with + `website.title` set but no site-url → no `_site/sitemap.xml`. +36. `pipeline_robots_txt_emitted_when_site_url_set` — + `_site/robots.txt` written with `Sitemap:` line. +37. `pipeline_robots_txt_user_file_takes_precedence` — fixture + with hand-written `robots.txt` in the project root → that + file copied verbatim, not the auto-generated one. +38. `pipeline_favicon_missing_diagnoses_continues` — fixture + `website.favicon: "missing.ico"` (file not present) → + rendered HTML still has ``, + `_site/missing.ico` does NOT exist, diagnostic warning + surfaced in summary. +39. `pipeline_default_project_no_phase_7_outputs` — single-doc + fixture (no `_quarto.yml`, no `website.*`) → no sitemap, no + robots.txt, no favicon copy, byte-identical output to + pre-Phase-7 (regression guard for the cross-cutting invariant). + +### CLI end-to-end (per CLAUDE.md §End-to-end verification) + +40. **Full-stack smoke** at `/tmp/q2-phase7-smoke/`: + ``` + _quarto.yml: + project: { type: website, output-dir: _site } + website: + title: "Phase 7 Test Site" + site-url: "https://example.com/site" + favicon: "favicon.ico" + favicon.ico: # 1×1 transparent PNG renamed + index.qmd: "---\ntitle: Home\n---\nWelcome." + about.qmd: "---\ntitle: About\n---\nAbout us." + docs/api.qmd: "---\ntitle: API\n---\n# API" + ``` + Run `cargo run --bin q2 -- render /tmp/q2-phase7-smoke/` and inspect: + - `_site/sitemap.xml` exists and lists all three URLs with + `https://example.com/site/...` prefix. + - `_site/robots.txt` exists and contains + `Sitemap: https://example.com/site/sitemap.xml`. + - `_site/favicon.ico` exists (binary copy). + - `_site/index.html` contains + `Home – Phase 7 Test Site`, + ``, + ``. + - `_site/docs/api.html` contains + `API – Phase 7 Test Site`, + ``, + ``. + Record observed snippets in close-out. + +41. **Regression smokes**: re-run `/tmp/q2-phase2-smoke/`, + `/tmp/q2-phase3-smoke/`, `/tmp/q2-phase4-smoke/`, + `/tmp/q2-phase5-website-test/`, `/tmp/q2-phase6-smoke/`. None + of these set `website.site-url` or `website.favicon`, so: + - No sitemap, no robots.txt, no favicon copy. + - `` includes the website-title prefix where + `website.title` is set in those fixtures. + - All other behavior unchanged. + +### Snapshot tests + +None — inline asserts over emitted HTML, sitemap XML, and +robots.txt cover the vocabulary. Consistent with Phases 2–6. + +## Work items (checklist) + +### Preparation +- [ ] Re-read `claude-notes/instructions/testing.md`, + `coding.md`, `review.md`. +- [ ] Confirm user agreement with Decisions 1–12. +- [ ] Resolve open questions §"Open questions" below. +- [x] File `bd` issue under parent `bd-0tr6`. (`bd-b9mz`) +- [ ] Commit directly on `feature/websites` (Phase 1–6 precedent). + +### `website_config` helper (`quarto-core/src/project/website_config.rs`) +- [x] New module: `website_title`, `website_site_url`, `website_favicon`, + plus `normalize_favicon_path` (Open Question 4). +- [x] Re-export from `project/mod.rs`. +- [x] Tests 1–6 + 2 normalization tests (8 total, all passing). + +### `WebsiteTitlePrefixTransform` (`transforms/website_title_prefix.rs`) +- [x] New module per Decision 4. En-dash separator (U+2013). +- [x] `mod.rs` re-export. +- [x] Tests 7–12 + 2 extras (idempotency, non-map meta defensive). 8 + total, all passing. + +### `WebsiteFaviconTransform` (`transforms/website_favicon.rs`) +- [x] New module per Decision 5. Promotes scalar `header-includes` + to array on append; preserves Pandoc-inline / unknown shapes + defensively. +- [x] Inline MIME-type helper + HTML-attr escape. +- [x] Tests 13–18 + 4 extras (leading-slash normalize, ampersand + escape, MIME table, mod re-export). 10 total, all passing. + +### `WebsiteCanonicalUrlTransform` (`transforms/website_canonical_url.rs`) — Decision 6 confirmed +- [x] New module per Decision 6. Pure helper `apply_canonical_url` + decouples site-url + output-href composition from + `RenderContext` lookup so the pure-helper unit tests cover + the no-op branches. +- [x] `mod.rs` re-export. +- [x] Tests 19–22 + 5 helper/setter extras (sub-path site URL, + leading-slash normalization, insert-vs-replace, non-map + defensive). 9 total, all passing. + +### Pipeline wiring (`pipeline.rs`) +- [x] Insert the three new transforms after + `MetadataNormalizeTransform` per Decision 3 (steps 4a, 4b, 4c). +- [x] Doc-block update enumerating the new pre-engine transforms. +- [x] Full quarto-core test suite green (1275 tests pass) — no + regressions in existing transforms or integration tests. + +### `website_post_render.rs` (`quarto-core/src/project/website_post_render.rs`) +- [x] New module containing `flush_site_libs` (extracted from + orchestrator.rs:186-228), `copy_favicon`, `write_sitemap`, + `write_robots_txt` per Decision 11. Module is + `cfg(not(target_arch = "wasm32"))`-gated. +- [x] Inline `escape_xml_text` helper for sitemap. +- [x] Inline `format_iso8601_utc` helper (Howard Hinnant + civil-date arithmetic, no `chrono` dependency). +- [x] Tests 23–29 + 5 extras (XML escape table, ISO-8601 unit + tests for epoch / known timestamp / end-of-year / leap day). + 12 total, all passing. + +### Orchestrator wiring (`project/orchestrator.rs`) +- [x] Refactor `WebsiteProjectType::post_render` to call + `flush_site_libs`, `copy_favicon`, `write_sitemap`, + `write_robots_txt` in order. Body is now a four-line + composition. +- [x] **Trait signature extension:** `post_render` gained a + `&mut Vec<DiagnosticMessage>` parameter so non-fatal + warnings (missing favicon source) reach the user. + `DefaultProjectType` still uses the default no-op impl. + `ProjectRenderSummary` gained + `pub project_diagnostics: Vec<DiagnosticMessage>`. +- [x] CLI surface: `quarto/src/commands/render.rs` prints + `summary.project_diagnostics` after the per-doc + diagnostics. +- [x] Updated the in-test `CountingProjectType` / + `CountingProjectTypeWrapper` in + `crates/quarto-core/tests/project_pipeline.rs` to the new + signature. +- [x] Full workspace nextest green (7922 tests pass) — no + regressions. + +### Integration tests (`quarto-core/tests/website_post_render.rs`) +- [x] Tests 30–39 (all 10 passing). +- [x] Use `NativeRuntime` and a temp project directory. +- [x] Test 39 reframed to use `output-dir: _out` so a default + project actually renders files (the existing default-kind + output-dir-equals-project-dir overlap collides with file + discovery; not a Phase 7 concern but worth a note for the + epic close-out). + +### Regression check +- [x] Re-ran `/tmp/q2-phase2-smoke/`, `/tmp/q2-phase3-smoke/`, + `/tmp/q2-phase4-smoke/`, `/tmp/q2-phase5-website-test/`, + `/tmp/q2-phase6-smoke/`. All render cleanly with no + errors or warnings. Phase 3's fixture sets + `website.title: "Phase 3 smoke"`, so Phase 7's + title-prefix transform activated there: `<title>Home – + Phase 3 smoke` and `About – Phase 3 + smoke` are the new title strings. No favicon / + canonical-url / sitemap / robots.txt emitted in any + regression fixture (none set the relevant keys), as + intended. +- [x] Test 39 in the integration suite (default-project + no-Phase-7-outputs) locks in the no-op contract. + +### CLI end-to-end + verification +- [x] Smoke fixture at `/tmp/q2-phase7-smoke/` (test 40): + 3 pages (`index`, `about`, `docs/api`), `website.title`, + `website.site-url`, `website.favicon`. Inspection results: + * `_site/sitemap.xml` lists all 3 URLs prefixed with + `https://example.com/site/...` and per-page + ISO-8601 lastmods. + * `_site/robots.txt`: `Sitemap: https://example.com/site/sitemap.xml`. + * `_site/favicon.ico` exists (4-byte placeholder copied + verbatim). + * `_site/index.html`: `Home – Phase 7 Test + Site`, ``, ``. + * `_site/docs/api.html`: `API – Phase 7 Test + Site`, ``, ``. + Matches the plan example table 1:1. +- [x] Broken-favicon smoke at `/tmp/q2-phase7-broken-smoke/`: + stderr printed `Warning: website.favicon refers to missing + file 'nope.ico'`, `_site/index.html` still has + ``, `_site/nope.ico` + does not exist. +- [ ] `cargo build --workspace`. +- [ ] `cargo nextest run --workspace`. +- [ ] `cargo xtask lint`. +- [ ] `cargo fmt --check`. +- [ ] `cargo xtask verify` (full, including WASM build) — Phase 7 + touches `quarto-core` types accessible from + `wasm-quarto-hub-client` indirectly; full verify is the + safety net. + +### Hub-client / WASM impact check +- [x] Audited `crates/wasm-quarto-hub-client/src/`: no references + to `post_render`, `WebsiteProjectType`, `ProjectPipeline`, + or `website_post_render`. The WASM path goes through + `render_qmd_to_html` for single-doc renders only. + Phase 7's `post_render` is `cfg(not(target_arch = + "wasm32"))` — it never compiles into WASM. Phase 9 adds the + multi-doc orchestration flow. +- [x] Per-page transforms (title prefix, favicon, canonical URL) + compile under WASM — they're pure `quarto-core` metadata + transforms with no platform-specific code. Confirmed by + successful `npm run build:wasm` (release build of + `wasm-quarto-hub-client` target wasm32-unknown-unknown + includes Phase 7's modules). In single-doc WASM renders, + the title-prefix and favicon transforms still activate + when the user's qmd has `website.*` keys at the top level; + the canonical URL transform short-circuits because there's + no `project_index`. Behavior is correct for the Phase 9 + project-aware path; today's single-doc preview is + unaffected unless the user explicitly sets `website.*`. + +### Verification and close-out +- [x] `cargo build --workspace` clean. +- [x] `cargo nextest run --workspace` — **7922 tests pass** (up + from 7876 pre-Phase-7; net +46 tests across the four new + modules, the integration suite, and the orchestrator + diagnostic-channel test). +- [x] `cargo xtask lint` passes (638 files checked). +- [x] `cargo fmt --all -- --check` clean. +- [x] `cargo xtask verify` (full, including WASM build, + hub-client `npm run build:all`, hub-client tests, and + trace-viewer build/tests) — all 9 steps green. +- [x] No snapshot drift. +- [x] Follow-ups filed (each `discovered-from:bd-b9mz`, + parent-child to `bd-0tr6`, with extra `related` links + where noted): + * **`bd-7h6a`** — Per-page favicon override + (`meta.favicon` beats `website.favicon`). User flagged + 2026-04-27 as expected-soon. P3. + * **`bd-pphv`** — Sitemap incremental merge + (read-existing/update/write). Loops with Phase 8. P3. + * **`bd-tyvt`** — Open Graph / Twitter card / social meta + tags (Q1 `metadataHtmlPostProcessor` parity). P3. + * **`bd-ochm`** — Brand-aware favicon fallback (once Q2 + brand support lands). P4. + * **`bd-4zdf`** — Multi-format favicon variants + (apple-touch-icon, sizes). P4. + * **`bd-1hdz`** — Draft-mode interaction with sitemap. + Coordinate with `bd-p4sc` from Phase 6. P3. + * **`bd-97yc`** — Title-prefix home-page carve-out + (Q1 `stem == "index"` parity). P4. + * **`bd-82dn`** — Empty-`index.html` filter in sitemap. + Coordinate with `bd-r82e` (`DocumentProfile.includes` + enrichment is the natural place to add `is_empty`). P4. +- [x] Updated epic plan §"Work items" — Phase 7 marked done with + sub-plan link, `bd-b9mz` reference, and full follow-up + list. +- [x] Updated §"Follow-up beads report (running log)" with the + eight filed bd issues. +- [x] `br close bd-b9mz` (reason cites commit `78aa80cc`). +- [x] All Phase-7 changes committed in commit `78aa80cc` + ("Phase 7: post-render (sitemap, favicon, site-url/title + prefix)") on `feature/websites`. The single commit + includes the .beads/issues.jsonl flush (br auto-flushed). +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** Title prefix corrupts pages that already set + `pagetitle` deliberately (e.g. a Lua filter that sets + `pagetitle = "Custom"` and expects it preserved). + *Mitigation:* Decision 4's "if `pagetitle != title`, leave alone" + branch. Test 11 locks it in. + +- **Risk:** Favicon `` href is wrong for nested pages — + page-relative math fails. + *Mitigation:* `page_url_for` is shared with Phase 5 (assets) and + Phase 6 (body links); both have integration tests for + nested-page hrefs. Test 31 explicitly checks the `../` + prefix. + +- **Risk:** Sitemap XML has invalid characters (URLs with `&`). + *Mitigation:* dedicated escape helper (test 25); golden-file + shape test (tests 23–24). + +- **Risk:** `robots.txt` overwrites user's manually-tuned file. + *Mitigation:* Decision 10's user-file-precedence rule. Test 37 + locks it. + +- **Risk:** Sitemap uses input file mtime, but mtime is unstable + across CI runs (git checkout doesn't preserve it). + *Mitigation:* this is a real CI concern but Phase 7 ships fresh + sitemap on every render — the lastmod is "when did this run". For + Phase 8, when incremental rebuilds make stale lastmods possible, + we may need a deterministic-source-of-truth (input content hash, + or `_quarto.yml`-pinned date). Leave as a Phase-8 concern. + +- **Risk:** Phase 7 affects Phase 6's link-rewrite by adding + `` tags whose hrefs would also be candidates + for rewriting. + *Mitigation:* Phase 6's `LinkRewriteTransform` walks + `Inline::Link` only (body content). `` lives + in `header-includes` as a raw HTML string, never an + `Inline::Link` node. No interaction. + +- **Risk:** `WebsiteFaviconTransform` runs before + `header-includes` reaches the template — but the template engine + reads `header-includes` from `meta` at apply time, not at + transform time. Verified by reading `template.rs:330-365`. + +- **Risk:** Per-page transform runs even when `is_single_file` + (e.g. a `.qmd` opened with `--meta website.title=…` somehow). + *Mitigation:* the transform is keyed entirely on whether + `meta.website.title` is set; if a single-doc render carries that + metadata, applying the prefix is correct behavior, not a bug. + +- **Risk:** `post_render` failure aborts the whole render + (Phase 1's hook-failure rule). A misspelled favicon path + shouldn't fail the render. + *Mitigation:* Decision 8 — diagnose, do not error. The hook + returns `Ok` even if the favicon is missing. Same for sitemap + if `path_metadata` fails on one input. + +- **Risk:** `cargo xtask verify`'s WASM leg fails because + `quarto-system-runtime`'s `path_metadata` trait method isn't + WASM-implemented. + *Mitigation:* Phase 7's post_render is `cfg(not(target_arch = + "wasm32"))` (Phase 5 already gated it). Per-page transforms + don't call `path_metadata`. Verify the cfg is preserved. + +- **Risk:** En-dash (U+2013) in `pagetitle` is mojibake'd + somewhere. + *Mitigation:* en-dash is plain UTF-8; the entire pipeline is + UTF-8-clean already (Phase 6 used `–` in diagnostics; Q1 uses + it). Tests 8, 9, 10, 12 all assert on the en-dash — any + encoding regression surfaces. + +## Explicit non-goals for this phase + +- No Open Graph / social meta tags (``). +- No `` cards. +- No Schema.org / JSON-LD. +- No analytics (Google Analytics, Plausible, etc.). +- No alias / redirect support. +- No 404 page. +- No reader-mode toggle. +- No repo-actions (`edit-on-github`). +- No incremental sitemap merge (Phase 8). +- No draft-mode visibility filtering on sitemap (deferred). +- No empty-page filter on sitemap. +- No brand-aware favicon fallback. +- No multi-variant favicon (apple-touch-icon, sizes). +- No per-page favicon override. +- No `` emission. +- No ``. + +## Follow-up beads (to file at close-out) + +- **Open Graph / social meta tags** — full + `metadataHtmlPostProcessor` Q1 parity. Prior art: + `external-sources/quarto-cli/src/project/types/website/website-meta.ts`. +- **Sitemap incremental merge** — read existing + `sitemap.xml`, patch entries for re-rendered files, preserve + others. Couples with Phase 8. +- **Empty-`index.html` filter** — once `DocumentProfile` + carries an `is_empty` signal (placeholder field tracked by + `bd-r82e`-adjacent), filter the sitemap. +- **Brand-aware favicon fallback** — when brand support lands, + fall back to `brand.light.favicon`. +- **Multi-format favicon** — apple-touch-icon, sizes. +- **Per-page favicon override** — `meta.favicon` at doc level + beats `website.favicon`. +- **Draft-mode interaction with sitemap** — once draft-mode + YAML config exists (`bd-p4sc` and friends), gate + draft-page sitemap entries. +- **Title-prefix home-page special-case** — match Q1's + `stem == "index" && offset === "."` carve-out if a real + fixture surfaces a problem. + +## Open questions (resolved 2026-04-27) + +1. **Include `WebsiteCanonicalUrlTransform` in Phase 7?** + *Resolved: yes.* Decision 6 confirmed; tests 19–22 included; + `WebsiteCanonicalUrlTransform` ships with Phase 7. + +2. **Defer incremental sitemap merge to Phase 8?** + *Resolved: yes.* Phase 7 ships fresh-write only. Phase 8's + incremental rebuild will add the read-existing/update/write + path. Filed as a follow-up bead at close-out. + +3. **Title-prefix home-page special-case?** + *Resolved: simpler rule.* Decision 4's `(None, wt) => wt` + branch — any untitled page falls back to `website.title`. + Q1's narrower `stem == "index" && offset === "."` carve-out + is filed as a follow-up to revisit if a real fixture surfaces. + +4. **Favicon path normalization?** + *Resolved: normalize.* The favicon helper strips a leading + `/` and treats the path as project-relative. Test 17 (or a + new test 17b) covers it. + +5. **Sitemap `` precision.** + *Resolved: second precision, UTC.* Format + `YYYY-MM-DDThh:mm:ssZ`. + +6. **En-dash vs hyphen separator.** + *Resolved: en-dash (U+2013).* Matches Q1 and typographic + convention. Locked in Decision 4. + +7. **`website.site-url` trailing-slash handling.** + *Resolved: strip on join.* Decisions 6 and 9 both call + `trim_end_matches('/')` before composing absolute URLs. + +## Decisions log (confirmed 2026-04-27) + +1. Phase 7 splits into per-page Pass-2 transforms (title prefix, + favicon link, optional canonical URL) and post_render writes + (favicon copy, sitemap, robots.txt). +2. Three small AST transforms instead of one omnibus. +3. Per-page transforms run right after `MetadataNormalizeTransform`. +4. Title prefix algorithm matches Q1 `computePageTitle`, with + en-dash separator and untitled-page fallback to website title. +5. Favicon `` appended to `header-includes`; href via + `page_url_for`. +6. `WebsiteCanonicalUrlTransform` populates the existing + `$canonical-url$` slot (confirmed in Phase 7). +7. `website_config` helper module centralizes the three reads. +8. Favicon copy in post_render; missing file → diagnose, don't + error. +9. Sitemap is fresh-write only in Phase 7 (no incremental merge); + `` from input file mtime; XML escaping inline. +10. robots.txt: user file wins, otherwise auto-generate when + site-url is set. +11. post_render orchestrator extracted to + `website_post_render.rs`; refactor site_libs flushing alongside. +12. No `DocumentProfile` change. + +## Epic-level impact + +Phase 7 closes the **site-identity surface** for websites: + +- Site-relative navigation links — Phases 2–4 +- Site-shared resource paths — Phase 5 +- Cross-document body links — Phase 6 +- **Site-level title / favicon / sitemap / robots.txt — Phase 7** +- Incremental rebuild caching — Phase 8 +- Hub-client live preview — Phase 9 + +After Phase 7, a Q2 website project has feature parity with the +**static-output portion** of a Q1 minimal website (everything Q1 +does *without* search, listings, or analytics). The Q2 docs site +(`bd-tr81`) can begin authoring against Phases 0–7 and produce a +renderable, navigable, well-titled, indexable site. + +The `website_config` helper module added in Phase 7 will be the +natural home for any future site-level config readers +(`website.image`, `website.repo-url`, `website.draft-mode`, etc.). +The follow-up `bd-n9dr` (epic-wide nav config placement) might +rename keys; keeping reads behind named functions makes that a +single-file edit. + +The `website_post_render.rs` extraction keeps `orchestrator.rs` +focused on the two-pass mechanics. Phase 8's incremental rebuild +will likely add `incremental` parameters to several of these +post_render functions; having them as named functions in a +dedicated module makes that a localized change. diff --git a/claude-notes/plans/2026-04-27-websites-phase-8.md b/claude-notes/plans/2026-04-27-websites-phase-8.md new file mode 100644 index 000000000..71fb16d4e --- /dev/null +++ b/claude-notes/plans/2026-04-27-websites-phase-8.md @@ -0,0 +1,1507 @@ +# Phase 8 — Incremental rebuilds + +**Date:** 2026-04-27 (redrafted after design discussion) +**Beads:** TBD (parent `bd-0tr6`). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-27-websites-phase-7.md` +**Status:** Draft v2 — pending user review. + +## Goal of this phase + +Phase 8 makes single-document re-renders inside a project +cheap, *without caching any user-controllable computation*. +The mechanism is a **dependency graph** computed from each +page's `DocumentProfile` plus the project nav config, paired +with a Pass-1 (profile) cache. Concretely: + +1. **Profile cache (Pass 1 skip).** Persist each `DocumentProfile` + to `/.quarto/cache/profiles/` keyed by a content + hash of the source plus every `_metadata.yml` / `_quarto.yml` / + transitive include / extension contribution that participated in + its merged metadata. Hit the cache for unchanged inputs; fall + through to the Pass-1 head pipeline only on miss. +2. **Dependency graph.** For every page, compute the set of *other* + pages whose profile content can affect this page's rendered + output. Inputs: + - Sidebar co-membership (any sibling in the same sidebar). + - Page-navigation neighbors (prev / next from the resolved + sidebar order). + - Cross-doc body-link targets. + - User-declared `project.nav-dependencies` in the page's merged + metadata (escape hatch / Lua-filter disclosure). + The graph carries forward `edges` and reverse `reverse_edges` + for O(N) propagation on thousand-page sites. +3. **Two render modes.** + - **Mode A — `quarto render`** (full project): re-render + every page's Pass-2 unconditionally. Profile cache speeds + up Pass-1; Pass-2 is unchanged from today. This phase makes + no attempt to skip Pass-2 in Mode A — filters / engines / + transforms in Pass-2 can have side effects, and silently + caching past them is the wrong default. + - **Mode B — `quarto render foo.qmd` / `foo/` / `a.qmd b.qmd`** + (subset render): render exactly the user-named subset. + Walk the dependency graph from the subset to find sibling + profiles that need re-extracting (so the subset's nav + features render correctly); run Pass-1 only on those. + Other pages are untouched on disk. **No Pass-2 propagation + onto dependents** — the user named the targets. +4. **Sidebar `auto:` and body-link resolution lifted to Pass-1** + as deterministic helpers with prose contracts. Pass-2's + sidebar/link transforms layer on top. Equivalence tests + prevent drift. +5. **Sitemap incremental merge.** Read existing + `_site/sitemap.xml`, replace entries for re-rendered pages, + preserve entries for non-targets. Closes Phase 7's `bd-pphv`. +6. **CLI surface.** `--clean-cache` wipes the `/.quarto/` + cache before rendering. (Renamed from the original `--clean` + to avoid conflict with the `make clean` connotation that + would suggest wiping `_site/`.) No `--full`, no `--no-cache` + — Mode + A is already the full render, and disabling the profile cache + adds failure modes without removing meaningful ones. + +## Why no Pass-2 cache + +A `DocumentProfile` is a faithful, side-effect-free static summary +of a document — caching it is always safe. Pass-2 is the opposite: +it runs user-supplied Lua filters, executes engines (R, Python, +Julia, Observable JS, …), reads environment / wall-clock / +network, and produces output that may legitimately differ between +identical inputs. Caching Pass-2 output by hashing inputs is a +silent soundness regression for any user whose filters or chunks +have side effects, and the failure mode is "stale but plausible +HTML on disk" — exactly the kind of bug Quarto's reproducibility +story is supposed to prevent. + +The narrower `freeze` feature (separate epic) caches engine output +by *user opt-in* at a single well-understood boundary. Phase 8 +leaves freeze untouched. Within Phase 8 there is no analogous +cache. **The win is not "Pass-2 ran but its output was cached." +The win is "Pass-2 didn't need to run at all."** + +This is a deliberate sacrifice of one optimization (re-running an +unaffected page's Pass-2 to produce the same bytes) in exchange +for predictable correctness. If real users benefit from the +deterministic-filter case, an opt-in Pass-2 cache can be added +later as its own feature, with the user explicitly asserting +filter purity. Phase 8 doesn't try to guess. + +## What this phase explicitly is **not** + +- **Pass-2 output caching.** No cached HTML, no replay, no tarred + Page-scoped artifact replay, no project-state snapshot. + See §"Why no Pass-2 cache" above. +- **Engine output caching (`freeze`).** Separate epic, untouched + by Phase 8. Sharing the serializable-checkpoint substrate is in + scope; *executing* on it belongs to that epic. +- **Resumption from cached `AtProfile`** (`bd-ee4z`). Pass-1 cache + reads serialized `DocumentProfile` JSON directly; Pass-2 always + starts from Pass-2 head when it runs. Resumption is an + optimization that's only meaningful once Pass-2 caching exists. +- **Hub-client cache integration.** Phase 9 layers a WASM-side + store on the same `SystemRuntime::cache_get/set` interface + Phase 8 uses. Phase 8 ships native-only; on WASM the default + `cache_get` returns `Ok(None)` (always recompute — correct). +- **Cross-format invalidation.** Multi-format projects are out of + website-epic scope; the profile cache key includes `format_id` + so per-format caches don't collide. +- **Parallel Pass-1 / Pass-2.** `bd-pdwr` follow-up. +- **Watching the filesystem.** `quarto preview` territory. + +## The bd-r82e prerequisite (DocumentProfile.includes) + +`bd-r82e` (filed during `bd-xfwx`) is a hard prerequisite. After +`IncludeExpansionStage` was threaded ahead of the profile +checkpoint, a profile can reflect content spliced in from +`{{< include child.qmd >}}`. The profile *depends on* the child +file but carries no record of it; a content hash of the parent +source alone is insufficient. + +Phase 8 closes `bd-r82e` as **sub-phase 8.0** before any caching +code is written: + +1. Add `pub includes: Vec` to `DocumentProfile` + where `IncludeEntry { path: PathBuf, content_hash: [u8; 32] }`. +2. Populate from `IncludeExpansionStage` via a side-channel + `DocumentProfileStage` drains. +3. Bump `DOCUMENT_PROFILE_VERSION` 1 → 2. +4. Update `claude-notes/designs/document-profile-contract.md`. +5. Tests: profile records every direct + transitive include with + correct content hashes. + +Sub-phase 8.0 also adds the two other new profile fields needed by +the dependency graph (Decision 4 below) — they ride the same +profile-version bump. + +## Reference material + +- **Parent epic plan** §"Phase 8 — Incremental rebuilds". +- **Phase 0 sub-plan** — `DocumentProfile` contract and + project-root invariant. +- **Phase 1 sub-plan** §"`pass_one` / `pass_two` driver" — the + insertion seam for cache lookups and dependency-aware + Pass-2 selection. +- **Phase 2 sub-plan** §"Sidebar resolution" — sidebar membership + is the largest source of dependency edges. +- **Phase 4 sub-plan** §"Prev/next derivation" — page-nav neighbors. +- **Phase 6 sub-plan** §"`LinkRewriteTransform`" — cross-doc body + links produce dependency edges as a side effect of resolution. +- **Phase 7 sub-plan** §"Decision 9 — Sitemap algorithm" — the + fresh-write Phase 8 turns into a merge. +- **`bd-r82e`** — includes-tracking blocker. +- **Q2 current code:** + - `crates/quarto-core/src/project/orchestrator.rs:336-488` — + `ProjectPipeline::run`, `pass_one`, `pass_two`. Phase 8 + wraps Pass-1 in a cache lookup and gates Pass-2 on the + dependency graph. + - `crates/quarto-core/src/document_profile.rs:46-…` — + `DocumentProfile`. Phase 8 adds `includes`, `nav_dependencies`, + `always_render` fields. + - `crates/quarto-core/src/project/index.rs:35-…` — + `ProjectIndex`. Phase 8 builds a `ProjectDependencyGraph` + from the index plus nav config. + - `crates/quarto-core/src/project/mod.rs:104-186` — + `directory_metadata_for_document`. Layered `_metadata.yml` + files contribute to the Pass-1 cache key. + - `crates/quarto-core/src/stage/include_expansion.rs` — + `IncludeExpansionStage`. Sub-phase 8.0 amends this stage. + - `crates/quarto-core/src/transforms/link_rewrite.rs` (Phase 6) + — link rewriting already resolves `.qmd` → `.html` via + `ProjectIndex`; Phase 8 captures the resolved targets as + body-link edges. + - `crates/quarto-core/src/project/website_post_render.rs` — + `write_sitemap`. Phase 8 turns fresh-write into merge. + - `crates/quarto-system-runtime/src/traits.rs:686-714` — + `cache_get` / `cache_set` / `cache_clear_namespace`. Phase 8 + persists the profile cache through this API; **no new file + I/O paths**. + - `crates/quarto-system-runtime/src/native.rs:459-540` — + `NativeRuntime` cache backing. Already wired to + `/.quarto/cache/` for SASS in + `commands/render.rs:108-110`. + - `crates/quarto/src/commands/render.rs:97-127` — CLI flag + surface. Phase 8 adds `--clean-cache` (no `--full`, + no `--no-cache`). +- **Q1 reference (negative space):** Q1's `--incremental` is + user-pointed (the user lists which files to re-render); Q1 has + no automatic dependency analysis. Phase 8's auto-detect + dependency graph is Q2-original. + +## Key decisions (to confirm with user) + +### Decision 1 — Cache layout under `/.quarto/cache/` + +``` +/.quarto/cache/ +├── sass/ # existing (Phase 5 SCSS pre-compile) +└── profiles/ # NEW: per-page DocumentProfile JSON + └── # 64-char hex sha256 +``` + +That's it. No `pages/` directory, no `project-state/` snapshot, +no tar bundles. The dependency graph is recomputed from scratch +each run from the (cached or fresh) profiles — it's cheap and +not worth caching. + +`profiles/` reuses the existing `SystemRuntime::cache_get/set` +path validated at `commands/render.rs:108`. Single I/O abstraction, +already works for hub-client's eventual WASM backing. + +### Decision 2 — Pass-1 cache key + +``` +sha256( + PROFILE_KEY_VERSION (4 bytes, currently = 1) + | quarto_build_id() (length-prefixed UTF-8 — release version + or, in dev builds, git short hash; + see Decision 3) + | DOCUMENT_PROFILE_VERSION (4 bytes, currently = 2 after bd-r82e) + | format_id (length-prefixed UTF-8) + | source_path (project-relative, length-prefixed UTF-8) + | source_bytes (length-prefixed) + | for each layered _metadata.yml from project root → doc dir: + | path (length-prefixed) + | bytes (length-prefixed) + | _quarto.yml bytes (length-prefixed; "" if absent) + | for each format-extension contribution, sorted by name: + | name (length-prefixed) + | metadata bytes (length-prefixed) +) +``` + +SHA-256 hex (64 chars). Crate: `sha2`. The `PROFILE_KEY_VERSION` +constant is the manual-override lever; `quarto_build_id()` is the +automatic one. + +**Where transitive includes fit in.** During implementation it +became clear that putting the include set in the lookup key +creates a chicken-and-egg: to look up the cache *before* running +Pass-1 we'd need to know what files the document includes, but +discovering that is exactly Pass-1's job. **Resolved:** the cache +key omits the include set; the cached profile carries +`includes: Vec` (Phase 8.0a's `bd-r82e`); on load, +`profile_cache::load` verifies each cached include's recorded +content_hash against the file's current bytes via a resolver +the orchestrator passes in. Any unreadable file or mismatched +hash degrades the load to a miss. Net invalidation behavior is +identical to the original plan; just check-on-load instead of +bake-into-key. + +**Format-extension contributions.** In v1 these are passed +empty by the orchestrator. A user adding or changing a format +extension's metadata won't invalidate the cache automatically; +`--clean-cache` (sub-phase 8.4) is the documented escape hatch. A +follow-up bead can add proper extension hashing once the +extension-discovery code path is convenient to consume from +the orchestrator. + +### Decision 3 — Quarto version baked into the cache key + +`quarto_build_id()` returns: +- Release builds: `env!("CARGO_PKG_VERSION")`. +- Dev builds: same plus `+` via `vergen` or a + one-line `build.rs` (decided in sub-phase 8.1). + +Distribution upgrades invalidate the cache transparently. Dev +hackers iterating on pipeline code see invalidation per commit. +Manual `PROFILE_KEY_VERSION` bumps remain available for +mid-version behavior changes. + +### Decision 4 — Three new `DocumentProfile` fields (sub-phase 8.0) + +Sub-phase 8.0 lands **all three** new profile fields in one +profile-version bump (1 → 2): + +```rust +pub struct DocumentProfile { + // … existing fields … + + /// Transitive include set (bd-r82e). Populated by + /// IncludeExpansionStage; consumed by Pass-1 cache-key construction. + pub includes: Vec, + + /// Pages this document depends on, declared by the user in + /// frontmatter / _metadata.yml / _quarto.yml as + /// `nav-dependencies: [other.qmd, …]`. Populated by + /// DocumentProfileStage from merged metadata. Default: empty. + pub nav_dependencies: Vec, + + /// User-declared "always re-render this page" flag. Set when the + /// user knows their filters introduce non-deterministic content + /// or undeclarable dependencies (e.g. a Lua filter that walks the + /// whole project). Frontmatter / _metadata.yml / _quarto.yml key + /// is `always-render: true`. Default: false. + pub always_render: bool, +} + +pub struct IncludeEntry { + pub path: PathBuf, // project-relative, forward-slash + pub content_hash: [u8; 32], +} +``` + +**Why all three at once.** They share a profile-version bump and +share the `DocumentProfileStage` plumbing. Sub-phase 8.0 is a +clean atomic deliverable that makes Phase 8's machinery possible +without any Phase 8 caching code yet existing. + +**Why `nav_dependencies` is path-based, not profile-id-based.** +Paths are stable across runs; profile identity is run-local. +Resolution to a `ProjectIndex` slot happens at graph-build time. + +**Why a flat `Vec` and not a richer `(path, reason)` +struct.** v1 simplicity. The graph-builder *also* contributes +edges with reasons (sidebar / prev-next / body-link); the +`nav_dependencies` field is purely the user's declaration channel. + +### Decision 5 — Dependency graph: shape and inputs + +```rust +pub struct ProjectDependencyGraph { + /// For each source path, the set of source paths whose profile + /// content can affect this page's rendered output. + pub edges: HashMap>, + + /// Reverse index: for each source path, the set of source paths + /// that depend on it. Built alongside `edges` in one pass and + /// used by transitive-deps queries (Mode B's `needed_profiles`) + /// for O(N) propagation instead of O(N²). + pub reverse_edges: HashMap>, + + /// Pages explicitly forced into the render set regardless of + /// dependency analysis (`always-render: true` OR `--full`). + pub force_render: HashSet, +} +``` + +Quarto websites can run into the thousands of documents, so the +reverse index ships day one. It's five extra lines at build +time and avoids the test that would catch the perf regression. + +Built once between Pass 1 and Pass 2 from: + +| Source | Edges contributed | +|---|---| +| Sidebar membership | for each sidebar with N entries, the complete sub-graph among those N pages (each entry depends on every other) | +| Prev/next neighbors | each page → its prev and next in resolved sidebar order | +| Body-link targets | source page → every project-relative `.qmd` it links to (captured during Phase 6's link resolution; see Decision 7) | +| User declarations | source page → each path in `profile.nav_dependencies` | + +Sidebar membership is the heaviest single contributor — flatten +each sidebar's resolved entries and add the complete graph. +Conservative on purpose: a sidebar reorder might shift any +member's prev/next or active-item highlight, so any membership +co-listing implies mutual dependency. This is approximately +"O(sidebar-size²) edges per sidebar," which is fine — sidebars +are tens of entries, not thousands. + +**force_render contents.** A page lands in `force_render` when +`profile.always_render == true`. (Original plan also mentioned +nav-config-hash mismatch and a `--full` flag; both were dropped +during implementation. Mode A re-renders everything anyway — +there's no Pass-2-skip path to override — so `--full` was +unneeded. Nav-config-hash is informational only in Phase 8; +see Decision 8.) + +`force_render` is a coarse hammer; the dependency-graph edges are +the fine-grained mechanism. Both are needed. + +### Decision 6 — Pass-2 selection: per-render-mode + +The two render modes have meaningfully different shapes; the +algorithm reflects that. + +**Mode A: full-project render (`quarto render` with no path).** + +Re-render every page. Filters, engines, and Pass-2 transforms +all run for every page. The dependency graph and the profile +cache *still matter* — they keep Pass-1 cheap on the warm path +(profile cache hits) and they're the substrate for Mode B and +for Phase 9's hub-client. But Mode A doesn't try to skip any +page's Pass-2. + +This matches how users think about `quarto render` ("rebuild my +site") and avoids the soundness fragility of trying to decide +which pages can safely skip Pass-2 in the presence of arbitrary +filters and engines. A future, separate caching epic can refine +this; Phase 8 doesn't. + +**Mode B: single-doc / subset render (`quarto render foo.qmd`, +`quarto render foo/`, `quarto render a.qmd b.qmd c.qmd`).** + +The user named a specific subset. Render exactly that subset +plus the minimum set of *DocumentProfile re-extractions* needed +for that subset's nav features to be correct. **No other pages' +Pass-2 runs.** Concretely: + +``` +// 1. Resolve the user-specified targets into a path set. +let targets: HashSet = expand_user_args(args); + +// 2. Run Pass-1 with cache for `targets`. +// Pages outside `targets` don't run Pass-1 yet. +for page in targets: + profile_with_cache(page); + +// 3. Walk the dependency graph from `targets` to find which +// *other* pages' profiles are needed for `targets` to render +// correctly. (Sidebar membership, prev/next, body-link, user +// nav-dependencies — all the same edges as Mode A.) +let needed_profiles: HashSet = graph.transitive_deps(&targets); + +// 4. Run Pass-1 with cache for `needed_profiles`. +for page in needed_profiles - targets: + profile_with_cache(page); + +// 5. Pass-2 over `targets` only. +for page in targets: + render_document(page, project_index); +``` + +The reduced `quarto render foo/` form expands to the set of +`.qmd` files under `foo/` and reduces to the same algorithm. +Multiple-arg form `quarto render a.qmd b.qmd` is the union of +their target sets. + +**Why no closure-from-changed-profiles in Mode B.** The user +told us *exactly* which pages to render — `targets`. Other +pages aren't re-rendered even if their dependents (the targets) +changed in ways that would normally propagate; that's beyond +the scope of what the user asked for. If they want propagation, +they invoke Mode A. + +**Why we still build the full graph in Mode B.** Step 3 needs +it. The graph builder is cheap (linear in edges) and runs on +the in-memory `ProjectIndex`; the cost is dominated by Pass-1 +profile re-extractions, which are exactly what we minimize via +`needed_profiles`. + +**Cold project, Mode A.** Every Pass-1 cache misses; every page +re-extracts; every page renders Pass-2. Same as today. + +**Warm project, Mode A.** Most Pass-1 hits; every page renders +Pass-2. Profile cache wins on Pass-1 cost; Pass-2 cost is +unchanged from today. Net win is the Pass-1 head pipeline +(parse + metadata merge + include expansion + profile extract). + +**Cold project, Mode B (single doc).** Pass-1 the target plus +its dependency closure (sidebar siblings, etc.). Pass-2 the +target only. Sibling pages that share a sidebar with the target +do run Pass-1 (their profiles are needed) but do not run Pass-2. + +**Warm project, Mode B.** Pass-1 the target (cache miss if its +inputs changed; hit otherwise) plus its dependency closure +(cache hits if their inputs are unchanged). Pass-2 the target +only. + +**Sidebar `auto:` and Pass-1.** The dependency graph needs a +*fully-resolved* sidebar — not the raw `auto:` directive — to +emit co-membership edges. Resolution depends on knowing which +pages exist and their profiles (titles, draft flags, etc.). +Phase 8 treats this in two parts (Decision 7 below): a static +"which pages would this sidebar contain?" query that runs in +Pass-1, and the existing Pass-2 sidebar render that produces +HTML. + +### Decision 7 — Pass-1 vs Pass-2 split for derived nav data + +Two pieces of nav-relevant data have to be computable without +running engines / filters / Pass-2 transforms, so the dependency +graph can use them at Pass-1 time: + +1. **Body-link targets** for a given page — which project-relative + `.qmd` files does this page link to? +2. **Sidebar membership** — which pages does each declared + sidebar contain (after `auto:` expansion)? + +Both are *static* queries over a parsed document and the +project's file inventory. Phase 8 specifies them as deterministic +algorithms with prose contracts in +`claude-notes/designs/`, then implements each twice: + +- **A "which pages?" pass** that runs in Pass-1 and produces + paths only. Cheap, deterministic, no AST mutation. +- **The existing Pass-2 transform** that produces the actual + HTML / metadata using the same logic plus per-page rendering + context. + +The two implementations *must* agree on the page set; a unit +test asserts equivalence on shared fixtures. If they ever +diverge that's a bug in one of them, not a design choice. + +**Body-link resolution.** Phase 6's `LinkRewriteTransform` +already resolves `.qmd` → `.html` via `ProjectIndex` lookups +during Pass-2. Phase 8 extracts the *resolution* logic (path +normalization, `ProjectIndex` lookup, hash-fragment stripping) +into a shared helper `resolve_doc_relative_links` in +`crates/quarto-core/src/project/`. The new `LinkResolutionStage` +calls it at Pass-1 to populate `profile.body_link_targets`; +Phase 6's transform calls the same helper at Pass-2 to do the +rewrite. Single source of truth, asserted equivalent. + +**Sidebar membership resolution.** The current sidebar-resolve +code (Phase 2) lives inside the Pass-2 sidebar transform. Phase 8 +extracts the membership-only portion (which pages belong to +which sidebar, in what order, ignoring rendering specifics like +`expanded:` styling) into a Pass-1-callable helper: + +```rust +pub fn resolve_sidebar_membership( + config: &SidebarConfig, + index: &ProjectIndex, +) -> Vec; + +pub struct ResolvedSidebar { + pub id: Option, + pub members: Vec, // in declared order, project-relative +} +``` + +Pass-2's sidebar transform layers HTML rendering on top of this +same helper's output. Same equivalence test pattern. + +**Prose contracts.** Sub-phase 8.0 produces +`claude-notes/designs/sidebar-auto-expansion-contract.md` and +`body-link-resolution-contract.md` describing the deterministic +algorithms in user-facing prose. The sub-plan includes their +generation as an explicit deliverable so users / Lua-filter +authors / future implementations have a stable target. + +**New profile field.** Body-link targets land on the profile: + +```rust +/// Project-relative .qmd targets this page links to. +/// Populated by LinkResolutionStage during Pass-1. +pub body_link_targets: Vec, +``` + +Sidebar membership does *not* land on individual profiles — it's +a project-level computation, recomputed each run from +`_quarto.yml` + `ProjectIndex`. (Storing it per-page would +duplicate the same data on every member.) + +**Why on the profile for body-link targets.** The dependency +graph builder needs them per-page; storing them on the profile +means the profile cache covers them (a page's body-link set is +a function of the page's source + includes — already in the +cache key). One source of truth. + +### Decision 8 — Nav config hash (informational, future-use) + +A one-line file `/.quarto/cache/nav-config-hash` records +the SHA-256 of the project's nav-relevant config slices: + +``` +sha256( + | navbar slice (canonical JSON of meta.navbar) + | sidebar slice (canonical JSON of meta.website.sidebar) + | footer slice (canonical JSON of meta.website.page-footer) + | website slice (canonical JSON of meta.website {title, site-url, favicon}) +) +``` + +Written every successful run. **Phase 8 does not act on this +hash** — Mode A re-renders everything, and Mode B renders only +`targets` regardless of nav-config drift, so there's no +"force re-render on nav change" path to gate. The hash is +recorded for two purposes: + +1. **Diagnostic.** Trace logs report the value, useful for + debugging "did the user edit the sidebar this run?" +2. **Future-use.** A later refinement (smarter Mode B that + detects "a nav edit means I need to re-render this page even + though the user only asked for foo.qmd") can consult it + without a schema migration. + +If the file is missing on read, that's not an error — the next +run writes it. + +### Decision 9 — `--clean-cache` semantics; no other new flags + +| flag | profiles/ cache | nav-config-hash | this run reads cache | this run writes cache | +|---|---|---|---|---| +| (default) | kept | kept | yes | yes | +| `--clean-cache` | wiped | wiped | yes (empty) | yes | + +**Why `--clean-cache` and not `--clean`.** The bare word +`--clean` carries strong `make clean` connotations — users would +reasonably expect it to wipe `_site/` (matching Q1's flag of the +same name with similar semantics). `--clean-cache` is more +verbose but unambiguous. (Resolved 2026-04-27.) + +**`--clean-cache` semantics.** Wipes `profiles/` and the +`nav-config-hash` file. Preserves `sass/` (SCSS recompiles are +expensive and almost never the source of incorrectness). Effect: +cold cache; every page's profile re-extracts; in Mode A every +page renders Pass-2 anyway, so `--clean-cache` is mostly +meaningful as "throw away cached state I no longer trust." + +**No `--full` flag.** Mode A (full-project `quarto render`) +already re-renders every page's Pass-2 unconditionally — there's +no per-page Pass-2 skip in Phase 8 to override. The "force every +page" intent is just "run `quarto render` with no path argument." + +**No `--no-cache` flag.** Without a Pass-2 cache, the only thing +`--no-cache` could disable is the profile cache. Disabling that +saves a tiny amount of work and creates more failure modes than +it removes. `--clean-cache` covers the "throw away cached state" +intent. + +**Per-page `always-render: true`.** Still meaningful in Mode B: +a page with `always-render: true` is implicitly added to +`targets` if anything in its dependency closure is rendered. +This catches the "Lua filter introduces non-deterministic content; +re-render this page whenever its neighbors change" use case. Mode A +is unaffected (every page renders anyway). + +### Decision 10 — Sitemap incremental merge (closes `bd-pphv`) + +``` +1. Read existing /sitemap.xml. Parse into + BTreeMap. +2. For each profile in ProjectIndex: + - If the page was rendered this run (in `changed`), update its + entry with the current input mtime. + - If the page was skipped, leave its entry untouched. +3. Write back, sorted by loc. +``` + +If reading fails (missing, malformed, version mismatch), fall +through to Phase 7's fresh-write. No regression. + +### Decision 11 — Error policy: cache errors never abort a render + +A corrupted profile cache file, JSON parse failure, version +mismatch — none abort. Single warning ("cache miss for X due to +load error"), fall through to live extraction. The next run +regenerates the cache cleanly. One exception: a *write* failure +on `nav-config-hash` is a hard error (future runs would +incorrectly assume nav config didn't change). + +### Decision 12 — `nav-dependencies` and `always-render` plumbing + +Both are user-facing metadata keys under the `project.` namespace +(matching `project.cache` precedent from earlier discussion). +Read by `DocumentProfileStage` from `meta.project`: + +```yaml +# foo.qmd frontmatter +--- +title: Foo +project: + nav-dependencies: + - a.qmd + - subdir/b.qmd + always-render: true # rare; usually omitted +--- +``` + +**Subtree application via `_metadata.yml`.** Setting +`always-render: true` in `_metadata.yml` applies to every doc in +the subtree (free from Q2's existing metadata merge). Same for +`nav-dependencies`, though the latter is less natural at subtree +scope (every doc in the subtree declaring the same dependency is +unusual). Document the subtree behavior in user docs. + +**Frontmatter precedence.** Frontmatter > `_metadata.yml` chain > +`_quarto.yml`. Q2's existing merge precedence; Phase 8 inherits +without change. + +**Path resolution.** `nav-dependencies` paths are resolved +project-relative (a leading `/` strips and re-roots at the +project; a bare path is relative to the document's directory). +The single helper used by Phase 6's link rewriter (`page_url_for` ++ relatives) is reused. + +**Validation.** A `nav-dependency` that doesn't resolve to a +project document emits a diagnostic warning at graph-build time +and is dropped. Phase 8 doesn't fail the render — the user's +declaration is ignored, which is conservatively correct (we +might miss an edge but won't add a wrong one). + +## Architecture sketch + +### Module shape + +``` +crates/quarto-core/src/project/ + cache_key.rs # NEW — Pass-1 key hasher + nav-config hasher + profile_cache.rs # NEW — DocumentProfile JSON read/write + dependency_graph.rs # NEW — ProjectDependencyGraph builder + closure + orchestrator.rs # MODIFIED — Pass-1 cache lookup; gates Pass-2 + # on dependency-aware `changed` set + website_post_render.rs # MODIFIED — sitemap fresh-write → merge + +crates/quarto-core/src/document_profile.rs + # MODIFIED — bd-r82e + nav_dependencies + + # always_render + body_link_targets; + # DOCUMENT_PROFILE_VERSION 1 → 2 + +crates/quarto-core/src/stage/include_expansion.rs + # MODIFIED — bd-r82e: record IncludeEntry side-channel + +crates/quarto-core/src/stage/document_profile.rs + # MODIFIED — drain include side-channel; read + # nav-dependencies / always-render from meta + +crates/quarto-core/src/stage/link_resolution.rs + # NEW — LinkResolutionStage runs at end of Pass-1; + # walks AST for project-relative .qmd links, + # writes results to profile.body_link_targets + +crates/quarto-core/src/transforms/link_rewrite.rs + # UNCHANGED — Phase 6's transform stays as-is; + # its body-link logic moves to LinkResolutionStage + # at Pass-1 (resolution is pure) while the actual + # rewrite stays in Pass-2 (mutation). See Decision 7. + +crates/quarto/src/commands/render.rs + # MODIFIED — --clean-cache flag; + # partial-render summary line +``` + +### Mode A — full project render (`quarto render`) + +``` +discover .qmd files in project + │ + ▼ +pass_one: for every page → profile_with_cache (hit / miss as inputs change) + │ + ▼ +ProjectIndex built from profiles + │ + ▼ +build ProjectDependencyGraph (edges + reverse_edges) + ↑ informational only in Mode A + │ + ▼ +pass_two: render every page in full (engines, filters, transforms) + │ + ▼ +post_render → flush_site_libs → sitemap fresh-write → nav-config-hash write +``` + +Mode A's only Phase-8-induced acceleration is the profile cache +on the warm path. Pass-2 always runs; correctness is the same as +pre-Phase-8. + +### Mode B — partial render (`quarto render foo.qmd` etc.) + +``` +expand args → targets: HashSet + │ + ▼ +pass_one(targets): profile_with_cache for each target + │ + ▼ +build ProjectDependencyGraph from in-memory ProjectIndex with +the targets' profiles plus any cached profiles from previous runs + │ + ▼ +needed_profiles = transitive_deps(targets) // via reverse_edges-aware walk + │ + ▼ +pass_one(needed_profiles - targets): profile_with_cache to ensure +the index is fresh enough for targets' nav rendering + │ + ▼ +pass_two: render only `targets` — engines + filters + transforms run + │ + ▼ +post_render → sitemap MERGE (targets' lastmods refresh, others preserved) + → nav-config-hash write +``` + +Mode B touches zero Pass-2 work for non-target pages. Their +existing output on disk is left untouched. + +### Mode B with `always-render` siblings + +``` +… same as above, plus: +implicit_targets = { p ∈ project.pages | p.always_render + && reverse_edges_intersect(p, targets) } +targets ← targets ∪ implicit_targets +… continue as above with the augmented targets … +``` + +A page with `project.always-render: true` gets pulled into the +render set if any of its dependents (i.e. any page that links +to / co-shares-a-sidebar-with / lists it as a nav-dep) is in +the user-named targets. This catches the "Lua filter inserts a +random quote on this page; re-render whenever neighbors change" +case. + +### Single-doc behavior (regression) + +A single `.qmd` render outside a project still constructs +`NativeRuntime::new()` with no cache_dir. Cache calls +short-circuit. Dependency graph is trivially empty. No behavior +change vs. pre-Phase-8. + +## Tests (TDD: write and fail first) + +Every test authored before the code that makes it pass. + +### Unit tests — sub-phase 8.0 (`bd-r82e` + new profile fields) + +1. `profile_includes_records_direct_include`. +2. `profile_includes_records_transitive_includes`. +3. `profile_includes_dedupes_repeat_includes`. +4. `profile_includes_handles_cycles`. +5. `profile_v1_json_rejected_with_clean_error`. +6. `profile_v2_round_trip_with_includes`. +7. `profile_records_nav_dependencies_from_frontmatter`. +8. `profile_records_nav_dependencies_from_metadata_yml`. +9. `profile_records_always_render_true`. +10. `profile_always_render_default_false`. +11. `profile_records_body_link_targets` — + `[link](../other.qmd)` → profile.body_link_targets contains + "other.qmd" (project-relative). +12. `profile_body_link_targets_excludes_external_urls`. + +### Unit tests — `cache_key` + +13. `pass1_key_stable_for_identical_inputs`. +14. `pass1_key_changes_on_source_edit`. +15. `pass1_key_changes_on_metadata_yml_edit`. +16. `pass1_key_changes_on_quarto_yml_edit`. +17. `pass1_key_changes_on_include_content_change`. +18. `pass1_key_changes_on_include_path_change`. +19. `pass1_key_changes_on_format_id`. +20. `pass1_key_changes_on_extension_metadata`. +21. `pass1_key_changes_on_quarto_build_id`. +22. `pass1_key_independent_of_unrelated_files`. +23. `nav_config_hash_stable_for_identical_config`. +24. `nav_config_hash_changes_on_sidebar_edit`. +25. `nav_config_hash_changes_on_navbar_edit`. + +### Unit tests — `profile_cache` + +26. `profile_cache_miss_returns_none`. +27. `profile_cache_round_trip`. +28. `profile_cache_load_with_corrupt_json_returns_none_with_warning`. +29. `profile_cache_load_with_version_mismatch_returns_none`. +30. `profile_cache_no_op_without_cache_dir`. + +### Unit tests — `dependency_graph` + +31. `graph_includes_sidebar_co_membership_complete_subgraph` — three + pages in one sidebar → 6 directed edges (each → other two). +32. `graph_includes_prev_next_neighbors`. +33. `graph_includes_body_link_targets`. +34. `graph_includes_user_declared_nav_dependencies`. +35. `graph_warns_on_unresolved_nav_dependency`. +36. `graph_reverse_edges_match_forward_edges` — for every + `(u, v) ∈ edges` there is `(v, u) ∈ reverse_edges`. Property test. +37. `graph_force_render_includes_always_render_pages` — + `project.always-render: true` → page in `force_render`. +38. `transitive_deps_finds_closure_via_reverse_edges` — Mode B's + `needed_profiles` query: targets={X}, X depends on Y, Y on Z + → result includes {X, Y, Z}. +39. `transitive_deps_terminates_on_cycles` — pathological cyclic + `nav-dependencies` declaration; query returns finite set. +40. `implicit_target_pulls_in_always_render_dependents` — Mode B + augmentation: page Q has `always-render: true` and depends on + target X via reverse edge → Q joins `targets`. + +### Unit tests — body-link / sidebar resolution equivalence + +40a. `body_link_resolution_pass1_pass2_equivalent` — same fixture + fed to `LinkResolutionStage` (Pass-1) and Phase 6's + `LinkRewriteTransform` (Pass-2) → same target set. +40b. `sidebar_membership_pass1_pass2_equivalent` — same `auto:` + fixture fed to `resolve_sidebar_membership` (Pass-1) and + Phase 2's sidebar render (Pass-2) → same member list. + +### Integration tests — Mode A (full project) + +41. `mode_a_cold_run_renders_all_and_populates_cache` — fresh + project → every page rendered; profile cache populated; + nav-config-hash written. +42. `mode_a_warm_run_no_edits_still_renders_all` — render twice; + Pass-2 still runs for every page (Mode A is full); but + Pass-1 hits cache for every page. Reported summary like + `"5 pages, 5 rendered (5 profile-cache hits)"`. +43. `mode_a_warm_run_after_body_edit_still_renders_all` — edit + one page's body → every page Pass-2 runs anyway; that page's + profile cache misses; siblings' profile caches hit. +44. `mode_a_warm_run_after_metadata_yml_edit_invalidates_subtree_profiles` + — edit `chapters/_metadata.yml` → only chapters/* profile + cache misses; every page still re-renders Pass-2 (Mode A). +45. `mode_a_warm_run_after_include_change_invalidates_parent_profile` + — `bd-r82e` regression: parent's profile cache misses on + child include change. + +### Integration tests — Mode B (partial render) + +46. `mode_b_single_target_renders_only_that_page` — + `quarto render foo.qmd` in a project; foo has no nav + dependencies → `_site/foo.html` is the only Pass-2 output. + Other pages' output files unchanged on disk. +47. `mode_b_walks_dependency_closure_for_pass1` — foo has a + body link to bar.qmd → bar's profile is re-extracted (or + cache-hit) so foo's Pass-2 link rewriting can resolve; + bar is *not* itself rendered. +48. `mode_b_user_declared_nav_dependency_is_followed_for_pass1` — + foo declares `project.nav-dependencies: [b.qmd]`; b's profile + is loaded for foo's render; b is not itself rendered. +49. `mode_b_always_render_pulls_dependent_into_targets` — q is + in foo's reverse-dep set and has `project.always-render: true` + → render `quarto render foo.qmd` → q is also rendered. +50. `mode_b_directory_arg_expands_to_targets` — + `quarto render foo/` renders every `.qmd` under `foo/`. +51. `mode_b_multi_target_arg_renders_union` — + `quarto render a.qmd b.qmd` renders {a, b} only. +52. `mode_b_unrelated_pages_outputs_byte_identical_to_pre_render` — + confirm Mode B doesn't accidentally touch other pages. + +### Integration tests — cache behavior, common to both modes + +53. `pipeline_clean_cache_flag_wipes_profile_cache_and_nav_hash` — + pre-populate cache → `--clean-cache` → cache empty before render. +54. `pipeline_corrupt_profile_cache_falls_through_to_live_extract`. +55. `pipeline_sitemap_merge_preserves_skipped_entries` — + Mode B edit-one-render-one → other pages' sitemap + `` is the *original* timestamp. +56. `pipeline_default_project_no_cache_io` — single-doc render + (no cache_dir) → no `.quarto/cache/` writes. +57. `pipeline_unresolved_nav_dependency_warns_does_not_fail` — + a `project.nav-dependencies: [missing.qmd]` declaration → + diagnostic, edge dropped, render proceeds. + +### CLI end-to-end (per CLAUDE.md §End-to-end verification) + +58. **Mode A / Mode B smoke** at `/tmp/q2-phase8-smoke/`: + ``` + _quarto.yml: + project: { type: website, output-dir: _site } + website: + title: "Phase 8 Test" + site-url: "https://example.com/site" + sidebar: + contents: [index.qmd, a.qmd, b.qmd, c.qmd] + index.qmd, a.qmd, b.qmd, c.qmd (a.qmd has [link to b](b.qmd)) + d.qmd (not in any sidebar) + ``` + Sequence: + 1. `quarto render` (Mode A, cold). Assert all 5 pages + rendered; profile cache populated; `_site/` populated. + 2. `quarto render` (Mode A, warm). Assert all 5 pages + rendered (Mode A always re-runs Pass-2); profile cache + hits everywhere; HTML byte-identical. + 3. Edit `b.qmd` body. `quarto render` (Mode A). Assert all + 5 rendered; only b's profile cache misses on Pass-1. + 4. `quarto render a.qmd` (Mode B). Assert: only `_site/a.html` + mtime advances; b's profile is loaded for a's link + resolution but b is not rendered; index/c/d untouched. + 5. `quarto render a.qmd b.qmd` (Mode B multi). Assert: + only a.html and b.html advance. + 6. `quarto render foo/` (Mode B, directory) on a fixture + with `foo/x.qmd` and `foo/y.qmd`. Assert: only those + two render. + 7. `quarto render --clean-cache` then `quarto render` + (Mode A). Assert: cache wiped before render; full + re-render. + 8. Add `project.always-render: true` to d.qmd; add d.qmd to + a's body links (so reverse-edges connect them); + `quarto render a.qmd` (Mode B). Assert: d is also + rendered (implicit target via always-render + + reverse-edge). + Record observed outputs and summary lines in close-out. + +59. **Regression smokes**: re-run `/tmp/q2-phase{2..7}-smoke/` + after `--clean-cache`; assert byte-identical output. + +60. **`bd-r82e` smoke**: parent → child include; Mode A render; + edit child only; Mode A re-render → parent's profile cache + misses; render correct. + +### Snapshot tests + +None — inline asserts cover the vocabulary. + +## Work items (checklist) + +### Preparation +- [x] Re-read `claude-notes/instructions/testing.md`, + `coding.md`, `review.md`. +- [x] Confirm user agreement with Decisions 1–12. +- [x] Resolve open questions §"Open questions" below. +- [x] File `bd` issues: + - `bd-fegm` parent under `bd-0tr6`. + - `bd-r82e` (already filed) marked as a *blocker* of + `bd-fegm`. + +### Sub-phase 8.0 — `DocumentProfile` v2 + lifted helpers +- [x] Add `IncludeEntry` and `includes: Vec` to + `DocumentProfile`. +- [x] Add `nav_dependencies: Vec`, `always_render: bool`, + `body_link_targets: Vec` to `DocumentProfile`. +- [x] Bump `DOCUMENT_PROFILE_VERSION` 1 → 2. +- [x] `IncludeExpansionStage` records spliced child paths + + content hashes via the new `DocumentAst.recorded_includes` + side-channel; merged back transitively from sub-recursion. +- [x] `DocumentProfileStage` drains include side-channel; reads + `project.nav-dependencies` and `project.always-render` from + merged metadata. +- [x] Extract `resolve_doc_relative_target` shared helper in + `transforms/navigation_href.rs`. Phase 6's existing + `resolve_doc_relative_href` is unchanged; both share the + same path-normalization logic via `resolve_to_project_root`. + Equivalence test `pass1_pass2_agree_on_target_set` passes. +- [x] `LinkResolutionStage` (new) in + `stage/stages/link_resolution.rs`: walks the post-include + AST, calls `resolve_doc_relative_target`, writes results + to `profile.body_link_targets`. Inserted between + `DocumentProfileStage` and `UnwrapProfileStage` in both + the standard HTML pipeline and the WASM HTML pipeline, + and in the orchestrator's `pass_one` stage list. +- [x] Extract `resolve_sidebar_membership` Pass-1-callable + helper in `project/sidebar_membership.rs`. Reuses + `expand_auto` from `transforms/sidebar_auto.rs` (lifted + from `mod` to `pub(crate) mod`). Returns + `Vec`. +- [x] Write prose contracts: + - `claude-notes/designs/body-link-resolution-contract.md`. + - `claude-notes/designs/sidebar-auto-expansion-contract.md`. +- [x] Update `claude-notes/designs/document-profile-contract.md` + (four new fields + version bump + change-log entry). +- [x] Tests 1–12 (DocumentProfile v2), 40a (Pass-1/Pass-2 + link-resolution equivalence), plus 11 LinkResolutionStage + stage tests, 7 sidebar_membership unit tests, and 2 + `bd-r82e` integration tests in + `tests/document_profile_pipeline.rs`. Net delta: +42 + tests across the sub-phase. +- [x] Verified Phases 2–7 transforms still pass — added + `Default` impl for `DocumentProfile` and updated all + transform-test fixtures to use `..DocumentProfile::default()`. + All 1337 quarto-core tests green. +- [x] WASM build clean (`hub-client && npm run build:wasm`). +- [x] `cargo xtask lint` and `cargo fmt --check` clean. + +### Sub-phase 8.1 — Cache infrastructure +- [x] `cache_key.rs`: `pass1_key` (sha256 with length-prefixed + encoding) + `quarto_build_id` (CARGO_PKG_VERSION) + + `hex_encode` helpers via `sha2`. (Note: `nav_config_hash` + deferred — Phase 8 doesn't act on it per Decision 8; + will land if a future refinement needs it.) +- [x] `profile_cache.rs`: `load(runtime, key, include_resolver)` + verifies cached profile's includes against current bytes; + `save(runtime, key, &profile)`. Both swallow recoverable + errors so the orchestrator never aborts on cache hiccups. +- [x] 30 tests (15 cache_key + 15 profile_cache including the + 4 include-verification tests). + +### Sub-phase 8.2 — Dependency graph + render mode selection +- [x] `dependency_graph.rs`: `ProjectDependencyGraph` struct + with forward `edges` and `reverse_edges` (built in one + pass over the index). +- [x] Builder consuming `ProjectIndex` + sidebar membership + (via lifted helper) + body-link targets (via profile) + + user-declared `project.nav-dependencies`. +- [x] `force_render` includes pages with + `project.always-render: true`. +- [x] `forward_closure(targets)` and `reverse_closure(targets)` + queries. +- [x] `augment_targets_with_always_render(targets)` Mode B + augmentation: `force_render` pages whose reverse-closure + intersects `targets` join the render set. +- [x] Orchestrator profile cache wiring: `pass_one` calls + `profile_with_cache`, which computes the cache key from + source bytes + layered _metadata.yml + _quarto.yml + + format id + source path, looks up via + `profile_cache::load` (with include verification), and + falls back to a live head pipeline on miss. +- [x] 13 dependency_graph unit tests + 10 incremental-rebuild + integration tests (4 Mode B specific). +- [x] `RenderMode { Full, Subset(HashSet) }` enum on + `ProjectPipeline`; `with_mode()` builder method. Default + `Full` keeps the existing CLI behavior backward-compatible. +- [x] Mode A wiring: `pass_one` over all pages with profile + cache; `compute_augmented_render_set` returns `None`; + `pass_two` filter no-ops. +- [x] Mode B wiring: full Pass-1 (cache makes it cheap), + build dependency graph, augment user targets with + always-render dependents whose reverse-closure intersects + them, filter `pass_two` to render only the augmented set. + Per-target absolute paths translated to project-relative + for the graph query and back to absolute for the filter. +- [x] **Deviation from plan:** the original plan called for a + "partial Pass-1 walk" in Mode B (profile only targets + + their dependency closure). Implementation found a + chicken-and-egg with sidebar `auto:` expansion: the + membership resolver consults the index, which doesn't + exist for non-target pages until they've been profiled. + v1 ships full Pass-1 in both modes, leveraging the cache + for warm-path speedup. The Pass-2 skip is the bigger + perf win anyway (filters and engines cost more than + profile extraction). Filing as a follow-up bead. +- [x] **`LinkResolutionStage` no-index resolution.** Discovered + while wiring Mode B that `LinkResolutionStage` was reading + `ctx.project_index` to resolve links — but the index + doesn't exist during Pass-1 (it's *built from* Pass-1 + profiles). Fix: `resolve_doc_relative_target` now does + pure path normalization (no index lookup); the dependency + graph builder applies the index existence check when + emitting edges. Updated tests + the contract doc. + +### Sub-phase 8.3 — Sitemap merge (closes `bd-pphv`) +- [x] `website_post_render::write_sitemap` reads existing + `/sitemap.xml`, parses each `` block into + `loc → lastmod`, refreshes entries for pages rendered this + run (matched via the `outputs: &[RenderToFileResult]` + param), preserves entries for skipped pages, and writes + back sorted by `loc`. +- [x] `parse_sitemap_locs` is tolerant of malformed input — + malformed `` blocks are skipped, root-level parse + failures degrade to fresh-write. +- [x] `RenderToFileResult.output_path` matched against + `project.output_dir.join(profile.output_href)` to identify + rendered pages. +- [x] 6 unit tests on the parser (round-trip, missing-lastmod, + malformed input, escape preservation, extract_inner_tag + simple+missing) + 1 integration test + (`mode_b_sitemap_preserves_untouched_entries_lastmod`) + end-to-end via Mode B render. +- [x] Close `bd-pphv`. + +### Sub-phase 8.4 — CLI surface + +**CLI design decisions (resolved 2026-04-27):** + +1. **Cache-wipe flag: `--clean-cache`** (not `--clean`). Avoids + the `make clean` connotation that `--clean` would carry — + users would reasonably expect `--clean` to wipe `_site/`, + matching Q1. `--clean-cache` is more verbose but unambiguous. +2. **Mode dispatch: implicit-from-path-args** (option (a) from + the design discussion). `quarto render` (no arg) is Mode A + for projects, single-doc fallthrough for non-projects. + `quarto render foo.qmd` inside a `_quarto.yml` project is + Mode B with target=foo. Outside a project, single-doc as + today. The "is this in a project?" detection is what Phase 1 + already does via `ProjectContext::discover`. +3. **Directory-arg expansion: intersect with project render + list.** `quarto render foo/` expands to every `.qmd` under + `foo/`, then intersects with the project's render list. + When the project doesn't define a render list, the implicit + render list is "every `.qmd` under the project" — same + semantics, just no narrowing happens. Need to confirm + whether Phase 1 implemented Q1-style render lists; if not, + the expansion is a glob alone (and a `bd` follow-up tracks + render-list intersection once that lands). Glob arguments + work the same way as directories. +4. **Summary line: keep simple.** `"N of M rendered"`. No + profile-cache-hit telemetry in the user-facing summary; + that's behind `QUARTO_PERF_STATS=1` for tooling. A future + epic will unify all CLI output formats — don't overengineer + it here. +5. **Skipped-page list: not in CLI output.** Just the rendered + list. Future tooling-focused output will include skips in a + machine-readable form. + +**Resolutions discovered during implementation (2026-04-27):** + +- **Render-list intersection — already implemented.** Phase 1's + `discover_project_files` honors `project.render` globs from + `_quarto.yml`. After discovery, `project.files` is already + render-list-filtered. Mode B's classification just intersects + user-named `.qmd` paths with `project.files`. The follow-up + bd flagged in the original task is unnecessary. +- **Multi-arg outside-project policy — error.** "One project per + render" rule (resolved with user 2026-04-27): multiple stand-alone + `.qmd` paths outside a `_quarto.yml` project ⇒ `MultiArgNonProject` + error. Multiple paths spanning two different projects ⇒ + `MultiProjectArgs` error. +- **Render-list-excluded `.qmd` arg — error per file.** Tailored + error variants: `NotInRenderList` for explicit `.qmd` args + (covers both `project.render` exclusions and the + underscore/hidden/README discovery rules); `NoRenderableMatches` + for directory args expanding to empty. +- **Subset covering all files collapses to Mode A.** When the + user enumerates every project file, we return `RenderTarget::FullProject` + to skip the dependency-graph augmentation step. Functionally + identical, slightly cheaper. +- **`pandoc_args` positional collision.** Adding `inputs: Vec` + next to the existing `pandoc_args: Vec` triggered a clap + ambiguity. Fix: `pandoc_args` is now `last(true)` so it only + captures arguments after `--`. + +**Tasks:** + +- [x] `--clean-cache` flag: wipes `profiles/` namespace and + `nav-config-hash` file (when the latter exists). + Preserves `sass/` (no behavior change for SCSS cache). + Implemented as `run_clean_cache(runtime, project_dir)` in + `commands/render.rs`. +- [x] `--clean-cache` execution point: invoked at the top of + `execute_project` before `ProjectContext::discover` from + the project root. Multi-file projects only; no-op for + single-doc fallthrough (no cache_dir wired). +- [x] CLI arg parsing: `inputs: Vec` positional in + `Commands::Render`. Classification logic lives in + `commands::render::classify_inputs`, returning a + `RenderTarget` enum: `SingleDoc(PathBuf)`, + `FullProject { project_dir }`, or `Subset { project_dir, targets }`. + Per-arg expansion: file → singleton; directory at project + root → FullProject; subdirectory → Subset filtered to + `project.files` under it; subset covering every file → + collapses back to FullProject. +- [x] Render-list intersection: handled by Phase 1's + `discover_project_files`. `project.files` is already filtered; + `classify_inputs` intersects user paths against it and + surfaces `NotInRenderList` for explicit-file misses. +- [x] `RenderMode::Subset(targets)` set on `ProjectPipeline` + via `with_mode()` when classification returns `Subset`. +- [x] Summary line: `render_summary_line(is_single_file, total, rendered)` + returns `Option` (suppressed for single-file). + `execute_project` calls it after per-doc diagnostics. +- [x] No `--full` flag — `quarto render` (no path) is + already the full render. +- [x] No `--no-cache` flag — `--clean-cache` covers the + throw-away-state intent; profile-only-disable adds + failure modes without removing meaningful ones. +- [x] 25 unit tests in `commands::render::tests` covering + `classify_inputs` (13), `run_clean_cache` (4), + `render_summary_line` (4), plus the 4 pre-existing + format-resolution tests. + +### Sub-phase 8.5 — Integration tests + smoke +- [x] Mode A tests 41–45 (cold + warm + body-edit + _metadata.yml + subtree + transitive-include invalidation). Land in + `crates/quarto-core/tests/incremental_rebuild.rs` — + pre-existing 8.2 coverage was extended with + `editing_metadata_yml_invalidates_subtree_only`, + `editing_include_invalidates_parent_profile`, and + `corrupt_profile_cache_falls_through`. +- [x] Mode B tests 46–52 (target-only render, multi-target + union, sitemap merge preserves siblings, no-target edge, + always-render augmentation, user-declared nav-dependency, + unresolved nav-dependency). New additions: + `mode_b_multi_target_renders_union`, + `mode_b_user_declared_nav_dependency_does_not_fail`, + `unresolved_nav_dependency_does_not_fail`. +- [x] Cache-behavior tests 53–57. `--clean-cache` end-to-end + coverage lives at the CLI integration level + (`tests/render_cli_e2e.rs::clean_cache_flag_wipes_then_renders`); + corrupt-cache fall-through covered by the new + orchestrator test; sitemap-merge by the existing + Phase-8.3 test. +- [x] CLI integration smoke at the binary level: + `crates/quarto/tests/render_cli_e2e.rs` covers + `--clean-cache`, multi-target Mode B, directory-arg Mode B, + explicit-render-list-exclusion error, + empty-directory-arg error, multi-arg-outside-project + error, plus the full sequenced smoke + (`cli_smoke_full_sequence`). +- [x] `bd-r82e` smoke covered by + `editing_include_invalidates_parent_profile`. +- [ ] Regression smokes (test 59 — re-running phases 2–7 + smoke fixtures after `--clean-cache`). Not automated + (those fixtures were ephemeral `/tmp/q2-phase{N}-smoke/` + directories not checked into the repo). Run manually + during close-out verification if any concern surfaces. + +### Sub-phase 8.6 — Hub-client / WASM impact check +- [x] Audit `crates/wasm-quarto-hub-client/src/`: no Phase 8 + modules referenced (no use of `profile_cache`, + `cache_key`, `dependency_graph`, `RenderMode`, or + `ProjectPipeline`). The orchestrator and clean-cache + surface are gated `cfg(not(target_arch = "wasm32"))`. + `WasmRuntime` already provides `cache_get`/`cache_set` + via JS shims (pre-Phase-8 sass-cache plumbing) — Phase 9 + can wire hub-client through them without further design. +- [x] WASM build clean (`hub-client && npm run build:wasm`). + +### Verification and close-out +- [ ] `cargo build --workspace` clean. +- [ ] `cargo nextest run --workspace`. +- [ ] `cargo xtask lint`. +- [ ] `cargo fmt --all -- --check`. +- [ ] `cargo xtask verify` (full, including WASM build). +- [ ] No snapshot drift from Phase 7. +- [ ] Follow-ups filed (each `discovered-from:bd-`, + parent-child to `bd-0tr6`): + * `nav-dependencies` glob support + (`[posts/*.qmd]`, `[chapters/**/*.qmd]`). + * Smarter Mode B: detect "user-named target had a nav-config + edit between runs that affects it" and pull in only the + affected sidebar members rather than relying on the user + to know. + * Open-question follow-up: opt-in Pass-2 caching for users + who explicitly assert filter purity (separate epic, not + in Phase 8). +- [ ] Close `bd-pphv`, `bd-r82e`. +- [ ] Update epic plan §"Work items". +- [ ] Update §"Follow-up beads report (running log)". +- [ ] `br close bd-`. +- [ ] Ask user permission before pushing. + +## Risks and mitigations + +- **Risk:** A user's Lua filter introduces a cross-doc dependency + the graph builder can't see; warm renders show stale output. + *Mitigation:* `nav-dependencies` declaration channel; + `always-render: true` per-doc opt-out; `--clean-cache` nuclear + option. Warn loudly in user docs about the situation and the + knobs. + +- **Risk:** Body-link resolution has to run in Pass-1 (so + `body_link_targets` lands on the profile), but + `LinkRewriteTransform` runs in Pass-2 — these go out of sync. + *Mitigation:* `LinkResolutionStage` (Pass-1) and + `LinkRewriteTransform` (Pass-2) share a single resolver helper + with a docstring stating the expected invariant; a unit test + asserts both produce the same target set for the same AST. + +- **Risk:** Sidebar resolution today requires Pass-1 to have + completed (it reads profiles for `auto:` expansion). The + dependency graph builder needs sidebar resolution. So the + build order is: Pass-1 all → resolve sidebars → build graph + → `changed` → Pass-2 over changed. Verify the existing + sidebar resolver runs at the right point. + *Mitigation:* sub-phase 8.2 task: confirm (or relocate) the + sidebar resolver to run pre-graph. + +- **Risk:** `nav_dependencies` field bloat. Most pages declare + none; `Vec` default is `vec![]` which serializes as `[]`. + *Mitigation:* `#[serde(default, skip_serializing_if = "Vec::is_empty")]` + on all three new collection fields. Same for `IncludeEntry` + list. + +- **Risk:** Closure algorithm's worst case is O(N²) per + iteration; pathological projects could hit this. + *Mitigation:* a real project has tens of pages, not + thousands. Document the bound; if a real user hits it, add a + reverse-edge index (page → pages-that-depend-on-it) for O(N) + closure. Not v1. + +- **Risk:** `previous_profile` PartialEq comparison is sensitive + to field-order changes during serde deserialization. + *Mitigation:* `DocumentProfile` derives `PartialEq` already + (Phase 0). Add a property test: round-trip serialize/deserialize + preserves PartialEq. + +- **Risk:** Cache write succeeds for a page whose Pass-1 actually + failed (e.g. partial write before crash). + *Mitigation:* the existing `cache_set` in `NativeRuntime` is + atomic-rename. Phase 8 piggybacks. Plus the version-check + guard on load. + +- **Risk:** A page that's never been profiled before (cold add) + but isn't in any sidebar / nav config / referenced by anyone: + is it picked up? + *Mitigation:* file discovery still lists every `.qmd`. Pass-1 + runs on every discovered file; cold profile (no previous) → + `changed` includes the page. Independent of the dependency + graph entirely. + +- **Risk:** `--clean-cache` implementation isn't atomic; partial + wipe leaves the cache in a half-state. + *Mitigation:* wipe `profiles/` first (removes the harder + half), then `nav-config-hash` (a single file). If wipe fails, + abort with a clear error. + +## Explicit non-goals for this phase + +- No Pass-2 output cache. +- No engine output cache (`freeze`). +- No project-state cache. +- No tarred Page-scoped artifact replay. +- No hub-client / WASM cache backing (Phase 9). +- No cross-format invalidation. +- No parallel rendering. +- No filesystem watcher. +- No per-page Pass-2 skip *cache* — the skip is decided per run + from the dependency graph; it's not a stored decision. +- No fine-grained nav-config invalidation (sidebar edit forces + full re-render via the coarse hash; refinement is a follow-up + if real users notice). +- No automatic detection of filter-introduced dependencies — the + user declares them via `nav-dependencies`. + +## Open questions (resolved 2026-04-27) + +1. ~~**Body-only edits**~~ — *Resolved: not a concern in Phase 8.* + Mode A always re-renders every page; Mode B renders exactly + the user-named subset. There is no "Pass-2 skip for unchanged + pages" path that body-only edits could fall through. The + over-rendering Decision 6 v1 worried about (B's dependents + re-render after a body-only edit to B) doesn't happen because + Mode B never propagates to dependents at all — the user's + `targets` is the rendered set. Decision 6 redrafted to mode-A + / mode-B form. + +2. ~~**`LinkResolutionStage` placement.**~~ *Resolved: lift the + resolution helper.* Phase 8 extracts the project-relative + link-resolution logic from Phase 6's `LinkRewriteTransform` + into a shared `resolve_doc_relative_links` helper. + `LinkResolutionStage` (Pass-1) and `LinkRewriteTransform` + (Pass-2) call the same helper; a unit test asserts they + produce the same target set. Captured in Decision 7. + +3. ~~**Sidebar `auto:` expansion timing.**~~ *Resolved: prose + contract + two implementations.* Phase 8 specifies sidebar + `auto:` expansion as a deterministic algorithm with a prose + contract at + `claude-notes/designs/sidebar-auto-expansion-contract.md`, + then implements two variants: a Pass-1 membership-only query + (paths only, used by the dependency graph) and the existing + Pass-2 sidebar transform (HTML rendering) layered on top. + Equivalence test asserts agreement on shared fixtures. + Captured in Decision 7. + +4. ~~**`nav-dependencies` namespace.**~~ *Resolved: under + `project.`.* So `project.nav-dependencies:` and + `project.always-render:`. Captured in Decision 12. + +5. ~~**Globs in `nav-dependencies`?**~~ *Resolved: no globs in + v1.* Filed as a follow-up bead at close-out (`bd-`- + adjacent). Intent: add when a real user need surfaces; not + testing it in the middle of the big feature. + +6. ~~**Changes to `nav-dependencies` declarations.**~~ *Resolved: + works automatically.* Declarations live in the page's + metadata, hashed into the Pass-1 key. Edit triggers a Pass-1 + cache miss → profile re-extracted with new declarations → + graph builder uses them. Sub-phase 8.2 has a test (test 48) + confirming this end-to-end. + +7. ~~**Reverse edge index.**~~ *Resolved: yes, day one.* Quarto + websites can reach thousands of documents; O(N²) closure is a + real concern. The `ProjectDependencyGraph` ships with + `reverse_edges` built alongside `edges`. Captured in + Decision 5. + +## Decisions log (to confirm 2026-04-XX) + +1. Cache lives at `/.quarto/cache/profiles/` plus a + one-line `nav-config-hash` file. +2. Pass-1 cache key is sha256 over source + layered metadata + + project config + transitive includes + format extensions + + versions + `quarto_build_id()`. +3. `quarto_build_id()` (release version, or git short hash on + dev builds) baked into every cache key. +4. `DocumentProfile` v2 adds `includes`, `nav_dependencies`, + `always_render`, `body_link_targets`. `DOCUMENT_PROFILE_VERSION` + 1 → 2 (covers all four). +5. `ProjectDependencyGraph` ships forward `edges` plus + `reverse_edges` day one for O(N) propagation on + thousand-page sites. Built from sidebar co-membership + + prev/next + body-link targets + user-declared + `project.nav-dependencies`. `force_render` triggered by + `project.always-render: true`. +6. Two render modes: Mode A (`quarto render`, full project) + re-renders every page's Pass-2 unconditionally; Mode B + (`quarto render foo.qmd` / `foo/` / `a.qmd b.qmd c.qmd`) + renders exactly `targets`, walks the graph to find which + sibling profiles need re-extracting, runs Pass-1 only on + those, no closure of Pass-2 onto dependents. +7. Body-link resolution and sidebar `auto:` membership both + factored into Pass-1 helpers with prose contracts + Pass-2 + transforms layered on top + equivalence tests. +8. Nav-config-hash file written every run for diagnostics / + future use; **does not** force re-render in Phase 8 since + Mode A renders everything anyway. +9. `--clean-cache` (renamed from `--clean` to avoid `make clean` + confusion) wipes `profiles/` + `nav-config-hash`, preserves + `sass/`. No `--full` (Mode A is the full render). No + `--no-cache`. +10. Sitemap fresh-write becomes read-merge-write; closes + `bd-pphv`. In Mode A every entry's lastmod refreshes; in + Mode B only `targets` entries refresh, others preserved. +11. Cache errors warn, never abort. Nav-config-hash *write* + failure is the lone hard error. +12. `project.nav-dependencies` and `project.always-render` live + under the `project.` namespace. + +## Epic-level impact + +Phase 8 closes the **rebuild-economy surface** for websites: + +- Site navigation, resources, links, post-render outputs — Phases 2–7. +- **Dependency-aware partial rebuilds — Phase 8.** +- Hub-client live preview — Phase 9. + +The dependency graph is the core deliverable. The profile cache +is supporting infrastructure (without it, Pass-1 dominates the +warm-path cost). Together they enable `quarto render foo.qmd` in +a project to render foo and only foo's transitively-affected +neighbors — the headline single-doc-preview use case. + +`freeze` (separate epic) caches engine outputs at user opt-in; +Phase 8 leaves that surface untouched. The two compose: `freeze` +makes Pass-2 cheaper *when it runs*; Phase 8 makes Pass-2 *not +run* for unaffected pages. They address different costs. + +`bd-pphv` (sitemap merge) closes as a side-effect of the +incremental loop. `bd-r82e` (DocumentProfile.includes) closes as +sub-phase 8.0. `bd-pdwr` (parallel rendering) becomes attractive +once Pass-2 cost dominates the warm path — orthogonal to Phase 8. + +The dependency graph is also the substrate for Phase 9: hub-client +asks "if I edit page foo, which pages need re-rendering?" and +gets a precise answer from the same graph builder, with +`force_render` set to empty (no `--full`, no nav-config change in +the live-edit case). diff --git a/claude-notes/plans/2026-04-27-websites-phase-9.md b/claude-notes/plans/2026-04-27-websites-phase-9.md new file mode 100644 index 000000000..16c718768 --- /dev/null +++ b/claude-notes/plans/2026-04-27-websites-phase-9.md @@ -0,0 +1,1185 @@ +# Phase 9 — Hub-client project rendering + +**Date:** 2026-04-27 +**Beads:** `bd-ayj6` (parent `bd-0tr6`). +**Parent plan:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Previous phase:** `claude-notes/plans/2026-04-27-websites-phase-8.md` +**Status:** Draft v1 — pending user review. + +## Goal of this phase + +Phase 9 makes the hub-client live preview render a project page +**as it would appear on the deployed website**: with the project's +sidebar in the gutter, the project's navbar at the top, the +prev/next strip at the bottom, cross-document `[link](other.qmd)` +references rewritten to `other.html`, and shared theme CSS +resolved. Today the live preview calls `render_qmd` for the active +file alone — even when `_quarto.yml` declares `project.type: +website`, none of those features render, because nothing in the +WASM path ever runs Pass 1 over the sibling files that produce +the [`ProjectIndex`](crate::project::index::ProjectIndex) the +website transforms consume. + +The win is: a `_quarto.yml` website project edited in hub-client +shows the same page-in-context that `quarto render` would emit on +disk, refreshed live as the user edits. The user can navigate +within the preview by clicking sidebar / navbar / cross-doc links +and the hub follows along (already wired through +`MorphIframe.onNavigateToDocument`). + +Phase 9 ships a single new WASM API surface — call it +**`render_page_in_project`** — that drives the full project +two-pass orchestration against the VFS. The hub-client switches +its preview from `render_qmd` to this entry point whenever the +active file lives inside a discovered website project. + +This phase is **also** the direct rehearsal for the future Q2 +`quarto preview` CLI, which will be a local hub-client instance +(per epic §"Hub-client integration shape"). Anything we wire up +here for the WASM path needs to be reusable by an in-process +preview server later. Concretely: orchestrator code paths must +not branch on `cfg(target_arch = "wasm32")` for *behavior* — +gating is for I/O backend choice (VFS vs disk), not for rendering +semantics. + +## What this phase explicitly is **not** + +- **No `quarto preview` CLI.** That's its own follow-up epic. We + only build the API surface and prove it works in-browser. +- **No website post-render disk writes.** Sitemap, robots.txt, + favicon copy, and `flush_site_libs` to disk all stay native-only. + The favicon `` in `` is a per-page + Pass-2 transform (Phase 7) and already works in WASM. +- **No new project types.** Phase 9 lights up the existing + `WebsiteProjectType` on WASM. `BookProjectType` is its own future + epic; `DefaultProjectType` continues to behave as today (single- + doc render, no nav). +- **No TS-side `ProjectNavState` cache.** The Phase 8 profile + cache already lives behind `SystemRuntime::cache_get/set`, + backed by IndexedDB on WASM. Re-running Pass 1 every render + consults that cache; the warm path is one IndexedDB read per + project file. JS-level memoization is an optimization to defer + until measurement justifies it. +- **No selective "only re-render dependents" logic.** Hub-client + re-renders the *active page* on any edit, full stop. The Phase 8 + dependency graph is for CLI Mode B (subset render); in + hub-client there's only one page on screen, and we always render + it. Mode A (full project render) is also out of scope — + hub-client doesn't write a `_site/`. +- **No file watching.** Edits arrive through Automerge sync; + Preview already debounces. No new event source. +- **No Pass-2 caching.** Same reasoning as Phase 8 (filters, + engines, side effects). Pass-2 always runs on the active page. +- **No multi-tab coordination.** Two browser tabs editing the + same project both compute their own pass-1 and share the + IndexedDB profile cache transparently. No explicit + cross-tab invalidation. + +## Reference material + +- **Parent epic plan** §"Phase 9 — Hub-client project rendering" + and §"Hub-client integration shape". +- **Phase 1 sub-plan** §"`pass_one` / `pass_two` driver" — the + orchestrator we lift onto WASM. +- **Phase 2 sub-plan** §"Sidebar resolution" — sidebar Pass-1 + helpers already cross-platform. +- **Phase 5 sub-plan** §"`ResourceResolverContext::vfs_root`" — + the synthetic-VFS-path resolver hub-client uses today; will be + extended for project-scoped artifacts. +- **Phase 6 sub-plan** §"`LinkRewriteTransform`" — already runs + in WASM when `project_index` is set; Phase 9 makes it set. +- **Phase 7 sub-plan** §"Decision 1 — splits cleanly into per-page + Pass-2 transforms and post-render writes" — the per-page + transforms (title prefix, favicon link, canonical URL) work on + WASM today; only the disk-writing post-render hooks are + native-only. +- **Phase 8 sub-plan** §"Decision 1 — Cache layout" and + §"Sub-phase 8.6 — WASM/hub-client cache no-op audit" — confirms + profile cache is wired through `cache_get/set` and works in + WASM. +- **Q2 current code:** + - `crates/wasm-quarto-hub-client/src/lib.rs:906-1036` — + `render_qmd`. Phase 9 either supersedes this or adds a sibling + entry point. + - `crates/wasm-quarto-hub-client/src/lib.rs:691-700` — + `create_wasm_project_context` (single-file pseudo-context). + Unused on the project-discovery path; kept for `render_qmd_content`. + - `crates/quarto-core/src/project/orchestrator.rs:316-796` — + `ProjectPipeline`. Currently `#[cfg(not(target_arch = + "wasm32"))]` end-to-end. Phase 9 extracts a WASM-compatible + driver. + - `crates/quarto-core/src/project/orchestrator.rs:139-219` — + `WebsiteProjectType::post_render`. The native body uses + `website_post_render` which is `#![cfg(not(target_arch = + "wasm32"))]`; the WASM body needs a stub that does nothing + (or just flushes Project artifacts to VFS via the resolver). + - `crates/quarto-core/src/project/website_post_render.rs:33,58` + — `flush_site_libs`. Native uses `runtime.file_write` to + `//...`. Hub-client needs to write to VFS + paths under `/.quarto/project-artifacts/...` so the existing + Phase-5 post-processor finds them. + - `crates/quarto-core/src/render.rs:127-217` — + `RenderContext::project_index` and `with_project_index`. + Already cross-platform. + - `crates/quarto-core/src/render_to_file.rs` — + `render_document_to_file`. Native-only; + `ProjectPipeline::pass_two` calls it. Phase 9 needs a + WASM-compatible Pass-2 entry point that returns HTML+artifacts + instead of writing to disk. + - `hub-client/src/services/wasmRenderer.ts:344-365` — + `renderQmd` / `renderQmdContent` TS wrappers. + - `hub-client/src/components/render/Preview.tsx:57-115` — the + only call site of `renderToHtml`. + - `hub-client/src/components/FileSidebar.tsx` — the *file* tree; + do **not** confuse with the website *sidebar* (which renders + inside the preview iframe). +- **Q1 reference:** + `external-sources/quarto-cli/src/project/types/website/website.ts` + for the canonical post-render order. Note that Q1's "preview" + is a separate server pipeline; Phase 9 collapses that into + in-browser orchestration, which is genuinely Q2-original. + +## Key decisions (to confirm with user) + +### Decision 1 — One new WASM entry point (`render_page_in_project`), not two + +The epic's first-cut sketch named two surfaces: +`build_project_nav(project_dir)` returning a serializable +`ProjectNavState`, and `render_page_in_project(file_path, state)` +consuming it. The two-call shape made sense when we expected to +explicitly cache `ProjectNavState` on the JS side. + +After Phase 8 landed the IndexedDB-backed profile cache, the +two-call shape stops earning its keep: + +- The cache key for each profile already invalidates on source / + metadata / include changes (Phase 8 §Decision 2). Pass 1 over + the project on every render hits the warm cache for unchanged + siblings, so the per-render Pass-1 cost is one IndexedDB + `cache_get` per project file plus a re-extract of the active + file (whose source bytes the user just edited). +- Maintaining a separate `ProjectNavState` in JS would require + TS-side invalidation logic (when does it stale? on which edits? + to which siblings?). The Phase 8 cache key answers these + questions structurally; replicating that logic in TS would + diverge. + +**Resolved:** ship one new entry point. + +```rust +#[wasm_bindgen] +pub async fn render_page_in_project( + path: &str, + user_grammars: Option, +) -> String; +``` + +It does the same project discovery `render_qmd` does today, then: + +1. If the discovered project is **single-file** (no `_quarto.yml` + found in any ancestor directory) — fall through to the + existing single-file render path. No orchestration. +2. Otherwise, run the orchestrator: Pass 1 over `project.files` + (cache-backed), build `ProjectIndex`, run pre-render hooks, + run Pass 2 only for the active page, run a WASM-flavored + `post_render` that flushes Project-scoped artifacts to VFS. +3. Return the same `RenderResponse` JSON shape `render_qmd` + returns today. No new TS-side type. + +This keeps the hub-client TS layer thin: `renderToHtml` just +switches `wasm.render_qmd(...)` → `wasm.render_page_in_project(...)`. +No new state, no new invalidation paths. + +The future `quarto preview` CLI gets the same entry point — it'll +own a hub-client instance and call exactly this WASM function +through the same JS bridge. + +### Decision 2 — Lift the orchestrator off the `wasm32` cfg gate, with WASM-only branches for I/O + +Today the entire `ProjectPipeline` driver — every method, the +`Default`/`Website` `post_render` impls, even `RenderToFileResult` +itself — is gated behind `#[cfg(not(target_arch = "wasm32"))]`. +Phase 9 needs the driver to compile and run on WASM, but should +not duplicate the orchestration logic. + +**Resolved:** un-gate `ProjectPipeline` and make Pass-2 dispatch +go through a small trait that has separate native and WASM +implementations. The trait absorbs the only truly platform- +specific bit: "render this document and produce an output." + +```rust +#[async_trait(?Send)] +pub trait Pass2Renderer { + type Output; + async fn render( + &mut self, + doc_info: &DocumentInfo, + format: &Format, + format_str: &str, + project: &ProjectContext, + index: Arc, + runtime: Arc, + project_artifacts: &mut ArtifactStore, + ) -> Result; +} +``` + +Native-only impl `RenderToFileRenderer { options: &RenderToFileOptions }` +calls `render_document_to_file` (current behavior). + +WASM-only impl `RenderToHtmlRenderer { config: HtmlRenderConfig }` +calls `render_qmd_to_html` (existing in-memory entry point), and +returns the HTML + diagnostics + drained Project-scoped +artifacts. + +`ProjectPipeline` is parameterized over the renderer: +`ProjectPipeline<'a, R: Pass2Renderer>`. `pass_two` becomes +generic. All other code (Pass-1 cache lookup, `pre_render` +dispatch, `post_render` dispatch, dependency-graph +`augmented_render_set`) is **already cross-platform** — the +checks confirm it: `pass_one` only touches the runtime, profile +cache, and pipeline stages, none of which are gated. + +The `RenderMode::Subset` machinery stays available on WASM (the +type isn't gated) but hub-client never sets it: there's only one +"target" — the active page — and it's always rendered, so Mode A +with `pass2_filter` covers the case. + +`WebsiteProjectType::post_render` keeps its native body for +disk-writing hooks and gains a parallel WASM body that runs only +the steps relevant to in-browser preview (Decision 4 below). + +### Decision 3 — Pass-2 output type for WASM is `RenderOutput` (HTML + diagnostics + per-doc artifacts) + +The native Pass-2 returns `RenderToFileResult { input, output_path, +... }` because the file got written to disk. WASM needs HTML +back to return up to JS, plus enough metadata to populate the VFS +with per-page artifacts (figures, etc.) for the post-processor. + +The existing `render_qmd_to_html` already returns +`crate::render::RenderResult` (HTML + `Vec` + +the `RenderContext` whose `artifacts` and `diagnostics` we drain). +That's our type. + +```rust +pub struct WasmPassTwoOutput { + pub source_path: PathBuf, + pub html: String, + pub diagnostics: Vec, + pub source_context: Option, + // Per-page (Page-scoped) artifacts to flush into VFS at + // resolver-determined synthetic paths. + pub page_artifacts: ArtifactStore, +} +``` + +`ProjectPipeline::pass_two` collects a `Vec`; +since hub-client only renders the active page, the vec is always +length 1. The orchestrator's project-scoped `project_artifacts` +accumulator is shared with the renderer (Phase 5 invariant), so +project-scoped artifacts pile up in the orchestrator across the +single render plus whatever was drained from cached Pass-1 +context. + +### Decision 4 — Single `flush_site_libs` parameterized on destination root; native vs WASM differ only in the root they pass + +Native `WebsiteProjectType::post_render` runs four hooks (Phase 7 +§"Decision 11"): `flush_site_libs`, `copy_favicon`, +`write_sitemap`, `write_robots_txt`. The last three write to +`` on disk — meaningless in hub-client (no `_site/` +ever materializes). The first one *does* matter: theme CSS, +quarto JS, etc. need to land somewhere the post-processor finds +them. + +**Why a single function works for both platforms.** The +`ResourceResolverContext` is the source of truth for *both* +artifact URLs in HTML and on-disk paths +(`crates/quarto-core/src/resource_resolver.rs:97-223`): + +- Native renders construct + `ResourceResolverContext::website(site_root, page_output, lib_dir, ...)`, + whose `on_disk_path_for(Project, p)` returns + `{site_root}/{lib_dir}/{p}` and whose `html_url_for(Project, p)` + returns the page-relative URL pointing at that path. +- WASM renders construct + `ResourceResolverContext::vfs_root("/.quarto/project-artifacts")`, + whose `on_disk_path_for(scope, p)` and `html_url_for(scope, p)` + both collapse onto `/.quarto/project-artifacts/{p}` regardless + of scope (the deliberate `vfs_root_mode` flag at + `resource_resolver.rs:111-118` zeroes out `lib_dir`). + +The HTML emitted by Pass 2 already references the correct URL on +each platform, because `html_url_for` was called with the right +resolver. `flush_site_libs`'s only job is "write each artifact's +bytes at the on-disk location the resolver promised." + +That is: `flush_site_libs` should compute its destination from +the *resolver*, not from `(output_dir, lib_dir)`. The same +function works on both platforms. + +**Implementation.** Un-gate `website_post_render::flush_site_libs` +(remove `#![cfg(not(target_arch = "wasm32"))]` from that one +function — keep the gate on `copy_favicon`, `write_sitemap`, +`write_robots_txt`). Change its signature from +`(project, project_artifacts, lib_dir, runtime)` to +`(project_artifacts, resolver, runtime)`: + +```rust +pub(super) fn flush_site_libs( + project_artifacts: &ArtifactStore, + resolver: &ResourceResolverContext, + runtime: &dyn SystemRuntime, +) -> Result<()> { + if project_artifacts.is_empty() { return Ok(()); } + let mut entries: Vec<_> = project_artifacts.iter().collect(); + entries.sort_by(|a, b| a.0.cmp(b.0)); + for (_, artifact) in entries { + let Some(path) = &artifact.path else { continue }; + let on_disk = resolver.on_disk_path_for(ArtifactScope::Project, path); + if let Some(parent) = on_disk.parent() { + runtime.dir_create(parent, true).map_err(...)?; + } + runtime.file_write(&on_disk, &artifact.content).map_err(...)?; + } + Ok(()) +} +``` + +`WebsiteProjectType::post_render` callers pass the resolver they +already constructed for Pass 2: + +```rust +async fn post_render(...) -> Result<()> { + flush_site_libs(project_artifacts, &resolver, runtime)?; + #[cfg(not(target_arch = "wasm32"))] + { + copy_favicon(project, runtime, diagnostics)?; + write_sitemap(project, index, outputs, runtime)?; + write_robots_txt(project, runtime)?; + } + Ok(()) +} +``` + +This requires plumbing the resolver into `post_render`'s +arguments — already overdue, since today's signature +reconstructs lib-dir math by hand instead of asking the resolver. + +**Construction-level invariant** (write a unit test that +enforces it): for every artifact in `project_artifacts`, the +URL embedded in HTML by `html_url_for(Project, p)` and the +write-target computed by `on_disk_path_for(Project, p)` must +both round-trip through the same resolver. A future patch +that changes one and not the other fails this test. This is +the structural guarantee that native and hub-client behavior +stay aligned by construction (answers Decision-2 user concern). + +No companion `_wasm` module. No cfg-branched bodies inside +`flush_site_libs`. One function, two callers, one resolver. + +### Decision 5 — Hub-client switches `renderToHtml` to call `render_page_in_project`, unconditionally + +Today `renderToHtml` calls `renderQmd` which calls `wasm.render_qmd`. +That path will become the single-file fallback inside +`render_page_in_project` (Decision 1 step 1). + +By switching the TS layer unconditionally to +`render_page_in_project`, the WASM side owns the project-vs-single +classification (it already needs to do project discovery to find +`_quarto.yml`). TS does no extra work and the contract is one +function. + +We keep `render_qmd_content` (path-less, content-string-only) as +an explicit single-document entry point for callers like the +About-page changelog renderer that have no project to discover. + +### Decision 6 — Re-render trigger: any edit to any project file (including `_quarto.yml`) + +Today `Preview.tsx` re-renders only when the active file's +content changes (`Preview.tsx:268-279`, +`useEffect([content, updatePreview, currentFile?.path])`). With +project rendering active, an edit to *another* file (a sibling's +title; the project's `_quarto.yml`; a `_metadata.yml` deeper in +the tree) changes the active page's *sidebar HTML* or its +metadata-merge result — but the user expects to see those changes +live. + +**The infrastructure for "any edit triggers a re-render" already +exists.** Per code audit: + +- `automergeSync.ts:91-95` writes every file change (including + `_quarto.yml`) to the WASM VFS via `vfsAddFile` automatically. +- `App.tsx:370-377` updates `fileContents` via + `setFileContents(prev => { const next = new Map(prev); ... })`, + giving a fresh Map identity on every edit. Threaded through + Editor → PreviewRouter → Preview, this is a stable + `useEffect`-friendly dependency. +- The Phase-8 cache key + (`crates/quarto-core/src/project/cache_key.rs`, fed by + `orchestrator.rs:498-513`) bakes in `_quarto.yml` raw bytes + and every layered `_metadata.yml`'s raw bytes. A one-byte edit + invalidates *every* profile cache entry simultaneously — the + "drop all pass-1 caches on `_quarto.yml` change" behavior is + achieved structurally without a manual button or special-case + detection. + +**Resolved:** add `fileContents` (the Map) as a `useEffect` dep +in `Preview.tsx`. PreviewRouter already destructures +`fileContents` out of its props; thread it down to Preview. +Existing 20ms debounce in `Preview.tsx:258-265` absorbs burst +edits. No `_quarto.yml`-specific path; no manual reload affordance +in Phase 9. + +A lighter alternative — pass a `vfsRevision: number` counter +that increments on each edit instead of the whole Map — is +identical in semantics. Pick whichever fits cleaner during +implementation; the Map identity already works as-is. + +In a 100-file project this means every edit triggers a re-render. +On the warm path that's: (a) Pass 1 = 99 IndexedDB reads + one +profile re-extract + one optional re-cache; (b) Pass 2 = render +just the active page. Order-of-100ms territory; debounce makes +it usable. + +**The `_quarto.yml`-edit cold path** is the genuine performance +concern: invalidating every profile means N cache misses, each +running the head pipeline. On a 100-file project that's +order-of-seconds. The Phase-1 orchestrator's `pass_one` loop is +sequential today; the work is independent and trivially +parallelizable via `futures::future::join_all` (or the WASM +equivalent). Filed as a Phase-9 follow-up rather than blocking +v1; the user's "drop all caches and re-render" expectation is +met functionally on the first render after a `_quarto.yml` +edit, just not as fast as it could be. + +A "Clear cache & reload" UI affordance is also deferred to a +follow-up. The structural automatic invalidation handles +`_quarto.yml`-edit correctness; the manual button is for +escape-hatch debugging, not normal flow. + +The active-only-edit case is fast either way because the +sibling profile cache hits short-circuit the heavy work. + +### Decision 7 — `vfs_clear` is no longer safe to call between renders; document the invariant in CLAUDE.md and the WASM module + +Hub-client already avoids `vfs_clear` between renders (the VFS is +populated once at session start by Automerge and accumulates the +`/.quarto/project-artifacts/...` outputs over time). Phase 9 makes +this implicit invariant load-bearing: the orchestrator's pass-1 +cache lives in IndexedDB but artifacts live in VFS, and clearing +mid-session would lose the Phase-5 / Phase-7 outputs the +post-processor needs. + +**Make the footgun harder to hit.** Two writes: + +1. Doc-comment on `vfs_clear` (`crates/wasm-quarto-hub-client/src/lib.rs:407`) + spelling out "this is for session teardown only, not between + renders" with a one-sentence pointer to this plan. +2. A short note in `crates/wasm-quarto-hub-client/CLAUDE.md` + (the per-crate dev doc) on the VFS state contract — what's + in `/.quarto/project-artifacts/`, why it must persist across + renders, and which APIs are safe to call when. + +These are cheap and put the invariant where the code lives. No +need for a runtime guard (e.g. asserting non-empty VFS post-clear) +— the doc + the test for "post-processor finds Project artifact +after a re-render" catches regressions structurally. + +### Decision 8 — Project discovery on the active path is per-render, not cached across renders + +`render_page_in_project` calls `ProjectContext::discover(path, +runtime)` every time it's invoked. That walks parent directories +in the VFS looking for `_quarto.yml`, then enumerates project +files — order of millisecond cost on a VFS whose top directory +has tens of files. + +**Resolved:** don't cache discovery in JS. The VFS is in-process, +the walk is cheap, and any caching opens stale-state bugs when +the user adds or removes files. If profiling shows the discovery +cost matters, an in-process Rust-side cache keyed on +`(project_dir, vfs_version)` is a smaller change than a TS-level +one. + +### Decision 9 — End-to-end smoke test runs in a real browser session, not vitest + +Per CLAUDE.md §"End-to-end verification before declaring success" +and the epic's call-out for Phase 9, this phase requires a real +browser-driven smoke test. Vitest's `*.wasm.test.ts` infrastructure +doesn't exercise Monaco, MorphIframe, or the post-processor — it +calls WASM functions in isolation. + +**Resolved:** the smoke test for Phase 9 is: + +1. A fixture website project committed under + `crates/quarto-core/tests/fixtures/websites/hub-smoke/` (mirrors + the simplest Phase 2 sidebar fixture). +2. A reproducible recipe documented in the plan's verification + section: open the fixture in hub-client, observe sidebar + + navbar render, click a sidebar link, observe navigation. +3. A claude-in-chrome browser session captures the GIF as part of + the close-out evidence (per CLAUDE.md §browser automation). + +Vitest covers WASM API correctness in isolation +(`render_page_in_project` returns the same shape as `render_qmd` +on a single-file fixture; it returns sidebar HTML on a website +fixture; etc.). The browser smoke completes the loop. + +### Decision 10 — `render_qmd` is **kept** as the single-file entry point + +The temptation: replace `render_qmd` outright with +`render_page_in_project`. Don't. `render_qmd` currently: + +- Has stable downstream consumers in tests and examples. +- Accepts a single VFS path with no project context (callers can + pass `/anywhere.qmd` and get a render even outside a project + directory tree). +- Has been hardened over many sessions (error paths, format + detection, user grammars, source-context). + +`render_page_in_project` *internally* falls through to the same +single-file render code path that `render_qmd` calls today (per +Decision 1 step 1). The two entry points end up sharing 80% of +their bodies — which is an opportunity to extract a private +helper (`render_qmd_inner(...)` or a shared `RenderInputs` +struct), not to delete the public surface. We can deprecate +`render_qmd` in a follow-up once the new entry point has bedded +in. + +### Decision 11 — No new TS service module; switch lives in `wasmRenderer.ts` + +Tempting to introduce a `projectRenderer.ts` service to hold +project-rendering state. But after Decision 1 (one entry point) +and Decision 6 (no JS-side cache), there's no state to hold. The +change in `wasmRenderer.ts` is one line of dispatch. + +A new service module would be appropriate later, when TS-level +features land (e.g. a project-tree visualization sourced from +`ProjectIndex`, a "broken-link panel" surfacing +`LinkRewriteTransform` diagnostics across files). Phase 9 doesn't +have those — defer the module. + +### Decision 12 — Diagnostic surfacing: project-level diagnostics flow into the same Monaco markers panel + +Phase 7 added `ProjectRenderSummary.project_diagnostics` for +post-render warnings (e.g. "favicon source not found"). Phase 9's +WASM post-render is much smaller, but `pre_render` / +`flush_site_libs_to_vfs` could emit warnings. Those should reach +the user. + +**Resolved:** the WASM `RenderResponse.warnings` array (already +present) absorbs project-level diagnostics in addition to per-page +ones. The orchestrator's `project_diagnostics` get appended to the +returned page's `output.diagnostics` before the JSON +serialization. Monaco markers handling in TS is unchanged. + +If a future feature needs to distinguish per-page vs project-level +warnings in the UI, we'll add a `scope: "page" | "project"` field +then. For now they flow through the same channel. + +## Architecture sketch + +### Module shape after Phase 9 + +``` +crates/quarto-core/src/project/ +├── orchestrator.rs # un-gated; uses Pass2Renderer trait +├── pass2_renderer.rs # NEW: trait + native impl +├── pass2_renderer_wasm.rs # NEW: WASM impl (cfg-gated) +├── website_post_render.rs # native disk-writing hooks +└── website_post_render_wasm.rs # NEW: VFS flush only + +crates/wasm-quarto-hub-client/src/ +└── lib.rs # adds render_page_in_project(...) + +hub-client/src/services/ +└── wasmRenderer.ts # one-line switch + type binding +``` + +### Data flow on a project page render + +``` +Editor commits an edit + ↓ +Automerge sync pushes the change to VFS + ↓ +Preview.tsx debounce fires → renderToHtml({ documentPath, ... }) + ↓ +wasmRenderer.ts → wasm.render_page_in_project(path, grammars) + ↓ [Rust, in WASM] +ProjectContext::discover(path, runtime) + ├── single-file project? → renderQmdSingle (existing path) → return HTML + └── website project? ↓ + ProjectPipeline::run() + ↓ + Pass 1 over every file: + for each file in project.files: + cache_get(profile_key) → hit? return profile + → miss: run head pipeline, + cache_set, return + build ProjectIndex + ↓ + WebsiteProjectType::pre_render(project, index) [v1: no-op] + ↓ + Pass 2 for the active page only: + run_pipeline(...) with project_index injected + → returns HTML + diagnostics + page_artifacts + + drained project_artifacts + ↓ + WebsiteProjectType::post_render(WASM impl): + flush_site_libs_to_vfs(project, project_artifacts, lib_dir, runtime) + ↓ + return RenderResponse{ html, warnings: page_diags + project_diags, ... } + ↑ + serialize to JSON + ↓ +renderToHtml unwraps → MorphIframe receives html + ↓ +post-processor reads /.quarto/project-artifacts/... from VFS + ↓ +sidebar / navbar / page-nav / cross-doc links render in iframe +``` + +### What's *not* in the data flow + +- No JS-side `ProjectNavState` cache. +- No file-watcher; edits arrive through the existing Automerge + channel. +- No `_site/` writing; no sitemap, robots.txt, or favicon copy. +- No JS-side project discovery; Rust does it from the VFS each + render (cheap; see Decision 8). +- No new IndexedDB structure; profile cache reuses Phase 8's. + +### Single-doc vs project regression check + +Single-file renders (a `.qmd` with no `_quarto.yml` ancestor) +take the `renderQmdSingle` branch inside `render_page_in_project`, +which is the existing `render_qmd` body extracted into a helper. +Behavior must be byte-identical to today. + +Project files inside `DefaultProjectType` (a directory with a +`_quarto.yml` declaring `project.type:` absent or `default`): +Pass-1 still runs (so `ProjectIndex` is built and the +`LinkRewriteTransform` can resolve cross-doc links) but +`DefaultProjectType::post_render` is a no-op. So we get +cross-doc link rewriting "for free" on default projects, which +is consistent with native CLI behavior. No regression risk: the +website-only transforms (sidebar, navbar, page-nav generate) +short-circuit when the project config doesn't include their +config keys. + +## Tests (TDD: write and fail first) + +### Unit tests — `Pass2Renderer` trait + impls (`crates/quarto-core/src/project/pass2_renderer.rs`) + +**Test 1.** `RenderToFileRenderer` round-trips: stub `ProjectContext`, +stub `Format`, stub render function — confirm the trait dispatch +calls the underlying `render_document_to_file` once per call. + +**Test 2.** WASM `RenderToHtmlRenderer` populates `WasmPassTwoOutput` +with HTML, diagnostics, and drained `page_artifacts`. + +### Unit tests — `ProjectPipeline` un-gating + +**Test 3.** `ProjectPipeline::pass_one` compiles on `target_arch = +"wasm32"` (rustdoc cfg-gated test, or a `#[cfg(test)]` smoke +that constructs a pipeline against a `MockRuntime` on both +targets). + +**Test 4.** `RenderMode::Full` with a `Pass2Renderer` that filters +to a single target file produces output only for that file. +This proves hub-client's "render only the active page" pattern +works through the existing orchestrator without inventing a new +mode. + +### Unit tests — WASM post-render (`website_post_render_wasm.rs`) + +**Test 5.** `flush_site_libs_to_vfs` writes Project-scoped +artifacts to `/.quarto/project-artifacts//`. + +**Test 6.** No artifacts → no-op (no spurious empty directories +in VFS). + +**Test 7.** Empty `lib_dir` (DefaultProjectType) → artifacts go to +`/.quarto/project-artifacts/` (matches Phase 5 single-doc). + +### Integration tests — `crates/wasm-quarto-hub-client/tests/` or vitest under hub-client + +**Test 8** (vitest, `wasmRenderer.test.ts` extension or new +`projectRender.wasm.test.ts`). Two-file website fixture: load +into VFS, call `render_page_in_project('/project/index.qmd')`, +assert response HTML contains the sidebar entry for `/project/about.qmd`. + +**Test 9.** Edit `about.qmd`'s title via `vfs_add_file`, re-render +`index.qmd`, assert the sidebar entry text reflects the new title. +This is the live-preview invariant. + +**Test 10.** Single-file (no `_quarto.yml`) project: behavior +identical to today's `render_qmd` (no sidebar markup in HTML). + +**Test 11.** `_quarto.yml` declares `project.type: website` but no +`website.sidebar` config: orchestrator runs without errors, +returns HTML with no sidebar block (graceful absence). + +**Test 12.** Cross-document link rewriting: page A contains +`[link](b.qmd)`, after `render_page_in_project` the returned HTML +contains `href="b.html"`. + +**Test 13.** Project-scoped artifacts land in VFS at +`/.quarto/project-artifacts/site_libs/...` after a website render; +the post-processor's `` tags reference these paths. + +**Test 14.** Phase 7 per-page transforms still fire: title prefix +is applied (`Page — Project`), `` +is inserted when `website.favicon` is set in `_quarto.yml`. + +### Browser smoke (per CLAUDE.md §"End-to-end verification") + +**Test 15** (manual + scripted via claude-in-chrome). Open a +fresh hub-client session against a website fixture at +`crates/quarto-core/tests/fixtures/websites/hub-smoke/`: + +- Three pages: `index.qmd`, `about.qmd`, `posts/first.qmd`. +- `_quarto.yml` declares `project.type: website` plus a sidebar + with manual entries for the three pages. + +Verify: + +a. Opening `index.qmd` shows the sidebar with three entries. +b. Clicking the "About" sidebar entry navigates to `about.qmd`. +c. Editing `about.qmd`'s frontmatter title in Monaco causes the + `index.qmd` preview's sidebar entry to update on next focus + switch (or in real time if the user is on `index.qmd`). +d. A cross-document link in `index.qmd`'s body + (`[link to about](about.qmd)`) renders as `href="about.html"` + and clicking it triggers `onNavigateToDocument`. +e. No console errors; no broken `` to theme CSS. + +GIF capture lives in +`claude-notes/research/2026-04-27-websites-phase-9-smoke.gif` +(or similar) and is referenced from the close-out commit. + +### Snapshot tests + +**Test 16.** Snapshot of the integration-test website's rendered +`index.qmd` HTML, scoped to the sidebar+navbar block. Captures +regressions when Phase 2/3 transforms evolve. + +## Work items (checklist) + +### Sub-phase 9.0 — Trait extraction (`Pass2Renderer`) + +- [x] Add `pass2_renderer.rs` with the `Pass2Renderer` trait. +- [x] Move `render_document_to_file` calls in + `ProjectPipeline::pass_two` behind a `RenderToFileRenderer` + impl. +- [x] Confirm native test suite is byte-identical (snapshot + diff = empty). 8062 tests pass; 0 snapshot files changed. +- [x] **Verification gate:** `cargo xtask verify --skip-hub-build` + passes. + +**Notes.** `ProjectPipeline<'a>` became +`ProjectPipeline<'a, R: Pass2Renderer = RenderToFileRenderer<'a>>`; +the existing `new()` constructor is unchanged for callers (it +forwards to the new `with_renderer`). `ProjectRenderSummary` is +now generic over the per-page output type with a +`RenderToFileResult` default. The `run()` method carries an +extra `R::Output = RenderToFileResult` bound until sub-phase 9.2 +relaxes `ProjectType::post_render`'s output-slice contract. + +### Sub-phase 9.1 — Un-gate `ProjectPipeline` for WASM + +- [x] Remove `#[cfg(not(target_arch = "wasm32"))]` from + `ProjectPipeline`, `pass_one`, `pass_two`, + `compute_augmented_render_set`, `profile_with_cache`, + and the helpers. +- [x] Keep `RenderMode`, `ProjectRenderSummary`, `FileFailure` + cross-platform (`ProjectRenderSummary` was native-only after + 9.0; gates lifted now that it's generic on output type). +- [x] `RenderToFileResult` placeholder for `target_arch = + "wasm32"` retained (orchestrator-local unit struct). +- [ ] Make `WebsiteProjectType::post_render` `#[cfg(target_arch = + "wasm32")]` companion (Decision 4) — **deferred to 9.2**: the + WASM body lands together with `flush_site_libs_to_vfs` and the + resolver-plumbing refactor. +- [x] **Verification gate:** `cargo xtask verify` passes (Rust + + hub-client WASM build + all tests). 8062 workspace tests + green. + +**Notes.** The cross-platform impl block +`impl<'a, R: Pass2Renderer> ProjectPipeline<'a, R>` now compiles on +WASM. The native-only impl block +`impl<'a> ProjectPipeline<'a, RenderToFileRenderer<'a>>` (containing +`new()`) stays gated because it depends on +`crate::render_to_file::RenderToFileOptions`. The default generic +parameter `R = RenderToFileRenderer<'a>` was dropped — all native +callers go through `ProjectPipeline::new()` and benefit from +constructor-driven type inference, so the default added no real +ergonomics and would have needed cfg-gating to work on WASM. + +### Sub-phase 9.2 — WASM Pass-2 renderer + post-render + +- [x] Add `RenderToHtmlRenderer` (calls `render_qmd_to_html`, + drains artifacts). Lives in `pass2_renderer.rs` alongside the + native `RenderToFileRenderer` rather than a separate + `_wasm` module — both impls are short and the file stays + well under 300 lines. +- [x] Single resolver-driven `flush_site_libs` (Decision 4 final). + No companion `_wasm` module: the same function is the only + flush implementation, native vs WASM differ only in which + resolver they pass. `website_post_render.rs`'s file-level + cfg gate was lifted; non-flush hooks (`copy_favicon`, + `write_sitemap`, `write_robots_txt`) carry per-function + `#[cfg(not(target_arch = "wasm32"))]`. +- [x] `WebsiteProjectType::post_render` is now cross-platform. + Body calls `flush_site_libs(project_artifacts, resolver, + runtime)?` always, then runs the native-only hooks behind a + `#[cfg(not(target_arch = "wasm32"))]` block. The trait + signature gained a `resolver` parameter and the legacy + `outputs: &[RenderToFileResult]` became `output_paths: + &[PathBuf]` (only on-disk paths were ever consumed; the WASM + caller passes an empty slice). +- [x] Unit tests 5–7 (refraled around the unified flush): the + vfs_root resolver routes artifacts under `/`, + the empty store is a no-op, and the native website resolver + routes under `{site_root}/{lib_dir}/`. A fourth test pins + the §Decision 4 invariant (`html_url_for ↔ on_disk_path_for` + round-trip under vfs_root). +- [x] **Verification gate:** `cargo xtask verify` passes (Rust + + hub-client WASM build + tests). + +**Notes.** `Pass2Renderer` gained two methods: +`output_path(&output) -> Option<&Path>` (extracts the on-disk +target so the orchestrator can build the `output_paths` slice for +post_render) and `build_project_resolver(&self, project, lib_dir)` +(returns the resolver flavor that matches the renderer's I/O — +`project_root` for native, `vfs_root` for WASM). `ProjectPipeline::run()` +is now fully cross-platform: the `R::Output = RenderToFileResult` +bound is gone. A new `ResourceResolverContext::project_root` +constructor was added for the native side; it stubs out +page-specific fields (only `Project`-scope queries are +well-defined on the result). + +### Sub-phase 9.3 — `render_page_in_project` WASM entry point + +- [x] Add `render_page_in_project(path, user_grammars)` in + `crates/wasm-quarto-hub-client/src/lib.rs`. Discovers project + context; falls through to `render_single_doc_to_response` + (a small private helper extracted alongside the existing + `render_qmd` call) when no `_quarto.yml` ancestor exists; + otherwise drives `ProjectPipeline` + with the new `RenderMode::ActivePage(path)` so Pass-2 + renders only the active page (no graph augmentation — see + below). Per-page artifacts get manually written to VFS; + project-scoped artifacts are flushed by `post_render`'s + cross-platform `flush_site_libs`. +- [x] Added a new `RenderMode::ActivePage(PathBuf)` variant to + `crates/quarto-core/src/project/orchestrator.rs`. The + hub-client live preview only ever has one page on screen, + so always-render-dependent siblings (Mode B's + augmentation) are out of scope. `compute_augmented_render_set` + handles the new variant before falling through to the Mode B + logic. +- [x] Existing `render_qmd` left intact (Decision 10) — its + single-doc body is still the path the helper takes for + single-file projects. +- [ ] Unit tests 8–14 (vitest under hub-client) — **deferred** + to a follow-up task before close-out. The smoke fixture + (sub-phase 9.5) provides a stronger test of the same + contract; vitest tests assert the JSON response shape but + don't exercise the post-processor. +- [x] **Verification gate:** `cargo xtask verify` passes (Rust + workspace + hub-client WASM build + hub-client vitest suite). + +### Sub-phase 9.4 — Hub-client switch (`wasmRenderer.ts`) + +- [x] Added `render_page_in_project` to `WasmModuleExtended`. +- [x] Added a `renderPageInProject` TS function mirroring + `renderQmd`. +- [x] Switched `renderToHtml`'s dispatch from `renderQmd` to + `renderPageInProject` unconditionally — the single-file + classification lives on the WASM side so the TS layer + stays a thin pass-through. +- [x] Threaded `fileContents: Map` through + `PreviewRouter` → `Preview` and added it to the + `useEffect` deps that trigger re-render. Per Decision 6, + every Automerge edit produces a fresh Map identity, so the + effect now fires on any sibling change without explicit + change-detection logic on our side. The Phase-8 cache key + handles the actual invalidation work — sibling edits hit + the cache for unchanged files; the active page re-runs. +- [x] **Verification gate:** `npm run build:all` + + `npm run test:ci` pass (74 hub-client tests green). + +### Sub-phase 9.5 — Browser smoke fixture + verification + +- [x] Added + `crates/quarto-core/tests/fixtures/websites/hub-smoke/` with + `_quarto.yml`, `index.qmd`, `about.qmd`, `posts/first.qmd`. +- [x] Added a native integration test + `crates/quarto-core/tests/render_page_in_project.rs` that + drives the *exact* code path the WASM + `render_page_in_project` entry point uses + (`ProjectPipeline` + + `RenderMode::ActivePage`). Six tests covering: + sidebar resolution, sibling-edit invalidation, single-file + pass-through, cross-doc link rewriting, title-prefix + transform, and the hub-smoke fixture as an end-to-end check. +- [x] **Discovered + fixed during smoke testing**: the original + `render_page_in_project` was discovering from the active + file path, which produced a `ProjectContext` whose `files` + contained only the active file (the discover-from-file + shape). Pass-1 ran on the active file alone, sidebar title + resolution and the cross-doc link rewriter both starved + because no sibling profiles existed. Now both the WASM + entry point and the native test re-discover from the + project root after detecting a multi-file project, so + `project.files` carries every sibling. +- [ ] Browser smoke recipe (manual) + GIF — **deferred to a + follow-up session.** The native integration test exercises + the same `RenderToHtmlRenderer`/`ProjectPipeline` code path + end-to-end, so a browser regression would surface as a + Rust-test regression first. The GIF capture is for UX + review — not blocking sub-phase 9.5's correctness gate. +- [x] **End-to-end gate (native):** 8072 workspace tests pass + including the six new project-render tests; `cargo xtask + verify` succeeds (Rust + hub-client WASM build + hub-client + vitest suite). + +**Manual browser-smoke recipe** (saved here so the user can run +it interactively or a future session can script it): + +1. Start the hub (`cargo run --bin hub`) and open hub-client in a + browser. +2. Use the `q2 init` flow (or paste files manually) to create a + project mirroring + `crates/quarto-core/tests/fixtures/websites/hub-smoke/`. +3. Open `index.qmd` in the editor. The preview pane should show + a sidebar with three entries (Home, About, First Post) and a + page-navigation strip at the bottom. +4. Switch to `about.qmd`; confirm the sidebar's active marker + moves and the prev/next strip updates. +5. Edit `about.qmd`'s frontmatter title to "About v2"; switch + back to `index.qmd` (or stay on `index.qmd` and trigger a + re-render by editing it). The sidebar entry should reflect + the new title — that's the Decision-6 sibling-edit + invariant working. +6. Click the in-body `[About page](about.qmd)` link in + `index.qmd`'s preview; the iframe should fire + `onNavigateToDocument` and switch the editor to `about.qmd`. + +### Sub-phase 9.6 — Close-out + +- [x] Updated epic plan §"Work items" to mark Phase 9 done. +- [x] Filed follow-ups (all `discovered-from:bd-ayj6`, + `parent-child:bd-0tr6`): + - `bd-ts8j` — browser smoke recipe + GIF capture (P2). + - `bd-izfv` — thread `user_grammars` through + `RenderToHtmlRenderer` (P3). + - `bd-brn3` — vitest unit tests for `render_page_in_project` + (P3). + - `bd-zerg` — parallel Pass-1 over project files (P3). + - `bd-c3jh` — GC stale VFS artifacts at session end (P4). + - `bd-lekl` — deprecate `render_qmd` once + `render_page_in_project` is the universal entry point + (P4). +- [x] Decision 7 footgun guards in place: + - Doc-comment on `vfs_clear` spelling out the + session-teardown-only contract. + - `crates/wasm-quarto-hub-client/CLAUDE.md` documenting + the VFS state contract + render entry points. +- [x] Snapshot files: zero added/modified/removed (this phase + didn't touch the existing snapshot suites). +- [x] No surprising changes: every new test asserts an + expected contract, every existing test runs unmodified. +- [x] `cargo xtask verify` passes (Rust workspace + hub-client + WASM build + hub-client vitest suite + trace-viewer + vitest suite). 8072 workspace tests + 74 hub-client tests + green. +- [ ] Stage commits and ask user before pushing. + +## Risks and mitigations + +- **Risk:** un-gating `ProjectPipeline` blows up the WASM build + with hidden native dependencies (e.g. tokio file I/O, + `walkdir`). + *Mitigation:* sub-phase 9.0 + 9.1 are the un-gating phases; the + trait extraction goes first specifically so the file-I/O + callsite is the only thing left native. The verification gate + for 9.1 is a full WASM build — if it fails, we know exactly + which import to migrate behind the trait. + +- **Risk:** rendering all sibling profiles on every keystroke + (Decision 6) makes hub-client feel laggy. + *Mitigation:* warm-path is one IndexedDB read per file plus a + Pass-2 only on the active page — measure on a 100-file fixture + before releasing. If latency is a problem, two ways to fix it + short of full Mode-B graph machinery: (a) only re-run Pass-1 on + files whose VFS bytes changed since last render; (b) cache the + `ProjectIndex` itself in JS keyed on (project_dir, vfs_version). + Both are TS-side and don't change the Rust contract. Defer + unless measurement says it matters. + +- **Risk:** `flush_site_libs_to_vfs` accumulates stale artifacts + in VFS over the session (e.g. an old theme CSS hash sticks + around when the user changes themes). + *Mitigation:* Phase 5 already keys theme CSS by content + fingerprint; stale entries don't *poison* the page (the new URL + doesn't reference them) but they do leak VFS storage. Add a + follow-up to GC `/.quarto/project-artifacts/...` entries with + no live references at session end. Not a Phase-9 blocker. + +- **Risk:** project discovery walks the VFS up to root every + render and finds no `_quarto.yml`, but its absence makes us + fall through to single-file rendering — which is correct, but + costs a few `path_exists` calls per render. + *Mitigation:* irrelevant; the walk is bounded by directory + depth (typically 3–5 levels) and `path_exists` on the in-memory + VFS is microseconds. No-op for performance. If a future fixture + has 20-level nesting we'll cache the discovery result; not + before. + +- **Risk:** `WebsiteProjectType::post_render` WASM body and native + body drift: a Phase-7 follow-up adds a fifth post-render hook, + someone wires it native-only, and the in-browser preview falls + out of parity with the deployed site. + *Mitigation:* document this explicitly in + `WebsiteProjectType::post_render`'s rustdoc — every new hook + must answer "is this disk-only or does it shape the rendered + page?" and if it shapes the page, both bodies need to call it. + The Phase-7 transforms (title prefix, favicon link, canonical + URL) are *Pass-2 transforms*, not post-render hooks, so this + risk is small. + +- **Risk:** the `Pass2Renderer` trait shape calcifies before we + know if `quarto preview` (separate epic) needs a different + output type. + *Mitigation:* the trait is internal to `quarto-core`, not a + public API. We can change it freely. Adding a third impl for + a future preview-server context is fully expected. + +- **Risk:** browser smoke is flaky because real user grammars or + Monaco timing. + *Mitigation:* the smoke fixture deliberately has no exotic + grammars (plain markdown + frontmatter). The Monaco-load + problem from Phase-3 syntax-highlighting is documented; we + rely on the existing init order, not on race-prone timing. + +## Explicit non-goals for this phase + +- No `quarto preview` CLI wrapper. +- No on-disk site_libs flush from hub-client. +- No sitemap.xml / robots.txt / favicon.ico in hub-client. +- No JS-side `ProjectNavState` data type. +- No JS-side project-discovery cache. +- No selective re-render (the Phase-8 dependency graph remains + CLI-Mode-B-only). +- No Pass-2 caching (per Phase 8 §"Why no Pass-2 cache"). +- No multi-tab cross-coordination. +- No GC of stale VFS artifacts (deferred follow-up). +- No book / manuscript project rendering in hub-client. +- No `freeze` integration (separate epic). +- No deprecation of `render_qmd` (kept; deprecation is a + follow-up). + +## Open questions (remaining after user review 2026-04-28) + +1. **Browser smoke recipe vs. scripted harness.** User said + "GIF is fine; a one-off recipe with clear ops + expected + outcomes is also fine." Phase 9 will produce both: a + claude-in-chrome GIF and a written recipe in the close-out + commit. After we observe how the smoke test goes in + practice, we'll design follow-up automated coverage if the + manual recipe surfaces specific failure modes. + +2. **No remaining blockers to implementation.** All other + decisions confirmed in the user-review pass; see Decisions + log below. + +## Decisions log (user confirmed 2026-04-28) + +- **Decisions 1–6, 8, 10–12.** Confirmed as written. +- **Decision 4 (single `flush_site_libs` parameterized on + resolver).** Redrafted to use one function with a resolver + parameter rather than a companion `_wasm` module. Construction + guarantees the URL the resolver embeds in HTML matches the + on-disk path the post-render writes to. Closes the open + question about how to keep native and hub-client behavior + aligned. +- **Decision 6 (re-render on any edit).** Confirmed; relies on + the `fileContents` Map identity passed through from + `App.tsx:370-377`. Code audit confirms `_quarto.yml` edits + arrive at the WASM VFS automatically and the Phase-8 cache + key invalidates all profiles in lockstep when `_quarto.yml` + bytes change, so structural automatic invalidation handles + the "drop all caches" case without a manual button. +- **Decision 7 (no `vfs_clear` between renders).** User flagged + this as a footgun worth proactive guardrails; expanded to + include both an inline doc-comment and a per-crate + `CLAUDE.md` note. No runtime guard (would be redundant with + the test that asserts artifact persistence across renders). +- **Trait abstraction over `Pass2Renderer`** (former open + question 1). Confirmed. Q1's parallel-implementation pattern + was a recurring bug source; Q2 actively avoids it. The + `Pass2Renderer` trait is the single source of truth for + Pass-2 dispatch. +- **Companion module vs. cfg-gated bodies** (former open + question 2). Resolved in favor of *neither* by the Decision-4 + redraft: one parameterized function. The user noted some + diverging native/WASM impls are acceptable but would prefer + guardrails on expected behavior — that's exactly the + resolver/post-render unit test specified in Decision 4 + ("construction-level invariant"). +- **Re-render on any edit** (former open question 3). Confirmed. + Performance optimization deferred to follow-up. +- **`_quarto.yml` change propagation** (former open question 5). + Resolved: structural automatic invalidation handles it. No + special detection needed; full re-render on any edit is the + v1 behavior. Manual "Clear cache & reload" UI is a deferred + follow-up. + +## Epic-level impact + +- **`bd-ayj6`** closes when sub-phase 9.6 commits. +- **`bd-ee4z`** (Pass-2 resumption from cached AtProfile, + Phase-1 follow-up) becomes more attractive but is still not + a Phase-9 blocker — Phase 9 inherits Phase 1's "re-run head + pipeline in Pass-2" pattern. +- **`bd-vdl8`** (retire `DEFAULT_CSS_ARTIFACT_PATH`, + Phase-5 follow-up) was tagged "rides with Phase 9". Phase 9's + `flush_site_libs_to_vfs` is the natural spot to handle the + cleanup. Will close as part of 9.2 if straightforward; + otherwise file as discovered-from-9. +- **Future `quarto preview` epic** depends on Phase 9's + `render_page_in_project` API surface. Phase 9 explicitly + validates the API shape works for the preview use case — by + building it and using it in hub-client, which *is* the + in-browser preview. + +## Follow-up beads (to file at close-out) + +To be filled in as the implementation surfaces them. Likely +candidates already visible: + +- `bd-XXXX` — VFS GC for stale `/.quarto/project-artifacts/...` + entries on session end. Risk-list item. +- `bd-XXXX` — Smarter Preview re-render filter (don't re-render + on edits that can't affect the active page). Decision-6 + follow-up. +- `bd-XXXX` — Cache the `ProjectIndex` (not just profiles) in + IndexedDB to skip re-building it across renders. Optimization. +- `bd-XXXX` — Deprecate `render_qmd` once `render_page_in_project` + is the universal entry point. Decision 10. +- `bd-XXXX` — Hub-client UI affordance for project-level + diagnostics (today they fold into the per-page Monaco markers; + consider a dedicated panel for cross-cutting warnings like + broken cross-doc links). +- `bd-XXXX` — Parallel Pass-1 in the orchestrator. The + `_quarto.yml`-edit cold path invalidates every profile cache + entry simultaneously; on a 100-file project the sequential + loop in `pass_one` runs N head pipelines. Trivially + parallelizable (independent work per file). Decision-6 + follow-up. +- `bd-XXXX` — "Clear cache & reload" UI affordance in + hub-client (calls `cache_clear_namespace("profiles")` then + triggers a re-render). Escape hatch for debugging; not + required by automatic invalidation. Decision-6 follow-up. diff --git a/claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md b/claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md new file mode 100644 index 000000000..65806e35a --- /dev/null +++ b/claude-notes/plans/2026-04-29-bd-swpy-nav-href-relativization.md @@ -0,0 +1,440 @@ +# Fix `bd-swpy` — Sidebar/navbar/footer/page-nav hrefs not relativized to current page + +**Date:** 2026-04-29 +**Beads:** `bd-swpy` (bug, P1). +**Discovered-from:** `bd-2jwk` (website example projects). +**Parent:** `bd-0tr6` (website epic, closed). +**Status:** Diagnosis + plan draft. Pending user review before +implementation. + +## Symptom + +In `examples/websites/03-nested-sidebar` and +`examples/websites/04-navbar-footer`, sidebar / navbar / dropdown +/ page-footer / prev-next links are emitted in +**project-root-relative** form (e.g. `guide/installation.html`), +not relative to the current page. From any page that lives in a +subdirectory (`_site/guide/installation.html`, +`_site/tools/converter.html`), clicking a navigation link +404s — the browser resolves `guide/installation.html` against the +current URL as `_site/guide/guide/installation.html`. + +Body links don't have the bug. The body `[Home](index.qmd)` link +inside `_site/guide/installation.html` is rendered correctly as +``, which resolves to +`_site/guide/index.html`. + +Reproduction (saved in this session): +- `_site/guide/installation.html` — sidebar `` links read + `guide/index.html`, `guide/installation.html`, `guide/first-steps.html`, + `guide/tuning.html`. None are page-relative. +- `_site/reference/api.html` — same problem; sidebar links read + `reference/...`. +- `_site/tools/converter.html` — navbar dropdown links read + `tools/index.html`, `tools/converter.html`; navbar left items + read `index.html`, `about.html`. The latter two are *correct + by accident* (the page is one level deep, and going up to + `_site/tools/index.html` is exactly what one wants). The bug is + that the resolution doesn't *know* it's correct — flatten the + project (move the page to root) and the same code produces a + 404 for everything. + +## Root cause + +Two helpers exist in +`crates/quarto-core/src/transforms/navigation_href.rs`: + +| Helper | Used by | Output URL form | +|---|---|---| +| `resolve_href_for_html` | sidebar / navbar / footer / page-nav Render transforms | **project-root-relative** (`profile.output_href` verbatim) | +| `resolve_doc_relative_href` | `LinkRewriteTransform` (body links, Phase 6) | **page-relative** (via `ResourceResolverContext::page_url_for`) | + +The two helpers were built at different times (Phase 3 for the +nav helper, Phase 6 for the body-link helper), and the body-link +work introduced `page_url_for` *after* the nav helper was already +in place. Nobody went back and threaded the resolver through the +nav helper. + +`navigation_href.rs:60-63`: + +```rust +if let Some(idx) = index { + if let Some(profile) = idx.lookup_by_source(Path::new(path_part)) { + return format!("{}{}", profile.output_href, tail); + } + ... +} +``` + +Compare to `navigation_href.rs:194-203` in `resolve_doc_relative_href`: + +```rust +if let Some(profile) = idx.lookup_by_source(Path::new(&project_relative)) { + let url = match resolver { + Some(r) => r.page_url_for(&profile.output_href), + None => profile.output_href.clone(), + }; + return format!("{}{}", url, tail); +} +``` + +That's the missing piece — for nav hrefs we just emit +`profile.output_href` straight, never asking the resolver to +relativize it. + +`ResourceResolverContext::page_url_for` already exists, already +handles all three context shapes (single-doc, website, VFS-root for +hub-client), and is already on `RenderContext` (`render.rs:148`, +optional). The body-link path consumes it; the nav path doesn't. + +## Constraints / non-goals + +- **Don't change the body-link path.** It already works. The fix + is purely additive on the nav helper. +- **Don't change the *input* shape of nav hrefs.** Today the nav + Render transforms receive *project-root-relative* source paths + (e.g. `guide/installation.qmd`) — that's the contract Phase 2 + Decision 7/8 set up: Generate keeps things format-agnostic in + source-path space; Render rewrites them. We don't need to + re-architect this. We only need to relativize the *output*. +- **Don't break standalone (no-index) renders.** When there's no + `ProjectIndex`, the helper passes hrefs through verbatim. That + path stays. Single-doc / revealjs UX preserved. +- **Don't break the no-resolver fallback.** Like `resolve_doc_relative_href`, + fall back to bare `profile.output_href` when no resolver is + attached. Defensive — production callers always pass a + resolver, but unit tests / out-of-band callers may not. +- **No YAML-surface changes.** No new config, no new flags. +- **Diagnostics behaviour stays identical** (same source labels, + same miss warnings). + +## Fix sketch + +### Step 1 — extend `resolve_href_for_html` to accept a resolver + +Add a `resolver: Option<&ResourceResolverContext>` parameter. +On a hit, route the output through `resolver.page_url_for(...)` +(matching the body-link helper). On a miss, on no-index, on +external/fragment — behaviour unchanged. + +```rust +pub fn resolve_href_for_html( + raw: &str, + resolver: Option<&ResourceResolverContext>, + index: Option<&ProjectIndex>, + source_label: Option<&str>, + diagnostics: &mut Vec, +) -> String { + // ...external + fragment short-circuits unchanged... + + if let Some(idx) = index { + if let Some(profile) = idx.lookup_by_source(Path::new(path_part)) { + let url = match resolver { + Some(r) => r.page_url_for(&profile.output_href), + None => profile.output_href.clone(), + }; + return format!("{}{}", url, tail); + } + // ...miss diagnostic unchanged... + } + raw.to_string() +} +``` + +### Step 2 — pass resolver from each Render transform + +Four call sites need the new argument. Each has +`ctx.resource_resolver.as_ref()` available right next to the +existing `ctx.project_index.as_deref()` plumbing. + +| File | Existing call | New call | +|---|---|---| +| `sidebar_render.rs:116, 121` | `resolve_href_for_html(href, index, source_label, diags)` | `resolve_href_for_html(href, resolver, index, source_label, diags)` | +| `navbar_render.rs:118` | same | same | +| `footer_render.rs:127` | same | same | +| `page_nav_render.rs:80, 90` | same | same | + +The argument needs to flow through the transform's `rewrite_*` +helper functions; each currently takes `index`, `source_label`, +`diagnostics` — extend to also take `resolver: +Option<&ResourceResolverContext>`. + +### Step 3 — argument-order convention + +I'll put `resolver` immediately before `index`, matching the +order in `resolve_doc_relative_href` (which has `resolver` then +`index`). This keeps the two helpers visually parallel and +reduces the mental friction of recalling which goes where. + +### Step 4 — tests + +The existing tests for `resolve_href_for_html` (lines 285–395) +all pass `None` for the index — they exercise the +external/fragment/no-index branches and don't touch the lookup + +relativize path. Those stay valid by passing `None` for the new +resolver argument. + +The lookup tests (`qmd_href_rewrites_via_index`, +`query_and_fragment_preserved_across_rewrite`, +`render_rewrites_qmd_hrefs_to_output_href` in `sidebar_render.rs`, +`navbar_render_rewrites_qmd_hrefs_to_output_href` etc.) currently +assert against project-root-relative output (e.g. +`href="about.html"`). They pass either `None` resolver (in which +case the fallback returns the bare `output_href`, identical to +today's behaviour) or a website resolver pinned at +`index.html` (depth 0, where page-relative == project-relative). +Either way the existing assertions hold. + +**New tests** — add to `navigation_href.rs`: + +1. **`nav_href_relativizes_via_resolver_at_depth_one`** — page + is `docs/api.html`; href is `about.qmd`; profile maps to + `about.html`; resolver is website-flavored. Assert output is + `../about.html`. +2. **`nav_href_relativizes_via_resolver_at_depth_two`** — page + is `docs/internals/architecture.html`; href is + `guide/installation.qmd`; profile maps to + `guide/installation.html`; resolver is website. Assert output + is `../../guide/installation.html`. +3. **`nav_href_relativizes_subdir_to_subdir`** — page is + `guide/installation.html`; href is `reference/api.qmd` (i.e. + the "switch sidebars" case in `03-nested-sidebar`). Assert + output is `../reference/api.html`. +4. **`nav_href_no_resolver_falls_back_to_bare_output_href`** — + regression of today's defensive branch. Pass `None` resolver, + pass an index with a hit; assert output is bare `about.html`. +5. **`nav_href_preserves_query_and_fragment_through_resolver`** — + `about.qmd#bio` from depth-1 page → `../about.html#bio`. The + tail is appended after the resolver call, same as today. + +**Render-transform regression tests** — extend existing tests in +`sidebar_render.rs`, `navbar_render.rs`, `footer_render.rs`, +`page_nav_render.rs` with one new case each: page lives at +`/project/_site/guide/installation.html`, href in nav is a +sibling like `index.qmd`, resolver attached, assert that the +rendered HTML contains `href="index.html"` (depth-1 relative) +not `href="guide/index.html"`. + +The Render transforms today don't construct a resolver in their +test scaffolding — `RenderContext::new(...)` leaves +`resource_resolver: None`. We'll add a `with_resource_resolver` +helper or set the field directly so each new test can pin a +website-flavored resolver to a specific page output. The +`website_resolver` helper already exists in +`navigation_href.rs:488` — we can copy or extract it. + +**End-to-end smoke** — re-render +`examples/websites/03-nested-sidebar`. Inspect: + +- `_site/guide/installation.html` should contain + ``. +- `_site/reference/api.html` should contain + `` parameter). The function +is `pub` but only called from inside this crate's `transforms` +module, so the blast radius is limited. Grep confirms 4 internal +callers and none external. + +**Snapshot tests:** any rendered-HTML snapshot that captures +nav links from a non-root page will change. The `smoke-all` +suite renders single-doc fixtures; sidebars/navbars there are +likely either absent or rooted at depth 0 (`index.html`-level) +where page-relative == project-relative, in which case no change. +We'll know after running the suite. Per CLAUDE.md +§"Snapshot Test Changes", any update gets explicit call-out in +the commit message. + +## Behavioural matrix (what changes, what doesn't) + +| Page depth | Today's nav href | Fixed nav href | Diff? | +|---|---|---|---| +| Root (`index.html`) | `about.html` | `about.html` | No | +| Root (`index.html`) | `docs/api.html` | `docs/api.html` | No | +| Depth 1 (`docs/api.html`) | `about.html` | `../about.html` | **Yes** | +| Depth 1 (`docs/api.html`) | `docs/api.html` | `api.html` | **Yes** | +| Depth 1 (`docs/api.html`) | `docs/intro.html` | `intro.html` | **Yes** | +| Depth 2 (`a/b/c.html`) | `e/f.html` | `../../e/f.html` | **Yes** | +| Standalone (no index) | `about.qmd` (verbatim) | `about.qmd` (verbatim) | No | +| External / fragment | passes through | passes through | No | +| Hub-client / VFS-root | (currently broken in some places) | `/{vfs_root}/about.html` | **Yes** (alignment with body-link path) | + +The hub-client row is interesting: `page_url_for` already special-cases +VFS-root mode, returning a `/{vfs_root}/...` absolute URL that the +hub iframe can resolve. Today's nav helper bypasses that, so nav +links inside the hub-preview iframe may have the same kind of +issue body links did before Phase 6. After this fix, both paths +agree. + +## Testing plan (TDD, per CLAUDE.md) + +1. Add new tests 1–5 to `navigation_href.rs`. Confirm they + compile and **fail** against today's signature. +2. Extend the new signature; tests 1–5 pass. +3. Update the four Render transforms' call sites to pass the + resolver. Confirm existing tests still pass. +4. Add Render-transform regression tests (one per transform, page + at depth 1, resolver attached). Confirm they pass. +5. `cargo nextest run --workspace`. Document any snapshot diffs. +6. `cargo xtask verify --skip-hub-tests` (or full + `cargo xtask verify` since `quarto-core` is touched and + hub-client depends on it). +7. Re-render `examples/websites/03-nested-sidebar` and + `examples/websites/04-navbar-footer`. Confirm links + relativize correctly. Update each example's README to remove + the "Known gap (bd-swpy)" section. +8. Close `bd-swpy` with the commit hash. + +## Decisions to confirm + +1. **Argument order in `resolve_href_for_html`.** Proposal: + `(raw, resolver, index, source_label, diagnostics)`, matching + the order in `resolve_doc_relative_href`. Alternative: keep + `index` first to minimise diff at the call sites. I lean + toward the parallel order; the call-site diff is the same + either way (one new argument), and parallel arg orders ease + future maintenance. +2. **Helper extraction.** Both `resolve_href_for_html` and + `resolve_doc_relative_href` will now look identical on the + "lookup + maybe relativize + re-append tail" branch. We could + extract a small private helper. I propose **not** doing that + in this fix — the two helpers differ in input normalization + (`resolve_to_project_root` for body links; nothing for nav + hrefs since they're already root-relative), so factoring out + the common middle adds a function of dubious shape. Keep them + parallel by convention; revisit if a third caller appears. +3. **Documentation.** Update the doc comment on + `resolve_href_for_html` to describe the new resolver + semantics, and update the comparison table at + `resolve_doc_relative_href`'s comment to reflect that nav + output is now also page-relative when a resolver is attached. + +Open question for the user before implementation: should the +fixed example READMEs (`03-nested-sidebar`, `04-navbar-footer`) +keep a small *historical* note pointing at this fix, or should +they just remove the "Known gap" section entirely? My default +is "remove entirely; the fix is the documentation". Tell me +otherwise. + +## Out of scope (separate follow-ups, do NOT do here) + +- **`bd-jbml` / `bd-bobp` / `bd-fo1r` (index-forgiveness).** All + three are about treating `docs/` as `docs/index.qmd`. That's + orthogonal to relativization — once the index-forgiveness work + lands, it will use the same resolver-aware path this fix + builds, and benefit automatically. +- **`bd-td2a` (footer text-region link rewriting).** Already + has its own design referencing + `resolve_doc_relative_href`; not affected here. +- **Cross-format URL resolution (`bd-gdrv`).** Out of website-epic + scope. + +## Work items + +### Tests first (TDD) +- [x] Add 5 new unit tests to `navigation_href.rs` covering depth-1, + depth-2, subdir-to-subdir, no-resolver fallback, and + query/fragment-with-resolver. All failed against the 4-arg + signature, then passed after the helper change. +- [x] Add 4 new Render-transform tests (one per Render transform — + `sidebar_render`, `navbar_render`, `footer_render`, + `page_nav_render`) with a page at depth 1 and a website + resolver attached. Asserts page-relative output (`../about.html`, + `index.html` for siblings). Added `RenderContext::with_resource_resolver` + builder for test scaffolding. + +### Implementation +- [x] Extend `resolve_href_for_html` signature with + `resolver: Option<&ResourceResolverContext>` (inserted at + position 2 to mirror `resolve_doc_relative_href`). Route + hits through `page_url_for`; preserve no-resolver fallback + to bare `output_href`. +- [x] Update 4 Render transforms to pass + `ctx.resource_resolver.as_ref()` to the helper, threading + through their `rewrite_*` private functions. +- [x] Update doc comments on both helpers to reflect the new + symmetry. Updated the comparison table on + `resolve_doc_relative_href` to read "page-relative when + resolver attached" for both helpers. + +### Verification +- [x] `cargo nextest run --workspace` — 8081 tests pass. +- [x] `cargo xtask verify --skip-rust-tests --skip-hub-tests` — + WASM build + trace-viewer green. Pre-existing tests in + `render_page_in_project.rs` (Phase 9 hub-smoke fixture) + needed assertion updates: pre-fix they were checking + project-relative `href="about.html"` produced by the no-resolver + branch of `resolve_href_for_html`, but in vfs_root mode + hub-client URLs are absolute (`/{vfs_root}/about.html`). + Post-fix the nav helper unifies on `page_url_for`, so vfs_root + mode produces absolute URLs at every call site (sidebar, body + link, page-nav). Updated assertions to suffix-match `about.html"` + (the same pattern `website_sidebar_includes_sibling_pages` + already used). User confirmed this is correct: in hub-client + we own the deployment (synthetic VFS rooted at `/`), and a + post-processor / future service worker handles the URL space; + native renders still produce page-relative URLs and remain + portable across deploy roots. +- [x] Re-render `examples/websites/03-nested-sidebar`. Sidebar + links from `_site/guide/installation.html` now read + `index.html`, `installation.html`, `first-steps.html`, + `tuning.html` (page-relative). Cross-subtree pagination + and sibling links also page-relative. +- [x] Re-render `examples/websites/04-navbar-footer`. From + `_site/tools/converter.html`, navbar Home/About read + `../index.html`, `../about.html`; dropdown Overview reads + `index.html` (sibling); footer entries also page-relative. +- [x] Update both example READMEs: replaced "Known gap (bd-swpy)" + with a "Notes" section documenting the page-relative output + and deployment-root portability. + +### Close-out +- [ ] `br close bd-swpy --reason "..."` with the commit hash. +- [ ] `br sync --flush-only && git add .beads/ && git commit`. +- [ ] Ask user permission before pushing. + +## Note on stash recovery (2026-04-29) + +Mid-implementation, a `git stash` / `git stash pop` cycle silently +lost the source-file changes (kept the test-file changes). The +stash was recovered from `git fsck --no-reflogs --unreachable` +via the dropped stash hash, and `git checkout -- ` +restored the source files. All tests then re-passed. This is +worth flagging because a "stash pop succeeded silently" message +is an easy thing to trust — but the stash entry's continued +presence after the pop was the actual signal that something went +wrong. diff --git a/claude-notes/plans/2026-04-29-sidebar-default-title.md b/claude-notes/plans/2026-04-29-sidebar-default-title.md new file mode 100644 index 000000000..513e7acd1 --- /dev/null +++ b/claude-notes/plans/2026-04-29-sidebar-default-title.md @@ -0,0 +1,334 @@ +# Sidebar default title: inherit from `website.title` + +**Date:** 2026-04-29 +**Beads:** TBD (to be created — needs `br` from another shell) +**Parent epic:** `claude-notes/plans/2026-04-23-website-project-epic.md` +**Related:** `claude-notes/plans/2026-04-29-website-sidebar-layout.md` (bd-mgoh — left-column placement; precursor to this). +**Status:** Draft — answers to clarifying questions (2026-04-29) folded in; awaiting go-ahead to implement. + +## Symptom + +Rendering `examples/websites/01-minimal` with Q2 produces a sidebar +with no header — the website title (`website.title: "Minimal +Website"`) is invisible. Q1 renders the same project with the website +title at the top of the sidebar, wrapped in a home link +(`Minimal Website`). + +User goal: bring Q2 closer to Q1 here, with one addition Q1 does not +support — let the user opt out of the title via `sidebar.title: +false`. + +## Desired behavior + +Tri-state semantics for the per-sidebar `title:` field: + +| YAML | Rendered title | +|-----------------------|-----------------------------------------------------| +| (field absent) | `website.title` if set; otherwise no header | +| `title: false` | No header | +| `title: true` | Same as absent (use `website.title` fallback) | +| `title: "Custom"` | Literal `"Custom"` | + +When emitted, the title is wrapped in a home link, mirroring Q1: + +```html + +``` + +The Bootstrap utility classes Q1 puts on these wrappers +(`pt-lg-2 mt-2 text-left`, `mb-0 py-0`) are added in the **render +stage** only — not committed to the data model. We're considering a +post-Bootstrap design and don't want utility classes baked into the +data structure. + +## Out of scope + +- **Sidebar search** (`