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
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: Bug report
about: Report a reproducible problem with the CueMap Rust Engine
title: "[Bug]: "
labels: ""
assignees: ""
---

## Describe the bug

<!-- What happened, and what did you expect to happen? -->

## Reproduction

<!-- Include the smallest possible example, request, file, or repository layout. Remove secrets and personal data. -->

```text

```

## Environment

- CueMap version/commit:
- Operating system and architecture:
- Rust version or installation method:
- SDK/MCP version, if applicable:

## Logs and configuration

<!-- Include relevant logs and configuration with credentials removed. -->
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Feature request
about: Suggest an improvement for the CueMap Rust Engine
title: "[Feature]: "
labels: ""
assignees: ""
---

## Problem

<!-- What user problem or limitation would this address? -->

## Proposed solution

<!-- Describe the behavior or interface you would like. -->

## Alternatives considered

<!-- What workarounds or alternative designs have you considered? -->

## Additional context

<!-- Examples, links, compatibility requirements, or related issues. -->
30 changes: 30 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Summary

<!-- What problem does this change solve? -->

## Changes

<!-- List the important implementation or documentation changes. -->

## Testing

- [ ] `cargo check --locked --all-targets`
- [ ] `cargo test --locked`
- [ ] Relevant Windows, package, or integration checks were run or are covered by CI.
- [ ] For code changes, the lexical and hybrid release benchmarks were rerun and the hybrid recall average remains below 10 ms at every requested scale; results are included below.
- [ ] Candidate generation remains semantic-model-free; semantic models are used only for bounded post-generation reranking, with regression coverage if that boundary changed.

## Release impact

- [ ] No user-facing behavior change
- [ ] README/changelog updated
- [ ] Migration or compatibility notes included
- [ ] Version/package/release workflow impact reviewed

## Notes

<!-- Mention known limitations, follow-ups, or platform-specific details. -->

## Benchmark results

<!-- Required for code changes covered by CONTRIBUTING.md. Include hardware, commands, and lexical/hybrid average, P50, and P95 results. -->
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ on:
push:
branches:
- main
- v0.7.2
pull_request:
workflow_dispatch:
workflow_call:

permissions:
contents: read
Expand Down
214 changes: 181 additions & 33 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@ name: Build and Publish Optional NPM Binaries

on:
push:
branches: [main]
workflow_dispatch: # Allow manual triggering
tags: ["v*"]
workflow_dispatch:

jobs:
build-and-publish:
name: Build & Publish (${{ matrix.os }} - ${{ matrix.arch }})
coverage:
uses: ./.github/workflows/coverage.yml
secrets: inherit

build:
name: Build and verify (${{ matrix.os }} - ${{ matrix.arch }})
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
permissions:
contents: read
id-token: write

strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-22.04
container: rust:1.93-slim-bookworm
target: x86_64-unknown-linux-gnu
arch: x64
npm_os: linux
npm_arch: x64
pkg_name: engine-linux-x64
- os: ubuntu-24.04-arm
container: rust:1.93-slim-bookworm
target: aarch64-unknown-linux-gnu
arch: arm64
npm_os: linux
Expand All @@ -41,8 +47,18 @@ jobs:
npm_os: darwin
npm_arch: arm64
pkg_name: engine-darwin-arm64
- os: windows-latest
target: x86_64-pc-windows-msvc
arch: x64
npm_os: win32
npm_arch: x64
pkg_name: engine-win32-x64

steps:
- name: Install Linux build dependencies
if: runner.os == 'Linux'
run: apt-get update && apt-get install -y build-essential pkg-config libssl-dev ca-certificates curl git gzip

- name: Checkout Repository
uses: actions/checkout@v4

Expand All @@ -52,41 +68,66 @@ jobs:
node-version: '24'
registry-url: 'https://registry.npmjs.org'

- name: Update npm
run: npm install -g npm@latest
- name: Validate release tag
shell: bash
run: |
version="$(awk -F '"' '/^version = "/ { print $2; exit }' Cargo.toml)"
test "${GITHUB_REF_TYPE}" = "tag"
test "${GITHUB_REF_NAME}" = "v${version}"

- name: Setup Rust Toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@1.93.0
with:
targets: ${{ matrix.target }}

- name: Test publication guards
run: node --test scripts/publish-native-artifacts.test.cjs

- name: Test Rust Engine
run: cargo test --locked --all-targets -- --test-threads=1

- name: Build Rust Engine
run: cargo build --locked --release --target ${{ matrix.target }}

- name: Prepare NPM Package Structure
shell: bash
run: |
package_dir="npm-packages/${{ matrix.pkg_name }}"
mkdir -p "${package_dir}/bin" "${package_dir}/assets"

cp target/${{ matrix.target }}/release/cuemap "${package_dir}/bin/cuemap-native"
cp scripts/npm-native-wrapper.cjs "${package_dir}/bin/cuemap"
cp scripts/npm-native-README.md "${package_dir}/README.md"
cp LICENSE "${package_dir}/LICENSE"
chmod +x "${package_dir}/bin/cuemap" "${package_dir}/bin/cuemap-native"
mkdir -p "$package_dir/bin" "$package_dir/assets"

if [[ "${{ matrix.npm_os }}" == "win32" ]]; then
native_binary="cuemap.exe"
packaged_binary="cuemap-native.exe"
else
native_binary="cuemap"
packaged_binary="cuemap-native"
fi
cp "target/${{ matrix.target }}/release/$native_binary" "$package_dir/bin/$packaged_binary"
cp scripts/npm-native-wrapper.cjs "$package_dir/bin/cuemap"
cp scripts/npm-native-README.md "$package_dir/README.md"
cp LICENSE "$package_dir/LICENSE"
cp NOTICE "$package_dir/NOTICE"
cp THIRD_PARTY_NOTICES.txt "$package_dir/THIRD_PARTY_NOTICES.txt"
cp LGPL-2.1.txt "$package_dir/LGPL-2.1.txt"
cp ONNXRUNTIME-LICENSE.txt "$package_dir/ONNXRUNTIME-LICENSE.txt"
cp ONNXRUNTIME-NOTICES.txt "$package_dir/ONNXRUNTIME-NOTICES.txt"

if [[ "${{ matrix.npm_os }}" != "win32" ]]; then
chmod +x "$package_dir/bin/cuemap" "$package_dir/bin/$packaged_binary"
fi

tokenizer_url="https://cuemap.dev/assets/en_tokenizer.bin.gz"
tokenizer_sha256="f54fd31ec463f8646d0239bb531a64e0210ed1ae02bf5e3b42aeeb9bff8305ba"
curl -fsSL --retry 3 "${tokenizer_url}" -o "${package_dir}/assets/en_tokenizer.bin.gz"
curl -fsSL --retry 3 "$tokenizer_url" -o "$package_dir/assets/en_tokenizer.bin.gz"
node -e '
const fs = require("node:fs");
const crypto = require("node:crypto");
const [file, expected] = process.argv.slice(1);
const actual = crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
if (actual !== expected) throw new Error(`Tokenizer checksum mismatch: ${actual}`);
' "${package_dir}/assets/en_tokenizer.bin.gz" "${tokenizer_sha256}"
gzip -dc "${package_dir}/assets/en_tokenizer.bin.gz" > "${package_dir}/assets/en_tokenizer.bin"
rm "${package_dir}/assets/en_tokenizer.bin.gz"
' "$package_dir/assets/en_tokenizer.bin.gz" "$tokenizer_sha256"
gzip -dc "$package_dir/assets/en_tokenizer.bin.gz" > "$package_dir/assets/en_tokenizer.bin"
rm "$package_dir/assets/en_tokenizer.bin.gz"

version="$(awk -F '"' '/^version = "/ { print $2; exit }' Cargo.toml)"
node -e '
Expand All @@ -100,32 +141,139 @@ jobs:
os: [os],
cpu: [cpu],
bin: { cuemap: "bin/cuemap" },
files: ["bin", "assets", "README.md", "LICENSE"],
files: ["bin", "assets", "README.md", "LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.txt", "LGPL-2.1.txt", "ONNXRUNTIME-LICENSE.txt", "ONNXRUNTIME-NOTICES.txt"],
repository: { type: "git", url: "https://github.com/cuemap-dev/cuemap.git" },
author: "Kaan Demirel",
license: "BSL-1.1",
license: "Apache-2.0",
publishConfig: { access: "public" },
};
if (os === "linux") manifest.libc = ["glibc"];
fs.writeFileSync(output, `${JSON.stringify(manifest, null, 2)}\n`);
' "${package_dir}/package.json" "${version}" "${{ matrix.npm_os }}" "${{ matrix.npm_arch }}" "${{ matrix.pkg_name }}"
' "$package_dir/package.json" "$version" "${{ matrix.npm_os }}" "${{ matrix.npm_arch }}" "${{ matrix.pkg_name }}"

- name: Verify NPM package contents
working-directory: npm-packages/${{ matrix.pkg_name }}
shell: bash
run: |
test -x bin/cuemap
test -x bin/cuemap-native
test -f bin/cuemap
if [[ "${{ matrix.npm_os }}" == "win32" ]]; then
test -f bin/cuemap-native.exe
else
test -f bin/cuemap-native
fi
test -s assets/en_tokenizer.bin
npm pack --dry-run

- name: Publish to NPM
- name: Exercise packaged engine
run: node scripts/native-package-smoke.cjs npm-packages/${{ matrix.pkg_name }}

- name: Pack verified artifact
working-directory: npm-packages/${{ matrix.pkg_name }}
run: npm pack

- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.pkg_name }}
path: npm-packages/${{ matrix.pkg_name }}/*.tgz
if-no-files-found: error

consumer-preflight:
needs: build
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
package: engine-linux-x64
- os: ubuntu-24.04-arm
package: engine-linux-arm64
- os: macos-15-intel
package: engine-darwin-x64
- os: macos-latest
package: engine-darwin-arm64
- os: windows-latest
package: engine-win32-x64
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
path: rust_engine
- uses: actions/checkout@v4
with:
repository: cuemap-dev/typescript-sdk
ref: ${{ github.ref_name }}
path: typescript-sdk
- uses: actions/checkout@v4
with:
repository: cuemap-dev/python-sdk
ref: ${{ github.ref_name }}
path: python-sdk
- uses: actions/checkout@v4
with:
repository: cuemap-dev/cuemap-mcp
ref: ${{ github.ref_name }}
path: mcp-server
- uses: actions/checkout@v4
with:
repository: cuemap-dev/agent-plugin
ref: ${{ github.ref_name }}
path: agent-plugin
- uses: actions/setup-node@v4
with:
node-version: '24'
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: npm ci
working-directory: typescript-sdk
- run: npm run build
working-directory: typescript-sdk
- run: npm install --ignore-scripts --omit=optional --no-save --package-lock=false ../typescript-sdk
working-directory: mcp-server
- run: python -m pip install -e './python-sdk[dev]' wheel
- uses: actions/download-artifact@v4
with:
name: ${{ matrix.package }}
path: release-artifact
- name: Select tested native artifact
shell: bash
run: |
package_name="$(node -p 'require("./package.json").name')"
package_version="$(node -p 'require("./package.json").version')"
if npm view "${package_name}@${package_version}" version --registry=https://registry.npmjs.org >/dev/null 2>&1; then
echo "${package_name}@${package_version} already exists; skipping publish"
else
npm publish --access public --provenance --verbose
fi
artifact="$(find "$GITHUB_WORKSPACE/release-artifact" -name '*.tgz' -print -quit)"
test -n "$artifact"
echo "CUEMAP_RELEASE_ENGINE_TARBALL=$artifact" >> "$GITHUB_ENV"
- run: node rust_engine/scripts/release-preflight.cjs

docker-runtime:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- run: docker build -t cuemap-release-check .
- name: Check authenticated container
shell: bash
run: |
version="$(awk -F '"' '/^version = "/ { print $2; exit }' Cargo.toml)"
python3 scripts/verify-docker-runtime.py --image cuemap-release-check --version "$version"

publish:
needs: [build, coverage, consumer-preflight, docker-runtime]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
registry-url: https://registry.npmjs.org
- uses: actions/download-artifact@v4
with:
pattern: engine-*
path: packages
merge-multiple: true
- name: Publish exactly the tested tarballs
run: node scripts/publish-native-artifacts.cjs packages
Loading
Loading