No description
  • TypeScript 47%
  • Svelte 31.6%
  • Lua 12.1%
  • Rust 8.8%
  • CSS 0.3%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Andrew Tyler c668e84177 ui: commit the .gitignore the sweep found untracked
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 12:32:25 -05:00
docs Plugin sandbox: close the pre-policy and redirect holes (#8) 2026-09-03 04:49:10 -05:00
plugins Rename: pane_editor scope -> layout_editor (ecosystem-wide migration) 2026-09-02 21:33:15 -05:00
src-tauri Plugin sandbox: close the pre-policy and redirect holes (#8) 2026-09-03 04:49:10 -05:00
ui ui: commit the .gitignore the sweep found untracked 2026-09-04 12:32:25 -05:00
.gitignore plugins: wasmoon Lua runtime, HttpBridge, manager + three stub source plugins 2026-08-23 15:35:57 -05:00
package-lock.json build: commit lockfiles (root package-lock.json, src-tauri Cargo.lock) 2026-08-23 15:25:44 -05:00
package.json tauri: scaffold Tauri 2 shell with plugin_http bridge 2026-08-23 15:25:20 -05:00
README.md Rename: pane_editor scope -> layout_editor (ecosystem-wide migration) 2026-09-02 21:33:15 -05:00
SPEC.md Plugin sandbox: close the pre-policy and redirect holes (#8) 2026-09-03 04:49:10 -05:00
TODO.md Traced-logo round-trip hardening + grouped results (#7) 2026-08-30 23:02:13 -05:00

kreeader-metadata-manager

A metadata-review app for GCD / Metron maintainers: browse, fix, and add comic-issue metadata entries across sources, side by side. All data access is plugin-driven — each source (GCD, Metron, kreeader) is a Lua plugin (run via wasmoon in the webview) that defines that service's HTTP calls and column schema. The same UI runs in a plain browser or as a Tauri 2 desktop app; the desktop shell adds a native HTTP bridge so plugin requests are not subject to webview CORS. See SPEC.md for the full design.

Prerequisites

  • Node.js 20+ and npm — the UI (Vite + Svelte 5 + TypeScript).
  • Rust (stable, via rustup) — only needed for the Tauri desktop app.
  • Linux desktop builds additionally need the Tauri system deps: webkit2gtk-4.1, gtk3, and the usual build tools. See Tauri prerequisites.

Install JS deps once in each package:

npm install            # repo root: @tauri-apps/cli
npm --prefix ui install

Browser dev (quickest)

npm --prefix ui run dev     # or: npm run dev

Open http://localhost:5173. Everything works in the browser, including the Lua plugin runtime.

Tauri desktop app

npm run tauri:dev      # dev window against the Vite dev server
npm run tauri:build    # release binary (npx tauri build --no-bundle)

tauri:build produces the binary under src-tauri/target/release/. Always build through the Tauri CLI, never bare cargo build — the CLI enables the custom-protocol feature and builds the frontend first; a bare cargo build produces an app with no embedded frontend.

Rust-side unit tests (the plugin_http bridge):

cargo test --manifest-path src-tauri/Cargo.toml

Plugins

Lua plugin sources live in plugins/ (gcd.lua, metron.lua, kreeader.lua) and are copied into ui/public/plugins/ at build time, then fetched at runtime — they are not bundled. The runtime accepts additional plugin source text, but the current UI does not expose add, enable, or disable controls.

Plugin files are copied wholesale from plugins/ into ui/public/plugins/ by ui/scripts/copy-plugins.mjs, which runs from the predev, prebuild and pretest hooks — a new .lua file is picked up with no build change. It does need an entry in plugins/index.json, which is the manifest the app fetches to know what to load.

A plugin may also declare settings (non-secret values it cannot hard-code, such as a server URL, read with host.setting(name) and edited under Settings → Plugin settings) and optional capabilities. The only optional capability today is the traced-logo group — logo_propose, logo_trace_save, logo_trace_search, logo_search_results — which drives the lasso logo tracer in the entry modal. A source whose plugin does not implement them does not get the feature, rather than getting a button that fails; see SPEC.md for the shapes and docs/USER-GUIDE.md for what it does. The server half is merged on kreeader-server master (b2830d8, kreeader-server#150): /api/comics/{id}/logotrace, /logopropose and /api/logos/search. Against an older server every call says so — the server stamps X-Kreeader-Logo-Trace: 1 on every traced-logo response, so "this build does not have the feature" is never confused with "no such comic". Traced-logo calls also require the layout_editor scope on whatever credential you configure.

Tests

npm --prefix ui test        # vitest: geometry, plugin runtime, matching, covers
npm --prefix ui run check   # svelte-check + tsc

Both must pass before a push, along with npm run build. vite build does not typecheck modules nothing imports yet, so check is not optional.

Plugin HTTP: browser vs. desktop

  • Tauri app: plugin HTTP goes through the native plugin_http command (reqwest in the Rust shell), so requests are not subject to webview CORS.
  • Browser mode: plugin HTTP uses plain fetch, so it is subject to CORS. For sources that don't send permissive CORS headers, run the app behind a dev proxy (e.g. a Vite server.proxy entry or any reverse proxy that forwards to the source API) — CORS setup is the deployer's concern.

kreeader-server specifically

The manager cannot fix this from the client side, so it is written down here rather than discovered. kreeader-server routes every endpoint through its CORS middleware, which emits Access-Control-Allow-Origin and answers preflight OPTIONS — but only for the origin named in its own config:

[server]
cors_origin = "http://localhost:5173"

Set it to the origin the manager is actually served from (the Vite dev server above, or wherever the built app is hosted). With cors_origin unset — the default — the browser blocks every response before the app sees it, which surfaces as a send failure with no HTTP status rather than as an error from the server.

No such setting is needed for the desktop app: its requests go through the Rust plugin_http bridge, which is not a browser.

A cross-origin response exposes only the CORS-safelisted headers to JavaScript, so a browser can only read X-Kreeader-Logo-Trace at all because kreeader-server's CORS middleware lists it in Access-Control-Expose-Headers (ff5e335 and later). If a genuine 404 reads as "this server has no traced-logo endpoints" against a server you believe is current, that means one of: an old server (before ff5e335), a proxy stripping the header, or cors_origin not naming this app's origin — not a limitation of a current server. The desktop build reads every header regardless and is unaffected by any of this.