texlite 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +403 -0
  3. package/README.zh-CN.md +391 -0
  4. package/dist/client/assets/GitDialog-BHHxSBn3.js +3 -0
  5. package/dist/client/assets/HistoryDialog-Dlv57tYf.js +5 -0
  6. package/dist/client/assets/LatexEditor-B-0VRUPv.js +55 -0
  7. package/dist/client/assets/PdfPreview-617TWFJN.js +1 -0
  8. package/dist/client/assets/ProjectNavigationDialogs-Cpt2LVEt.js +1 -0
  9. package/dist/client/assets/SystemMetricsDialog-fkFHVVzJ.js +1 -0
  10. package/dist/client/assets/editor-JxT6uSYX.js +14 -0
  11. package/dist/client/assets/index-Bc5CmFMl.js +15 -0
  12. package/dist/client/assets/index-CMqYAbDx.css +1 -0
  13. package/dist/client/assets/pdf-DPnwNQHb.js +55 -0
  14. package/dist/client/assets/pdf.worker.min-CHFwMXne.mjs +29 -0
  15. package/dist/client/assets/plus-DzbLkp6l.js +1 -0
  16. package/dist/client/assets/react-CsO_xvbl.js +49 -0
  17. package/dist/client/assets/spellCheck-R6fUM9oA.js +49783 -0
  18. package/dist/client/index.html +20 -0
  19. package/dist/client/logo.svg +4 -0
  20. package/dist/server/anchors.js +95 -0
  21. package/dist/server/app.js +1624 -0
  22. package/dist/server/archive.js +26 -0
  23. package/dist/server/auth.js +42 -0
  24. package/dist/server/cli.js +318 -0
  25. package/dist/server/collaboration.js +635 -0
  26. package/dist/server/compileArtifacts.js +86 -0
  27. package/dist/server/compileDiagnostics.js +227 -0
  28. package/dist/server/compiler.js +514 -0
  29. package/dist/server/config.js +336 -0
  30. package/dist/server/db.js +280 -0
  31. package/dist/server/environment.js +57 -0
  32. package/dist/server/files.js +121 -0
  33. package/dist/server/git.js +414 -0
  34. package/dist/server/history.js +379 -0
  35. package/dist/server/http.js +7 -0
  36. package/dist/server/index.js +75 -0
  37. package/dist/server/latexCompletion.js +296 -0
  38. package/dist/server/metrics.js +34 -0
  39. package/dist/server/pm2.js +234 -0
  40. package/dist/server/projectOutline.js +101 -0
  41. package/dist/server/projectSearch.js +112 -0
  42. package/dist/server/projects.js +29 -0
  43. package/dist/server/routes/compile.js +343 -0
  44. package/dist/server/runtimePaths.js +42 -0
  45. package/dist/server/security.js +29 -0
  46. package/dist/server/spellCheck.js +195 -0
  47. package/dist/server/synctex.js +56 -0
  48. package/dist/server/zip.js +185 -0
  49. package/package.json +110 -0
  50. package/preview.png +0 -0
  51. package/texlite.config.example.json +33 -0
package/README.md ADDED
@@ -0,0 +1,403 @@
1
+ # texLite
2
+
3
+ texLite is a lightweight, local-first web workspace for writing, compiling, previewing, and discussing LaTeX documents. It is intended for a small group of trusted users on one server. It uses the LaTeX installation already available on the host instead of shipping a LaTeX container, and keeps the rest of the stack deliberately small.
4
+
5
+ **Documentation:** English (this file) · [简体中文](README.zh-CN.md)
6
+
7
+ [![CI](https://github.com/SWUFE-DB-Group/TexLite/actions/workflows/ci.yml/badge.svg)](https://github.com/SWUFE-DB-Group/TexLite/actions/workflows/ci.yml)
8
+
9
+ ![texLite preview](preview.png)
10
+
11
+ ## Design goals
12
+
13
+ - Use the host's TeX Live/LaTeX installation so it can be updated independently.
14
+ - Avoid Redis, MongoDB, and a reverse proxy for the default localhost deployment.
15
+ - Keep projects and generated artifacts on the local filesystem.
16
+ - Use SQLite through better-sqlite3 for durable application data.
17
+ - Provide useful collaboration for a small number of active sessions without requiring a distributed deployment.
18
+
19
+ ## Features
20
+
21
+ - Administrator initialization and user administration; public registration is disabled.
22
+ - Per-user permission to create projects (disabled by default for newly created users).
23
+ - Project, folder, file, and attachment management, including drag-and-drop uploads.
24
+ - ZIP project import with safe extraction and automatic main-document selection.
25
+ - List/grid project views, search, sorting by last modification or creation time, and private Finder-style color tags.
26
+ - Project rename, source ZIP download, deletion, owner and modification metadata.
27
+ - English and Chinese UI with browser-language detection and a language switcher.
28
+ - CodeMirror LaTeX editing with syntax highlighting, folding, completion, quick file opening, current-file and project-wide search/replace, a cross-file outline, and configurable appearance.
29
+ - Yjs CRDT collaboration with active-session avatars, remote cursors, acknowledged server saves, and a browser-local IndexedDB draft for reconnect recovery; the practical limit is about ten concurrent sessions per project.
30
+ - Automatic content-addressed project history with labels, file comparison, single-file restore, and full-project restore checkpoints.
31
+ - Source-range comments with replies, resolved state, user/time metadata, and anchor remapping after edits.
32
+ - Host-side latexmk compilation with pdflatex, xelatex, and lualatex options, project-level latexmkrc, serialized project jobs, persistent incremental caches, immutable published snapshots, retained PDFs, SyncTeX navigation, structured clickable diagnostics, and downloadable artifacts such as .bbl files.
33
+ - Project sharing with read-only or read/write access. Read-only users can still add and reply to comments.
34
+ - Owner-only local Git history and GitHub backup: commit, push, diff, checkout, and restore tracked changes.
35
+ - Optional PM2 process management for automatic restart, status, and logs.
36
+ - Administrator-only live system metrics for compile queues, collaboration sessions, event-loop delay, memory, and recent operation latency.
37
+
38
+ ## Architecture
39
+
40
+ | Area | Implementation |
41
+ | --- | --- |
42
+ | Browser UI | React, Vite, CodeMirror, PDF.js |
43
+ | API and static server | Fastify, WebSocket |
44
+ | Collaboration | Yjs, y-websocket, y-codemirror.next |
45
+ | Database | SQLite via better-sqlite3 |
46
+ | Files | Local project directories under the configured data directory |
47
+ | Compilation | Host latexmk and a configured LaTeX engine |
48
+ | Git backup | Host git and the GitHub REST API |
49
+
50
+ texLite is designed as a single Node.js process. Do not run multiple application instances against the same SQLite database or project directory; the in-memory collaboration service and compile queue are intentionally single-instance.
51
+
52
+ ## Requirements
53
+
54
+ - Node.js 24 or newer
55
+ - npm
56
+ - git (optional; required only for the project-owner Git/GitHub integration)
57
+ - latexmk
58
+ - At least one configured engine: pdflatex, xelatex, or lualatex
59
+
60
+ Check the host before initialization:
61
+
62
+ ~~~bash
63
+ node --version
64
+ npm --version
65
+ latexmk --version
66
+ xelatex --version
67
+ # Optional, when Git/GitHub integration is needed:
68
+ git --version
69
+ ~~~
70
+
71
+ npm run init and application startup check latexmk and every engine in latex.allowedEngines. Git is deliberately excluded from this core check, so a host without Git can initialize and run TexLite normally. When a project owner opens the Git panel or invokes a Git/GitHub operation, TexLite checks git.binary on demand and shows an actionable error if Git is unavailable.
72
+
73
+ ## Quick start
74
+
75
+ ### Global npm installation
76
+
77
+ The published package provides a `texlite` executable. It keeps configuration
78
+ and project data outside the global npm installation:
79
+
80
+ ~~~bash
81
+ npm install --global texlite
82
+ texlite init
83
+ texlite start
84
+ texlite status
85
+ ~~~
86
+
87
+ Open http://127.0.0.1:3000. The service can be stopped or restarted from any
88
+ working directory:
89
+
90
+ ~~~bash
91
+ texlite stop
92
+ texlite restart
93
+ texlite logs
94
+ ~~~
95
+
96
+ The default configuration is
97
+ `$XDG_CONFIG_HOME/texlite/texlite.config.json`, or
98
+ `~/.config/texlite/texlite.config.json` when `XDG_CONFIG_HOME` is not set. The
99
+ default data directory is `$XDG_DATA_HOME/texlite`, or
100
+ `~/.local/share/texlite`. Use `--config PATH` or `TEXLITE_CONFIG` to select a
101
+ different configuration file.
102
+
103
+ `texlite serve` runs the server in the foreground and is suitable for Docker,
104
+ systemd, and debugging. `start`, `status`, `stop`, `restart`, and `logs` use the
105
+ PM2 dependency bundled with the package.
106
+
107
+ For a clean upgrade:
108
+
109
+ ~~~bash
110
+ npm update --global texlite
111
+ texlite restart
112
+ ~~~
113
+
114
+ Uninstalling the npm package does not remove the configuration or project data:
115
+
116
+ ~~~bash
117
+ npm uninstall --global texlite
118
+ ~~~
119
+
120
+ ### Repository/source installation
121
+
122
+ ~~~bash
123
+ npm ci
124
+ cp texlite.config.example.json texlite.config.json
125
+ export TEXLITE_CONFIG="$PWD/texlite.config.json"
126
+ # Edit texlite.config.json if needed.
127
+ npm run init
128
+ npm run build
129
+ npm start
130
+ ~~~
131
+
132
+ The default server binds to localhost and does not expose public registration.
133
+ The initialization command asks for the first administrator account; the server
134
+ refuses to start until at least one active administrator exists.
135
+
136
+ For a non-interactive initialization, set the following environment variables for that command only:
137
+
138
+ ~~~bash
139
+ TEXLITE_INIT_USERNAME=admin \
140
+ TEXLITE_INIT_DISPLAY_NAME=Administrator \
141
+ TEXLITE_INIT_PASSWORD='use-a-password-of-at-least-8-characters' \
142
+ npm run init
143
+ ~~~
144
+
145
+ Avoid putting the password in shell history on a shared machine.
146
+
147
+ ## Development and verification
148
+
149
+ Run the API/server watcher and Vite in separate terminals:
150
+
151
+ ~~~bash
152
+ npm run dev # API and server at http://127.0.0.1:3000
153
+ npm run dev:web # Vite UI at http://127.0.0.1:5173
154
+ ~~~
155
+
156
+ Vite proxies /api requests to the server. Before a production-style run, use:
157
+
158
+ ~~~bash
159
+ npm run typecheck
160
+ npm test
161
+ npm run build
162
+ npm start
163
+ ~~~
164
+
165
+ ## Configuration
166
+
167
+ Configuration path precedence is:
168
+
169
+ 1. `--config PATH` passed to the `texlite` executable;
170
+ 2. `TEXLITE_CONFIG`;
171
+ 3. `$XDG_CONFIG_HOME/texlite/texlite.config.json`;
172
+ 4. `~/.config/texlite/texlite.config.json`.
173
+
174
+ Relative paths in the configuration are resolved relative to that configuration
175
+ file. `storage.dataDir` defaults to `$XDG_DATA_HOME/texlite`, or
176
+ `~/.local/share/texlite`. Set `storage.dataDir` in the configuration, or use
177
+ `TEXLITE_DATA_DIR`, to choose another data directory. The production client
178
+ bundle defaults to the `dist/client` directory inside the installed package;
179
+ `TEXLITE_CLIENT_DIR` can override it for development or custom deployments.
180
+
181
+ The example configuration is intentionally complete:
182
+
183
+ ~~~json
184
+ {
185
+ "siteName": "TexLite",
186
+ "adminEmail": "admin@example.com",
187
+ "sessionDays": 14,
188
+ "server": { "host": "127.0.0.1", "port": 3000 },
189
+ "storage": { "dataDir": ".texlite" },
190
+ "uploads": { "maxFileSizeMB": 50 },
191
+ "history": { "maxVersions": 200, "maxStorageMB": 512 },
192
+ "git": {
193
+ "binary": "git",
194
+ "operationTimeoutSeconds": 120,
195
+ "githubApiBaseUrl": "https://api.github.com"
196
+ },
197
+ "latex": {
198
+ "latexmk": "latexmk",
199
+ "defaultEngine": "xelatex",
200
+ "allowedEngines": ["pdflatex", "xelatex", "lualatex"],
201
+ "extraArgs": [],
202
+ "allowProjectLatexmkrc": true,
203
+ "compileTimeoutSeconds": 600,
204
+ "maxCompileJobs": 10
205
+ }
206
+ }
207
+ ~~~
208
+
209
+ The checked-in example uses `.texlite` as an explicit repository-development
210
+ path. A configuration generated by `texlite init` uses the XDG data directory
211
+ default described above instead.
212
+
213
+ Important settings:
214
+
215
+ - server.host and server.port: network bind address and port. Keep the host at 127.0.0.1 unless a separately secured deployment is intended.
216
+ - storage.dataDir: SQLite database, project sources, compile output, and the Git token encryption key.
217
+ - uploads.maxFileSizeMB: maximum size for a project upload, a ZIP entry, project files, and attachments. The default is 50 MB.
218
+ - history.maxVersions: maximum number of ordinary, unlabeled versions retained per project. Initial and labeled versions are protected.
219
+ - history.maxStorageMB: soft per-project limit for deduplicated history objects. The oldest ordinary versions are removed first; protected versions and the current internal baseline can exceed this limit.
220
+ - latex.defaultEngine, latex.allowedEngines, latex.extraArgs: compile choices available in the UI.
221
+ - latex.compileTimeoutSeconds: timeout for one compile job.
222
+ - latex.maxCompileJobs: global number of concurrent LaTeX processes. Jobs for the same project and root document are serialized; newer source versions supersede older queued requests. Different root documents use independent workspaces and may compile concurrently within this global limit.
223
+ - latex.allowProjectLatexmkrc: allow a project to supply a multi-line latexmkrc. A project rc file is executable Perl configuration and should only be enabled for trusted users.
224
+
225
+ ### Effective defaults and startup validation
226
+
227
+ When a setting is omitted, texLite uses the following built-in defaults (the
228
+ generated example file may choose to show an explicit value such as an admin
229
+ email):
230
+
231
+ | Setting | Effective default |
232
+ | --- | --- |
233
+ | `siteName` | `TexLite` |
234
+ | `adminEmail` | empty |
235
+ | `server.host` / `server.port` | `127.0.0.1` / `3000` |
236
+ | `storage.dataDir` | `$XDG_DATA_HOME/texlite` or `~/.local/share/texlite` |
237
+ | `clientDir` | `dist/client` inside the installed package |
238
+ | `sessionDays` | `14` |
239
+ | `uploads.maxFileSizeMB` | `50` MB |
240
+ | `history.maxVersions` | `200` ordinary versions per project |
241
+ | `history.maxStorageMB` | `512` MB per project (soft limit) |
242
+ | `latex.latexmk` | `latexmk` |
243
+ | `latex.defaultEngine` | `xelatex` |
244
+ | `latex.allowedEngines` | `pdflatex`, `xelatex`, `lualatex` |
245
+ | `latex.extraArgs` | `[]` |
246
+ | `latex.allowProjectLatexmkrc` | `true` |
247
+ | `latex.compileTimeoutSeconds` | `600` seconds |
248
+ | `latex.maxCompileJobs` | `10` |
249
+ | `git.binary` / `git.operationTimeoutSeconds` | `git` / `120` seconds |
250
+ | `git.githubApiBaseUrl` | `https://api.github.com` |
251
+
252
+ Configuration is validated before environment checks, database opening, or
253
+ the HTTP listener starts. Explicit values are never silently replaced by a
254
+ default. The accepted ranges are: port `1–65535`, sessions `1–3650` days,
255
+ upload size `1–2048` MB, history versions `10–5000`, history storage
256
+ `16–102400` MB, compile timeout `1–3600` seconds, compile jobs `1–32`,
257
+ and Git timeout `1–3600` seconds. Engine names must be supported, unique, and
258
+ the allowed-engine list must include the selected default engine. Data and
259
+ project paths must not point at files (the data directory cannot be the
260
+ filesystem root); a missing data directory must have an existing writable
261
+ parent. The GitHub API endpoint must be an `http://` or `https://` URL.
262
+
263
+ Invalid JSON types, empty required strings, malformed integers (including
264
+ decimal or non-numeric environment overrides), unsupported engines, invalid
265
+ URLs, and unusable paths stop startup with the setting name, expected value,
266
+ and a remediation hint. The same validation runs during `npm run init`, so a
267
+ configuration can be checked before creating the first administrator.
268
+
269
+ Environment variables override the corresponding file values:
270
+
271
+ ~~~text
272
+ TEXLITE_CONFIG
273
+ XDG_CONFIG_HOME XDG_DATA_HOME
274
+ TEXLITE_SITE_NAME TEXLITE_ADMIN_EMAIL
275
+ TEXLITE_HOST TEXLITE_PORT
276
+ TEXLITE_DATA_DIR TEXLITE_CLIENT_DIR
277
+ TEXLITE_SESSION_DAYS TEXLITE_MAX_UPLOAD_SIZE_MB
278
+ TEXLITE_HISTORY_MAX_VERSIONS TEXLITE_HISTORY_MAX_STORAGE_MB
279
+ TEXLITE_LATEXMK TEXLITE_DEFAULT_ENGINE
280
+ TEXLITE_COMPILE_TIMEOUT TEXLITE_MAX_COMPILE_JOBS
281
+ TEXLITE_GIT TEXLITE_GIT_TIMEOUT
282
+ TEXLITE_GITHUB_API_URL
283
+ ~~~
284
+
285
+ texLite does not run tlmgr or install missing packages. Updating TeX Live on the host changes the environment used by the next compile.
286
+
287
+ ## Service management
288
+
289
+ For a global npm installation, the lifecycle commands use the bundled PM2
290
+ runtime. No separate global PM2 installation is needed:
291
+
292
+ ~~~bash
293
+ texlite start
294
+ texlite status
295
+ texlite logs
296
+ texlite restart
297
+ texlite stop
298
+ ~~~
299
+
300
+ `texlite doctor` validates configuration, paths, LaTeX, and the administrator;
301
+ add `--git` to check the optional Git integration. `texlite config` prints the
302
+ effective paths and values. `texlite serve` keeps the process in the foreground
303
+ and does not start PM2.
304
+
305
+ For repository deployments, `ecosystem.config.cjs` and the npm PM2 wrappers are
306
+ also available. It deliberately runs one forked instance (`instances: 1`);
307
+ cluster mode is not supported because collaboration state, the compile queue,
308
+ SQLite, and the project filesystem are local to one process.
309
+
310
+ ~~~bash
311
+ npm install --global pm2
312
+ npm run build
313
+ pm2 start ecosystem.config.cjs
314
+ pm2 status
315
+ pm2 logs texlite
316
+ ~~~
317
+
318
+ The repository wrappers are `npm run pm2:start`, `npm run pm2:restart`,
319
+ `npm run pm2:stop`, `npm run pm2:delete`, `npm run pm2:logs`, and
320
+ `npm run pm2:save`.
321
+
322
+ After deploying new code:
323
+
324
+ ~~~bash
325
+ npm run build
326
+ pm2 restart texlite --update-env
327
+ ~~~
328
+
329
+ To keep the process across reboots, run the command printed by pm2 startup, then save the process list:
330
+
331
+ ~~~bash
332
+ pm2 save
333
+ ~~~
334
+
335
+ Useful lifecycle commands are pm2 stop texlite, pm2 restart texlite, pm2 delete texlite, and pm2 monit.
336
+
337
+ ## Collaboration and compilation model
338
+
339
+ The editor uses a Yjs CRDT document for concurrent editing. Each active browser session is shown in the project header, and remote cursor colors identify editors. The intended scale is up to roughly ten active sessions on one project. The save indicator changes to “saved” only after the server acknowledges durable source persistence. Unsynchronized updates are also retained in browser IndexedDB and replayed after a transient disconnect; a history restore or Git checkout rotates the collaboration epoch so an obsolete local draft cannot overwrite the restored tree. Deleting or moving a file rejects late edits from sessions that still held its old editor binding.
340
+
341
+ The main document saved in project settings is the default root. When a user opens another `.tex` file containing `\documentclass`, that file becomes the compile root for that browser session; opening an included fragment does not change the current root. Only the current root is compiled. Compile status, logs, retained PDF, artifacts, outline, and SyncTeX state are keyed by root document, so collaborators working on different roots do not see each other's compile notification or replace each other's PDF.
342
+
343
+ Compilation is isolated from editing:
344
+
345
+ 1. The server captures an immutable source snapshot.
346
+ 2. Changed files are synchronized into a persistent compile workspace keyed by project, root document, and compiler settings.
347
+ 3. latexmk reuses its dependency database and auxiliary files; jobs for the same root remain serialized.
348
+ 4. The resulting PDF, logs, SyncTeX, and other artifacts are copied into an immutable run bundle.
349
+ 5. A successful bundle is published atomically as the latest retained result.
350
+
351
+ The mutable cache for one root is never used concurrently, while different roots have separate caches and published artifacts are never modified in place. A user can continue viewing the previous PDF while a new compile is running. latexmk handles the necessary repeated passes for BibTeX-based documents and avoids rerunning BibTeX when its inputs have not changed. Compile responses expose a Server-Timing header for snapshot, cache synchronization, latexmk, artifact-copy, and total request time. TexLite does not retain a browsable compile history: it keeps only the latest attempt state and, when needed, the last successful result currently published for each root document. Older database rows and immutable artifact bundles are removed automatically.
352
+
353
+ ## History, navigation, and diagnostics
354
+
355
+ Automatic history records source/file operations, compiler-setting changes, Git operations, restores, and acknowledged collaborative saves. Collaborative saves use fixed two-minute version windows, so continuous editing still creates useful recovery points without recording every keystroke. TexLite retains the latest 200 ordinary versions by default, plus every labeled and initial version. File contents are stored as complete SHA-256-addressed objects: unchanged data is reused, while a changed file creates a new complete object. A 512 MB soft per-project limit removes the oldest ordinary versions first; protected versions and the current internal baseline may exceed it. Project owners can see history storage usage and delete one version or clear all history without changing current project files. Unreferenced objects are garbage-collected. History is useful for correcting writing mistakes, but it is not a replacement for backing up the complete data directory.
356
+
357
+ Use Ctrl/Cmd+P to open a project file quickly and Ctrl/Cmd+Shift+F for literal project-wide search and replace. Project replacement is staged as one operation and creates a history version. The outline follows `\\input`, `\\include`, and `\\subfile` references from the main document. Structured warning/error entries resolve project-relative file names and jump directly to the matching source line; the raw latexmk transcript remains available.
358
+
359
+ Administrators can open **System status** on the project list. It reports only counts and timings—never source text, passwords, Git tokens, or comments. The same data is available at authenticated endpoint `GET /api/health/metrics`.
360
+
361
+ ## GitHub backup
362
+
363
+ The Git panel is visible only to the project owner. A GitHub personal access token is configured per project and stored encrypted in SQLite. The local repository is initialized in the project source directory; Git identity is temporary for each command:
364
+
365
+ ~~~text
366
+ user.name = project owner's username
367
+ user.email = <username>@texlite.com
368
+ ~~~
369
+
370
+ For a fine-grained GitHub token, the intended trusted-user deployment should grant repository Administration and Contents read/write permissions and use All repositories, because a repository may not exist when the token is configured and later repositories may be created. The token never appears in the remote URL or command-line arguments.
371
+
372
+ Normal checkout uses Git's preserving behavior and refuses conflicts. Only the explicit force option discards tracked, untracked, and ignored working-tree files. After checking out a historical revision, return to the default branch before committing or pushing.
373
+
374
+ ## Data, backup, and deletion
375
+
376
+ The default data directory is:
377
+
378
+ ~~~text
379
+ .texlite/
380
+ ├── texlite.db
381
+ ├── texlite.db-wal
382
+ ├── texlite.db-shm
383
+ ├── git-token.key
384
+ └── projects/
385
+ └── <project-id>/
386
+ ├── source/
387
+ └── output/
388
+ └── .texlite/ # compile cache/runs and history objects
389
+ ~~~
390
+
391
+ Back up texlite.db, git-token.key, and projects/ together. The encryption key is required to recover saved GitHub tokens. SQLite WAL files should be included when taking a live filesystem backup, or use a SQLite-aware backup procedure.
392
+
393
+ Deleting a user removes their memberships and comments remain attributable as “Deleted User”. Depending on the administrator's choice, projects owned by that user can be transferred to the current administrator or deleted together with their files. The last active administrator cannot be removed or disabled.
394
+
395
+ ## Security boundaries
396
+
397
+ texLite is designed for trusted users on localhost. The default compiler disables shell escape, does not concatenate shell commands, and enforces compile timeouts and concurrency limits. Nevertheless, LaTeX itself and a project latexmkrc are not a security sandbox. Before exposing texLite to an untrusted network or public registration, add an isolated compiler sandbox and an appropriate authentication/reverse-proxy layer.
398
+
399
+ ## License and status
400
+
401
+ texLite is licensed under the GNU Affero General Public License v3.0. See [LICENSE](LICENSE). If you need proprietary modifications or commercial terms different from AGPL-3.0, contact the copyright holder for a separate commercial license.
402
+
403
+ This repository is an early, single-host application rather than a drop-in replacement for Overleaf. Review and adapt the deployment, backup, and security settings for the environment in which it will run.