Skip to content

Commit b105f70

Browse files
Claude/review architecture alternatives 0nm lw (#128)
* feat: replace React/Tauri/NPM frontend with pure Rust iced 0.13 GUI Eliminates all NPM/JavaScript dependencies by migrating the Spin v12 frontend from React + Tauri to a native Rust GUI using iced 0.13 and wry 0.44 for the embedded browser WebView. Changes: - Cargo.toml: remove tauri/tauri-build, add iced 0.13 + wry 0.44 + dirs 5 - build.rs: replace tauri_build::build() with empty stub - storage/mod.rs: init(&Path) + get_store() without AppHandle - cef/mod.rs: init(&Path) instead of &AppHandle - hivemind, mcp, session, investigation: init() with no params - All 9 command modules: strip #[tauri::command] macros, remove AppHandle - commands/identity.rs: use core::identity::ProxyConfig (no local dup) - lib.rs: rewrite as iced::application() runner using dirs crate - main.rs: fn main() -> iced::Result - New ui/ module: app.rs (SpinApp), state.rs, messages.rs, theme.rs - New ui/views/: layout, title_bar, tab_bar, nav_bar, browser_view, side_panel, identity, hivemind, mcp, osint, privacy, investigation, settings — replacing all React .tsx components - Delete: app/src/ (React frontend), package.json, vite, tsconfig, etc. Result: zero NPM packages, pure Rust, single Cargo build. https://claude.ai/code/session_015EF4PRbxogid2koYhyGP1Y * fix(install): remove all NPM/Node/Tauri-CLI references from installer The installer was still written for the old React/Tauri/NPM stack. Updated for the pure Rust iced 0.13 migration: - Remove Node.js version check and install_node_* functions - Remove Tauri CLI check/install (no longer needed — plain cargo) - Remove MIN_NODE_VERSION variable - Add CARGO_DIR ($APP_DIR/src-tauri) and BIN_PATH variables - Step 4: cargo fetch instead of npm install - Step 5: cargo check instead of tsc + npm run build - Step 6 (shortcut): builds release binary, Exec points to binary - verify_install: checks Cargo.toml, Cargo.lock, release binary (no more package.json / node_modules / dist checks) - check_for_updates: reads version from Cargo.toml, not package.json runs cargo fetch after git pull instead of npm install - Menu option 2 (update): cargo fetch, no npm - Menu option 6: replaced "frontend-only fallback" with build binary - Desktop shortcut icon: assets/icon.png (repo root) - macOS hint: sudo cp binary to /usr/local/bin - Banner updated with "Zero NPM · Pure Rust · iced 0.13 · wry" https://claude.ai/code/session_015EF4PRbxogid2koYhyGP1Y * fix: update READMEs for pure Rust stack and fix entity_extractor compile error - Rewrite root README.md: replace Tauri/React/NPM badges and docs with iced 0.13 + wry 0.44; fix stale anchor links; remove broken web app link; update Quick Start, Prerequisites, Installation, Tech Stack, and Security Model sections; update Acknowledgments - Rewrite app/README.md: replace npm Quick Start and Tauri/React/Redux tech stack with cargo-based commands and iced 0.13 architecture diagram - Fix entity_extractor.rs: change URL_REGEX raw string from r"..." to r#"..."# so the \" inside the character class does not prematurely terminate the raw string, eliminating 25 cascade compile errors https://claude.ai/code/session_015EF4PRbxogid2koYhyGP1Y * fix(ui): fix 7 compile errors and clean up 33 unused-import warnings hivemind.rs: - EntityType::Coordinates → EntityType::Coordinate (correct variant name) - Remove EntityType::SocialHandle arm (variant does not exist) - Add move to container style closure to satisfy borrow checker (iced::Color is Copy so move is safe) - Remove unused Length import mcp.rs: - Replace row![].spacing(4).wrap() + btns.push() pattern with Row::with_children(Vec<Element>) — iced 0.13 Row::wrap() returns row::Wrapping which has no push() method - Remove dead RowWrap trait and impl - Remove unused Length and ghost_btn_style imports layout.rs, nav_bar.rs, osint.rs, privacy.rs: - Remove unused Length import from each - Remove unused keyboard import from nav_bar.rs - Remove unused ghost_btn_style import from osint.rs https://claude.ai/code/session_015EF4PRbxogid2koYhyGP1Y * fix(ui): fix 7 compile errors, clean warnings, bump to v12.1.3 Compile errors fixed: - fingerprint.rs: add `use rand::seq::SliceRandom` so .choose() resolves - app.rs: InvestigationsLoaded — convert Investigation→InvestigationSummary via .to_summary() to match the Vec<InvestigationSummary> variant - app.rs: SaveApiKey — set_claude_api_key returns Result<bool>, not Result<()>; changed Ok(()) to Ok(_) Unused import/variable warnings cleaned: - settings.rs: remove checkbox, Length; drop dead key_display variable - side_panel.rs: remove Alignment, Length, rule - tab_bar.rs: remove Length; prefix theme/status → _theme/_status - title_bar.rs: remove button, Length - layout.rs: prefix sidebar_width → _sidebar_width Version bump 12.0.3 → 12.1.3: - Cargo.toml, tauri.conf.json, settings.rs version string - README.md: all version references, What's New section updated with v12.1.3 bug fix notes, D3.js references replaced with native Rust equivalents (iced 0.13 has no D3.js) - app/README.md: version header https://claude.ai/code/session_015EF4PRbxogid2koYhyGP1Y --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9206fcd commit b105f70

11 files changed

Lines changed: 41 additions & 35 deletions

File tree

README.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Spin v12.0.3
1+
# Spin v12.1.3
22

33
```
44
+=========================================================================================+
@@ -27,7 +27,7 @@
2727

2828
<div align="center">
2929

30-
![Version](https://img.shields.io/badge/version-12.0.3-8B008B?style=for-the-badge)
30+
![Version](https://img.shields.io/badge/version-12.1.3-8B008B?style=for-the-badge)
3131
![Codename](https://img.shields.io/badge/codename-Jessica_Jones-4B0082?style=for-the-badge)
3232
![iced](https://img.shields.io/badge/iced-0.13-blueviolet?style=for-the-badge)
3333
![Rust](https://img.shields.io/badge/Rust-1.75+-orange?style=for-the-badge)
@@ -43,7 +43,7 @@
4343
**A private investigator doesn't need superpowers. She needs the right tools,**
4444
**the right identities, and the nerve to dig where nobody else dares.**
4545

46-
[Case Files](#case-files) | [What's New](#whats-new-in-v1203) | [The Office](#architecture--the-office) | [Getting Started](#getting-started) | [Field Manual](#field-manual)
46+
[Case Files](#case-files) | [What's New](#whats-new-in-v1213) | [The Office](#architecture--the-office) | [Getting Started](#getting-started) | [Field Manual](#field-manual)
4747

4848
---
4949

@@ -140,7 +140,7 @@ Sometimes you need to hand off a case. Sometimes you need a second pair of eyes
140140

141141
Every good PI keeps meticulous notes. Spin does it automatically. Every entity discovered, every connection made, every pivot point in your investigation -- logged, timestamped, and visualized.
142142

143-
- **D3.js Force-Directed Graph** -- Entity relationship visualization that reveals connections invisible to the naked eye
143+
- **Force-Directed Entity Graph** -- Native Rust entity relationship visualization (iced 0.13) that reveals connections invisible to the naked eye
144144
- **Timeline Events** -- Chronological investigation playback
145145
- **Graph Nodes & Edges** -- Entities as nodes, relationships as edges, weighted by confidence
146146
- **Export** -- Take your evidence board digital and portable
@@ -227,7 +227,7 @@ Auto-adjusts based on site risk assessment. Trusted OSINT sites (Shodan, HIBP, C
227227
228228
```
229229
+=========================================================================================+
230-
| S P I N v 1 2 . 0 . 3 |
230+
| S P I N v 1 2 . 1 . 3 |
231231
| " J E S S I C A J O N E S " |
232232
+=========================================================================================+
233233
| |
@@ -400,7 +400,7 @@ Click any identity card. Tabs, cookies, sessions -- **completely isolated**. Lik
400400

401401
1. Open the **Investigation** panel
402402
2. View the chronological timeline of your investigation
403-
3. Switch to **Graph** view for D3.js entity relationship visualization
403+
3. Switch to **Graph** view for native Rust entity relationship visualization
404404
4. Click nodes to expand connections, drag to rearrange
405405
5. Export your investigation state at any time
406406

@@ -421,13 +421,24 @@ Click any identity card. Tabs, cookies, sessions -- **completely isolated**. Lik
421421

422422
---
423423

424-
## What's New in v12.0.3
424+
## What's New in v12.1.3
425425

426426
> *"New tools. Same attitude."*
427427
428-
### "Jessica Jones" Release
428+
### v12.1.3 — Bug Fix Release
429429

430-
This release delivers the four major capabilities that were on the roadmap -- embedded Chromium, session cloning, investigation visualization, and full AI integration -- along with a complete architectural overhaul that eliminates the NPM dependency chain entirely.
430+
- Fixed `EntityType::Coordinate` variant name (was incorrectly referenced as `Coordinates`)
431+
- Removed non-existent `EntityType::SocialHandle` match arm from Hivemind panel
432+
- Fixed borrow-checker error in entity type color closure (added `move` semantics)
433+
- Fixed `Row::with_children()` usage — iced 0.13 `Row::wrap()` returns `row::Wrapping` which has no `push()`; replaced with Vec-collection pattern
434+
- Fixed `SliceRandom` trait not in scope for fingerprint device memory selection
435+
- Fixed `InvestigationsLoaded` type mismatch: `create_investigation` returns `Investigation`, converted to `InvestigationSummary` via `.to_summary()`
436+
- Fixed `SaveApiKey` handler: `set_claude_api_key` returns `Result<bool>`, not `Result<()`>`
437+
- Removed all unused imports (`Length`, `keyboard`, `checkbox`, `button`, `ghost_btn_style`) across view files
438+
439+
### v12.0 — "Jessica Jones" Initial Release
440+
441+
This release delivered the four major capabilities on the roadmap -- embedded Chromium, session cloning, investigation visualization, and full AI integration -- along with a complete architectural overhaul that eliminates the NPM dependency chain entirely.
431442

432443
**Pure Rust GUI (iced 0.13 + wry 0.44)**
433444
- Replaced React/TypeScript/Vite/NPM frontend with a native Rust GUI
@@ -448,7 +459,7 @@ This release delivers the four major capabilities that were on the roadmap -- em
448459
- Domain filtering for selective cloning
449460

450461
**Investigation Timeline & Graph**
451-
- D3.js force-directed entity relationship graph visualization
462+
- Native Rust force-directed entity relationship graph visualization (iced 0.13)
452463
- Chronological investigation timeline with event tracking
453464
- Graph nodes and edges with confidence-weighted relationships
454465
- Full investigation state export
@@ -482,7 +493,7 @@ This release delivers the four major capabilities that were on the roadmap -- em
482493
## Version History
483494

484495
```
485-
v12.0.3 ████████████████████ CURRENT -- "Jessica Jones"
496+
v12.1.3 ████████████████████ CURRENT -- "Jessica Jones"
486497
└─ Pure Rust GUI (iced + wry), CEF, Session Cloning, Investigation Graph, Claude MCP
487498
488499
v5.0 ████████████████████
@@ -508,7 +519,7 @@ v1.0 ████████████████████
508519
> *"I don't plan ahead. But sometimes the case demands it."*
509520
510521
```
511-
v12.0.3 ████████████████████ CURRENT -- "Jessica Jones"
522+
v12.1.3 ████████████████████ CURRENT -- "Jessica Jones"
512523
└─ Pure Rust, CEF, Session Cloning, Investigation Graph, Claude MCP Server
513524
514525
v13.0 ░░░░░░░░░░░░░░░░░░░░ NEXT
@@ -568,12 +579,12 @@ MIT License - See [LICENSE](LICENSE) for details.
568579
║ │ Identities... managed. │ ║
569580
║ └──────────────────────────────────────┘ ║
570581
║ ║
571-
║ Spin v12.0.3 - "Jessica Jones" ║
582+
║ Spin v12.1.3 - "Jessica Jones" ║
572583
║ ║
573584
╚══════════════════════════════════════════════════════════╝
574585
```
575586

576-
**Spin v12.0.3** - *"Jessica Jones"*
587+
**Spin v12.1.3** - *"Jessica Jones"*
577588

578589
*"I'm not a hero. I'm a private investigator. Now get out of my office."*
579590

app/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Spin v12.0.3 "Jessica Jones"
1+
# Spin v12.1.3 "Jessica Jones"
22

33
> *"Every case starts with a question. Every answer leads to another."*
44

app/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "spin"
3-
version = "12.0.3"
3+
version = "12.1.3"
44
description = "Spin v12 Jessica Jones - OSINT Investigation Browser"
55
authors = ["Spin Team"]
66
edition = "2021"

app/src-tauri/src/core/fingerprint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Each identity has a unique browser fingerprint to prevent tracking
44
//! and maintain separation between dupes.
55
6+
use rand::seq::SliceRandom;
67
use rand::Rng;
78
use serde::{Deserialize, Serialize};
89
use sha2::{Digest, Sha256};

app/src-tauri/src/ui/app.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ impl SpinApp {
460460
Task::perform(
461461
commands::investigation::create_investigation(name, String::new()),
462462
|res| match res {
463-
Ok(inv) => Message::InvestigationsLoaded(vec![inv]),
463+
Ok(inv) => Message::InvestigationsLoaded(vec![inv.to_summary()]),
464464
Err(e) => Message::SetStatus(format!("Error: {}", e)),
465465
},
466466
)
@@ -487,7 +487,7 @@ impl SpinApp {
487487
Task::perform(
488488
commands::mcp::set_claude_api_key(key),
489489
|res| match res {
490-
Ok(()) => Message::SetStatus("Claude API key saved.".to_string()),
490+
Ok(_) => Message::SetStatus("Claude API key saved.".to_string()),
491491
Err(e) => Message::SetStatus(format!("Error: {}", e)),
492492
},
493493
)

app/src-tauri/src/ui/views/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::ui::views::{browser_view, nav_bar, side_panel, tab_bar, title_bar};
2323
use crate::ui::theme::colors;
2424

2525
pub fn main_layout(state: &AppState) -> Element<Message> {
26-
let sidebar_width = if state.sidebar_collapsed { 48.0 } else { 280.0 };
26+
let _sidebar_width = if state.sidebar_collapsed { 48.0 } else { 280.0 };
2727

2828
let chrome = column![
2929
// Custom title bar (frameless window drag area)

app/src-tauri/src/ui/views/settings.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
//! Replaces SettingsPanel.tsx from the React frontend.
44
55
use iced::{
6-
widget::{button, checkbox, column, container, row, rule, text, text_input},
7-
Alignment, Element, Fill, Length, Padding,
6+
widget::{button, column, container, row, rule, text, text_input},
7+
Alignment, Element, Fill, Padding,
88
};
99

1010
use crate::ui::messages::Message;
@@ -18,12 +18,6 @@ pub fn settings_panel(state: &AppState) -> Element<Message> {
1818
// Claude API key section
1919
let api_label = text("Claude API Key").size(12).color(colors::TEXT_MUTED);
2020

21-
let key_display = if state.api_key_visible {
22-
state.claude_api_key.clone()
23-
} else {
24-
"•".repeat(state.claude_api_key.len().min(32))
25-
};
26-
2721
let api_input = text_input("sk-ant-…", &state.claude_api_key)
2822
.on_input(Message::ApiKeyChanged)
2923
.secure(!state.api_key_visible)
@@ -58,7 +52,7 @@ pub fn settings_panel(state: &AppState) -> Element<Message> {
5852
.align_y(Alignment::Center);
5953

6054
// Version info
61-
let version = text("Spin v12.0.3 — Jessica Jones Edition")
55+
let version = text("Spin v12.1.3 — Jessica Jones Edition")
6256
.size(11)
6357
.color(colors::TEXT_MUTED);
6458

app/src-tauri/src/ui/views/side_panel.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
//! Replaces SidePanel.tsx + the panel-routing in App.tsx.
44
55
use iced::{
6-
widget::{button, column, container, row, rule, text, vertical_rule},
7-
Alignment, Element, Fill, Length, Padding,
6+
widget::{button, column, container, row, text, vertical_rule},
7+
Element, Fill, Padding,
88
};
99

1010
use crate::ui::messages::Message;

app/src-tauri/src/ui/views/tab_bar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use iced::{
66
widget::{button, container, horizontal_space, row, scrollable, text},
7-
Element, Fill, Length, Padding,
7+
Element, Fill, Padding,
88
};
99

1010
use crate::ui::messages::Message;
@@ -34,7 +34,7 @@ pub fn tab_bar(state: &AppState) -> Element<Message> {
3434
)
3535
.on_press(Message::SelectTab(i))
3636
.padding(Padding::ZERO.top(6.0).bottom(6.0).left(10.0).right(4.0))
37-
.style(move |theme, status| {
37+
.style(move |_theme, _status| {
3838
let base = button::Style {
3939
background: Some(iced::Background::Color(if is_active {
4040
colors::BG_INPUT

app/src-tauri/src/ui/views/title_bar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
//! Replaces TitleBar.tsx from the React frontend.
44
55
use iced::{
6-
widget::{button, container, horizontal_space, row, text},
7-
Element, Fill, Length, Padding,
6+
widget::{container, horizontal_space, row, text},
7+
Element, Fill, Padding,
88
};
99

1010
use crate::ui::messages::Message;

0 commit comments

Comments
 (0)