feat: Git workflow, Vim mode, and preview→editor SyncTeX
Add three core VISION features on top of the barebones MVP: Git workflow (backend + frontend): - Backend: simple-git wrapper with per-project repo isolation, init (idempotent .gitignore reconciliation, handles empty repos), status, log, commit (per-commit identity via -c flags), remote, push, pull - gitFor() now refuses to run without the project's own .git, preventing accidental parent-repo detection when projects/ lives inside the typst-leaf worktree - Frontend: GitPanel (branch, ahead/behind, inline commit, push/pull, remote prompt, collapsible log), SettingsPanel (git identity in localStorage), Ctrl+Shift+S focuses commit input - Status/log refresh driven by gitVersion bumps (no polling) with cancellation guards across project switches - Auto-init on status failure for pre-existing projects Vim mode: - Off-by-default toggle persisted to localStorage - Dynamic monaco-vim import, status bar div, StrictMode-safe lifecycle via editorReady reset on unmount SyncTeX (preview → editor): - Handle tinymist/preview/scrollSource notification and window/showDocument request - Cross-platform path normalization (Windows drive letters, native backslash paths, URL-decoded paths) - Editor jump effect with Monaco selection/reveal/focus, clears on completion Robustness fixes across review cycles: - Cancellation guards on git status/log effects to prevent stale writes - bumpGitVersion after auto-init so log viewer updates - jsonOrThrow extracts structured backend errors, handles empty bodies - SettingsPanel/GitPanel validate localStorage identity shape - GitPanel clears log state on project switch - File path URI encoding preserves path separators (segment-wise encode) - tsconfig lib bumped to ES2021 for String.replaceAll AGENTS.md: removed stale execa/monaco-languageclient references PLAN.md: implementation plan for this chunk
This commit is contained in:
@@ -26,8 +26,8 @@ typst-leaf-backend/ Node.js/TS — stateless orchestration: spawns tinymist,
|
||||
typst-leaf-frontend/ React (Vite) + Monaco — the IDE SPA; also contains src-tauri/ for the desktop build
|
||||
```
|
||||
|
||||
* **Backend** (`typst-leaf-backend/`): ESM (`"type": "module"`), strict TS with `noUncheckedIndexedAccess`. Entry: `src/index.ts`. Dev via `tsx watch`; build via `tsc` → `dist/`. Uses `express` + `ws` + `simple-git` + `execa` + `zod`.
|
||||
* **Frontend** (`typst-leaf-frontend/`): React 19 + Vite. Monaco Editor wired to LSP via `monaco-languageclient` + `vscode-ws-jsonrpc`. Styling is **Tailwind v4** via the `@tailwindcss/vite` plugin (import with `@import "tailwindcss"`; there is no `tailwind.config.js`).
|
||||
* **Backend** (`typst-leaf-backend/`): ESM (`"type": "module"`), strict TS with `noUncheckedIndexedAccess`. Entry: `src/index.ts`. Dev via `tsx watch`; build via `tsc` → `dist/`. Uses `express` + `ws` + `simple-git` + `zod`.
|
||||
* **Frontend** (`typst-leaf-frontend/`): React 19 + Vite. Monaco Editor wired to LSP via a raw JSON-RPC WebSocket client (`src/lsp.ts`). Styling is **Tailwind v4** via the `@tailwindcss/vite` plugin (import with `@import "tailwindcss"`; there is no `tailwind.config.js`).
|
||||
* **Tauri v2** lives at `typst-leaf-frontend/src-tauri/`. It shells out to `pnpm dev`/`pnpm build` and serves `../dist`.
|
||||
* **Data plane:** `ws://localhost:4000/lsp` (LSP), `ws://localhost:4000/preview` (SVG stream).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user