{"id":50399313,"url":"https://github.com/typoverflow/typpy","last_synced_at":"2026-05-30T22:30:35.482Z","repository":{"id":357039228,"uuid":"1235030211","full_name":"typoverflow/typpy","owner":"typoverflow","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-11T03:59:55.000Z","size":811,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T04:33:32.356Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/typoverflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T00:11:18.000Z","updated_at":"2026-05-11T03:59:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/typoverflow/typpy","commit_stats":null,"previous_names":["typoverflow/typpy"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/typoverflow/typpy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typoverflow%2Ftyppy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typoverflow%2Ftyppy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typoverflow%2Ftyppy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typoverflow%2Ftyppy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typoverflow","download_url":"https://codeload.github.com/typoverflow/typpy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typoverflow%2Ftyppy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33712579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T22:30:32.209Z","updated_at":"2026-05-30T22:30:35.475Z","avatar_url":"https://github.com/typoverflow.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# typpy\n\nA lightweight, native macOS editor for [Hugo](https://gohugo.io) blogs. WYSIWYG markdown, on-the-fly image compression, built-in git, and a one-click Hugo dev server with side-by-side preview.\n\ntyppy is theme- and section-agnostic — it works on any Hugo project with a `content/` directory.\n\n\u003cbr /\u003e\n\n## Features\n\n- **WYSIWYG markdown editor** built on Tiptap. Tables, task lists, links, code blocks, headings — all rendered inline as you type. Embedded HTML (`\u003ccenter\u003e`, `\u003cfigure\u003e`, raw `\u003cimg\u003e`) is preserved verbatim on save.\n- **Live front-matter form** with image thumbnails. Auto-detects YAML or TOML. Add/remove fields without touching syntax.\n- **Drag-and-drop image import** with automatic compression. Camera-sized JPEGs get resized + re-encoded into your page bundle in one step; configurable max width / quality / format.\n- **Git integration** (pull / commit / push) that shells out to your existing `git` — uses your SSH keys, GPG signing, credentials. Visual file-checklist commit dialog.\n- **Hugo dev server** with a single click. Captures stdout/stderr into a resizable log panel so theme or module errors are visible. Side preview pane iframes the current post at the right URL.\n- **Orphan-aware port handling** — if `:1313` is held by a runaway hugo from a previous session, typpy detects it (by process name, never blindly), terminates it, and starts cleanly on the same port.\n- **Native `.app`** — ~4 MB binary, ~80 MB RAM idle, no Electron.\n\n\u003cbr /\u003e\n\n## Requirements\n\n- macOS 12 or later (Apple Silicon)\n- `hugo` on `PATH` — `brew install hugo`\n- `git` on `PATH`\n- `go` on `PATH` *only* if your Hugo site uses [Hugo Modules](https://gohugo.io/hugo-modules/) — `brew install go`\n\nTo build from source you also need:\n\n- [Rust](https://rustup.rs) (stable, 1.85+)\n- Node.js 20+ and npm\n\n\u003cbr /\u003e\n\n## Install (pre-built)\n\nDownload the latest `.dmg` from the [Releases](../../releases) page, drag `typpy.app` into `/Applications`, and open it.\n\nThe app is **not** signed or notarized. On first launch macOS will refuse to open it; right-click → Open, then confirm in the dialog. Alternatively: `xattr -d com.apple.quarantine /Applications/typpy.app`.\n\n\u003cbr /\u003e\n\n## Build from source\n\n```bash\ngit clone https://github.com/typoverflow/typpy.git\ncd typpy\nnpm install\nnpm run tauri build\n```\n\nArtifacts land in:\n\n- `src-tauri/target/release/bundle/macos/typpy.app`\n- `src-tauri/target/release/bundle/dmg/typpy_\u003cversion\u003e_aarch64.dmg`\n\n\u003cbr /\u003e\n\n## Develop\n\n```bash\nnpm run tauri dev\n```\n\nFirst start compiles Rust (~2 min); subsequent starts are fast (~5s).\n\nType-check without running:\n\n```bash\nnpx tsc --noEmit                 # frontend\ncd src-tauri \u0026\u0026 cargo check      # backend\n```\n\nSettings live at `~/Library/Application Support/io.gaocx.typpy/settings.json` — delete to reset to the welcome screen.\n\n\u003cbr /\u003e\n\n## Project layout\n\n```\ntyppy/\n├── src/                  React + TypeScript frontend\n│   ├── api/tauri.ts      Typed wrappers around Rust commands\n│   ├── components/       UI (Sidebar, Editor, TopBar, dialogs, etc.)\n│   ├── store/app.ts      Zustand store\n│   └── styles.css        Tailwind v4 + editor styles\n├── src-tauri/            Rust backend\n│   ├── src/\n│   │   ├── lib.rs        Tauri commands + invoke_handler\n│   │   ├── repo.rs       Hugo project detection + content tree\n│   │   ├── frontmatter.rs YAML/TOML front-matter split/join\n│   │   ├── imaging.rs    Image resize + re-encode\n│   │   ├── gitops.rs     Shell-out to `git`\n│   │   ├── hugo.rs       Hugo server lifecycle + orphan cleanup\n│   │   └── settings.rs   Persisted user prefs\n│   ├── capabilities/     Tauri permission scopes\n│   └── tauri.conf.json   App metadata + window config\n└── package.json\n```\n\n\u003cbr /\u003e\n\n## How it talks to your blog\n\ntyppy treats the Hugo project as the source of truth:\n\n- **Reads:** scans `content/` for sections (`post/`, `page/`, etc.) and page bundles (`section/slug/index.md` + co-located images). Front-matter is parsed (YAML or TOML) and shown as a structured form; the body is rendered in the WYSIWYG editor.\n- **Writes:** on save, typpy serializes the form back into the original front-matter format and writes the file. Existing YAML field order is preserved as much as possible; unknown fields pass through untouched.\n- **Images:** dropped/pasted images are compressed with the `image` crate, written into the bundle directory next to `index.md`, and referenced by a relative filename — exactly how Hugo expects.\n- **Git:** never auto-commits. The commit dialog shows you exactly what will be staged.\n\nThis means you can keep editing the same posts in vim or VS Code — typpy doesn't write anything outside the file you're editing.\n\n\u003cbr /\u003e\n\n## Roadmap / known limitations\n\n- Lossy WebP not supported yet (the `image` crate ships lossless WebP only). Use JPEG if you need small files.\n- No code-block syntax highlighting in the editor (works fine when previewed via Hugo).\n- `git pull` is `--ff-only`. Conflicts must be resolved in a terminal.\n- macOS Apple Silicon only for now. Tauri itself is cross-platform; cross-compile PRs welcome.\n\n\u003cbr /\u003e\n\n## Contributing\n\nBug reports and feature requests are welcome via Issues. For pull requests:\n\n1. Open an issue first if it's a non-trivial change, so we can agree on direction.\n2. Keep PRs scoped — one feature/fix per PR.\n3. Run `npx tsc --noEmit` and `cargo check` before pushing.\n\n\u003cbr /\u003e\n\n## License\n\n[MIT](./LICENSE) © 2026 typoverflow\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypoverflow%2Ftyppy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftypoverflow%2Ftyppy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypoverflow%2Ftyppy/lists"}