Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: CI

on:
push:
pull_request:

jobs:
windows:
name: Windows Checks
runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 24
cache: npm

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown

- name: Install wasm-pack
uses: taiki-e/install-action@v2
with:
tool: wasm-pack@0.10.3

- name: Install npm dependencies
run: npm ci

- name: Dependency audit
run: npm audit

- name: Rebuild WASM package
run: npm run wasm:build

- name: Verify WASM package exists
run: |
if (-not (Test-Path src/lib/wasm/framesmith_runtime_wasm.js)) {
throw "Missing generated WASM JavaScript binding"
}
if (-not (Test-Path src/lib/wasm/framesmith_runtime_wasm.d.ts)) {
throw "Missing generated WASM TypeScript declarations"
}

- name: Refresh generated schemas
run: cargo run --manifest-path src-tauri/Cargo.toml --bin generate_schema

- name: Verify generated files are current
run: git diff --exit-code -- schemas/rules.schema.json

- name: Install Playwright browser
run: npx playwright install chromium

- name: TypeScript and Svelte check
run: npm run check

- name: Frontend and logic tests
run: npm run test:run

- name: Browser smoke tests
run: npm run test:e2e

- name: Build web frontend
run: npm run build

- name: Rust formatting
run: |
cargo fmt --check --manifest-path src-tauri/Cargo.toml
cargo fmt --check --manifest-path crates/framesmith-runtime/Cargo.toml
cargo fmt --check --manifest-path crates/framesmith-runtime-wasm/Cargo.toml
cargo fmt --check --manifest-path crates/framesmith-fspack/Cargo.toml

- name: Test Tauri backend
run: cargo test --manifest-path src-tauri/Cargo.toml

- name: Test runtime crate
run: cargo test --manifest-path crates/framesmith-runtime/Cargo.toml

- name: Build runtime WASM test fixture
run: cargo run --manifest-path src-tauri/Cargo.toml --bin framesmith-cli -- export --project . --character test_char --adapter fspk --out exports/test_char.fspk

- name: Test runtime WASM crate
run: cargo test --manifest-path crates/framesmith-runtime-wasm/Cargo.toml

- name: Test FSPK reader crate
run: cargo test --manifest-path crates/framesmith-fspack/Cargo.toml

- name: Clippy Tauri backend
run: cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings

- name: Clippy runtime crates
run: |
cargo clippy --manifest-path crates/framesmith-runtime/Cargo.toml --all-targets -- -D warnings
cargo clippy --manifest-path crates/framesmith-runtime-wasm/Cargo.toml --all-targets -- -D warnings
cargo clippy --manifest-path crates/framesmith-fspack/Cargo.toml --all-targets -- -D warnings

- name: Verify branch protection helper fixture
run: .\scripts\check-branch-protection.ps1 -ProtectionJsonPath tests\fixtures\github-branch-protection-main.json -RequirePullRequest

- name: Build Tauri app
run: npm run tauri build

- name: Verify Windows installer outputs
run: .\scripts\verify-windows-installer-artifacts.ps1 -Path src-tauri\target\release\bundle

- name: Upload Windows installers
uses: actions/upload-artifact@v4
with:
name: framesmith-windows-installers
path: |
src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/nsis/*setup.exe
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ node_modules
/build
/.svelte-kit
/package
/playwright-report
/test-results
.env
.env.*
!.env.example
Expand All @@ -13,4 +15,4 @@ vite.config.ts.timestamp-*
# Export output directory (keep .gitkeep)
/exports/*
!/exports/.gitkeep
nul
nul
5 changes: 2 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ framesmith/
README.md, design.md, data-formats.md, rules-spec.md,
zx-fspack.md, mcp-server.md, runtime-guide.md, runtime-api.md,
cli.md, global-states.md, character-authoring-guide.md,
movement-reference.md
plans/ # Implementation plans (removed when done)
movement-reference.md, implementation-history.md
```

## Task-Type Routing
Expand Down Expand Up @@ -157,7 +156,7 @@ npm run test:run # vitest (training, rendercore tests)
cargo run --bin mcp -- --characters-dir ../characters

# CLI export (from framesmith/src-tauri/)
cargo run --bin framesmith -- export --all --project .. --out-dir ../exports
cargo run --bin framesmith-cli -- export --project .. --all --out-dir ../exports
```

## Editor Views
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ It manages portable character data on disk (JSON) and exports runtime-specific f
- State editor with sprite and GLTF preview
- Cancel graph view for route visualization
- Rules system for defaults and validation
- Export adapters (`json-blob`, `zx-fspack`)
- Export adapters (`json-blob`, `fspk`)
- MCP server for scripted and LLM-assisted workflows

## Framesmith project format
Expand Down Expand Up @@ -73,7 +73,7 @@ See `docs/mcp-server.md` for tools, resources, and integration details.

```bash
cd src-tauri
cargo run --bin framesmith -- export --project .. --all --out-dir ../exports
cargo run --bin framesmith-cli -- export --project .. --all --out-dir ../exports
```

See `docs/cli.md` for full CLI reference.
Expand Down
2 changes: 1 addition & 1 deletion crates/framesmith-fspack/src/view/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl<'a> EventArgView<'a> {
if self.tag() != EVENT_ARG_TAG_I64 {
return None;
}
Some(read_i64_le(self.data, 12)?)
read_i64_le(self.data, 12)
}

pub fn value_f32(&self) -> Option<f32> {
Expand Down
9 changes: 5 additions & 4 deletions crates/framesmith-fspack/src/view/hitbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
use crate::bytes::{read_u16_le, read_u32_le, read_u8};
use crate::fixed::{Q12_4, Q8_8};

/// HitWindow record size (24 bytes)
pub const HIT_WINDOW_SIZE: usize = 24;
/// HitWindow record size (28 bytes)
pub const HIT_WINDOW_SIZE: usize = 28;

/// Shape record size (12 bytes)
pub const SHAPE_SIZE: usize = 12;
Expand All @@ -24,7 +24,7 @@ pub const SHAPE_KIND_CAPSULE: u8 = 3;

/// Zero-copy view over hit windows section.
///
/// Each entry is a HitWindow24 (24 bytes).
/// Each entry is a HitWindow28 (28 bytes).
#[derive(Clone, Copy)]
pub struct HitWindowsView<'a> {
data: &'a [u8],
Expand Down Expand Up @@ -74,7 +74,7 @@ impl<'a> HitWindowsView<'a> {
}
}

/// Zero-copy view over a single HitWindow24 record (24 bytes minimum).
/// Zero-copy view over a single HitWindow28 record.
///
/// Layout:
/// - 0: start_f (u8)
Expand All @@ -91,6 +91,7 @@ impl<'a> HitWindowsView<'a> {
/// - 16-17: shapes_len (u16)
/// - 18-21: cancels_off (u32)
/// - 22-23: cancels_len (u16)
///
/// Optional extended fields (backwards-compatible):
/// - 24-25: hit_pushback (i16, Q12.4 fixed-point)
/// - 26-27: block_pushback (i16, Q12.4 fixed-point)
Expand Down
6 changes: 3 additions & 3 deletions crates/framesmith-fspack/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub const SECTION_KEYFRAMES_KEYS: u32 = 3;
/// Array of StateRecord structs
pub const SECTION_STATES: u32 = 4;

/// Array of HitWindow24 structs
/// Array of HitWindow28 structs
pub const SECTION_HIT_WINDOWS: u32 = 5;

/// Array of HurtWindow12 structs
Expand Down Expand Up @@ -205,7 +205,7 @@ impl<'a> PackView<'a> {

// Parse section headers
let mut sections = [SectionInfo::default(); MAX_SECTIONS];
for i in 0..section_count {
for (i, section) in sections.iter_mut().enumerate().take(section_count) {
let header_offset = HEADER_SIZE + i * SECTION_HEADER_SIZE;

let kind = read_u32_le(bytes, header_offset).ok_or(Error::OutOfBounds)?;
Expand All @@ -221,7 +221,7 @@ impl<'a> PackView<'a> {
return Err(Error::OutOfBounds);
}

sections[i] = SectionInfo {
*section = SectionInfo {
kind,
offset,
len,
Expand Down
Loading
Loading