Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
aad2d59
Plan and agent files.
lzandman May 11, 2026
1254654
Upgrade TypeScript (2.9 → 5.8)
lzandman May 11, 2026
ad57dbe
Migrate TSLint → ESLint
lzandman May 11, 2026
037758d
Removed Babel.
lzandman May 11, 2026
33c0cc0
Updated plan.
lzandman May 11, 2026
af1785e
Upgrade Webpack (4 → 5)
lzandman May 11, 2026
d9d0594
Electron upgraded from 8.2.1 to 12.x.
lzandman May 11, 2026
bf353bd
Updated plan to better reflect Electron upgrade process.
lzandman May 11, 2026
d3034cc
Retroactively updated plan.
lzandman May 11, 2026
2bcabd8
Keep the plan updated.
lzandman May 11, 2026
dc2804c
Stage 2.2
lzandman May 11, 2026
e99e8f6
Stage 2.3
lzandman May 11, 2026
ae5383a
Stage 2.4
lzandman May 11, 2026
c716c2a
Stage 2.5. Electron upgraded from 12.2.3 → 42.0.1 in 4 hops.
lzandman May 11, 2026
a1f859a
Stage 2.6
lzandman May 11, 2026
b7661e5
Stage 2.7
lzandman May 11, 2026
659d779
Updated plan.
lzandman May 11, 2026
c7064ea
Stage 3.1
lzandman May 11, 2026
80354a1
Stage 3.2.
lzandman May 11, 2026
b0d2ca2
Fix.
lzandman May 11, 2026
bf330c7
4.1 Upgrade Redux Stack.
lzandman May 11, 2026
df52a87
Stage 5.
lzandman May 11, 2026
22ea729
Stage 6.1
lzandman May 11, 2026
5d48d7f
Stage 6.2
lzandman May 11, 2026
59e427b
Defer further work.
lzandman May 11, 2026
e81d02b
Fixed loading project in DEV mode.
lzandman May 11, 2026
d4507d3
Updated README.md
lzandman May 11, 2026
185429d
Added AUTHORS.md
lzandman May 11, 2026
abcc7ae
Remove update support files.
lzandman May 11, 2026
e5f7de4
Update TypeScript module and resolution settings to node16
lzandman May 11, 2026
dfefcfa
Mouse drag fix.
lzandman May 11, 2026
552fe49
Fix clipboard copy for use with sandbox.
lzandman May 11, 2026
df8ca40
Image opacity now controlled using a range input instead of dim check…
lzandman May 11, 2026
c7c9cee
PR description
lzandman May 11, 2026
44d94e2
Compact PR text.
lzandman May 11, 2026
2ce7f7c
Added various tests.
lzandman May 11, 2026
c0c3fe6
Updated PR text
lzandman May 11, 2026
b92dad3
Cleanup
lzandman May 11, 2026
7e29123
Merge branch 'upstream-pr-158' into merge-upstream-pr-158
EtiennePagec May 12, 2026
041c074
fix post-merge build issues
EtiennePagec May 12, 2026
df1d303
fix drag and fullscreen regressions
EtiennePagec May 12, 2026
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
14 changes: 0 additions & 14 deletions .babelrc

This file was deleted.

40 changes: 40 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"indent": ["warn", 2, { "SwitchCase": 1 }],
"eqeqeq": "off",
"prefer-const": "off",
"no-case-declarations": "off",
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "ignore"
}],
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-types": "off"
},
"env": {
"browser": true,
"node": true,
"es2022": true
},
"ignorePatterns": ["build/", "node_modules/", "__tests__/", "*.js"]
}
22 changes: 6 additions & 16 deletions .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,23 @@ jobs:
with:
node-version-file: .nvmrc

- name: Enable Yarn 1
shell: pwsh
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
yarn --version

- name: Install dependencies
run: corepack yarn install --frozen-lockfile
run: npm ci

- name: Lint
run: corepack yarn lint
run: npm run lint

- name: Build development bundles
run: corepack yarn build-dev

- name: Build test bundles
run: corepack yarn build-test
run: npm run build-dev

- name: Run unit tests
run: corepack yarn test:unit
run: npm run test:unit

- name: Run export and project tests
run: corepack yarn test:export-project
run: npm run test:export-project

- name: Build unpacked Windows package
run: corepack yarn dist-preview
run: npm run dist-preview

- name: Upload unpacked app
uses: actions/upload-artifact@v4
Expand Down
13 changes: 3 additions & 10 deletions .github/workflows/windows-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,14 @@ jobs:
with:
node-version-file: .nvmrc

- name: Enable Yarn 1
shell: pwsh
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
yarn --version

- name: Install dependencies
run: corepack yarn install --frozen-lockfile
run: npm ci

- name: Verify build and tests
run: corepack yarn verify
run: npm run verify

- name: Build Windows installer
run: corepack yarn dist-win
run: npm run dist-win

- name: Upload installer artifact
uses: actions/upload-artifact@v4
Expand Down
67 changes: 67 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# AGENTS.md — fSpy Project Guide

## Project Overview

fSpy is a cross-platform Electron 42 desktop application for camera matching from still images. It uses React 18, Konva 9 / react-konva 18 for canvas rendering, Redux 5 for state management, and Webpack 5 for bundling. TypeScript 5.8 with strict mode. Licensed under GPL-3.0.

## Architecture

### Process model

- **Main process** (`src/main/index.ts`): Electron lifecycle, window management, IPC handlers, all file system access.
- **Preload script** (`src/main/preload.ts`): Uses `contextBridge.exposeInMainWorld('electronAPI', ...)` to expose a typed API surface to the renderer. Kept minimal.
- **Renderer** (`src/gui/`): React/Redux UI. Has **no** direct access to Node.js APIs or Electron internals — all system access goes through `window.electronAPI`.

### Security model

- `contextIsolation: true`, `nodeIntegration: false`, `sandbox: true`.
- No `remote` module. No `eval()` or `new Function()` in renderer code.
- IPC pattern: `ipcMain.handle` / `ipcRenderer.invoke` for request-response; `ipcMain.on` / `ipcRenderer.send` for fire-and-forget.
- Do not expose raw `ipcRenderer` to the renderer. Add new IPC channels to `src/main/preload.ts` and `src/gui/types/electron-api.ts`.

### Build targets

Webpack produces three bundles (see `webpack.config.js`):
1. `main` — target `electron-main`
2. `gui` — target `web` (renderer, no Node.js externals)
3. `preload` — target `electron-preload`

## Code Style

- TypeScript strict mode. Do not add `@ts-ignore` or `any` to work around type issues — fix the types properly.
- Prefer `const` over `let`. Never use `var`.
- Use ES module import syntax (`import`/`export`), not `require()`, in TypeScript source files.
- Indent with 2 spaces. LF line endings.
- Do not add comments or JSDoc to unchanged code.
- Do not refactor or "improve" code beyond what is necessary for the task at hand.

## Component Patterns

- Existing class components do not need to be converted to function components unless required by a dependency change.
- Do not introduce new class components. Any new code should use function components with hooks.
- Redux: existing `connect()` + `legacy_createStore` pattern is in use. Action type strings are stable — do not rename them.

## Project File Format

- The `.fspy` binary format is documented in `project_file_format.md` and must remain backward-compatible.
- Existing `.fspy` files in `test_data/` must load correctly after any code changes.
- File I/O in the renderer uses `DataView`/`Uint8Array`/`TextEncoder`/`TextDecoder` (no `Buffer`).

## Testing

- Tests live in `tests/` and run via Jest 29 + ts-jest. Config in `jest.config.js`.
- Run: `npm test`.
- Test with the `.fspy` files in `test_data/` to verify project file compatibility.

## Dependencies

- **License**: GPL-3.0. Do not introduce dependencies with incompatible licenses (SSPL, proprietary, AGPL). Prefer MIT/Apache-2.0/BSD/ISC.
- Pin major versions in `package.json` (e.g., `^5.8.0`, not `*` or `latest`).
- Run `npm audit` after dependency changes and fix critical/high vulnerabilities before merging.
- Prefer well-maintained packages with recent releases.

## File Structure

- Do not restructure the `src/` directory layout unless a dependency requires it.
- Preload script source: `src/main/preload.ts`.
- Electron API type definitions: `src/gui/types/electron-api.ts`.
12 changes: 12 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Authors

## Creator and original author

- **Per Gantelius** ([@stuffmatic](https://github.com/stuffmatic)) — per@stuffmatic.com

## Contributors

- **Leon Zandman** ([@leonzandman](https://github.com/leonzandman))
- **Darío Hereñú** ([@magallania](https://github.com/magallania))
- **Luis García-Tornel** ([@tornel](https://github.com/tornel))
- **Tuk Bredsdorff**
33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,32 @@ In theory, camera parameters computed by fSpy could be used in any application t

Interested in writing an importer for your favorite application? Then the [fSpy project file format spec](https://github.com/stuffmatic/fSpy/blob/develop/project_file_format.md) is a good starting point.


## Building and running

The following instructions are for developers. If you just want to run the app, download the latest build from the [fSpy-UE releases page](https://github.com/EnneiteG/fSpy-UE/releases).

fSpy is written in [Typescript](https://www.typescriptlang.org) using [Electron](https://electronjs.org), [React](https://reactjs.org) and [Redux](https://redux.js.org). [Visual Studio Code](https://code.visualstudio.com) is recommended for a pleasant editing experience.

To install necessary dependencies, run
Node.js 22 is the recommended development runtime for the current Electron build stack. The repository includes an `.nvmrc` file for this purpose. npm is the package manager for this fork.

To install necessary dependencies, run:

```
corepack enable
yarn
npm ci
```

Node.js 22 is the recommended development runtime for the current Electron build stack. The repository includes an `.nvmrc` file for this purpose, and Yarn 1 should be launched through Corepack.

The `src` folder contains two subfolders `main` and `gui`, containing code for the [Electron main and renderer processes](https://electronjs.org/docs/tutorial/application-architecture) respectively.
The `src` folder contains `main` and `gui`, containing code for the [Electron main and renderer processes](https://electronjs.org/docs/tutorial/application-architecture) respectively, and `cli`, which contains a command-line interface for processing fSpy project files without the GUI. The main process includes a preload script (`src/main/preload.ts`) that bridges the renderer and main processes via IPC.

Here's how to run the app in development mode
Here's how to run the app in development mode:

1. Run `yarn dev-server` in a separate terminal tab to start the dev server
2. Run `yarn build-dev` to build both the main and GUI code. This build step is needed to generate main process code used to start up the app.
3. Run `yarn electron-dev` in a separate terminal tab to start an Electron instance which uses the dev server to provide automatic reloading on GUI code changes.
1. Run `npm run dev-server` in a separate terminal tab to start the dev server.
2. Run `npm run build-dev` to build the main, preload, and GUI code. This build step is needed to generate main process and preload code used to start up the app.
3. Run `npm run electron-dev` in a separate terminal tab to start an Electron instance which uses the dev server to provide automatic reloading on GUI code changes.

To test a packaged app without creating installers, run:

```
yarn dist-preview
npm run dist-preview
```

On Windows, this creates an unpacked app in `dist/win-unpacked`.
Expand All @@ -56,23 +54,20 @@ When launching the unpacked app from a terminal, make sure `ELECTRON_RUN_AS_NODE
Remove-Item Env:ELECTRON_RUN_AS_NODE -ErrorAction SilentlyContinue
```

⚠️ The current build process is not ideal. For example, it lacks support for live reloading on main process code changes. Changes to main process code require a manual rebuild, i.e steps 2-3, in order to show up in the app.


## Creating binaries for distribution

To create installers and archives for all configured platforms, run
To create installers and archives for all configured platforms, run:

```
yarn dist
npm run dist
```

which invokes [Electron builder](https://github.com/electron-userland/electron-builder).

To create a Windows installer locally, run:

```
yarn dist-win
npm run dist-win
```

On Windows, this creates an x64 NSIS setup executable in `dist/`. GitHub also has a `Windows Release` workflow that builds the same installer. Pushing a tag such as `v0.1.0-ue` creates a GitHub Release and attaches the generated installer. The generated file names use the version from `package.json`.
On Windows, this creates an x64 NSIS setup executable in `dist/`. GitHub also has a `Windows Release` workflow that builds the same installer. Pushing a tag such as `v0.3.0-ue` creates a GitHub Release and attaches the generated installer. The generated file names use the version from `package.json`.
8 changes: 8 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('jest').Config} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/tests'],
testMatch: ['**/*tests.ts', '**/*specs.ts', '**/*_tests.ts'],
reporters: ['default', 'jest-junit']
}
Loading
Loading