{"_id":"@plannotator/atomic-editor","_rev":"5-15ec218361b3320d9439704c348d1cf5","name":"@plannotator/atomic-editor","dist-tags":{"latest":"0.8.1"},"versions":{"0.5.0":{"name":"@plannotator/atomic-editor","version":"0.5.0","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"author":{"name":"Kenny Bergquist"},"license":"MIT","_id":"@plannotator/atomic-editor@0.5.0","maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"homepage":"https://github.com/plannotator/atomic-editor#readme","bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"dist":{"shasum":"0bb4bdfe2514161d06c95f1927d7785176289e7a","tarball":"https://registry.npmjs.org/@plannotator/atomic-editor/-/atomic-editor-0.5.0.tgz","fileCount":53,"integrity":"sha512-nJfa6CZ3S0Ywg++HxJLZ9AqPrruhrurVAisFFvCIQmyUnyEt270CfNnVoVyUZBGYHPy47mtybtMZJaN9LXpnCg==","signatures":[{"sig":"MEUCIQD1gh2RCpSVu+0/WB3zfnEC9jk3S9g9fEdZ7r/6XJNSfQIgMIfNcvGS3KhOzs6sAwxt4g00ef6TU4gpCdL4Tngmfrw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":404460},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./styles.css":"./dist/styles/inline-preview.css","./code-languages":{"types":"./dist/code-languages.d.ts","default":"./dist/code-languages.js"}},"gitHead":"888a9622851d6320d04de6da5789747b997a8613","scripts":{"dev":"vite --host 0.0.0.0","test":"vitest run","build":"tsc -p tsconfig.build.json && cpy src/styles/inline-preview.css dist/styles --flat","prepare":"npm run build","test:e2e":"node scripts/test-editor.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:demo":"vite build","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build","test:e2e:headed":"node scripts/test-editor.mjs --headed"},"_npmUser":{"name":"backnotprop","email":"backnotprop@gmail.com"},"repository":{"url":"git+https://github.com/plannotator/atomic-editor.git","type":"git"},"_npmVersion":"11.12.1","description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","react":"^18.3.1","vitest":"^3.2.4","cpy-cli":"^5.0.0","happy-dom":"^20.9.0","react-dom":"^18.3.1","playwright":"^1.59.1","typescript":"^5.6.0","@types/react":"^18.3.0","@lezer/common":"^1.2.3","@lezer/markdown":"^1.6.4","@codemirror/view":"^6.38.8","@lezer/highlight":"^1.2.3","@types/react-dom":"^18.3.0","@codemirror/state":"^6.5.2","@codemirror/search":"^6.5.11","@codemirror/lang-go":"^6.0.1","@codemirror/commands":"^6.10.0","@codemirror/lang-cpp":"^6.0.3","@codemirror/lang-css":"^6.3.1","@codemirror/lang-php":"^6.0.2","@codemirror/lang-sql":"^6.10.0","@codemirror/lang-xml":"^6.1.0","@codemirror/language":"^6.12.3","@vitejs/plugin-react":"^4.3.0","@codemirror/lang-html":"^6.4.11","@codemirror/lang-java":"^6.0.2","@codemirror/lang-json":"^6.0.2","@codemirror/lang-rust":"^6.0.2","@codemirror/lang-yaml":"^6.1.3","@codemirror/lang-python":"^6.2.1","@codemirror/autocomplete":"^6.20.0","@codemirror/legacy-modes":"^6.5.2","@codemirror/lang-markdown":"^6.5.0","@codemirror/lang-javascript":"^6.2.5"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","@lezer/common":"^1.0.0","@lezer/markdown":"^1.0.0","@codemirror/view":"^6.0.0","@lezer/highlight":"^1.0.0","@codemirror/state":"^6.0.0","@codemirror/search":"^6.0.0","@codemirror/lang-go":"^6.0.0","@codemirror/commands":"^6.0.0","@codemirror/lang-cpp":"^6.0.0","@codemirror/lang-css":"^6.0.0","@codemirror/lang-php":"^6.0.0","@codemirror/lang-sql":"^6.0.0","@codemirror/lang-xml":"^6.0.0","@codemirror/language":"^6.0.0","@codemirror/lang-html":"^6.0.0","@codemirror/lang-java":"^6.0.0","@codemirror/lang-json":"^6.0.0","@codemirror/lang-rust":"^6.0.0","@codemirror/lang-yaml":"^6.0.0","@codemirror/lang-python":"^6.0.0","@codemirror/autocomplete":"^6.0.0","@codemirror/legacy-modes":"^6.0.0","@codemirror/lang-markdown":"^6.0.0","@codemirror/lang-javascript":"^6.0.0"},"peerDependenciesMeta":{"@codemirror/lang-go":{"optional":true},"@codemirror/lang-cpp":{"optional":true},"@codemirror/lang-css":{"optional":true},"@codemirror/lang-php":{"optional":true},"@codemirror/lang-sql":{"optional":true},"@codemirror/lang-xml":{"optional":true},"@codemirror/lang-html":{"optional":true},"@codemirror/lang-java":{"optional":true},"@codemirror/lang-json":{"optional":true},"@codemirror/lang-rust":{"optional":true},"@codemirror/lang-yaml":{"optional":true},"@codemirror/lang-python":{"optional":true},"@codemirror/legacy-modes":{"optional":true},"@codemirror/lang-javascript":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/atomic-editor_0.5.0_1783028156575_0.08533142495655577","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@plannotator/atomic-editor","version":"0.5.1","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"author":{"name":"Kenny Bergquist"},"license":"MIT","_id":"@plannotator/atomic-editor@0.5.1","maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"homepage":"https://github.com/plannotator/atomic-editor#readme","bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"dist":{"shasum":"f8e4987de09c6aeb9eac218f0491f842f4169e99","tarball":"https://registry.npmjs.org/@plannotator/atomic-editor/-/atomic-editor-0.5.1.tgz","fileCount":53,"integrity":"sha512-iBF9eAoi9Eih63lsi6icAw5rOiik42bZKI0CjEd0tsFmU72wlXVv3E/Y0mHBq5cZkxYx7t5GtyeCojSZFop7Mw==","signatures":[{"sig":"MEYCIQC9BJ0E3dpmsSRwpPr7VKDOMhTquJKDeKcyGdrom2flmQIhAPyHrdAYy0I7Ebl9MQZexHaPlPzm4jIVXpS8+uHFKbtf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":405018},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./styles.css":"./dist/styles/inline-preview.css","./code-languages":{"types":"./dist/code-languages.d.ts","default":"./dist/code-languages.js"}},"gitHead":"bdbaf5036db16b568fc3a401dd7b0b95a3983393","scripts":{"dev":"vite --host 0.0.0.0","test":"vitest run","build":"tsc -p tsconfig.build.json && cpy src/styles/inline-preview.css dist/styles --flat","prepare":"npm run build","test:e2e":"node scripts/test-editor.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:demo":"vite build","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build","test:e2e:headed":"node scripts/test-editor.mjs --headed"},"_npmUser":{"name":"backnotprop","email":"backnotprop@gmail.com"},"repository":{"url":"git+https://github.com/plannotator/atomic-editor.git","type":"git"},"_npmVersion":"11.12.1","description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","react":"^18.3.1","vitest":"^3.2.4","cpy-cli":"^5.0.0","happy-dom":"^20.9.0","react-dom":"^18.3.1","playwright":"^1.59.1","typescript":"^5.6.0","@types/react":"^18.3.0","@lezer/common":"^1.2.3","@lezer/markdown":"^1.6.4","@codemirror/view":"^6.38.8","@lezer/highlight":"^1.2.3","@types/react-dom":"^18.3.0","@codemirror/state":"^6.5.2","@codemirror/search":"^6.5.11","@codemirror/lang-go":"^6.0.1","@codemirror/commands":"^6.10.0","@codemirror/lang-cpp":"^6.0.3","@codemirror/lang-css":"^6.3.1","@codemirror/lang-php":"^6.0.2","@codemirror/lang-sql":"^6.10.0","@codemirror/lang-xml":"^6.1.0","@codemirror/language":"^6.12.3","@vitejs/plugin-react":"^4.3.0","@codemirror/lang-html":"^6.4.11","@codemirror/lang-java":"^6.0.2","@codemirror/lang-json":"^6.0.2","@codemirror/lang-rust":"^6.0.2","@codemirror/lang-yaml":"^6.1.3","@codemirror/lang-python":"^6.2.1","@codemirror/autocomplete":"^6.20.0","@codemirror/legacy-modes":"^6.5.2","@codemirror/lang-markdown":"^6.5.0","@codemirror/lang-javascript":"^6.2.5"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","typescript":"^5.0.0 || ^6.0.0","@lezer/common":"^1.0.0","@lezer/markdown":"^1.0.0","@codemirror/view":"^6.0.0","@lezer/highlight":"^1.0.0","@codemirror/state":"^6.0.0","@codemirror/search":"^6.0.0","@codemirror/lang-go":"^6.0.0","@codemirror/commands":"^6.0.0","@codemirror/lang-cpp":"^6.0.0","@codemirror/lang-css":"^6.0.0","@codemirror/lang-php":"^6.0.0","@codemirror/lang-sql":"^6.0.0","@codemirror/lang-xml":"^6.0.0","@codemirror/language":"^6.0.0","@codemirror/lang-html":"^6.0.0","@codemirror/lang-java":"^6.0.0","@codemirror/lang-json":"^6.0.0","@codemirror/lang-rust":"^6.0.0","@codemirror/lang-yaml":"^6.0.0","@codemirror/lang-python":"^6.0.0","@codemirror/autocomplete":"^6.0.0","@codemirror/legacy-modes":"^6.0.0","@codemirror/lang-markdown":"^6.0.0","@codemirror/lang-javascript":"^6.0.0"},"peerDependenciesMeta":{"typescript":{"optional":true},"@codemirror/lang-go":{"optional":true},"@codemirror/lang-cpp":{"optional":true},"@codemirror/lang-css":{"optional":true},"@codemirror/lang-php":{"optional":true},"@codemirror/lang-sql":{"optional":true},"@codemirror/lang-xml":{"optional":true},"@codemirror/lang-html":{"optional":true},"@codemirror/lang-java":{"optional":true},"@codemirror/lang-json":{"optional":true},"@codemirror/lang-rust":{"optional":true},"@codemirror/lang-yaml":{"optional":true},"@codemirror/lang-python":{"optional":true},"@codemirror/legacy-modes":{"optional":true},"@codemirror/lang-javascript":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/atomic-editor_0.5.1_1783484766471_0.1739484254279311","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@plannotator/atomic-editor","version":"0.7.0","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"author":{"name":"Kenny Bergquist"},"license":"MIT","_id":"@plannotator/atomic-editor@0.7.0","maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"homepage":"https://github.com/plannotator/atomic-editor#readme","bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"dist":{"shasum":"20e66fd1bcf66f0b4b514766c11e3793171a433b","tarball":"https://registry.npmjs.org/@plannotator/atomic-editor/-/atomic-editor-0.7.0.tgz","fileCount":73,"integrity":"sha512-8XDrcNXg13rNmTEWumH9nbXknTqE2BbFs2/+ssmrGzuQpMp7P0Nfd+8QTNVQdBJEKNJbprH9z9gkdTY4AmYeZg==","signatures":[{"sig":"MEYCIQCmONSH+hp2sD9Dw+7bZeAc89r8wJPMKNLoIVmsiAx5JQIhANZ8y8feLdzQ3ZQe+ybQjZTzMqmj7LelN3mrg6YA09+q","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":591786},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./styles.css":"./dist/styles/inline-preview.css","./code-languages":{"types":"./dist/code-languages.d.ts","default":"./dist/code-languages.js"}},"gitHead":"2305f3517300895747960443bb28b489b80eb07f","scripts":{"dev":"vite --host 0.0.0.0","test":"vitest run","build":"tsc -p tsconfig.build.json && cpy src/styles/inline-preview.css dist/styles --flat","prepare":"npm run build","test:e2e":"node scripts/test-editor.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:demo":"vite build","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build","test:e2e:headed":"node scripts/test-editor.mjs --headed"},"_npmUser":{"name":"backnotprop","email":"backnotprop@gmail.com"},"repository":{"url":"git+https://github.com/plannotator/atomic-editor.git","type":"git"},"_npmVersion":"11.12.1","description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","react":"^18.3.1","vitest":"^3.2.4","cpy-cli":"^5.0.0","happy-dom":"^20.9.0","react-dom":"^18.3.1","playwright":"^1.59.1","typescript":"^5.6.0","@types/react":"^18.3.0","@lezer/common":"^1.2.3","@lezer/markdown":"^1.6.4","@codemirror/view":"^6.38.8","@lezer/highlight":"^1.2.3","@types/react-dom":"^18.3.0","@codemirror/state":"^6.5.2","@codemirror/search":"^6.5.11","@codemirror/lang-go":"^6.0.1","@codemirror/commands":"^6.10.0","@codemirror/lang-cpp":"^6.0.3","@codemirror/lang-css":"^6.3.1","@codemirror/lang-php":"^6.0.2","@codemirror/lang-sql":"^6.10.0","@codemirror/lang-xml":"^6.1.0","@codemirror/language":"^6.12.3","@vitejs/plugin-react":"^4.3.0","@codemirror/lang-html":"^6.4.11","@codemirror/lang-java":"^6.0.2","@codemirror/lang-json":"^6.0.2","@codemirror/lang-rust":"^6.0.2","@codemirror/lang-yaml":"^6.1.3","@codemirror/lang-python":"^6.2.1","@codemirror/autocomplete":"^6.20.0","@codemirror/legacy-modes":"^6.5.2","@codemirror/lang-markdown":"^6.5.0","@codemirror/lang-javascript":"^6.2.5"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","typescript":"^5.0.0 || ^6.0.0","@lezer/common":"^1.0.0","@lezer/markdown":"^1.0.0","@codemirror/view":"^6.0.0","@lezer/highlight":"^1.0.0","@codemirror/state":"^6.0.0","@codemirror/search":"^6.0.0","@codemirror/lang-go":"^6.0.0","@codemirror/commands":"^6.0.0","@codemirror/lang-cpp":"^6.0.0","@codemirror/lang-css":"^6.0.0","@codemirror/lang-php":"^6.0.0","@codemirror/lang-sql":"^6.0.0","@codemirror/lang-xml":"^6.0.0","@codemirror/language":"^6.0.0","@codemirror/lang-html":"^6.0.0","@codemirror/lang-java":"^6.0.0","@codemirror/lang-json":"^6.0.0","@codemirror/lang-rust":"^6.0.0","@codemirror/lang-yaml":"^6.0.0","@codemirror/lang-python":"^6.0.0","@codemirror/autocomplete":"^6.0.0","@codemirror/legacy-modes":"^6.0.0","@codemirror/lang-markdown":"^6.0.0","@codemirror/lang-javascript":"^6.0.0"},"peerDependenciesMeta":{"typescript":{"optional":true},"@codemirror/lang-go":{"optional":true},"@codemirror/lang-cpp":{"optional":true},"@codemirror/lang-css":{"optional":true},"@codemirror/lang-php":{"optional":true},"@codemirror/lang-sql":{"optional":true},"@codemirror/lang-xml":{"optional":true},"@codemirror/lang-html":{"optional":true},"@codemirror/lang-java":{"optional":true},"@codemirror/lang-json":{"optional":true},"@codemirror/lang-rust":{"optional":true},"@codemirror/lang-yaml":{"optional":true},"@codemirror/lang-python":{"optional":true},"@codemirror/legacy-modes":{"optional":true},"@codemirror/lang-javascript":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/atomic-editor_0.7.0_1783622541239_0.6636720542267929","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@plannotator/atomic-editor","version":"0.8.0","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"author":{"name":"Kenny Bergquist"},"license":"MIT","_id":"@plannotator/atomic-editor@0.8.0","maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"homepage":"https://github.com/plannotator/atomic-editor#readme","bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"dist":{"shasum":"d5d1946f26b7da39cf030f385412e02abfeeca7e","tarball":"https://registry.npmjs.org/@plannotator/atomic-editor/-/atomic-editor-0.8.0.tgz","fileCount":81,"integrity":"sha512-s4IaRrlFjluYvMVRS/XJjAaHVR5I/4yAxAFWlUHk74RE7W9BQO8lazWgYgNyRSYQtdlEZsJiPgzaDeOuocErWg==","signatures":[{"sig":"MEUCIF4Se76OBy3gf7llronIzJ0q/xr5dX2BTLLeKCdgH0xDAiEAi1jmOxD9kSfy4wf+RY1U/iPb8s6VSC/pGYBpt4oZQr0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":646934},"main":"./dist/index.js","type":"module","_from":"file:/Users/ramos/oss/release-artifacts/plannotator-atomic-editor-0.8.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./styles.css":"./dist/styles/inline-preview.css","./code-languages":{"types":"./dist/code-languages.d.ts","default":"./dist/code-languages.js"}},"scripts":{"dev":"vite --host 0.0.0.0","test":"vitest run","build":"tsc -p tsconfig.build.json && cpy src/styles/inline-preview.css dist/styles --flat","prepare":"npm run build","test:e2e":"node scripts/test-editor.mjs","typecheck":"tsc -p tsconfig.json --noEmit","bench:diff":"node scripts/bench-inline-diff.mjs","build:demo":"vite build","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build","test:e2e:headed":"node scripts/test-editor.mjs --headed"},"_npmUser":{"name":"backnotprop","email":"backnotprop@gmail.com"},"_resolved":"/Users/ramos/oss/release-artifacts/plannotator-atomic-editor-0.8.0.tgz","_integrity":"sha512-s4IaRrlFjluYvMVRS/XJjAaHVR5I/4yAxAFWlUHk74RE7W9BQO8lazWgYgNyRSYQtdlEZsJiPgzaDeOuocErWg==","repository":{"url":"git+https://github.com/plannotator/atomic-editor.git","type":"git"},"_npmVersion":"11.12.1","description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","react":"^18.3.1","vitest":"^3.2.4","cpy-cli":"^5.0.0","happy-dom":"^20.9.0","react-dom":"^18.3.1","playwright":"^1.59.1","typescript":"^5.6.0","@types/react":"^18.3.0","@lezer/common":"^1.2.3","@lezer/markdown":"^1.6.4","@codemirror/view":"^6.38.8","@lezer/highlight":"^1.2.3","@types/react-dom":"^18.3.0","@codemirror/merge":"^6.12.2","@codemirror/state":"^6.5.2","@codemirror/search":"^6.5.11","@codemirror/lang-go":"^6.0.1","@codemirror/commands":"^6.10.0","@codemirror/lang-cpp":"^6.0.3","@codemirror/lang-css":"^6.3.1","@codemirror/lang-php":"^6.0.2","@codemirror/lang-sql":"^6.10.0","@codemirror/lang-xml":"^6.1.0","@codemirror/language":"^6.12.3","@vitejs/plugin-react":"^4.3.0","@codemirror/lang-html":"^6.4.11","@codemirror/lang-java":"^6.0.2","@codemirror/lang-json":"^6.0.2","@codemirror/lang-rust":"^6.0.2","@codemirror/lang-yaml":"^6.1.3","@codemirror/lang-python":"^6.2.1","@codemirror/autocomplete":"^6.20.0","@codemirror/legacy-modes":"^6.5.2","@codemirror/lang-markdown":"^6.5.0","@codemirror/lang-javascript":"^6.2.5"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","typescript":"^5.0.0 || ^6.0.0","@lezer/common":"^1.0.0","@lezer/markdown":"^1.0.0","@codemirror/view":"^6.0.0","@lezer/highlight":"^1.0.0","@codemirror/merge":"^6.0.0","@codemirror/state":"^6.0.0","@codemirror/search":"^6.0.0","@codemirror/lang-go":"^6.0.0","@codemirror/commands":"^6.0.0","@codemirror/lang-cpp":"^6.0.0","@codemirror/lang-css":"^6.0.0","@codemirror/lang-php":"^6.0.0","@codemirror/lang-sql":"^6.0.0","@codemirror/lang-xml":"^6.0.0","@codemirror/language":"^6.0.0","@codemirror/lang-html":"^6.0.0","@codemirror/lang-java":"^6.0.0","@codemirror/lang-json":"^6.0.0","@codemirror/lang-rust":"^6.0.0","@codemirror/lang-yaml":"^6.0.0","@codemirror/lang-python":"^6.0.0","@codemirror/autocomplete":"^6.0.0","@codemirror/legacy-modes":"^6.0.0","@codemirror/lang-markdown":"^6.0.0","@codemirror/lang-javascript":"^6.0.0"},"peerDependenciesMeta":{"typescript":{"optional":true},"@codemirror/lang-go":{"optional":true},"@codemirror/lang-cpp":{"optional":true},"@codemirror/lang-css":{"optional":true},"@codemirror/lang-php":{"optional":true},"@codemirror/lang-sql":{"optional":true},"@codemirror/lang-xml":{"optional":true},"@codemirror/lang-html":{"optional":true},"@codemirror/lang-java":{"optional":true},"@codemirror/lang-json":{"optional":true},"@codemirror/lang-rust":{"optional":true},"@codemirror/lang-yaml":{"optional":true},"@codemirror/lang-python":{"optional":true},"@codemirror/legacy-modes":{"optional":true},"@codemirror/lang-javascript":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/atomic-editor_0.8.0_1783662273920_0.6552072082541076","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@plannotator/atomic-editor","version":"0.8.1","description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"license":"MIT","author":{"name":"Kenny Bergquist"},"homepage":"https://github.com/plannotator/atomic-editor#readme","repository":{"type":"git","url":"git+https://github.com/plannotator/atomic-editor.git"},"bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./code-languages":{"types":"./dist/code-languages.d.ts","default":"./dist/code-languages.js"},"./styles.css":"./dist/styles/inline-preview.css"},"sideEffects":["**/*.css"],"engines":{"node":">=18"},"publishConfig":{"access":"public"},"scripts":{"dev":"vite --host 0.0.0.0","build":"tsc -p tsconfig.build.json && cpy src/styles/inline-preview.css dist/styles --flat","build:demo":"vite build","bench:diff":"node scripts/bench-inline-diff.mjs","bench:entry":"vite-node scripts/bench-editor-entry.mjs","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run","test:watch":"vitest","test:e2e":"node scripts/test-editor.mjs","test:e2e:headed":"node scripts/test-editor.mjs --headed","prepare":"npm run build","prepublishOnly":"npm run typecheck && npm run test && npm run build"},"peerDependencies":{"@codemirror/autocomplete":"^6.0.0","@codemirror/commands":"^6.0.0","@codemirror/lang-cpp":"^6.0.0","@codemirror/lang-css":"^6.0.0","@codemirror/lang-go":"^6.0.0","@codemirror/lang-html":"^6.0.0","@codemirror/lang-java":"^6.0.0","@codemirror/lang-javascript":"^6.0.0","@codemirror/lang-json":"^6.0.0","@codemirror/lang-markdown":"^6.0.0","@codemirror/lang-php":"^6.0.0","@codemirror/lang-python":"^6.0.0","@codemirror/lang-rust":"^6.0.0","@codemirror/lang-sql":"^6.0.0","@codemirror/lang-xml":"^6.0.0","@codemirror/lang-yaml":"^6.0.0","@codemirror/language":"^6.0.0","@codemirror/legacy-modes":"^6.0.0","@codemirror/merge":"^6.0.0","@codemirror/search":"^6.0.0","@codemirror/state":"^6.0.0","@codemirror/view":"^6.0.0","@lezer/common":"^1.0.0","@lezer/highlight":"^1.0.0","@lezer/markdown":"^1.0.0","react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","typescript":"^5.0.0 || ^6.0.0"},"peerDependenciesMeta":{"@codemirror/lang-cpp":{"optional":true},"@codemirror/lang-css":{"optional":true},"@codemirror/lang-go":{"optional":true},"@codemirror/lang-html":{"optional":true},"@codemirror/lang-java":{"optional":true},"@codemirror/lang-javascript":{"optional":true},"@codemirror/lang-json":{"optional":true},"@codemirror/lang-php":{"optional":true},"@codemirror/lang-python":{"optional":true},"@codemirror/lang-rust":{"optional":true},"@codemirror/lang-sql":{"optional":true},"@codemirror/lang-xml":{"optional":true},"@codemirror/lang-yaml":{"optional":true},"@codemirror/legacy-modes":{"optional":true},"typescript":{"optional":true}},"devDependencies":{"@codemirror/autocomplete":"^6.20.0","@codemirror/commands":"^6.10.0","@codemirror/lang-cpp":"^6.0.3","@codemirror/lang-css":"^6.3.1","@codemirror/lang-go":"^6.0.1","@codemirror/lang-html":"^6.4.11","@codemirror/lang-java":"^6.0.2","@codemirror/lang-javascript":"^6.2.5","@codemirror/lang-json":"^6.0.2","@codemirror/lang-markdown":"^6.5.0","@codemirror/lang-php":"^6.0.2","@codemirror/lang-python":"^6.2.1","@codemirror/lang-rust":"^6.0.2","@codemirror/lang-sql":"^6.10.0","@codemirror/lang-xml":"^6.1.0","@codemirror/lang-yaml":"^6.1.3","@codemirror/language":"^6.12.3","@codemirror/legacy-modes":"^6.5.2","@codemirror/merge":"^6.12.2","@codemirror/search":"^6.5.11","@codemirror/state":"^6.5.2","@codemirror/view":"^6.38.8","@lezer/common":"^1.2.3","@lezer/highlight":"^1.2.3","@lezer/markdown":"^1.6.4","@types/react":"^18.3.0","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.0","cpy-cli":"^5.0.0","happy-dom":"^20.9.0","playwright":"^1.59.1","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.6.0","vite":"^6.0.0","vite-node":"^3.2.4","vitest":"^3.2.4"},"_id":"@plannotator/atomic-editor@0.8.1","_integrity":"sha512-J6ulFUoJurX5EjZQKxnPb1Dm2ZwtioiDGuZUji2nrZX03D1ALcI5s2R03Y92w85mN+Ec/LutrukWrGFLBQTfwQ==","_resolved":"/private/tmp/claude-501/-Users-ramos-plannotator-plannotator/34d56d5a-33a8-4878-92b2-3f4318214ae2/scratchpad/plannotator-atomic-editor-0.8.1.tgz","_from":"file:plannotator-atomic-editor-0.8.1.tgz","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-J6ulFUoJurX5EjZQKxnPb1Dm2ZwtioiDGuZUji2nrZX03D1ALcI5s2R03Y92w85mN+Ec/LutrukWrGFLBQTfwQ==","shasum":"743ef85b271a1493247f9b97306bcc976dd23bf9","tarball":"https://registry.npmjs.org/@plannotator/atomic-editor/-/atomic-editor-0.8.1.tgz","fileCount":81,"unpackedSize":657369,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSRaW4aCkCqggzkREORUtat5wgdZblcBt1X08Fp5XizwIhAJfBPXc39LnbM+QgSDLoyvGGeAdyBcN3KMjGYhLJckNM"}]},"_npmUser":{"name":"backnotprop","email":"backnotprop@gmail.com"},"directories":{},"maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/atomic-editor_0.8.1_1787862060264_0.4276711541493643"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-02T21:35:56.275Z","modified":"2026-08-27T20:21:00.642Z","0.5.0":"2026-07-02T21:35:56.722Z","0.5.1":"2026-07-08T04:26:06.658Z","0.7.0":"2026-07-09T18:42:21.403Z","0.8.0":"2026-07-10T05:44:34.117Z","0.8.1":"2026-08-27T20:21:00.484Z"},"bugs":{"url":"https://github.com/plannotator/atomic-editor/issues"},"author":{"name":"Kenny Bergquist"},"license":"MIT","homepage":"https://github.com/plannotator/atomic-editor#readme","keywords":["codemirror","codemirror6","markdown","editor","wysiwyg","live-preview","obsidian","react"],"repository":{"type":"git","url":"git+https://github.com/plannotator/atomic-editor.git"},"description":"CodeMirror 6 markdown editor with Obsidian-style inline live preview. Plannotator fork of atomic-editor (adds YAML frontmatter parsing).","maintainers":[{"name":"backnotprop","email":"backnotprop@gmail.com"}],"readme":"# Atomic Editor (Plannotator fork)\n\n> This is [Plannotator](https://github.com/plannotator)'s fork of\n> [kenforthewin/atomic-editor](https://github.com/kenforthewin/atomic-editor),\n> published as `@plannotator/atomic-editor`. It tracks upstream closely and\n> carries a small set of changes we need (currently: YAML frontmatter\n> parsing), each also offered upstream as a PR. Unless you specifically want\n> those changes, prefer the original `@atomic-editor/editor`.\n\n**Obsidian-style live preview for [CodeMirror 6](https://codemirror.net/), in React.**\n\n[![npm version](https://img.shields.io/npm/v/@plannotator/atomic-editor?color=7c3aed&labelColor=2d2d2d)](https://www.npmjs.com/package/@plannotator/atomic-editor)\n[![license](https://img.shields.io/npm/l/@plannotator/atomic-editor?color=7c3aed&labelColor=2d2d2d)](./LICENSE)\n\nA markdown editor where formatting renders as you type — headings, bold,\ntables, images, task lists — while the text underneath stays plain markdown.\nThe document you read is the document you edit: no split preview, no mode\ntoggle, and copy / save / round-trip behave exactly like a plain textarea\nfull of markdown.\n\nIt's the writing surface behind\n[**Atomic**](https://github.com/kenforthewin/atomic), a personal knowledge\nbase — extracted to stand on its own, and hardened on real user documents.\n\n[**Try the live demo →**](https://kenforthewin.github.io/atomic-editor/)\n\n## Features\n\n- **Live preview.** Headings, emphasis, links, images,\n  and tables render inline; the raw syntax appears only on the line your\n  cursor is on, then tucks itself away when you move on.\n- **Raw markdown is the source of truth.** Every decoration is view-only, so\n  copy, save, and round-trip through any other markdown tool are byte-for-byte\n  identical to a plain textarea.\n- **Virtualized and layout-stable.** CM6 renders only the viewport, and lines\n  never reflow when you click into them — open a 500-page document and scroll\n  stays smooth, even on iOS.\n- **WYSIWYG tables.** Click a cell to edit in place; wide tables scroll\n  horizontally inside a contained wrapper instead of stretching the page.\n- **Wiki links.** `[[target]]` / `[[target|label]]` with async resolution,\n  autocomplete, and click-to-open — for knowledge-base-style cross-linking.\n- **Smart lists.** Enter continues tight bullets and task checkboxes, Enter on\n  an empty item dedents, and `- [ ]` becomes a real, clickable checkbox.\n- **Syntax-highlighted code** for 20+ languages, each grammar lazy-loaded the\n  first time a fence uses it so unused languages never hit the wire.\n- **Themed with CSS variables** — dark by default, light via a single\n  `data-theme=\"light\"` attribute, every color overridable.\n- **Minimal find panel** (Ctrl/Cmd+F) styled to match the editor.\n- **Frozen inline diffs.** Two revisions render as one review document with\n  inline insertions/deletions, change navigation, gutter rails, and complete\n  unchanged context.\n\n## Install\n\n```bash\nnpm install @atomic-editor/editor \\\n  @codemirror/state @codemirror/view @codemirror/commands \\\n  @codemirror/autocomplete @codemirror/language @codemirror/search \\\n  @codemirror/lang-markdown @codemirror/merge \\\n  @lezer/common @lezer/highlight \\\n  react react-dom\n```\n\nThe CodeMirror and React packages are declared as **peer dependencies**\nrather than regular deps. You install them alongside the editor so\nyour bundler resolves a single shared copy — two copies of\n`@codemirror/state` in one bundle would silently break the editor's\nstate-field identity checks.\n\nFenced-code language grammars (`@codemirror/lang-javascript`,\n`@codemirror/lang-python`, etc.) are **optional peers** — install only\nthe ones you want highlighted. See\n[Syntax highlighting](#syntax-highlighting) below.\n\n## Use\n\n```tsx\nimport { AtomicCodeMirrorEditor } from '@atomic-editor/editor';\nimport '@atomic-editor/editor/styles.css';\n\nfunction App() {\n  return (\n    <AtomicCodeMirrorEditor\n      markdownSource={'# Hello\\n\\nA paragraph.'}\n      onMarkdownChange={(md) => console.log(md)}\n      onLinkClick={(url) => window.open(url, '_blank', 'noopener,noreferrer')}\n    />\n  );\n}\n```\n\nThe editor fills its parent — wrap it in a height-bounded flex or grid\ncontainer.\n\n### Frozen inline diff\n\n`AtomicDiffEditor` renders the newer revision as the document and projects\ndeletions where they used to be. It is structurally separate from the editable\ncomponent: the content DOM is not editable, task/table controls are static, and\ndocument-changing transactions are rejected at both the CodeMirror state and\nview-dispatch boundaries.\n\n```tsx\nimport { AtomicDiffEditor, wikiLinks } from '@atomic-editor/editor';\nimport '@atomic-editor/editor/styles.css';\n\n<AtomicDiffEditor\n  originalMarkdown={savedRevision}\n  modifiedMarkdown={currentRevision}\n  extensions={[\n    wikiLinks({\n      resolve: (target) => store.resolve(target),\n      onOpen: (target) => router.open(target),\n    }),\n  ]}\n/>;\n```\n\nThe same `extensions` seam used by the editable surface is appended after the\ndiff and built-in Markdown decorations. Unchanged frontmatter, tables, images,\ntasks, and wiki links keep their rich reader rendering. When a change\nintersects one of those atomic ranges, its source is shown so the diff cannot\ndisappear behind a replacement widget.\n\nThe entire newer document remains visible, including every unchanged line.\nThe overview rail on the right maps additions, deletions, and replacements\nacross the file and jumps to the nearest change when clicked. It also supports\narrow-key navigation when focused.\n\nUseful options:\n\n- `allowInlineDiffs`, `highlightChanges`, and `gutter` — all default to `true`.\n- `showOverview={false}` — hide the clickable change overview rail.\n- `diffConfig={{ scanLimit, timeout }}` — override the bounded large-document\n  diff policy when a host has different latency/precision needs.\n- `showToolbar={false}` — hide the built-in count and previous/next navigation\n  when the host supplies its own controls through `AtomicDiffEditorHandle`.\n\nThe handle's `getMarkdown()` and `getOriginalMarkdown()` return the exact input\nstrings, including CRLF line endings; they do not reconstruct text from\nCodeMirror's normalized rendering model.\n\n### Imperative handle\n\nPass a ref if you need to drive the editor from outside — e.g. wire\nyour own toolbar buttons, or open the search panel from a global\nkeybinding:\n\n```tsx\nimport { useRef } from 'react';\nimport {\n  AtomicCodeMirrorEditor,\n  type AtomicCodeMirrorEditorHandle,\n} from '@atomic-editor/editor';\n\nfunction App() {\n  const editor = useRef<AtomicCodeMirrorEditorHandle | null>(null);\n  return (\n    <>\n      <button onClick={() => editor.current?.openSearch()}>Search</button>\n      <AtomicCodeMirrorEditor\n        markdownSource={'…'}\n        editorHandleRef={editor}\n      />\n    </>\n  );\n}\n```\n\nMethods: `focus`, `undo`, `redo`, `openSearch(query?)`, `closeSearch`,\n`revealText(query)`, `isSearchOpen`, `getMarkdown`, `getContentDOM`.\n\n### Arriving from a search result\n\nTwo props drop the user near a relevant paragraph on mount:\n\n- **`initialSearchText`** opens the search panel pre-filled with the\n  query. Full navigation surface — arrow keys to step through matches,\n  close to dismiss. Good when the user explicitly invoked find.\n- **`initialRevealText`** does a less intrusive scroll-into-view with\n  a 3.2 s fade-out highlight on the first match — no panel, no cursor\n  move. Good for \"I clicked a search result, take me to the paragraph\n  it came from\".\n\nBoth accept `string | null`. The reveal matcher falls back\nprogressively — exact, whitespace-collapsed, individual lines, then\ntruncated prefixes (140 and 80 chars) — so hits still resolve when\nthe query came from an LLM-massaged snippet that doesn't match the\nsource byte-for-byte. For post-mount reveals, call\n`editorHandle.revealText(query)` via the imperative handle.\n\nThe fade highlight uses CSS variables\n`--atomic-editor-initial-reveal-bg` and\n`--atomic-editor-initial-reveal-bg-strong`; override to theme the\npeak and settled colors independently of the main search-match\npalette.\n\n## Syntax highlighting\n\nFenced code blocks are plain monospace by default. To enable\nhighlighting, pass a `codeLanguages` array. `@codemirror/lang-markdown`\ndynamically imports each grammar the first time a fence uses it, so\nlarge lists don't bloat the initial bundle.\n\n### Option 1: use the curated list (~20 languages)\n\n```bash\n# Install the lang-* peers you want highlighted.\nnpm install \\\n  @codemirror/lang-javascript @codemirror/lang-python \\\n  @codemirror/lang-rust @codemirror/lang-go @codemirror/lang-html \\\n  @codemirror/lang-css @codemirror/lang-json @codemirror/lang-yaml \\\n  @codemirror/legacy-modes  # ruby/swift/shell/toml/dockerfile\n```\n\n```tsx\nimport { AtomicCodeMirrorEditor } from '@atomic-editor/editor';\nimport { ATOMIC_CODE_LANGUAGES } from '@atomic-editor/editor/code-languages';\n\n<AtomicCodeMirrorEditor\n  markdownSource={'…'}\n  codeLanguages={ATOMIC_CODE_LANGUAGES}\n/>\n```\n\nSee [`src/code-languages.ts`](./src/code-languages.ts) for the full\nlist (JavaScript, TypeScript, Python, Go, Rust, Ruby, Java, C, C++,\nPHP, Swift, Shell, SQL, HTML, CSS, XML, JSON, YAML, TOML, Dockerfile,\nMarkdown).\n\n### Option 2: bring your own\n\n```tsx\nimport { LanguageDescription } from '@codemirror/language';\nimport { python } from '@codemirror/lang-python';\n\nconst codeLanguages = [\n  LanguageDescription.of({\n    name: 'Python',\n    alias: ['py'],\n    extensions: ['py'],\n    load: () => Promise.resolve(python()),\n  }),\n];\n\n<AtomicCodeMirrorEditor markdownSource={'…'} codeLanguages={codeLanguages} />\n```\n\n## Wiki links\n\n`[[target]]` and `[[target|label]]` links — the way Atomic and Obsidian\ncross-link notes — ship as a composable extension. It renders labeled links,\nresolves bare targets asynchronously (to show a real title and a\nresolved / missing state), opens links on click, and offers autocomplete as\nsoon as you type `[[`:\n\n```tsx\nimport { AtomicCodeMirrorEditor, wikiLinks } from '@atomic-editor/editor';\n\n<AtomicCodeMirrorEditor\n  markdownSource={'See [[atom-42|the design doc]] for details.'}\n  extensions={[\n    wikiLinks({\n      suggest: async (query) => store.search(query),     // autocomplete source\n      resolve: async (target) => store.resolve(target),  // label + status for bare links\n      onOpen: (target) => router.open(target),           // click / Cmd-click to navigate\n    }),\n  ]}\n/>;\n```\n\nDraft links stay editable while the cursor is inside them; resolution is\ndebounced and cached. See [`src/wiki-links.ts`](./src/wiki-links.ts) for the\nfull config — custom serialization, resolver policies, suggestion limits, and\nthe `WikiLinkSuggestion` / `WikiLinkResolvedTarget` types.\n\n## Theming\n\nEvery color, font, and size reads from a CSS custom property with an\ninline fallback. Override on any ancestor of the editor.\n\nThe package ships a **light variant** that activates whenever\n`data-theme=\"light\"` is set on an ancestor — including `<html>` or\n`<body>`. The dark defaults remain unchanged; the light block just\nre-maps the same variables.\n\n```html\n<html data-theme=\"light\">…</html>\n```\n\n| Variable                              | Dark default (auto-light on `[data-theme=\"light\"]`) |\n| ------------------------------------- | --------------------------------------------------- |\n| `--atomic-editor-font`                | system sans                                         |\n| `--atomic-editor-font-mono`           | system mono                                         |\n| `--atomic-editor-body-size`           | `1.0625rem`                                         |\n| `--atomic-editor-body-leading`        | `1.7`                                               |\n| `--atomic-editor-measure`             | `70ch`                                              |\n| `--atomic-editor-fg`                  | `#dcddde`                                           |\n| `--atomic-editor-fg-muted`            | `#888`                                              |\n| `--atomic-editor-fg-faint`            | `#666`                                              |\n| `--atomic-editor-bg`                  | `#1e1e1e`                                           |\n| `--atomic-editor-bg-panel`            | `#252525`                                           |\n| `--atomic-editor-bg-surface`          | `#2d2d2d`                                           |\n| `--atomic-editor-border`              | `#3d3d3d`                                           |\n| `--atomic-editor-accent`              | `#7c3aed`                                           |\n| `--atomic-editor-accent-bright`       | `#a78bfa`                                           |\n| `--atomic-editor-accent-soft`         | blockquote rail / reveal tint                       |\n| `--atomic-editor-link`                | `#818cf8`                                           |\n| `--atomic-editor-link-hover`          | `#a5b4fc`                                           |\n| `--atomic-editor-code-bg`             | subtle dark panel                                   |\n| `--atomic-editor-selection-bg`        | accent-tinted 28%                                   |\n| `--atomic-editor-search-bg`           | accent-tinted 28%                                   |\n| `--atomic-editor-search-bg-active`    | accent-tinted 60%                                   |\n| **Code-token colors** (Palenight)     |                                                     |\n| `--atomic-editor-hl-keyword`          | `#c792ea`                                           |\n| `--atomic-editor-hl-string`           | `#c3e88d`                                           |\n| `--atomic-editor-hl-number`           | `#f78c6c`                                           |\n| `--atomic-editor-hl-comment`          | `#6a7a82`                                           |\n| `--atomic-editor-hl-type`             | `#ffcb6b`                                           |\n| `--atomic-editor-hl-function`         | `#82aaff`                                           |\n| `--atomic-editor-hl-property`         | `#82aaff`                                           |\n| `--atomic-editor-hl-regexp`           | `#f07178`                                           |\n| `--atomic-editor-hl-escape`           | `#89ddff`                                           |\n| `--atomic-editor-hl-tag`              | `#f07178`                                           |\n| `--atomic-editor-hl-variable`         | `#eeffff`                                           |\n| `--atomic-editor-hl-operator`         | `#89ddff`                                           |\n| `--atomic-editor-hl-invalid`          | `#ff5370`                                           |\n\n## Extending with plugins\n\nCodeMirror 6 is extension-based, and so is this package. Pass any\nnumber of CM6 extensions via the `extensions` prop to layer in\nautocomplete sources, custom decorations, domain-specific keymaps,\ncollaboration (yjs), vim mode, or anything else. (The\n[wiki-links](#wiki-links) extension above is built with exactly this hook.)\n\n```tsx\nimport { autocompletion, type CompletionContext } from '@codemirror/autocomplete';\n\nconst hashtags = autocompletion({\n  override: [(ctx: CompletionContext) => {\n    const match = ctx.matchBefore(/#\\w*$/);\n    if (!match) return null;\n    return {\n      from: match.from + 1,\n      options: myTagStore.list().map((tag) => ({ label: tag })),\n    };\n  }],\n});\n\n<AtomicCodeMirrorEditor\n  markdownSource={'…'}\n  extensions={[hashtags]}\n/>\n```\n\nConsumer extensions are appended after the built-ins, so wrap a custom\nkeymap in `Prec.high` (from `@codemirror/state`) if it needs to beat\nthe default bindings. The array is captured at mount — pass a stable\nreference unless you want a remount.\n\n### Low-level composition\n\nIf the React wrapper's extension set is too opinionated, every piece\nis exported individually so you can assemble a fully custom editor:\n\n```ts\nimport {\n  inlinePreview, // live preview decorations\n  imageBlocks,   // rendered image widgets\n  tables,        // WYSIWYG table widget\n  wikiLinks,     // [[...]] links\n  atomicEditorTheme,\n  atomicMarkdownSyntax,\n  extendEmphasisPair,\n} from '@atomic-editor/editor';\n```\n\nYou could build an editor that includes `inlinePreview()` + `tables()`\nbut skips `atomicEditorTheme` for your own `EditorView.theme({...})`,\nor swap `atomicMarkdownSyntax` for a custom\n`syntaxHighlighting(HighlightStyle.define([...]))`. At that point\nyou're outside the React wrapper and in plain CM6 territory.\n\n## Design notes\n\nSee [docs/architecture.md](./docs/architecture.md) for the full design\nrationale. Short version:\n\n- **Raw markdown is the source of truth.** All decorations are\n  view-only — copy, save, and round-trip to any markdown parser are\n  identical to what you'd expect from a plain textarea.\n- **No layout shifts.** Every line has a stable height regardless of\n  cursor position. Inline decorations hide syntax tokens on inactive\n  lines without changing line heights.\n- **Narrow invalidation.** Decoration rebuilds only touch lines whose\n  content (or surrounding trigger characters) changed, so editing a\n  paragraph in a 50KB doc costs O(change size), not O(doc).\n- **Mouse-freeze guard.** Clicks don't trigger a decoration rebuild\n  mid-interaction — eliminates a class of cursor-drift bugs.\n- **iOS-aware.** Momentum-scroll halts (image remount jank, heightmap\n  drift, anchor conflicts) were tracked down and fixed; the demo's\n  sample-size picker doubles as a stress harness for spotting any\n  regressions.\n\n## Contributing\n\n```bash\ngit clone https://github.com/kenforthewin/atomic-editor\ncd atomic-editor\nnpm install\nnpm run dev        # demo dev server at http://localhost:5173\nnpm test           # vitest unit tests\nnpm run build      # tsc emit to dist/\nnpm run test:e2e   # Playwright probe suite against the demo\n```\n\nThe Playwright suite (`scripts/test-editor.mjs`) is the primary\nregression-catching tool — around 50 probes covering CLS during idle /\nscroll / typing, click-freeze timing, every block-type decoration\n(headings, lists, tasks, tables, images, fences, HRs, wiki links),\ncursor-scoped link reveal, copy-as-raw-markdown, tight-list\ncontinuation, escape handling, and late-doc rendering via the\nparser-progress mechanic. Run after any change to the editor's\nextensions.\n\nBecause the editor ships inside [Atomic](https://github.com/kenforthewin/atomic),\nreal user documents are its de-facto fuzz corpus — odd inputs (multi-line\nlink titles, over-escaped RSS imports, wide tables) tend to surface there\nfirst, and fixes land here. Issues and PRs welcome.\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}