Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7688669
test: add TypeScript extension contract baseline
fffonion Oct 9, 2026
c549634
feat: replace JavaScript frontend with typed TypeScript
fffonion Oct 11, 2026
1dd07e8
fix: address compat review blockers
fffonion Oct 12, 2026
263806c
fix: validate TypeScript declaration type origin
fffonion Oct 12, 2026
cf652bc
fix: use sort_by_key for TypeScript fields
fffonion Oct 12, 2026
2f7ba39
test: make TypeScript fixture temp dirs portable
fffonion Oct 12, 2026
a477b97
typescript: add shared reference-array resource carrier
fffonion Oct 12, 2026
365a60f
Fix TS numeric builtins and isolate array runtime
fffonion Oct 12, 2026
3fa4f45
fix(typescript): preserve self-bearing move-owner closures
fffonion Oct 13, 2026
9cb9c7e
fix(typescript): keep arrow locals in their declaring closure
fffonion Oct 13, 2026
7ef1942
Add scalar factorial TypeScript compatibility
fffonion Oct 13, 2026
084c7bb
Avoid numeric equality hidden locals
fffonion Oct 13, 2026
2f8fb6f
Consume published Core host services in Compat CLI
fffonion Oct 13, 2026
59e5ef5
test: prove certified TypeScript resource roots
fffonion Oct 13, 2026
ed87099
test(runtime): prove certified capture-value replacement revokes auth…
fffonion Oct 13, 2026
8c99643
build: consume published generic Number AOT SDK
fffonion Oct 13, 2026
800ced8
fix(typescript): consume throw adapter statement result
fffonion Oct 13, 2026
7ba8748
feat(cli): consume certified source-file construction
fffonion Oct 13, 2026
6b919e9
test(runtime): prove guest detach and artifact rebinding boundaries
fffonion Oct 13, 2026
66df974
test(runtime): consume native checked-owner synchronization
fffonion Oct 13, 2026
12c0df7
test(runtime): prove bounded factory ownership lifecycle
fffonion Oct 14, 2026
75a0dc4
test(runtime): measure independent callable identity bounds
fffonion Oct 14, 2026
4397953
Compat B1: opt-in owned numeric-array production runtime
fffonion Oct 14, 2026
0889147
Compat B2: transparent numeric reference-array source with Float-proj…
Oct 14, 2026
83b5f16
Compat B2: strict-clippy fixes for Float projection and return inference
Oct 14, 2026
6641892
Compat B2: numeric Float projection at number call boundaries; callee…
fffonion Oct 14, 2026
3cec839
Compat B2 R3: typed host value-alias Number ABI; guarded fallback ori…
Oct 15, 2026
2d166c8
feat(typescript): lower lazy numeric generators in explicit mode
fffonion Oct 15, 2026
31be4f3
feat(typescript): explicit reference-array CLI selection with joint f…
fffonion Oct 15, 2026
72a61cc
feat(javascript): add typed ES5 capability bridge and Script admission
fffonion Oct 16, 2026
472b039
feat(javascript): decode ES5 literals from original source spans
fffonion Oct 16, 2026
cb70606
feat(javascript): add managed heap roots and tracing collection
fffonion Oct 17, 2026
c002e6f
feat(javascript): lower declaration instantiation and binding references
fffonion Oct 17, 2026
0ef920d
fix(javascript): guard strict duplicate-property conflicts in match
fffonion Oct 17, 2026
e4144f1
ci: optimize test profile while retaining debug checks
fffonion Oct 18, 2026
47d5692
feat(javascript): support strict source arguments and function length
fffonion Oct 18, 2026
9423afa
ci: integrate reviewed optimized test profile for ES5 verification
fffonion Oct 18, 2026
590b1b8
feat(js): add operand-preserving logical expressions
fffonion Oct 18, 2026
047acc2
feat(sdk): integrate typed Result Core API
fffonion Oct 18, 2026
3e348a0
feat(javascript): support conditional statements and return completion
fffonion Oct 19, 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
91 changes: 79 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
pull_request:

permissions:
contents: write
contents: read

env:
CARGO_TERM_COLOR: always
Expand All @@ -16,8 +16,10 @@ env:

jobs:
rust:
name: Rust lint and tests
name: Rust lint, tests, and CLI acceptance
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -26,18 +28,60 @@ jobs:
- name: Format check
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
run: cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
- name: Tests
run: cargo test --workspace -- --test-threads=1
- name: CLI smoke
env:
CARGO_PROFILE_TEST_OPT_LEVEL: "2"
CARGO_PROFILE_TEST_DEBUG_ASSERTIONS: "true"
CARGO_PROFILE_TEST_OVERFLOW_CHECKS: "true"
run: cargo test --locked --workspace -- --test-threads=1
- name: TypeScript, Lua, and version CLI smoke
run: |
cargo run --bin pd-vm-compat-run -- examples/example.js
cargo run --bin pd-vm-compat-run -- examples/example.lua
cargo run --bin pd-vm-compat-run -- --version
cargo run --locked --bin pd-vm-compat-run -- examples/example.ts
cargo run --locked --bin pd-vm-compat-run -- examples/example.mts
cargo run --locked --bin pd-vm-compat-run -- examples/example.lua
cargo run --locked --bin pd-vm-compat-run -- --version
- name: Selected reference-array CLI smoke
shell: bash
run: |
set -euo pipefail
scratch="$(mktemp -d)"
trap 'rm -rf "$scratch"' EXIT
mkdir -p "$scratch/sorts"
cp tests/fixtures/typescript/bubble_sort.ts "$scratch/sorts/"
cat > "$scratch/main.ts" <<'EOF'
import { bubbleSort as sort } from "./sorts/bubble_sort.ts";
const sorted = sort([8, 3, 5, 1, 4, 2]);
const eq = sorted[0] === 1 && sorted[5] === 8;
eq ? 1 : 0;
EOF
cargo run --locked --bin pd-vm-compat-run -- --typescript-reference-arrays --fuel 100000 "$scratch/main.ts" | grep -F "Int(1)"
- name: Reject JavaScript CLI entry files
shell: bash
run: |
set -euo pipefail
scratch="$(mktemp -d)"
trap 'rm -rf "$scratch"' EXIT
for extension in js mjs cjs; do
source="$scratch/rejected.$extension"
log="$scratch/rejected.$extension.log"
printf 'const value = "JavaScript must be rejected";\n' > "$source"
if cargo run --locked --bin pd-vm-compat-run -- "$source" >"$log" 2>&1; then
echo "unexpectedly accepted .$extension entry file" >&2
exit 1
fi
if ! grep -Fq ".$extension" "$log"; then
cat "$log" >&2
echo "diagnostic did not identify .$extension" >&2
exit 1
fi
done

binaries:
name: pd-vm-compat-run (${{ matrix.os }})
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
Expand All @@ -46,20 +90,43 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Build pd-vm-compat-run
run: cargo build --bin pd-vm-compat-run --release
run: cargo build --locked --bin pd-vm-compat-run --release
- name: Run typed frontend and Lua smoke fixtures
run: |
cargo run --locked --bin pd-vm-compat-run --release -- examples/example.ts
cargo run --locked --bin pd-vm-compat-run --release -- examples/example.mts
cargo run --locked --bin pd-vm-compat-run --release -- examples/example.lua
cargo run --locked --bin pd-vm-compat-run --release -- --version
- name: Stage pd-vm-compat-run artifact
shell: bash
run: |
set -euo pipefail
mkdir -p dist
suffix=""
if [[ "${{ runner.os }}" == "Windows" ]]; then suffix=".exe"; fi
cp "target/release/pd-vm-compat-run${suffix}" "dist/pd-vm-compat-run-${{ runner.os }}-${{ runner.arch }}${suffix}"
source="target/release/pd-vm-compat-run${suffix}"
test -f "$source"
cp "$source" "dist/pd-vm-compat-run-${{ runner.os }}-${{ runner.arch }}${suffix}"
- uses: actions/upload-artifact@v4
with:
name: pd-vm-compat-run-${{ runner.os }}-${{ runner.arch }}
path: dist/*
- name: Upload pd-vm-compat-run release asset
if: startsWith(github.ref, 'refs/tags/')

release-assets:
name: Attach release assets
if: startsWith(github.ref, 'refs/tags/')
needs: [rust, binaries]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all platform artifacts
uses: actions/download-artifact@v4
with:
pattern: pd-vm-compat-run-*
path: dist
merge-multiple: true
- name: Publish release assets
uses: softprops/action-gh-release@v2
with:
files: dist/*
156 changes: 30 additions & 126 deletions .github/workflows/publish-crates.yml
Original file line number Diff line number Diff line change
@@ -1,153 +1,57 @@
name: Publish crates
name: Publish compat crate

on:
push:
tags:
- 'v*'
- '[0-9]*'
workflow_dispatch:
inputs:
version:
description: 'Version to publish. Defaults to the pushed tag name without leading v.'
required: false
compat_version:
description: Exact pd-vm-compat-frontends version already present in Cargo.toml
required: true
type: string
pd_vm_version:
description: 'pd-vm dependency version override'
required: false
type: string
pd_edge_abi_version:
description: 'pd-edge-abi dependency version override'
required: false
description: Published pd-vm registry release supporting the typed frontend API; no default is selected
required: true
type: string

concurrency:
group: publish-crates-${{ github.ref }}
group: publish-compat-${{ github.ref }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
env:
PACKAGE_ORDER: pd-vm-compat-frontends
PD_VM_VERSION: ${{ inputs.pd_vm_version || '0.1.0' }}
PD_EDGE_ABI_VERSION: ${{ inputs.pd_edge_abi_version || '0.1.1' }}
WORKSPACE_VERSION_OVERRIDES: rustscript-compat-frontends=${{ inputs.version }} rustscript=${{ inputs.pd_vm_version || '0.1.0' }} pd-edge=${{ inputs.pd_edge_abi_version || '0.1.1' }}
steps:
- name: Checkout compatibility frontends
uses: actions/checkout@v4
with:
path: rustscript-compat-frontends
- name: Checkout rustscript dependency
uses: actions/checkout@v4
with:
repository: rustscript-lang/rustscript
path: rustscript
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish crate
working-directory: rustscript-compat-frontends
- uses: dtolnay/rust-toolchain@stable
- name: Test release preflight guards and rollback
run: python3 -m unittest discover -s scripts/tests -p 'test_*.py' -v
- name: Prepare the compat-only registry candidate
env:
COMPAT_VERSION: ${{ inputs.compat_version }}
PD_VM_VERSION: ${{ inputs.pd_vm_version }}
run: >-
python3 scripts/prepare-release.py
--compat-version "$COMPAT_VERSION"
--pd-vm-version "$PD_VM_VERSION"
- name: Verify package against the selected registry dependency
run: |
cargo fmt --all -- --check
cargo check --locked --workspace --all-targets
- name: Test prepared registry provenance and behavior
env:
PD_VM_EXPECTED_REGISTRY_VERSION: ${{ inputs.pd_vm_version }}
run: cargo test --locked --workspace -- --test-threads=1
- name: Package dry run
run: cargo publish --locked --dry-run --allow-dirty
- name: Publish compatibility crate only
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
INPUT_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ -z "${CARGO_REGISTRY_TOKEN:-}" ]]; then
echo "CARGO_REGISTRY_TOKEN is required" >&2
exit 1
fi
version="${INPUT_VERSION:-}"
if [[ -z "$version" ]]; then
version="${GITHUB_REF_NAME#v}"
fi
if [[ -z "$version" ]]; then
echo "version is required" >&2
exit 1
fi
export PUBLISH_VERSION="$version"
python3 - <<'PY'
import os, re
from pathlib import Path

version = os.environ['PUBLISH_VERSION']
dep_versions = {
'pd-vm': os.environ.get('PD_VM_VERSION') or '0.1.0',
'pd-host-function': os.environ.get('PD_VM_VERSION') or '0.1.0',
'pd-edge-abi': os.environ.get('PD_EDGE_ABI_VERSION') or '0.1.1',
}
workspace_versions = {}
for item in os.environ.get('WORKSPACE_VERSION_OVERRIDES', '').split():
if '=' in item:
name, value = item.split('=', 1)
if value:
workspace_versions[name] = value
dep_re = re.compile(r'^(\s*([A-Za-z0-9_-]+)\s*=\s*\{)(.*)(\}\s*)$')
for path in Path('..').rglob('Cargo.toml'):
if '.git' in path.parts or 'target' in path.parts:
continue
manifest_version = workspace_versions.get(path.parent.name, version)
lines = path.read_text().splitlines()
out = []
section = ''
for line in lines:
stripped = line.strip()
if stripped.startswith('[') and stripped.endswith(']'):
section = stripped
if section in ('[workspace.package]', '[package]') and stripped.startswith('version = '):
line = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{manifest_version}"', line)
match = dep_re.match(line)
if match and ('path' in match.group(3) or 'git' in match.group(3)):
prefix, key, body, suffix = match.groups()
package_match = re.search(r'package\s*=\s*"([^"]+)"', body)
dep_name = package_match.group(1) if package_match else key
dep_version = dep_versions.get(dep_name)
if dep_version:
body = re.sub(r'\s*,?\s*git\s*=\s*"[^"]*"', '', body)
body = re.sub(r'\s*,?\s*rev\s*=\s*"[^"]*"', '', body)
body = re.sub(r'\s*,?\s*path\s*=\s*"[^"]*"', '', body)
if re.search(r'version\s*=\s*"[^"]*"', body):
body = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{dep_version}"', body)
else:
body = body.strip().strip(',')
if body:
body = f'version = "{dep_version}", {body}'
else:
body = f'version = "{dep_version}"'
line = prefix + body + suffix
out.append(line)
path.write_text('\n'.join(out) + '\n')
PY
python3 - <<'PY'
import os, subprocess, sys, time, urllib.error, urllib.request

version = os.environ['PUBLISH_VERSION']
packages = os.environ['PACKAGE_ORDER'].split()
token = os.environ['CARGO_REGISTRY_TOKEN']

def exists(crate, crate_version):
url = f'https://crates.io/api/v1/crates/{crate}/{crate_version}'
try:
urllib.request.urlopen(url, timeout=20).read()
return True
except urllib.error.HTTPError as exc:
if exc.code == 404:
return False
raise

for package in packages:
if exists(package, version):
print(f'{package} {version} already published; skipping')
continue
for attempt in range(1, 19):
print(f'publishing {package} {version}, attempt {attempt}')
proc = subprocess.run([
'cargo', 'publish', '-p', package, '--no-verify', '--allow-dirty', '--token', token,
], text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(proc.stdout)
if proc.returncode == 0 or exists(package, version):
break
if attempt == 18:
sys.exit(proc.returncode)
time.sleep(20)
PY
cargo publish --locked --allow-dirty --token "$CARGO_REGISTRY_TOKEN"
Loading
Loading