flare-md 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Flare
2
+
3
+ Fast, themeable markdown viewer. Opens `.md` files in a native window with syntax highlighting, a table of contents sidebar, and live reload.
4
+
5
+ Built with [Tauri v2](https://v2.tauri.app/) and Rust.
6
+
7
+ ## Install
8
+
9
+ ### Installer (Windows)
10
+
11
+ Download the latest `.msi` or `.exe` installer from [Releases](https://github.com/GBX-Group/flare/releases).
12
+
13
+ ### npm
14
+
15
+ ```bash
16
+ npm install -g github:GBX-Group/flare
17
+ ```
18
+
19
+ Requires read access to the repo. Downloads a pre-built binary automatically.
20
+
21
+ ### Build from source
22
+
23
+ Requires [Rust](https://rustup.rs/) and the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/).
24
+
25
+ ```bash
26
+ git clone https://github.com/GBX-Group/flare.git
27
+ cd flare/src-tauri
28
+ cargo build --release
29
+ ```
30
+
31
+ Binary output: `src-tauri/target/release/flare.exe`
32
+
33
+ ## Usage
34
+
35
+ ```
36
+ flare <FILE> [--theme <THEME>]
37
+ ```
38
+
39
+ ```bash
40
+ flare README.md
41
+ flare docs/SPEC.md --theme github-light
42
+ ```
43
+
44
+ ## Themes
45
+
46
+ Three built-in themes, switchable from the dropdown in the sidebar:
47
+
48
+ | Theme | Description |
49
+ |-------|-------------|
50
+ | `github-dark` | GitHub dark mode (default) |
51
+ | `github-light` | GitHub light mode |
52
+ | `tokyo-night` | Tokyo Night color scheme |
53
+
54
+ Theme selection persists across sessions via localStorage.
55
+
56
+ ## Features
57
+
58
+ - **Native window** - lightweight Tauri/WebView2 app, not a browser tab
59
+ - **Table of contents** - auto-generated sidebar from headings
60
+ - **Live reload** - file watcher updates the view on save
61
+ - **Theme switching** - three themes, switchable at runtime
62
+ - **Syntax highlighting** - fenced code blocks with language classes
63
+ - **Small binary** - ~3 MB installer
64
+
65
+ ## Project Structure
66
+
67
+ ```
68
+ flare/
69
+ ├── src-tauri/ # Tauri + Rust application
70
+ │ ├── src/
71
+ │ │ ├── main.rs # CLI entry point (clap)
72
+ │ │ ├── lib.rs # Tauri setup, HTML gen, file watcher
73
+ │ │ ├── markdown.rs # Markdown-to-HTML renderer (pulldown-cmark)
74
+ │ │ ├── themes.rs # Embedded CSS themes
75
+ │ │ └── toc.rs # Table of contents generator
76
+ │ ├── icons/ # App icons (all sizes)
77
+ │ ├── Cargo.toml # Rust dependencies
78
+ │ └── tauri.conf.json # Tauri configuration
79
+ ├── bin/ # Node shim for npm install
80
+ ├── scripts/ # npm postinstall (binary download)
81
+ ├── docs/ # Spec and design docs
82
+ ├── package.json # npm package config
83
+ └── README.md
84
+ ```
85
+
86
+ ## License
87
+
88
+ Unlicensed. Internal use.
package/bin/flare ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require("child_process");
3
+ const path = require("path");
4
+
5
+ const ext = process.platform === "win32" ? ".exe" : "";
6
+ const binary = path.join(__dirname, `flare${ext}`);
7
+
8
+ const child = spawn(binary, process.argv.slice(2), {
9
+ detached: true,
10
+ stdio: "ignore",
11
+ });
12
+
13
+ child.on("error", (err) => {
14
+ console.error("flare: failed to launch:", err.message);
15
+ process.exit(1);
16
+ });
17
+
18
+ child.unref();
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "flare-md",
3
+ "version": "0.2.2",
4
+ "description": "Fast, themeable markdown viewer",
5
+ "repository": "github:GBX-Group/flare",
6
+ "license": "UNLICENSED",
7
+ "files": [
8
+ "bin/",
9
+ "scripts/"
10
+ ],
11
+ "bin": {
12
+ "flare": "bin/flare"
13
+ },
14
+ "scripts": {
15
+ "postinstall": "node scripts/install.js"
16
+ }
17
+ }
@@ -0,0 +1,108 @@
1
+ const https = require("https");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const { execSync } = require("child_process");
5
+
6
+ const VERSION = "0.2.2";
7
+ const REPO = "GBX-Group/flare";
8
+ const BIN_DIR = path.join(__dirname, "..", "bin");
9
+
10
+ const PLATFORM_MAP = {
11
+ "win32-x64": `Flare_${VERSION}_x64-setup.exe`,
12
+ };
13
+
14
+ // For now we only support Windows x64 (GBX standard)
15
+ // The installer approach doesn't work well for npm - just download the raw exe
16
+ const BINARY_NAME = process.platform === "win32" ? "flare.exe" : "flare";
17
+ const BINARY_PATH = path.join(BIN_DIR, BINARY_NAME);
18
+
19
+ function getDownloadUrl() {
20
+ // Download the raw exe from the release, not the installer
21
+ return `https://github.com/${REPO}/releases/download/v${VERSION}/flare-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`;
22
+ }
23
+
24
+ function download(url, dest) {
25
+ return new Promise((resolve, reject) => {
26
+ const follow = (url) => {
27
+ https
28
+ .get(url, { headers: { "User-Agent": "flare-installer" } }, (res) => {
29
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
30
+ follow(res.headers.location);
31
+ return;
32
+ }
33
+ if (res.statusCode !== 200) {
34
+ reject(new Error(`Download failed: HTTP ${res.statusCode} from ${url}`));
35
+ return;
36
+ }
37
+ const file = fs.createWriteStream(dest);
38
+ res.pipe(file);
39
+ file.on("finish", () => {
40
+ file.close();
41
+ resolve();
42
+ });
43
+ })
44
+ .on("error", reject);
45
+ };
46
+ follow(url);
47
+ });
48
+ }
49
+
50
+ async function main() {
51
+ const assetName = `flare-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`;
52
+
53
+ if (!fs.existsSync(BIN_DIR)) {
54
+ fs.mkdirSync(BIN_DIR, { recursive: true });
55
+ }
56
+
57
+ // Method 1: gh CLI (handles private repo auth)
58
+ try {
59
+ execSync("gh --version", { stdio: "ignore" });
60
+ console.log(`Flare: downloading binary via gh CLI...`);
61
+ execSync(
62
+ `gh release download v${VERSION} --repo ${REPO} --pattern "${assetName}" --output "${BINARY_PATH}" --clobber`,
63
+ { stdio: "inherit" }
64
+ );
65
+ if (process.platform !== "win32") {
66
+ fs.chmodSync(BINARY_PATH, 0o755);
67
+ }
68
+ console.log("Flare: installed successfully!");
69
+ return;
70
+ } catch (err) {
71
+ console.log("Flare: gh CLI download failed, trying direct HTTPS...");
72
+ }
73
+
74
+ // Method 2: Direct HTTPS (works for public repos)
75
+ try {
76
+ const releaseUrl = getDownloadUrl();
77
+ console.log(`Flare: downloading binary for ${process.platform}-${process.arch}...`);
78
+ await download(releaseUrl, BINARY_PATH);
79
+ if (process.platform !== "win32") {
80
+ fs.chmodSync(BINARY_PATH, 0o755);
81
+ }
82
+ console.log("Flare: installed successfully!");
83
+ return;
84
+ } catch (err) {
85
+ console.log(`Flare: HTTPS download failed (${err.message})`);
86
+ console.log("Flare: attempting to build from source...");
87
+ }
88
+
89
+ // Method 3: Build from source
90
+ try {
91
+ execSync("cargo --version", { stdio: "ignore" });
92
+ console.log("Flare: building from source with cargo...");
93
+ const tauriSrc = path.join(__dirname, "..", "src-tauri");
94
+ execSync("cargo build --release", { cwd: tauriSrc, stdio: "inherit" });
95
+ const builtBinary = path.join(tauriSrc, "target", "release", BINARY_NAME);
96
+ fs.copyFileSync(builtBinary, BINARY_PATH);
97
+ if (process.platform !== "win32") {
98
+ fs.chmodSync(BINARY_PATH, 0o755);
99
+ }
100
+ console.log("Flare: built and installed successfully!");
101
+ } catch (e) {
102
+ console.error("Flare: could not install. Download manually from:");
103
+ console.error(` https://github.com/${REPO}/releases/tag/v${VERSION}`);
104
+ process.exit(1);
105
+ }
106
+ }
107
+
108
+ main();