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
3 changes: 2 additions & 1 deletion .agents/skills/fusion-coding-standards/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ When you add behavior:

- Stage **individual files only**. Never `git add .` / `git add -A`.
- Only commit when the user asks.

- **Commit messages** follow [Conventional Commits](https://www.conventionalcommits.org/): `<type>(optional-scope): <summary>`. Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`, `release`. Optional hook (no npm): `git config core.hooksPath .githooks` → `.githooks/commit-msg`.
- Editor defaults: `.editorconfig` (LF, UTF-8, language-specific indent).
## Docs & skills hygiene

After introducing something agents or developers must know later:
Expand Down
41 changes: 41 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# EditorConfig — https://editorconfig.org
# Keep editors aligned across Rust, Python, Node, C#, and repo docs.

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{js,mjs,cjs,ts,tsx,jsx,json,yml,yaml}]
indent_size = 2

[*.{cs,csproj,props,targets}]
indent_size = 4

[*.{rs,toml}]
indent_size = 4

[*.py]
indent_size = 4
max_line_length = 100

[*.md]
trim_trailing_whitespace = false
indent_size = 2

[*.html]
indent_size = 2

[*.{css,scss}]
indent_size = 2

[Makefile]
indent_style = tab

[*.sh]
indent_size = 2
57 changes: 57 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env sh
# Validate Conventional Commits without Node/npm.
# Enable once per clone: git config core.hooksPath .githooks
#
# Format: <type>(optional-scope)!: <summary>
# Types: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|release

msg_file="$1"
if [ -z "$msg_file" ] || [ ! -f "$msg_file" ]; then
echo "commit-msg: missing commit message file" >&2
exit 1
fi

# First non-comment, non-empty line is the subject.
subject=$(
grep -v '^#' "$msg_file" | sed '/^[[:space:]]*$/d' | head -n 1
)

if [ -z "$subject" ]; then
echo "commit-msg: empty commit subject" >&2
exit 1
fi

# Allow merge / revert subjects produced by git itself.
case "$subject" in
Merge\ *|Revert\ *)
exit 0
;;
esac

pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|release)(\([a-z0-9._/-]+\))?(!)?: .+'

if ! printf '%s\n' "$subject" | grep -Eq "$pattern"; then
cat >&2 <<'EOF'
commit-msg: subject must follow Conventional Commits

<type>(optional-scope): <summary>

Examples:
feat(cache): add get_or_set helper
fix(node): restore swagger navbar versions
docs: expand root README install section
chore(release): bump to 2.0.2

Types: feat fix docs style refactor perf test build ci chore revert release
EOF
exit 1
fi

# Soft limit: keep the subject scannable in git log.
len=$(printf '%s' "$subject" | wc -c | tr -d ' ')
if [ "$len" -gt 100 ]; then
echo "commit-msg: subject is ${len} chars (max 100)" >&2
exit 1
fi

exit 0
121 changes: 121 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Fusion Framework

Class-based HTTP APIs with one shared Rust core and first-class bindings for **Python**, **Node.js**, and **C#**. Routes, middleware, OpenAPI/Swagger, cache, templates, and background tasks share the same semantics across languages — write once in `fusion-core`, expose through each binding.

| | |
|---|---|
| **Docs** | [fusion.cipherunit.xyz](https://fusion.cipherunit.xyz/) |
| **CLI / scaffolds** | [cipherunits/fusion-tool](https://github.com/cipherunits/fusion-tool) |
| **License** | [BSD 3-Clause](LICENSE) |
| **Version** | `2.0.1` |

## Why this repo

Most multi-language frameworks drift: each binding invents its own router rules and OpenAPI shapes. Fusion keeps shared behavior in Rust (`crates/fusion-core`) and thin glue in each language, so `api/[module]/{id}`, versioned Swagger, and middleware chains stay aligned.

## Install (applications)

Use published packages for app projects. Scaffold with Fusion Tool when you want a full project tree:

```bash
# CLI
# https://github.com/cipherunits/fusion-tool
fusion init --lang python --name my-app # or node / csharp
```

| Language | Package |
|----------|---------|
| Python | `pip install fusion-framework` |
| Node.js | `npm install fusion-framework` |
| C# | `dotnet add package Fusion-Framework` |

Binding-specific quick starts live next to the packages:

- [Python](crates/fusion-py/README.md)
- [Node](crates/fusion-node/README.md)
- [C#](bindings/csharp/FusionFramework/README.md)

## Repository layout

```text
crates/fusion-core/ Shared Rust: routing, HTTP, cache, templates, tasks
crates/fusion-py/ Python (PyO3) + fusion_framework package
crates/fusion-node/ Node (N-API) package published as fusion-framework
crates/fusion-ffi/ C ABI used by the C# binding
bindings/csharp/ Managed C# API (NuGet: Fusion-Framework)
examples/ Side-by-side demos (.py / .mjs / .cs)
tests/ Executable tests (not inside installable packages)
scripts/ Dev install + version bump helpers
.agents/skills/ Agent skills for contributors working in this repo
```

## Develop from source

Prerequisites: Rust (stable), Python 3.9+, Node 18+, .NET SDK matching the C# target (`net10.0`).

From the repo root:

```bash
./scripts/dev-install-python.sh --create-venv # or --venv .venv
./scripts/dev-install-node.sh
./scripts/dev-install-csharp.sh
# or all three:
./scripts/dev-install-all.sh
```

Details: [scripts/README.md](scripts/README.md).

### Tests

```bash
./tests/scripts/run-all.sh
```

Per binding and layout notes: [tests/README.md](tests/README.md).

### Examples

Runnable samples under `examples/` mirror public APIs across languages (routing, cache, middleware, templates, static files, and more). Prefer adding a trio (`.py` / `.mjs` / `.cs`) when you introduce a new cross-binding feature.

## Contributing

### Cross-binding parity

If a feature is user-facing in one binding (routes, middleware, permissions, settings, Swagger, UI helpers, …), implement it in **Python, Node, and C#** in the same change set unless the change is explicitly scoped. Put shared semantics in `fusion-core` first.

### Commit messages

Use [Conventional Commits](https://www.conventionalcommits.org/):

```text
<type>(optional-scope): <short summary>

feat(cache): add get_or_set helper
fix(node): restore swagger navbar versions
docs: expand root README install section
chore(release): bump to 2.0.2
```

Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`, `release`.

Optional local check (POSIX shell, no npm):

```bash
git config core.hooksPath .githooks
```

That installs [`.githooks/commit-msg`](.githooks/commit-msg). Editor defaults: [`.editorconfig`](.editorconfig).
### Staging

Stage files by path (`git add path/to/file`). Do not use `git add .` / `git add -A` in this repository.

## Links

- Site & docs: https://fusion.cipherunit.xyz/
- Issues: https://github.com/cipherunits/fusion-framework/issues
- Fusion Tool (CLI): https://github.com/cipherunits/fusion-tool
- Author: [CipherUnits](https://cipherunit.xyz)

## License

BSD 3-Clause. See [LICENSE](LICENSE).