Building and contributing
SpaceKnife is an MIT-licensed project on GitHub: DuskXi/SpaceKnife. Every kind of help counts: trying it on your machine and reporting what breaks, translating, writing documentation and writing code.
What you need
Section titled “What you need”- uv. It installs and manages Python 3.12 for the workspace.
- Node.js 22 with pnpm, for the Electron app. The website needs Node.js 22.12 or later.
- A Rust toolchain, for the native extension (the fast folder walker and the MFT reader). It is optional for development: without it every native path falls back to Python, and scans are several times slower. The installers require it.
Run from source
Section titled “Run from source”git clone https://github.com/DuskXi/SpaceKnife.gitcd SpaceKnifeuv sync --group nativepnpm -C apps/electron installpnpm -C apps/electron devuv sync --group nativesets up the Python workspace and compiles the native extension. Plainuv syncskips the extension.pnpm -C apps/electron devstarts the Electron app. It launches the backend from the repository’s environment (.venv);SPACEKNIFE_PYTHONpoints it at another interpreter.- The backend on its own:
uv run spaceknife serveprints onereadyline with the WebSocket address and a development token. Scans in a terminal:uv run spaceknife scan <path>(see Command line). - Set
SPACEKNIFE_HOMEto an empty folder to keep your experiments away from your real snapshots and settings.
Checks before a pull request
Section titled “Checks before a pull request”These are the checks CI runs. Python:
uv run ruff check .uv run ruff format --check .uv run mypy packages/protocol/src packages/backend/src packages/client/src tools/gen_design.pyuv run pytestGenerated files must be up to date:
uv run python tools/gen_design.py --checkuv run spaceknife schema --check packages/protocol/schema/protocol.schema.jsonuv run python tools/gen_ts_protocol.py --checkuv run python tools/gen_docs.py --checkThe Electron app and the translations:
pnpm -C apps/electron typecheckpnpm -C apps/electron testuv run python tools/i18n_check.py- CI runs the Python checks on Windows, Ubuntu 22.04 and macOS 14, with the native extension built, and the Electron checks with Node.js 22.
SPACEKNIFE_NO_NATIVE=1makes the backend use the Python fallbacks; the tests compare the native and Python results.- Keep tests and benchmarks small and short. Never scan or write large amounts of data on a contributor’s real drives.
Build the installers
Section titled “Build the installers”uv sync --locked --group native --group packagepnpm -C apps/electron installuv run python tools/build_package.pyThe script builds the installers of the system it runs on, into dist/electron/: the NSIS installer on Windows; AppImage, deb and rpm on Linux; a dmg for the Mac’s own architecture on macOS.
| Option | What it does |
|---|---|
--portable |
Also build the portable archive (Windows zip, Linux tar.gz) |
--no-installers |
Only the unpacked app (and the portable archive with --portable) |
--skip-backend |
Reuse the frozen backend in dist/backend/ when only the Electron side changed |
--targets AppImage deb rpm |
Linux: build only some of the formats |
It runs these steps: a release build of the native extension with the build machine’s paths removed; PyInstaller freezes the backend; a smoke test of the frozen backend (the native extension must load); on Linux, a check that nothing needs a glibc newer than 2.34 (RHEL 9); electron-vite build; the license files; electron-builder; a check that no packaged file contains the build machine’s home folder; on macOS, a check of the ad-hoc signature.
- The rpm needs
rpmbuild; the AppImage’s.zsyncfile needszsyncmake(without it the update information is still written). The first run of electron-builder downloads its tools. - Test a packaged app with
uv run python packaging/smoke_app.py dist/electron/win-unpacked/SpaceKnife.exe(orlinux-unpacked/spaceknife, or an AppImage). It starts the app minimized with a temporary data folder, waits for the backend and the start page, then closes it like a user would.
The details, including the release file names, are in docs/packaging.md.
The website and these pages
Section titled “The website and these pages”pnpm -C site installpnpm -C site devThe website lives in site/ (Astro with Starlight) and is published to GitHub Pages from main. These documentation pages are Markdown files: site/src/content/docs/docs/<id>.md in English and site/src/content/docs/zh/docs/<id>.md in Chinese, ordered by site/src/docs-nav.json. From 0.3.2 the app’s help page uses the same files. Read docs/docs-writing.md before you edit them: it lists the Markdown features both places can show. The shortcut and settings tables between <!-- generated:… --> markers are written by uv run python tools/gen_docs.py from palette/commands.py and settings.py; don’t edit them by hand, and rerun the script after changing a command or a setting. pnpm -C site build checks that every link points to an existing page.
Repository layout
Section titled “Repository layout”| Path | Contents |
|---|---|
packages/protocol |
The protocol: pydantic message models, binary frame codec, JSON Schema |
packages/backend |
The backend: WebSocket server, scanning, columnar store and snapshots, filter engine, layouts, views, monitoring, export, file operations, command line |
packages/native |
The native Rust extension (PyO3): parallel folder walking, MFT parsing |
packages/client |
Client core shared by Python front ends (no GUI dependencies) |
apps/electron |
The Electron app and its installer configuration (electron-builder.yml) |
design/tokens, design/icons |
Design tokens and icon sources; design/build is generated |
packaging |
The frozen backend (PyInstaller spec and entry point) and the smoke tests |
site |
The website and this documentation |
docs |
Design documents |
tools |
Code generation and developer tools: build_package.py, gen_design.py, gen_ts_protocol.py, i18n_check.py, demo/screenshots.py |
Design documents
Section titled “Design documents”The design documents describe how each part works and the contracts between the parts. They are written in Chinese.
| Document | What it covers |
|---|---|
| PLAN.md | The plan: decisions, architecture, modules, milestones and risks |
| UI-SPEC.md | The interface specification, requirement by requirement |
| protocol.md | The WebSocket protocol between the backend and the front ends |
| visuals.md | The visualizations: layout engines, wire formats, renderer components |
| plugins.md | Lessons and requirements for a future plugin system (not implemented) |
| packaging.md | Installers, the frozen backend, data locations, update checks |
| memory.md | The memory model: cost per item, mapped storage, the watchdog |
| i18n.md | How the interface texts are translated |
| docs-writing.md | How to write these documentation pages |
| native.md | The native extension, the scan helper and the disk-load limit |
| monitor.md | Live monitoring (the file change hooks) |
| manage.md | The delete basket, snapshot comparison, export, insights and settings import |
| filter-syntax.md | The filter language, formally |
| export-templates.md | The export template language, the export formats and spaceknife run |
| insights.md | The format of the insight rules |
When you change an interface between parts, change its document first.
How to contribute
Section titled “How to contribute”- Report problems: open a bug report; what to include is in Troubleshooting. Tests on a clean Windows 10, RHEL 9 or Ubuntu 22.04 are especially welcome.
- Suggest ideas in Discussions › Ideas or with a feature request.
- Pick an issue: issues labelled good first issue are self-contained. Comment before you start, so nobody duplicates the work.
- Translate: the interface has English and Simplified Chinese; see docs/i18n.md.
For pull requests:
- Match the surrounding code: naming, comment density, idioms. Python 3.12 with type hints (mypy strict); protocol messages are pydantic models; command-line output uses rich and logs use loguru.
- One change per pull request, with a short description of what and why, and tests for behaviour changes.
- Text the user sees goes through
_()/tr()in the backend ort()in the front end, with an English entry in the catalogs. - No personal data: examples, tests, screenshots and logs use made-up paths and names, such as
C:\Users\lenny\…or/home/lenny/…. - Windows and Linux must keep working; say so if you could only test one.
The full guide is CONTRIBUTING.md. By contributing you agree that your contribution is licensed under the MIT License, and everyone taking part follows the Code of Conduct. Security problems are reported privately, see SECURITY.md.