Repository navigation
kite 0.1.0
The first release of Kite: a single program that gives a Markdown blog a studio in the browser, and publishes it as a static site or runs it on a server.
Highlights
- Start in the browser. Run
kite runin an empty folder. The browser opens on a page that asks what the site is called, and then you are in the studio. - A studio for writing. A visual editor that reads and writes Markdown, with the source a click away; image uploads, categories and tags, drafts, scheduled posts, pages, and a preview drawn by the site's own theme.
- Your files stay yours. Content is plain Markdown on disk. Saving rewrites only what changed and keeps key order and comments, so editing a title is a one-line diff. Front matter is YAML or TOML, as Hugo writes it, and
kite doctor --fix-idsbrings the posts of a Hugo site in. - Publish your way. Export the site as a zip for any static host; deploy it to GitHub Pages with the workflow Kite writes, which also publishes scheduled posts when they fall due; commit and push with the built-in Git publisher; or run the site on a server with Docker.
- Themes. A default theme with light and dark modes and settings in the studio. Install another from a zip, try it on the whole site before switching, and give pages templates of their own.
- Plugins. A plugin adds code to pages, or runs WebAssembly in a sandbox while the site is built. The official ones: Analytics, Comments, Math and Diagrams and Search.
- One account. Sign in with a password on a server, or use the studio without one on your own computer.
Install
Download the archive for your system below, unpack it, put kite somewhere on your PATH, and run kite run in an empty folder. On macOS, xattr -d com.apple.quarantine kite lets a downloaded program run the first time.
To run a site on a server with Docker:
docker run -d --name kite --restart unless-stopped -p 127.0.0.1:1717:1717 -v kite-data:/data ghcr.io/kite-plus/kite:0.1.0Every archive can be checked against checksums.txt, and a given commit builds to the same binary on any machine.
Notes
Kite is in early development, and things may still change from one version to the next. The reference covers the studio, themes, plugins, configuration and deployment.
Every change in this release
Changelog
Features
- 895a068: feat(admin): a settings page the theme fills in (Amigoer i@amigoer.com)
- f4acd96: feat(admin): add a deploy page with a zip export (Amigoer i@amigoer.com)
- 325bca1: feat(admin): add a trash and keep unsaved edits (Amigoer i@amigoer.com)
- d40468f: feat(admin): add the account page and user menu (Amigoer i@amigoer.com)
- 71a8041: feat(admin): choose, install and customize themes (Amigoer i@amigoer.com)
- 76529be: feat(admin): collapsible rail and an account menu (Amigoer i@amigoer.com)
- 8ec27c5: feat(admin): color every status by its state (Amigoer i@amigoer.com)
- 75b56cd: feat(admin): complete the generated forms (Amigoer i@amigoer.com)
- 503c531: feat(admin): complete the site settings (Amigoer i@amigoer.com)
- 478b271: feat(admin): create a new site on the setup page (Amigoer i@amigoer.com)
- be613fd: feat(admin): cycle the theme with one click (Amigoer i@amigoer.com)
- d4fcdaa: feat(admin): drop the second settings menu (Amigoer i@amigoer.com)
- fbe92f2: feat(admin): filter the list by status in the toolbar (Amigoer i@amigoer.com)
- 9f6e1cb: feat(admin): give each term a color of its own (Amigoer i@amigoer.com)
- c721a86: feat(admin): head the dashboard with four states (Amigoer i@amigoer.com)
- 4aa5ca9: feat(admin): head the rail with the site, not a menu (Amigoer i@amigoer.com)
- 64c08eb: feat(admin): invite a first item on an empty list (Amigoer i@amigoer.com)
- 86a797c: feat(admin): lay out setup like the sign-in page (Amigoer i@amigoer.com)
- 1ce873e: feat(admin): lay terms out as cards (Amigoer i@amigoer.com)
- a6ef375: feat(admin): list categories and tags on pages of their own (Amigoer i@amigoer.com)
- 1a04dc2: feat(admin): manage plugins (Amigoer i@amigoer.com)
- dc2efb5: feat(admin): match the design mock exactly (Amigoer i@amigoer.com)
- fe75c29: feat(admin): name the tab after the page and site (Amigoer i@amigoer.com)
- 8fea817: feat(admin): open a list row from anywhere on it (Amigoer i@amigoer.com)
- 8fac8c4: feat(admin): open an existing project in a real UI (Amigoer i@amigoer.com)
- 1fea3f9: feat(admin): pick a page's template in the editor (Amigoer i@amigoer.com)
- 46a8cc0: feat(admin): pick dates from a calendar (Amigoer i@amigoer.com)
- c88a8bd: feat(admin): publish settings and themes (Amigoer i@amigoer.com)
- 7ae4fdd: feat(admin): rebuild the studio on shadcn-admin (Amigoer i@amigoer.com)
- 84fc129: feat(admin): rebuild the studio to the new design (Amigoer i@amigoer.com)
- 950f754: feat(admin): redraw the dashboard to the new mock (Amigoer i@amigoer.com)
- ec6971d: feat(admin): rename, merge and delete terms (Amigoer i@amigoer.com)
- 3a8b618: feat(admin): set the dashboard on one grid (Amigoer i@amigoer.com)
- 134084d: feat(admin): show a failed page inside the layout (Amigoer i@amigoer.com)
- 3cd1a0e: feat(admin): show pinned posts in the list (Amigoer i@amigoer.com)
- 66a0d9f: feat(admin): speak the operator's language (Amigoer i@amigoer.com)
- 1ca44aa: feat(admin): style toasts by state (Amigoer i@amigoer.com)
- 0e3a58b: feat(admin): use a light canvas and a blue accent (Amigoer i@amigoer.com)
- 587dbd1: feat(admin): write from the browser (Amigoer i@amigoer.com)
- bc7e40a: feat(api): accept writes through the change set (Amigoer i@amigoer.com)
- 0af640f: feat(api): configure the site and its theme (Amigoer i@amigoer.com)
- ceb4fef: feat(api): count a draft's words as its page will (Amigoer i@amigoer.com)
- ff4ffbb: feat(api): describe the API from the code that serves it (Amigoer i@amigoer.com)
- 8b17466: feat(api): export the site as a zip archive (Amigoer i@amigoer.com)
- fcdfc45: feat(api): install, list and set up plugins (Amigoer i@amigoer.com)
- 9953195: feat(api): list, install, remove and switch themes (Amigoer i@amigoer.com)
- 703fa0b: feat(api): rename, merge and remove taxonomy terms (Amigoer i@amigoer.com)
- f8b26bc: feat(api): render previews and store dropped files (Amigoer i@amigoer.com)
- 02e07cc: feat(api): serve the read model over HTTP (Amigoer i@amigoer.com)
- c1307bd: feat(api): turn a plugin on or off (Amigoer i@amigoer.com)
- 4935272: feat(auth): ask for a sign-in before the studio (Amigoer i@amigoer.com)
- 8c35920: feat(auth): implement local account management and session handling (Amigoer i@amigoer.com)
- 0839338: feat(auth): let the studio manage its own account (Amigoer i@amigoer.com)
- 63690cf: feat(build): add the static build engine (Amigoer i@amigoer.com)
- 188f938: feat(build): tell hooks each page's kind and text (Amigoer i@amigoer.com)
- 69240b3: feat(cli): add index and list commands (Amigoer i@amigoer.com)
- b76e509: feat(cli): add init, new, doctor and version commands (Amigoer i@amigoer.com)
- 2aa97fa: feat(cli): add kite build with reproducibility checking (Amigoer i@amigoer.com)
- 1f07c5e: feat(cli): add kite theme verify (Amigoer i@amigoer.com)
- f6aceb3: feat(cli): add plugin commands (Amigoer i@amigoer.com)
- ad64d54: feat(cli): add serve and run commands (Amigoer i@amigoer.com)
- b2f6007: feat(cli): let kite run create a site in a browser (Amigoer i@amigoer.com)
- ad6793b: feat(cli): manage the studio account from a shell (Amigoer i@amigoer.com)
- a4af320: feat(cli): publish scheduled posts on static sites (Amigoer i@amigoer.com)
- b1fdeeb: feat(content): add domain model and change set (Amigoer i@amigoer.com)
- 4ece8a4: feat(docker): add an image and a compose file (Amigoer i@amigoer.com)
- 43faa18: feat(editor): darken and enlarge toolbar buttons (Amigoer i@amigoer.com)
- c6cca48: feat(editor): give the preview a bar of its own (Amigoer i@amigoer.com)
- 4737c65: feat(editor): offer plain text in the heading menu (Amigoer i@amigoer.com)
- 9161e5e: feat(editor): put more tools on the toolbar (Amigoer i@amigoer.com)
- 13fc8d0: feat(editor): rule off the details panel sections (Amigoer i@amigoer.com)
- adc6fba: feat(editor): scroll editor and preview together (Amigoer i@amigoer.com)
- 2a64dbf: feat(editor): set the article in 16px (Amigoer i@amigoer.com)
- 364ea1a: feat(editor): show shortcuts in toolbar tooltips (Amigoer i@amigoer.com)
- 2e02059: feat(editor): show statuses with their icons and colors (Amigoer i@amigoer.com)
- 6c4bc21: feat(editor): size a new table on a grid (Amigoer i@amigoer.com)
- 00c1294: feat(editor): switch to the tiptap simple editor (Amigoer i@amigoer.com)
- ca32947: feat(editor): use arrows between title and body (Amigoer i@amigoer.com)
- 68341ce: feat(editor): write with tiptap, keep markdown (Amigoer i@amigoer.com)
- 7d71fa1: feat(frontmatter): add fidelity-preserving yaml codec (Amigoer i@amigoer.com)
- 3d618b2: feat(frontmatter): edit a config file without disturbing it (Amigoer i@amigoer.com)
- d9a0712: feat(frontmatter): read and edit TOML front matter (Amigoer i@amigoer.com)
- 750ed6c: feat(hook): add the extension bus and built-in hooks (Amigoer i@amigoer.com)
- 96ef6a0: feat(index): add the derived read model (Amigoer i@amigoer.com)
- 02c889e: feat(plugin): compile a module before enabling it (Amigoer i@amigoer.com)
- d863d61: feat(plugin): declare the hosts a plugin uses (Amigoer i@amigoer.com)
- 3e0c269: feat(plugin): inject code and publish plugin files (Amigoer i@amigoer.com)
- 693fc8d: feat(plugin): run build hooks from wasm modules (Amigoer i@amigoer.com)
- 9f63ff2: feat(plugin): skip injected code by front matter (Amigoer i@amigoer.com)
- a93b8ca: feat(publish): a publish button, and somewhere for it to go (Amigoer i@amigoer.com)
- ecf1f25: feat(publish): commit content without disturbing the repository (Amigoer i@amigoer.com)
- 4fd0b94: feat(publish): publish past a refusing hook (Amigoer i@amigoer.com)
- 4b3c00b: feat(publish): rebase onto a remote that moved on (Amigoer i@amigoer.com)
- e668a73: feat(publish): refuse a file the host will not take (Amigoer i@amigoer.com)
- 1ac4d9a: feat(publish): report GitHub Pages deployments (Amigoer i@amigoer.com)
- ba71d26: feat(reader): add the single content reader (Amigoer i@amigoer.com)
- 73f0286: feat(render): add the markdown pipeline (Amigoer i@amigoer.com)
- f1a1517: feat(render): add the url resolver and theme data contract (Amigoer i@amigoer.com)
- 9378570: feat(schema): add sections and read values by type (Amigoer i@amigoer.com)
- f9e7e0a: feat(serve): preview a theme on the whole site (Amigoer i@amigoer.com)
- fd89f70: feat(serve): render the site per request from the files (Amigoer i@amigoer.com)
- 2910097: feat(settings): remove a setting written as null (Amigoer i@amigoer.com)
- 23bf89f: feat(setup): guide the first run of a project (Amigoer i@amigoer.com)
- fbd5e00: feat(setup): install without a setup token (Amigoer i@amigoer.com)
- 97ce213: feat(setup): say when a password is right, not only when it is wrong (Amigoer i@amigoer.com)
- 09e61e1: feat(site): add keywords, time zone and site code (Amigoer i@amigoer.com)
- 699cabc: feat(site): list installed themes and try variants (Amigoer i@amigoer.com)
- 43ddad9: feat(store): add file-backed content store (Amigoer i@amigoer.com)
- 385eb87: feat(store): install and remove themes (Amigoer i@amigoer.com)
- 1b9bf71: feat(theme): add the theme engine and default theme (Amigoer i@amigoer.com)
- c494307: feat(theme): arrange the default theme's settings (Amigoer i@amigoer.com)
- f34e8f3: feat(theme): credit the site in the footer (Amigoer i@amigoer.com)
- 25ff0b9: feat(theme): let a page choose a layout the theme offers (Amigoer i@amigoer.com)
- f39d195: feat(theme): offer a links page in the default theme (Amigoer i@amigoer.com)
- b8e154b: feat(theme): read language packs and screenshots (Amigoer i@amigoer.com)
- 8df152f: feat(theme): redraw the default theme (Amigoer i@amigoer.com)
- e07efc4: feat(theme): refuse a theme made for another Kite (Amigoer i@amigoer.com)
- 961bee4: feat(theme): write the site's metadata into pages (Amigoer i@amigoer.com)
Fixes
- 787bee8: fix(admin): call the account holder the owner (Amigoer i@amigoer.com)
- 20becfa: fix(admin): choose a site language rather than type one (Amigoer i@amigoer.com)
- 7c6616b: fix(admin): darken the text colors (Amigoer i@amigoer.com)
- 729d529: fix(admin): date published items and show undated ones (Amigoer i@amigoer.com)
- c1a7f24: fix(admin): drop the gray page background (Amigoer i@amigoer.com)
- f057fcd: fix(admin): keep the cover picker inside the page (Amigoer i@amigoer.com)
- e8c0997: fix(admin): keep the editor title large on phones (Amigoer i@amigoer.com)
- e19577e: fix(admin): offer a reload when settings fail to load (Amigoer i@amigoer.com)
- 13dacee: fix(admin): plain stat cards that add up (Amigoer i@amigoer.com)
- dff353d: fix(admin): report an unreachable server (Amigoer i@amigoer.com)
- 088f0b5: fix(admin): show root-named images under a path (Amigoer i@amigoer.com)
- 58235ad: fix(admin): show the first row's top border (Amigoer i@amigoer.com)
- 786c6e0: fix(api): leave unset times out and list file times (Amigoer i@amigoer.com)
- 133c5ad: fix(auth): time a guess's delay from its refusal (Amigoer i@amigoer.com)
- a5f9c93: fix(build): hold back published posts dated later (Amigoer i@amigoer.com)
- 26200b0: fix(build): list items through the markdown hooks (Amigoer i@amigoer.com)
- b57faa0: fix(build): publish scheduled posts only when due (Amigoer i@amigoer.com)
- 653d0d8: fix(build): publish the files a page bundle owns (Amigoer i@amigoer.com)
- fc0faac: fix(build): title every kind of page deliberately (Amigoer i@amigoer.com)
- d49529d: fix(ci): point pnpm setup at web/package.json (Amigoer i@amigoer.com)
- 923f85f: fix(cli): build Pages sites for the Pages address (Amigoer i@amigoer.com)
- bfbd450: fix(content): name built-in taxonomies in the plural (Amigoer i@amigoer.com)
- ad70326: fix(editor): a click is not an edit (Amigoer i@amigoer.com)
- 4079978: fix(editor): draw task checkboxes like the admin's (Amigoer i@amigoer.com)
- 7f9c43e: fix(editor): keep markdown tables as written (Amigoer i@amigoer.com)
- a6e6c8b: fix(editor): let input methods keep their keys (Amigoer i@amigoer.com)
- dbedc00: fix(editor): let the toolbar end reach the edge (Amigoer i@amigoer.com)
- 84479d9: fix(editor): say a new item is not saved yet (Amigoer i@amigoer.com)
- c80fa00: fix(editor): show the word count the site shows (Amigoer i@amigoer.com)
- a0427bf: fix(editor): translate the quote button's tooltip (Amigoer i@amigoer.com)
- 7e844be: fix(frontmatter): compose edits within one section (Amigoer i@amigoer.com)
- 5c090df: fix(index): refuse two files claiming one id (Amigoer i@amigoer.com)
- 64f21f6: fix(index): roll back one refused file, not the whole pass (Amigoer i@amigoer.com)
- 1d2b396: fix(index): summarize prose instead of truncating markdown (Amigoer i@amigoer.com)
- cf79b00: fix(index): summarize with the markdown parser (Amigoer i@amigoer.com)
- c03eea5: fix(publish): carry plugins like themes (Amigoer i@amigoer.com)
- 68f4f2b: fix(publish): make hook refusals portable (Amigoer i@amigoer.com)
- 26fe1ef: fix(render): count lists, headings and tables (Amigoer i@amigoer.com)
- a562289: fix(render): put the site's path before body links (Amigoer i@amigoer.com)
- 6448767: fix(render): read escapes in plain text as written (Amigoer i@amigoer.com)
- d3644bf: fix(serve): answer for the feed and the sitemap (Amigoer i@amigoer.com)
- 54b6bf2: fix(serve): draw with templates as they are now (Amigoer i@amigoer.com)
- cfd0700: fix(serve): reload templates of a linked theme (Amigoer i@amigoer.com)
- eac6534: fix(serve): stop open pages from reloading forever (Amigoer i@amigoer.com)
- 34889bb: fix(store): lay the body out on the file's behalf (Amigoer i@amigoer.com)
- 92f4bc2: fix(store): settle a taken slug before writing the file (Amigoer i@amigoer.com)
- 9ca3b7e: fix(theme): make code blocks legible in dark mode (Amigoer i@amigoer.com)
- 32804a1: fix(url): honor the path in the base url (Amigoer i@amigoer.com)
- ce484bb: fix: compare go.mod before and after tidy, not against HEAD (Amigoer i@amigoer.com)
- 8ecce1a: fix: resolve every lint finding (Amigoer i@amigoer.com)
Performance
- 1ba94c4: perf: meet the latency targets for 2000 posts (Amigoer i@amigoer.com)
Refactors
- 3da49de: refactor(admin): build the studio on shadcn/ui (Amigoer i@amigoer.com)
- 349090f: refactor(build): let a caller plan and render one target (Amigoer i@amigoer.com)
- d104924: refactor(store): split scanning into walk and load (Amigoer i@amigoer.com)
- cb33c88: refactor(theme): share packs and version ranges (Amigoer i@amigoer.com)
Documentation
- b3e77f2: docs(design): add architecture and subsystem design (Amigoer i@amigoer.com)
- 7bb8e17: docs(design): bring the roadmap summary up to date (Amigoer i@amigoer.com)
- 045a5e4: docs(design): drop the theme-sdk repository (Amigoer i@amigoer.com)
- 6fbf75b: docs(design): give each theme its own repository (Amigoer i@amigoer.com)
- e9ceb9c: docs(design): mark theme install and strings done (Amigoer i@amigoer.com)
- 0d2cbd5: docs(design): record the admin's explore-style changes (Amigoer i@amigoer.com)
- 5403d81: docs(design): record the website and publish check (Amigoer i@amigoer.com)
- db387c2: docs(design): rename the research repo to lab (Amigoer i@amigoer.com)
- e17b44d: docs(readme): add overview, diagram, and roadmap (Amigoer i@amigoer.com)
- 78814dd: docs(readme): bring both readmes up to date (Amigoer i@amigoer.com)
- a57c273: docs(readme): describe the studio sign-in (Amigoer i@amigoer.com)
- cf2df3c: docs(readme): install from the release download (Amigoer i@amigoer.com)
- 03f6358: docs(readme): mention plugins (Amigoer i@amigoer.com)
- 15beb3d: docs(readme): simplify getting started and move detailed guides (Amigoer i@amigoer.com)
- faa22d9: docs: add a roadmap with verified status (Amigoer i@amigoer.com)
- 30d0827: docs: add readme (Amigoer i@amigoer.com)
- 25d1569: docs: add the logo to the readme (Amigoer i@amigoer.com)
- 6950544: docs: describe installing and switching themes (Amigoer i@amigoer.com)
- f0ea051: docs: describe managing the account in the studio (Amigoer i@amigoer.com)
- 81118c1: docs: describe plugins and their build hooks (Amigoer i@amigoer.com)
- de75e52: docs: describe starting in a browser and exporting (Amigoer i@amigoer.com)
- ab7f8d5: docs: describe the site settings (Amigoer i@amigoer.com)
- 2892ccd: docs: describe the visual editor (Amigoer i@amigoer.com)
- 6195d86: docs: drop multi-user from the plan (Amigoer i@amigoer.com)
- 21c2dca: docs: let the two deployments differ in features (Amigoer i@amigoer.com)
- 0956ebe: docs: license the project under Apache-2.0 (Amigoer i@amigoer.com)
- 1278892: docs: mark the editing admin done (Amigoer i@amigoer.com)
- b4a9e9b: docs: name 0.1 as the first release (Amigoer i@amigoer.com)
- 18e551f: docs: plan the first version of plugins (Amigoer i@amigoer.com)
- cb708b8: docs: record serve, run and the admin (Amigoer i@amigoer.com)
- f0a581f: docs: rewrite the readme and add a Chinese one (Amigoer i@amigoer.com)
Other
- c51a6ee: chore(admin): proxy the whole site in development (Amigoer i@amigoer.com)
- 67093d0: chore(cli): pin the workflows to current actions (Amigoer i@amigoer.com)
- 1298dbb: chore(release): ship the manual in the archives (Amigoer i@amigoer.com)
- 94a0a58: style(store): fix a misspelling in a comment (Amigoer i@amigoer.com)
- d396c9a: test(auth): skip the permission check on windows (Amigoer i@amigoer.com)
- 86e7e26: test(index): stop the racy timestamp test depending on machine speed (Amigoer i@amigoer.com)
- 577feeb: test(plugin): give only the endless module 200ms (Amigoer i@amigoer.com)
Install
Download the archive for your platform, or pin the version in a project
so that local builds and CI agree:
./kitew build
Verify a download against checksums.txt before running it.