Skip to content

Commit f3cd522

Browse files
hyperpolymathclaude
andcommitted
feat: replace Tauri with Gossamer — gossamer-rs backend
Removed Tauri dependency entirely. formatrix-gui now uses gossamer-rs for webview lifecycle and IPC command dispatch. All 9 document commands (load, save, convert, parse, render, detect, get_formats, events) converted from #[tauri::command] async to sync gossamer-rs handlers. - Deleted build.rs (tauri_build) and tauri.conf.json - Removed @tauri-apps from deno.json imports - Converted async tokio::fs → sync std::fs in commands - CLAUDE.md and README updated: Tauri → Gossamer Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2a0b0a1 commit f3cd522

File tree

24 files changed

+542
-385
lines changed

24 files changed

+542
-385
lines changed

.claude/CLAUDE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Cross-platform document editor with format tabs, allowing users to view and edit
77
## Architecture
88

99
- **Core**: Rust library with unified AST for format conversion
10-
- **GUI**: Tauri 2.0 with ReScript frontend (not TypeScript!)
10+
- **GUI**: Gossamer (own webview shell) with ReScript frontend (not TypeScript!)
1111
- **TUI**: Ada with AdaCurses (matches git-hud pattern)
1212
- **Storage**: ArangoDB for graph + document hybrid
1313
- **Pipelines**: Nickel for import/export transformations
@@ -28,13 +28,14 @@ Cross-platform document editor with format tabs, allowing users to view and edit
2828
- Go (use Rust)
2929
- Python (not applicable here)
3030
- Makefiles (use justfile)
31+
- Tauri (use Gossamer)
3132

3233
## Key Directories
3334

3435
```
3536
crates/
3637
├── formatrix-core/ # AST, parsers, renderers
37-
├── formatrix-gui/ # Tauri commands
38+
├── formatrix-gui/ # Gossamer commands
3839
├── formatrix-db/ # ArangoDB client
3940
└── formatrix-pipeline/ # Nickel executor
4041

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ nickel-lang-core = "0.10"
4141
tesseract-rs = "0.3"
4242
vosk = "0.3"
4343

44-
# GUI framework
45-
tauri = { version = "2", features = [] }
46-
tauri-build = "2"
47-
4844
# Serialization
4945
serde = { version = "1.0", features = ["derive"] }
5046
serde_json = "1.0"

README.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ This project must declare **MPL-2.0-or-later** for platform/tooling compatibilit
1717

1818
Philosophy: **Palimpsest**. The Palimpsest-MPL (PMPL) text is provided in `license/PMPL-1.0.txt`, and the canonical source is the palimpsest-license repository.
1919

20-
Cross-platform document editor with format tabs (TXT/MD/ADOC/DJOT/ORG/RST/TYP). Tauri 2.0 GUI + Ada TUI. Graph visualization, OCR, TTS/STT, Nickel pipelines.
20+
Cross-platform document editor with format tabs (TXT/MD/ADOC/DJOT/ORG/RST/TYP). Gossamer GUI + Ada TUI. Graph visualization, OCR, TTS/STT, Nickel pipelines.
2121

2222
== Features
2323

2424
* *Format Tabs* - View and edit the same document in multiple markup formats
2525
* *Unified AST* - Lossless conversion between formats
26-
* *GUI* - Tauri 2.0 with ReScript frontend
26+
* *GUI* - Gossamer with ReScript frontend
2727
* *TUI* - Ada with AdaCurses for terminal usage
2828
* *Graph Visualization* - ArangoDB for document relationships
2929
* *Accessibility* - OCR, TTS, STT support
@@ -67,7 +67,7 @@ just run-tui
6767
----
6868
crates/
6969
├── formatrix-core/ # AST, parsers, renderers
70-
├── formatrix-gui/ # Tauri commands
70+
├── formatrix-gui/ # Gossamer commands
7171
├── formatrix-db/ # ArangoDB client
7272
└── formatrix-pipeline/ # Nickel executor
7373

crates/formatrix-core/src/ast.rs

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,21 @@ impl Block {
254254
match self {
255255
Block::Paragraph { content, .. } => content.iter().map(|i| i.word_count()).sum(),
256256
Block::Heading { content, .. } => content.iter().map(|i| i.word_count()).sum(),
257-
Block::CodeBlock { content, .. } => {
258-
content.split_whitespace().count()
259-
}
257+
Block::CodeBlock { content, .. } => content.split_whitespace().count(),
260258
Block::BlockQuote { content, .. } => content.iter().map(|b| b.word_count()).sum(),
261-
Block::List { items, .. } => {
262-
items.iter().flat_map(|i| &i.content).map(|b| b.word_count()).sum()
263-
}
259+
Block::List { items, .. } => items
260+
.iter()
261+
.flat_map(|i| &i.content)
262+
.map(|b| b.word_count())
263+
.sum(),
264264
Block::Container { content, .. } => content.iter().map(|b| b.word_count()).sum(),
265-
Block::Figure { content, caption, .. } => {
265+
Block::Figure {
266+
content, caption, ..
267+
} => {
266268
let content_count: usize = content.iter().map(|b| b.word_count()).sum();
267-
let caption_count: usize = caption.as_ref().map_or(0, |c| c.iter().map(|i| i.word_count()).sum());
269+
let caption_count: usize = caption
270+
.as_ref()
271+
.map_or(0, |c| c.iter().map(|i| i.word_count()).sum());
268272
content_count + caption_count
269273
}
270274
_ => 0,
@@ -278,9 +282,11 @@ impl Block {
278282
Block::Heading { content, .. } => content.iter().map(|i| i.char_count()).sum(),
279283
Block::CodeBlock { content, .. } => content.chars().count(),
280284
Block::BlockQuote { content, .. } => content.iter().map(|b| b.char_count()).sum(),
281-
Block::List { items, .. } => {
282-
items.iter().flat_map(|i| &i.content).map(|b| b.char_count()).sum()
283-
}
285+
Block::List { items, .. } => items
286+
.iter()
287+
.flat_map(|i| &i.content)
288+
.map(|b| b.char_count())
289+
.sum(),
284290
Block::Container { content, .. } => content.iter().map(|b| b.char_count()).sum(),
285291
_ => 0,
286292
}
@@ -385,10 +391,16 @@ pub enum Inline {
385391
SmallCaps { content: Vec<Inline> },
386392

387393
/// Inline code
388-
Code { content: String, language: Option<String> },
394+
Code {
395+
content: String,
396+
language: Option<String>,
397+
},
389398

390399
/// Inline math
391-
Math { content: String, notation: MathNotation },
400+
Math {
401+
content: String,
402+
notation: MathNotation,
403+
},
392404

393405
/// Hyperlink
394406
Link {
@@ -435,10 +447,16 @@ pub enum Inline {
435447
},
436448

437449
/// Raw inline content from source format
438-
RawInline { format: SourceFormat, content: String },
450+
RawInline {
451+
format: SourceFormat,
452+
content: String,
453+
},
439454

440455
/// Quoted text
441-
Quoted { quote_type: QuoteType, content: Vec<Inline> },
456+
Quoted {
457+
quote_type: QuoteType,
458+
content: Vec<Inline>,
459+
},
442460

443461
/// Keyboard input
444462
Keyboard { content: String },
@@ -574,21 +592,24 @@ mod proptests {
574592

575593
// Strategy for generating Paragraphs
576594
fn paragraph_strategy() -> impl Strategy<Value = Block> {
577-
prop::collection::vec(simple_inline_strategy(), 0..5).prop_map(|content| {
578-
Block::Paragraph { content, span: None }
595+
prop::collection::vec(simple_inline_strategy(), 0..5).prop_map(|content| Block::Paragraph {
596+
content,
597+
span: None,
579598
})
580599
}
581600

582601
// Strategy for generating Headings
583602
fn heading_strategy() -> impl Strategy<Value = Block> {
584-
(1u8..=6, prop::collection::vec(simple_inline_strategy(), 1..4)).prop_map(
585-
|(level, content)| Block::Heading {
603+
(
604+
1u8..=6,
605+
prop::collection::vec(simple_inline_strategy(), 1..4),
606+
)
607+
.prop_map(|(level, content)| Block::Heading {
586608
level,
587609
content,
588610
id: None,
589611
span: None,
590-
},
591-
)
612+
})
592613
}
593614

594615
// Strategy for generating CodeBlocks

crates/formatrix-core/src/ffi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,9 @@ pub unsafe extern "C" fn formatrix_open_file(
434434
match file_ops::open_file(path_str) {
435435
Ok(opened) => {
436436
*out_format = opened.file_info.format.into();
437-
let handle = Box::new(DocumentHandle { doc: opened.document });
437+
let handle = Box::new(DocumentHandle {
438+
doc: opened.document,
439+
});
438440
*out_handle = Box::into_raw(handle);
439441
FfiResult::Success
440442
}

crates/formatrix-core/src/file_ops.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ pub fn format_from_content(content: &str) -> SourceFormat {
127127
if trimmed.lines().any(|line| {
128128
let chars: Vec<char> = line.chars().collect();
129129
chars.len() > 3
130-
&& chars.iter().all(|&c| c == '=' || c == '-' || c == '~' || c == '^')
130+
&& chars
131+
.iter()
132+
.all(|&c| c == '=' || c == '-' || c == '~' || c == '^')
131133
}) {
132134
return SourceFormat::ReStructuredText;
133135
}
@@ -222,7 +224,11 @@ pub fn open_file_as(
222224
}
223225

224226
/// Parse content string to Document
225-
fn parse_content(content: &str, format: SourceFormat, config: &ParseConfig) -> FileResult<Document> {
227+
fn parse_content(
228+
content: &str,
229+
format: SourceFormat,
230+
config: &ParseConfig,
231+
) -> FileResult<Document> {
226232
let doc = match format {
227233
SourceFormat::PlainText => PlainTextHandler::new().parse(content, config)?,
228234
SourceFormat::Markdown => MarkdownHandler::new().parse(content, config)?,
@@ -276,7 +282,11 @@ pub fn save_file_as(
276282
}
277283

278284
/// Render document to string
279-
fn render_content(doc: &Document, format: SourceFormat, config: &RenderConfig) -> FileResult<String> {
285+
fn render_content(
286+
doc: &Document,
287+
format: SourceFormat,
288+
config: &RenderConfig,
289+
) -> FileResult<String> {
280290
let output = match format {
281291
SourceFormat::PlainText => PlainTextHandler::new().render(doc, config)?,
282292
SourceFormat::Markdown => MarkdownHandler::new().render(doc, config)?,
@@ -290,10 +300,7 @@ fn render_content(doc: &Document, format: SourceFormat, config: &RenderConfig) -
290300
}
291301

292302
/// Convert a file from one format to another
293-
pub fn convert_file(
294-
input_path: impl AsRef<Path>,
295-
output_path: impl AsRef<Path>,
296-
) -> FileResult<()> {
303+
pub fn convert_file(input_path: impl AsRef<Path>, output_path: impl AsRef<Path>) -> FileResult<()> {
297304
convert_file_with_config(
298305
input_path,
299306
output_path,
@@ -326,8 +333,23 @@ pub fn extension_for_format(format: SourceFormat) -> &'static str {
326333
/// Get all supported file extensions
327334
pub fn supported_extensions() -> &'static [&'static str] {
328335
&[
329-
"txt", "text", "md", "markdown", "mdown", "mkd", "adoc", "asciidoc", "asc", "dj", "djot",
330-
"org", "rst", "rest", "restructuredtext", "typ", "typst",
336+
"txt",
337+
"text",
338+
"md",
339+
"markdown",
340+
"mdown",
341+
"mkd",
342+
"adoc",
343+
"asciidoc",
344+
"asc",
345+
"dj",
346+
"djot",
347+
"org",
348+
"rst",
349+
"rest",
350+
"restructuredtext",
351+
"typ",
352+
"typst",
331353
]
332354
}
333355

0 commit comments

Comments
 (0)