{"id":51161686,"url":"https://github.com/hasparus/loudmouth-looter","last_synced_at":"2026-06-26T14:30:43.368Z","repository":{"id":363323539,"uuid":"1262812054","full_name":"hasparus/loudmouth-looter","owner":"hasparus","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-22T13:54:31.000Z","size":121456,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T15:29:06.038Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hasparus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-08T10:47:47.000Z","updated_at":"2026-06-22T10:20:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hasparus/loudmouth-looter","commit_stats":null,"previous_names":["hasparus/loudmouth-looter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hasparus/loudmouth-looter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasparus%2Floudmouth-looter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasparus%2Floudmouth-looter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasparus%2Floudmouth-looter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasparus%2Floudmouth-looter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hasparus","download_url":"https://codeload.github.com/hasparus/loudmouth-looter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasparus%2Floudmouth-looter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34821764,"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-06-26T02:00:06.560Z","response_time":106,"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-06-26T14:30:42.561Z","updated_at":"2026-06-26T14:30:43.360Z","avatar_url":"https://github.com/hasparus.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# loudmouth-looter\n\nPersonal site with a rich-text MDX editor, live at [lol.haspar.us]. Scaffolded\nfrom [zaduma], an Astro starter for understated personal websites.\n\n[lol.haspar.us]: https://lol.haspar.us\n[zaduma]: https://github.com/hasparus/zaduma\n\n## Quick start\n\n```sh\nbun install\ncp .env.example .env.local   # fill in OG_IMAGE_SECRET (placeholder is fine locally)\nbun run dev                  # → http://localhost:4321\n# open http://localhost:4321/editor to try the MDX editor\n```\n\n## The editor\n\n`/editor` is a contenteditable React island backed by the File System Access\nAPI. Open a `.mdx` post, edit, save. Nothing hits a server.\n\n- **Slash menu**: type `/squares 4` (or `/circles`, `/rhombs`) to insert a Track\n  atom; `/arrow` and `/chevron` insert marker lines. Move cards are authored as\n  `\u003cMove\u003e` blocks in MDX.\n- **GFM tasks**: type `- [ ] ` to start an interactive task list.\n- **Track props**: `value` (static fill), `defaultValue` (interactive,\n  ephemeral), `max` (1–12). `value` beats `defaultValue`.\n- Atoms render identically in the editor and on published pages via the shared\n  stylesheet `src/editor/editor-atoms.css`.\n\n## Commands\n\n| Command             | Action                                                                               |\n| :------------------ | :----------------------------------------------------------------------------------- |\n| `bun run dev`       | Dev server at `localhost:4321`                                                       |\n| `bun run build`     | Production build to `./dist/` (needs `OG_IMAGE_SECRET`)                              |\n| `bun run preview`   | Preview the production build locally                                                 |\n| `bun run lint`      | ESLint (zero warnings allowed)                                                       |\n| `bun run typecheck` | `astro check` + two `tsc` passes (Solid + React)                                     |\n| `bun run format`    | Prettier write                                                                       |\n| `bun run ci`        | lint + prettier check (local pre-push gate; CI runs lint/typecheck/tests separately) |\n| `bun test src`      | Unit tests (always scope to `src`; bare `bun test` runs Playwright too)              |\n| `bun run test`      | Playwright e2e (requires `bun run build` first)                                      |\n\n## Project structure\n\n```\nposts/              MDX blog posts\npublic/             static assets\nsrc/\n  build-time/       remark/rehype plugins\n  editor/           React 19 rich-text editor (File System Access API)\n  global-styles/    fonts, body, prose\n  layouts/          BaseLayout.astro, PostLayout.astro\n  lib/              shared utils and UI components (SolidJS)\n  pages/            Astro routes\napi/                Vercel serverless functions\ne2e/                Playwright visual-regression + e2e tests\n```\n\n## Deploying\n\nCI (`/.github/workflows/ci.yml`) runs lint → typecheck → unit tests → build →\ne2e → Vercel deploy → Lighthouse.\n\nSecrets required in GitHub Actions:\n\n| Secret              | Purpose                              |\n| :------------------ | :----------------------------------- |\n| `OG_IMAGE_SECRET`   | Signs OG image URLs                  |\n| `VERCEL_TOKEN`      | Deploy gate (`HAS_VERCEL` condition) |\n| `VERCEL_ORG_ID`     | Vercel org                           |\n| `VERCEL_PROJECT_ID` | Vercel project                       |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasparus%2Floudmouth-looter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhasparus%2Floudmouth-looter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasparus%2Floudmouth-looter/lists"}