* fix(control-plane): force NODE_ENV=production for production build A globally-exported NODE_ENV=development (common in dev shells) overrides Next.js's production default during `next build`, bundling React's development build under the production server renderer. Static prerendering then crashes with "Cannot read properties of null (reading 'useContext')" — even on the built-in _global-error page. Pin NODE_ENV=production for the build step so it is robust regardless of the caller's shell. Docker is unaffected (it invokes next build directly in a clean env). * chore(dev): add one-shot dev environment setup script Add scripts/dev/setup.sh: an idempotent bootstrap that installs the required toolchains (uv/Python, Node/npm, Rust/cargo) when missing, creates .env, configures git hooks, installs all Python + Node workspace deps, pre-downloads the local ML models + tokenizer for offline use, and builds the TypeScript SDK and Rust CLI. Flags: --skip-build, --skip-models, --with-docs, --force. Document it in CONTRIBUTING.md as the recommended setup, keeping the manual steps as a fallback.
3.9 KiB
Contributing to Hindsight
Thanks for your interest in contributing to Hindsight!
Getting Started
-
Fork and clone the repository
git clone [email protected]:vectorize-io/hindsight.git cd hindsight -
Bootstrap your dev environment in one shot:
./scripts/dev/setup.shThis is idempotent (safe to re-run) and gets you ready to develop, including offline. It:
- installs the required toolchains if missing (uv/Python, Node/npm, Rust/cargo),
- creates
.envfrom.env.example(remember to add your LLM API key), - configures git hooks,
- installs all Python and Node workspace dependencies,
- pre-downloads the local ML models + tokenizer so the API runs offline,
- builds the TypeScript SDK and the Rust CLI.
Useful flags:
--skip-build(deps only),--skip-models(skip ML model download),--with-docs(also build the docs site),--force(rebuild artifacts). Docker image builds are out of scope. Run./scripts/dev/setup.sh --helpfor details.
Manual setup
If you'd rather set things up by hand instead of running the script above:
-
Set up your environment:
cp .env.example .envEdit the .env to add LLM API key and config as required
-
Install dependencies:
# Python dependencies uv sync --directory hindsight-api/ # Node dependencies (uses npm workspaces) npm install
Development
Running the API locally
./scripts/dev/start-api.sh
Running the Control Plane locally
./scripts/dev/start-control-plane.sh
Running the documentation locally
./scripts/dev/start-docs.sh
Running tests
cd hindsight-api
uv run pytest tests/
Code Style
We use Ruff for Python linting and formatting, and ESLint/Prettier for TypeScript.
Setting up git hooks (recommended)
Set up git hooks to automatically lint and format code before each commit:
./scripts/setup-hooks.sh
This configures git to use the hooks in .githooks/, which run all scripts in scripts/hooks/ on commit. The lint hook runs in parallel:
- Python:
ruff check --fix,ruff format,ty check - TypeScript:
eslint --fix,prettier
Manual linting and formatting
# Run all lints (same as pre-commit)
./scripts/hooks/lint.sh
# Or run individually for Python:
cd hindsight-api
uv run ruff check --fix . # Lint and auto-fix
uv run ruff format . # Format code
uv run ty check hindsight_api # Type check
Style guidelines
- Use Python type hints
- Follow existing code patterns
- Keep functions focused and well-named
Pull Requests
- Create a feature branch from
main - Make your changes
- Run tests to ensure nothing breaks
- Submit a PR with a clear description of changes
Release Process
The project uses scripts/release.sh for creating releases. This script automates the entire release workflow:
- Bumps version in all components (API, clients, CLI, control plane, Helm)
- Regenerates OpenAPI spec and client SDKs (Python, TypeScript, Rust)
- Updates documentation versioning
- Creates a commit and git tag
- Pushes to GitHub (triggers CI/CD to publish packages)
Usage
./scripts/release.sh <version>
Example:
./scripts/release.sh 0.5.0
Important for Developers
- During development, version bumps in
__init__.pydo NOT require client regeneration - Clients are only regenerated during releases
- Do not manually run
./scripts/generate-clients.shunless testing generation changes - Client version comments will reflect the API version from the latest release
Reporting Issues
Open an issue on GitHub with:
- Clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Environment details (OS, Python version)
Questions?
Open a discussion on GitHub or reach out to the maintainers.