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 +88 -0
- package/bin/flare +18 -0
- package/package.json +17 -0
- package/scripts/install.js +108 -0
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();
|