Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
67b8444
feat(js/ts): add CaseTest attribute for TypeScriptTaggedUnion cases t…
shayanhabibi Oct 15, 2026
505ba56
feat(js/ts): warn when CaseTest is used outside a TypeScriptTaggedUnion
shayanhabibi Oct 15, 2026
3353391
chore: update fable-metadata Fable.Core.dll for CaseTest
shayanhabibi Oct 15, 2026
ea2e7f8
Merge remote-tracking branch 'myfork/feat/ts-tagged-union-case-test' …
shayanhabibi Oct 15, 2026
ead0773
feat(js/ts): add InlineInterface for TypeScriptTaggedUnion cases
shayanhabibi Oct 20, 2026
6ce2aec
chore: update fable-metadata Fable.Core.dll for InlineInterface
shayanhabibi Oct 20, 2026
26e4093
chore: merge feat/ts-tagged-union-inline-interface into main_fork
shayanhabibi Oct 20, 2026
254af67
chore: merge InlineInterface and CaseTest from main_fork
shayanhabibi Oct 20, 2026
8423053
chore(fickle): rename NuGet package identities to Fickle
shayanhabibi Oct 20, 2026
fcaa079
feat(fickle): move CaseTest and InlineInterface into Fickle.Core
shayanhabibi Oct 20, 2026
0951332
feat(fickle): add --timings phase report to the CLI
shayanhabibi Oct 20, 2026
56dde55
feat(fickle): add Partas.Build CLI as Fickle.Build
shayanhabibi Oct 20, 2026
020b2bc
chore(fickle): drop fickle-build launcher scripts
shayanhabibi Oct 20, 2026
3a97972
build: add fcs-fork command to Fickle.Build
shayanhabibi Oct 20, 2026
3e6f71e
feat: compile against a net10-only FCS from fickle-fsharp
shayanhabibi Oct 20, 2026
35c290a
docs: record FCS profile findings in perf baseline
shayanhabibi Oct 20, 2026
52cd7c9
perf: skip witness codegen state for typars without trait constraints
shayanhabibi Oct 20, 2026
92f804b
docs: record that FCS type checking is the serial critical path
shayanhabibi Oct 20, 2026
da5f972
docs(perf): measure graph-based type checking headroom
shayanhabibi Oct 20, 2026
5911fee
perf: type check cold compiles in parallel over the file graph
shayanhabibi Oct 20, 2026
66caf36
perf: cache FCS symbol API results Fable reads repeatedly
shayanhabibi Oct 20, 2026
b7feb2c
perf: recheck only edited files and their dependents in watch mode
shayanhabibi Oct 20, 2026
d0d6b68
chore: remove build.bat and build.sh proxies
shayanhabibi Oct 20, 2026
8814b1f
chore: point docs, workflows and tasks at src/Fickle.Build
shayanhabibi Oct 20, 2026
8db380d
fix(js/ts): format DateTimeOffset in its own offset, not local time
shayanhabibi Oct 20, 2026
ddccdcf
chore: rename the fork from Fickle to Fickl
shayanhabibi Oct 20, 2026
cbd6e3f
fix(cli): choose deduplicated output dirs under a lock
shayanhabibi Oct 20, 2026
23634f2
feat(cli): record FCS activities with --timings
shayanhabibi Oct 20, 2026
2410c3e
feat(cli): cache type-checked package sources across compilations
shayanhabibi Oct 20, 2026
b393dfb
docs(perf): record performance frontiers and package cache results
shayanhabibi Oct 20, 2026
289831b
chore: release Fickl 0.2.0
shayanhabibi Oct 21, 2026
09c39b0
docs(perf): explain the Promise.fs stall in graph-based checking
shayanhabibi Oct 21, 2026
097f0f7
perf(fcs): skip extension methods when checking for IWSAMs used as types
shayanhabibi Oct 21, 2026
f61886c
perf(cache): cache package sets that cannot be one assembly as one as…
shayanhabibi Oct 21, 2026
01e3488
perf(cache): cache package sources for Python and BEAM
shayanhabibi Oct 21, 2026
1be7590
chore: release Fickl 0.3.0
shayanhabibi Oct 21, 2026
3c53677
perf(timings): report process JIT and CPU time
shayanhabibi Oct 21, 2026
cc325f8
perf(cli): ship composite ReadyToRun tool packages, TieredPGO off
shayanhabibi Oct 21, 2026
1f41576
chore: release Fickl 0.4.0
shayanhabibi Oct 21, 2026
d504db6
perf: overlap TargetFramework query with cracking and cache paket-fil…
shayanhabibi Oct 21, 2026
c110545
chore: merge upstream fable-compiler/fable main
shayanhabibi Oct 21, 2026
2deb7e2
perf: crack stated project references beside the main project
shayanhabibi Oct 21, 2026
107b673
perf: skip dependents in watch mode when an edit keeps the file's sig…
shayanhabibi Oct 21, 2026
e1985bb
chore: release Fickl 0.5.0
shayanhabibi Oct 21, 2026
e3ddbca
fix: stop cracking's dotnet msbuild processes when the compiler exits
shayanhabibi Oct 21, 2026
56687cf
perf: turn off .NET CLI telemetry for the compiler's own dotnet proce…
shayanhabibi Oct 21, 2026
a158c4f
chore: release Fickl 0.5.1
shayanhabibi Oct 21, 2026
ce3a5aa
docs: record the Fickl 0.5.1 end-to-end benchmark
shayanhabibi Oct 21, 2026
4194dcc
perf: update FCS with static abstract interface check fast path
shayanhabibi Oct 22, 2026
b5880cf
fix: preserve plugin compatibility and publish the Fickl package family
shayanhabibi Oct 22, 2026
ddf3365
docs: record Fickl 0.5.3 publication
shayanhabibi Oct 22, 2026
9d10f9e
docs: record partial FCS and Core performance investigations
shayanhabibi Oct 22, 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
4 changes: 2 additions & 2 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"permissions": {
"allow": [
"Bash(./build.sh fable-library *)",
"Bash(./build.sh test *)"
"Bash(dotnet run --project src/Fickl.Build -- fable-library *)",
"Bash(dotnet run --project src/Fickl.Build -- test *)"
],
"deny": [
"Read(lib/fcs/**)",
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ runs:
with:
node-version-file: package.json
cache: npm
# build.sh also installs in src/fable-compiler-js, src/fable-standalone and tests/React.
# The build also installs in src/fable-compiler-js, src/fable-standalone and tests/React.
cache-dependency-path: |
**/package-lock.json
!**/node_modules/**
26 changes: 13 additions & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ jobs:

- name: Fable Tests - JavaScript (linux)
if: matrix.platform == 'ubuntu-latest'
run: ./build.sh test javascript
run: dotnet run --project src/Fickl.Build -- test javascript

- name: Fable Tests - JavaScript (Windows)
if: matrix.platform == 'windows-latest'
run: .\build.bat test javascript
run: dotnet run --project src/Fickl.Build -- test javascript

# Separate build job for TypeScript
build-typescript:
Expand All @@ -108,7 +108,7 @@ jobs:
uses: ./.github/actions/setup-node

- name: Fable Tests - TypeScript
run: ./build.sh test typescript
run: dotnet run --project src/Fickl.Build -- test typescript

# - name: Fable Tests - TypeScript
# run: dotnet fsi build.fsx test-ts
Expand All @@ -128,7 +128,7 @@ jobs:
uses: ./.github/actions/setup-node

- name: Fable Tests
run: ./build.sh test integration
run: dotnet run --project src/Fickl.Build -- test integration

# Separate build job for Standalone
build-standalone:
Expand All @@ -145,7 +145,7 @@ jobs:
uses: ./.github/actions/setup-node

- name: Fable Tests
run: ./build.sh test standalone
run: dotnet run --project src/Fickl.Build -- test standalone

# Separate build job for Python since we use a test matrix (will run in parallell)
build-python:
Expand Down Expand Up @@ -179,7 +179,7 @@ jobs:

- name: Fable Library - Python (linux)
if: matrix.platform == 'ubuntu-latest'
run: ./build.sh fable-library --python
run: dotnet run --project src/Fickl.Build -- fable-library python

# PEP 561 requires the marker inside the package directory. CopyStage filters
# by extension, so it is easy to drop again; without it mypy refuses to read
Expand All @@ -192,15 +192,15 @@ jobs:

- name: Fable Library - Python (Windows)
if: matrix.platform == 'windows-latest'
run: .\build.bat fable-library --python
run: dotnet run --project src/Fickl.Build -- fable-library python

- name: Fable Tests - Python (linux)
if: matrix.platform == 'ubuntu-latest'
run: ./build.sh test python
run: dotnet run --project src/Fickl.Build -- test python

- name: Fable Tests - Python (Windows)
if: matrix.platform == 'windows-latest'
run: .\build.bat test python
run: dotnet run --project src/Fickl.Build -- test python

# Native/Rust-extension unit tests for the published fable-library package.
# These live in src/fable-library-py/tests and exercise hand-written sources
Expand Down Expand Up @@ -283,10 +283,10 @@ jobs:
components: rustfmt

- name: Fable Library - Rust
run: ./build.sh fable-library --rust
run: dotnet run --project src/Fickl.Build -- fable-library rust

- name: Fable Tests - Rust
run: ./build.sh test rust --features "${{ matrix.features }}"
run: dotnet run --project src/Fickl.Build -- test rust --features "${{ matrix.features }}"

# Separate build job for Dart
build-dart:
Expand All @@ -307,7 +307,7 @@ jobs:
uses: dart-lang/setup-dart@v1

- name: Fable Tests - Dart
run: ./build.sh test dart
run: dotnet run --project src/Fickl.Build -- test dart

# Separate build job for Beam (Erlang)
build-beam:
Expand All @@ -327,7 +327,7 @@ jobs:
rebar3-version: "3"

- name: Fable Tests - Beam
run: ./build.sh test beam
run: dotnet run --project src/Fickl.Build -- test beam

# Separate job to run F# analyzers
analyzers:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/easybuild-shipit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: ./.github/actions/setup-dotnet
# Run your tests before generating the changelog to make sure everything is working fine before creating a pull request.
- name: Prepare for release
run: ./build.sh prepare-release
run: dotnet run --project src/Fable.Build -- prepare-release
- name: ShipIt (Pull Request)
# Configure add --pre-release below when we want to create a pre-release, e.g. --pre-release beta
run: dotnet shipit
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:

- name: Build, and Release
run: |
./build.sh automated-release
dotnet run --project src/Fable.Build -- automated-release
env:
FABLE_NUGET_KEY: ${{ steps.login.outputs.NUGET_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Install Maturin
run: uv tool install maturin
- name: Transpile F# to Python
run: ./build.sh fable-library --python
run: dotnet run --project src/Fickl.Build -- fable-library python
- name: Install Dunamai
run: uv tool install dunamai
- name: Set version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-type-checking.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
pipx install maturin

- name: Build Python (compile only)
run: ./build.sh test python --compile-only
run: dotnet run --project src/Fickl.Build -- test python --compile-only

- name: Run Pyright and collect errors
id: pyright
Expand Down
80 changes: 30 additions & 50 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,91 +22,71 @@
{
"label": "Build fable-library - JavaScript",
"type": "shell",
"command": "dotnet",
"args": [
"run",
"--project",
"src/Fickl.Build",
"--",
"fable-library",
"--javascript"
"javascript"
],
"linux": {
"command": "${workspaceFolder}/build.sh"
},
"osx": {
"command": "${workspaceFolder}/build.sh"
},
"windows": {
"command": "${workspaceFolder}/build.cmd"
},
"problemMatcher": []
},
{
"label": "Build fable-library - TypeScript",
"type": "shell",
"command": "dotnet",
"args": [
"run",
"--project",
"src/Fickl.Build",
"--",
"fable-library",
"--typescript"
"typescript"
],
"linux": {
"command": "${workspaceFolder}/build.sh"
},
"osx": {
"command": "${workspaceFolder}/build.sh"
},
"windows": {
"command": "${workspaceFolder}/build.cmd"
},
"problemMatcher": []
},
{
"label": "Build fable-library - Python",
"type": "shell",
"command": "dotnet",
"args": [
"run",
"--project",
"src/Fickl.Build",
"--",
"fable-library",
"--python"
"python"
],
"linux": {
"command": "${workspaceFolder}/build.sh"
},
"osx": {
"command": "${workspaceFolder}/build.sh"
},
"windows": {
"command": "${workspaceFolder}/build.cmd"
},
"problemMatcher": []
},
{
"label": "Build fable-library - Dart",
"type": "shell",
"command": "dotnet",
"args": [
"run",
"--project",
"src/Fickl.Build",
"--",
"fable-library",
"--dart"
"dart"
],
"linux": {
"command": "${workspaceFolder}/build.sh"
},
"osx": {
"command": "${workspaceFolder}/build.sh"
},
"windows": {
"command": "${workspaceFolder}/build.cmd"
},
"problemMatcher": []
},
{
"label": "Build fable-library - Rust",
"type": "shell",
"command": "dotnet",
"args": [
"run",
"--project",
"src/Fickl.Build",
"--",
"fable-library",
"--rust"
"rust"
],
"linux": {
"command": "${workspaceFolder}/build.sh"
},
"osx": {
"command": "${workspaceFolder}/build.sh"
},
"windows": {
"command": "${workspaceFolder}/build.cmd"
},
"problemMatcher": []
},
{
Expand Down
22 changes: 11 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@ Fable is an F# to multi-language compiler that transpiles F# code to JavaScript,

## Build Commands

The build system is implemented in F# at `src/Fable.Build/`. All commands go through `build.sh` (or `build.bat` on Windows):
The build system is implemented in F# at `src/Fable.Build/`. All commands go through `src/Fickl.Build/`, which runs the same Fable.Build handlers:

```bash
./build.sh # Show all available commands
dotnet run --project src/Fickl.Build -- --help # Show all available commands

# Build runtime libraries
./build.sh fable-library --javascript # Also: --typescript, --python, --dart, --rust, --beam
dotnet run --project src/Fickl.Build -- fable-library javascript # Also: typescript, python, dart, rust, beam

# Run tests (targets: javascript, typescript, python, dart, rust, beam, integration)
./build.sh test javascript
./build.sh test javascript --watch # Watch mode (recompile on changes)
./build.sh test javascript --force-fable-library # Force fable-library rebuild (needed if you modified Fable compiler to fix the generation of `src/fable-library-*/**/*.fs` files)
dotnet run --project src/Fickl.Build -- test javascript
dotnet run --project src/Fickl.Build -- test javascript --watch # Watch mode (recompile on changes)
dotnet run --project src/Fickl.Build -- test javascript --force-fable-library # Force fable-library rebuild (needed if you modified Fable compiler to fix the generation of `src/fable-library-*/**/*.fs` files)

# Python-specific options
./build.sh test python --skip-fable-library-core # Skip slow Rust extension + .pyi rebuild (Python only)
./build.sh test python --type-check # Run Pyright type checking on Python output
dotnet run --project src/Fickl.Build -- test python --skip-fable-library-core # Skip slow Rust extension + .pyi rebuild (Python only)
dotnet run --project src/Fickl.Build -- test python --type-check # Run Pyright type checking on Python output

# Quick iteration (test on a minimal project)
./build.sh quicktest javascript # Also: typescript, python, dart, rust, beam
dotnet run --project src/Fickl.Build -- quicktest javascript # Also: typescript, python, dart, rust, beam
```

In most cases, you should not need to use `--force-fable-library`. Only use it if you modified compiler code that affects how F# files used in `src/fable-library-*/` are generated (e.g., changes to `FSharp2Fable.fs` that affect how F# AST is transformed into Fable AST for library files).

When running Python tooling directly with `uv` (e.g. `pytest`, `pyright`, `maturin`, ad-hoc scripts) instead of through `build.sh`, always pass `--frozen` (e.g. `uv run --frozen pytest`). Plain `uv run` silently resolves and rewrites `uv.lock` as a side effect of just running a command. If a command fails because the lock is out of date, stop and ask rather than letting `uv` update it.
When running Python tooling directly with `uv` (e.g. `pytest`, `pyright`, `maturin`, ad-hoc scripts) instead of through the build, always pass `--frozen` (e.g. `uv run --frozen pytest`). Plain `uv run` silently resolves and rewrites `uv.lock` as a side effect of just running a command. If a command fails because the lock is out of date, stop and ask rather than letting `uv` update it.

Build output goes to `temp/`: transpiled runtime libraries in `temp/fable-library-<target>/` and test output in `temp/tests/<target>/` (e.g., `temp/fable-library-beam/` and `temp/tests/beam/`).

Expand Down Expand Up @@ -100,7 +100,7 @@ Be careful when modifying shared files like `FableTransforms.fs`, `Transforms.Ut

All code in `fable-library-py` must be fully type-annotated using Python 3.13-compatible syntax, including PEP 695 type parameters. Avoid `Any`, `cast()`, and `# type: ignore` — these require justification. Keep functions small and simple: extract helpers and use early returns. The Rust extension modules (`fable-library-core`) exist to provide correct .NET semantics for numerics, arrays, etc. — not for performance (the FFI crossing is expensive).

All transpiled Python code is type-checked with Pyright at standard settings (`./build.sh test python --type-check`). Do not introduce type-checking regressions without justification.
All transpiled Python code is type-checked with Pyright at standard settings (`dotnet run --project src/Fickl.Build -- test python --type-check`). Do not introduce type-checking regressions without justification.

## Development Workflow

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Make sure the following **requirements** are installed in your system:

### Build

Run `./build.sh` or `./build.cmd` to see the build options.
Run `dotnet run --project src/Fickl.Build -- --help` to see the build options.

When using VSCode, you can also run the build tasks from the command palette (Ctrl+Shift+P) by typing `Run Task` and selecting the task you want to run.

Expand Down
4 changes: 0 additions & 4 deletions build.bat

This file was deleted.

4 changes: 0 additions & 4 deletions build.sh

This file was deleted.

Loading
Loading