Dockerfile-base: after Quarto is installed, run 'quarto add --no-prompt'
for a curated set of extensions into /opt/quarto-extensions/. Quarto
writes _extensions/<author>/<name>/ in the working dir, giving us a
clean shared store. Extensions included:
- igorlima/charged-ieee — IEEE paper format (Typst)
- quarto-ext/fontawesome — Font Awesome icons
- quarto-ext/attribution — attribution footer on RevealJS slides
- quarto-ext/pointer — laser pointer for presentations
- quarto-ext/drop — drop-down overlay for RevealJS
Adding more: one extra '&& quarto add --no-prompt <author>/<repo>' line.
QuartoRunner: before quarto render, merge /opt/quarto-extensions/_extensions/
into the compile dir's _extensions/ with 'cp -rn' (no-clobber). This
makes all pre-installed extensions available to every project without
any user action. Project-uploaded _extensions/ files take precedence
since cp -n never overwrites existing files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace Overleaf's original README with a Verso-specific one covering:
the project's purpose (collaborative Quarto editor), output formats
(typst/PDF and revealjs/HTML), quick-start Docker instructions, service
architecture overview, a minimal .qmd example, key env vars, and a
clear description of what differs from upstream Overleaf.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
collectOutputPdfSize() only calls stat() and sets .size on output.pdf.
All other output files (including output.html) keep size: undefined.
The previous check required file.size > 0 for both PDF and HTML, so
undefined > 0 always evaluated false for output.html, making every
RevealJS compile report 'failure' even when the file was produced.
Fix: require size > 0 only for output.pdf; accept output.html
regardless of size (it is always non-empty if Quarto succeeded).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LocalCommandRunner.replace() uses String.replace() which only substitutes
the FIRST occurrence of '$COMPILE_DIR' in the shell script string. The mv
commands had two more occurrences that stayed as literal '$COMPILE_DIR',
which the shell expanded to '', making 'mv /main.pdf /output.pdf' fail
silently. The file was produced (Quarto logged 'Output created: main.pdf')
but never renamed to output.pdf, so the pipeline reported failure.
Fix: mv uses relative filenames since the shell CWD is already the compile
directory (set by LocalCommandRunner via the spawnCwd option).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
clsi-nginx.conf: the types{} block was overriding all nginx defaults,
leaving HTML/CSS/JS/fonts as application/octet-stream. Add the full
set of web MIME types so RevealJS assets are served correctly. Also
needed for X-Content-Type-Options: nosniff to pass.
CompileController.js: success was hardcoded to require output.pdf.
Also accept output.html so a RevealJS compile is reported as
'success' rather than 'failure'.
QuartoRunner.js: remove hardcoded --to typst --output output.pdf.
Instead run `quarto render` without --to/--output so the YAML
frontmatter decides the format (typst → PDF, revealjs → HTML, etc.).
Pass --embed-resources so HTML output is self-contained (flag is
silently ignored by the typst backend). After render, rename
main.pdf → output.pdf or main.html → output.html so the pipeline
finds the standard canonical filename.
output-files.ts: handleOutputFiles now falls back to output.html when
output.pdf is absent. Download URL uses outputFile.path instead of
the hardcoded 'output.pdf' string.
pdf-viewer.tsx: when pdfUrl contains output.html, bypass PDF.js
entirely and render a sandboxed iframe (allow-scripts for RevealJS
interactivity, allow-presentation for fullscreen).
Usage: set `format: revealjs` in the .qmd YAML frontmatter to get
an HTML presentation preview; set `format: typst` for PDF.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
outline.ts: export NestingLevel so it can be used outside the file.
markdown/document-outline.ts: new enterMarkdownNode function that walks
the Lezer Markdown syntax tree and extracts ATXHeading1-6 and
SetextHeading1-2 nodes, mapping them to the same NestingLevel enum
used by the LaTeX outline (Section→SubSection→SubSubSection…).
Wrapped in makeProjectionStateField for incremental updates.
markdown/index.ts: register markdownDocumentOutline as a CodeMirror
extension in the Markdown LanguageSupport so the StateField is active
whenever a .qmd file is open.
codemirror-outline.tsx: fall back to markdownDocumentOutline when the
LaTeX documentOutline StateField is not present in the editor state
(i.e. when the active language is Markdown, not LaTeX).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous compile logs confirm Quarto handles --to typst --output
output.pdf correctly: pandoc produces main.typ, typst compiles it to
main.pdf, then Quarto renames to output.pdf. The mv-based approach was
unnecessary and incorrect.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--to typst combined with --output output.pdf caused Quarto to write a
Typst source file (.typ content) named output.pdf instead of invoking
the typst compiler, producing a text file that the PDF viewer could not
render (hence 'markdown not rendered' — it was literally showing the raw
.typ markup). Fix: let Quarto name the PDF after the input file
(main.qmd → main.pdf) and rename to output.pdf with mv afterwards.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Quarto resolves its cache dir as $HOME/.cache/quarto. The process runs
as www-data (home=/var/www) but that directory is root-owned, so Quarto
crashed immediately with PermissionDenied on mkdir. Pre-create the cache
dir and chown it to www-data at image build time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LocalCommandRunner: attach captured stdout to the error object when
exit code is 1, so callers can read Quarto's output even on failure.
QuartoRunner: stop propagating plain 'exited' errors from Quarto up
to CompileManager. A Quarto exit-code-1 is a compile failure, not a
server error — CLSI already detects failure by the absence of
output.pdf and returns status='failure' (HTTP 200). Previously it
fell through to the generic error handler (HTTP 500), which caused
the frontend to show "Server Error" instead of the log panel.
Only true process-level errors (terminated, timedout) are propagated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dockerfile-base: remove TeX Live (no longer needed), install Quarto
1.6.39 which bundles Typst for PDF output. This was the root cause
of all compile failures — the server-ce monolith never had Quarto.
QuartoRunner: run quarto via /bin/sh so stderr is merged into stdout
with 2>&1; write combined output to output.log (not output.stdout)
so the PDF-preview log panel picks it up and shows raw output.
Also write the log on error so failures are always visible.
CompileManager: guard DraftModeManager behind an isLatexFile check —
injecting LaTeX preamble commands into a .qmd file corrupts it and
causes a guaranteed compile failure when draft mode is requested.
ProjectCreationHandler + mainbasic.qmd: new projects now create
main.qmd with a minimal Quarto/Typst frontmatter instead of the
LaTeX main.tex; _createRootDoc names the file main.qmd accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- compiler-setting.tsx: replace hardcoded LaTeX compiler list with a
single Quarto option; drop now-unused getMeta/lodash imports
- project-settings.ts: add 'quarto' to ProjectCompiler union type
- ClsiManager: detect main.qmd as a default root document (preferred
over main.tex); replace hasMainFile boolean with detectedMainFile
so we know which filename to use
- settings.defaults.js: add 'qmd' to validRootDocExtensions so .qmd
files appear as selectable root documents in the UI
- ProjectRootDocManager: sort main.qmd before main.tex in the root
doc candidate list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add QuartoRunner.js: runs `quarto render --to typst --output output.pdf`,
using Typst (bundled with Quarto >= 1.4) so no separate LaTeX install needed
- Swap LatexRunner for QuartoRunner in CompileManager; remove latexmk-specific
stats, fdb metrics, and performance sampling that no longer apply
- Add 'quarto' to VALID_COMPILERS in RequestParser and set it as the default;
change default rootResourcePath from main.tex to main.qmd
- Add 'quarto' to safeCompilers and set it as the default in web settings
- Replace with-texlive Dockerfile stage with with-quarto (Quarto deb install);
add Quarto to the default final stage as well
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* [web] Replace `pro` with `commons` wording on institutional subscriptions
Replaces the wording in several places:
- subscription settings
- email tags
- features tooltip
- institution portal
GitOrigin-RevId: 1b9a0e51245ed8a41865300d9e9d555bc05e6c17
* [web] bump `js-yaml` in `reference-parser`
`.yarn/patches/referer-parser-npm-0.0.3.patch` bumps the `js-yaml` dependency,
but yarn patches don't take that into account the patched package.json for dependency resolution.
* Add RequestHelper test
GitOrigin-RevId: 8246f8ab54956897cc361d7c02b65e5363ad43ec
* [clsi] add request flag for isCompileFromHistory
* [clsi] derive cacheKey for history snapshot from compile dir
* [clsi] migrate convert project to document to compile from history
* [clsi] address review feedback
* [web] determine root doc at the time of converting the project
* [web] wait for flush before starting document conversion
* [saas-e2e] add tests for root doc override when converting project
GitOrigin-RevId: 71c578030949b89f3a74e7f7ab882dfa9c98c17a
* [clsi] Forward pandoc errors to web
* [clsi] Remove unused import
* [clsi] Align warning logs
* [clsi] Update HTTP response for errors
* [clsi] Update acceptance test with 422
* [clsi] Always return json body on 422
* [clsi] Include stderr in logs for non user facing errors
GitOrigin-RevId: 4284c8d4e8b7b45eac4997cd9e52ca4894b20412
* Pin @babel/plugin-transform-modules-systemjs to 7.29.4 via resolutions (GHSA-fv7c-fp4j-7gwp)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix missing comma in package.json resolutions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>
GitOrigin-RevId: d6f3e72234d64fd0afb8676b8652cc03b0cddbe0