Contributing to Tessera
Tessera is open for contributions. Whether you want to add a new technology stack, improve AI prompts, or fix bugs — contributions are welcome.
Setting Up the Dev Environment
# 1. Fork the repo on GitHub, then clone your fork
git clone https://github.com/YOUR-USERNAME/tessera-installer.git
cd tessera-installer
# 2. Install dependencies
composer install
# 3. Verify everything works
vendor/bin/phpunitYou should see 403 tests passing. All tests run with zero AI tokens — no API keys or AI tools needed for development.
Project Structure
tessera-installer/
├── bin/tessera # CLI entry point
├── src/
│ ├── NewCommand.php # Main `tessera new` orchestrator
│ ├── StepRunner.php # Executes AI steps with error recovery
│ ├── AiTool.php # Detects & runs AI CLI tools
│ ├── ToolRouter.php # Smart cross-tool routing
│ ├── ToolPreference.php # Plan tiers & tool ordering
│ ├── Memory.php # State persistence for resume
│ ├── SystemInfo.php # OS & tool detection
│ ├── Console.php # Terminal I/O & formatting
│ └── Stacks/
│ ├── StackInterface.php # Contract for all stacks
│ ├── StackRegistry.php # Stack discovery
│ ├── LaravelStack.php # Laravel + Filament
│ ├── NodeStack.php # Node.js / Next.js
│ ├── GoStack.php # Go backend
│ ├── FlutterStack.php # Flutter mobile
│ └── StaticStack.php # Static HTML + Tailwind
└── tests/
├── Unit/ # 8 unit test files
└── Integration/ # 2 integration test filesWhat You Can Contribute
Good first contributions
- Bug fixes — check open issues
- Documentation — fix typos, improve explanations, add examples
- Test coverage — add tests for edge cases
Bigger contributions
- New technology stacks — add a Ruby on Rails, Django, or Rust stack
- Improve AI prompts — make generated code better for specific use cases
- New features — after discussing in a GitHub issue first
How to Submit a Pull Request
Create a branch from
master:bashgit checkout -b fix/your-descriptionMake your changes and write tests if applicable
Run the test suite — all 403 tests must pass:
bashvendor/bin/phpunitRun code style (Laravel Pint):
bash../vendor/bin/pint src/ tests/Commit with a clear message:
bashgit commit -m "Fix: describe what you fixed and why"Push and open a PR against
master
Branch naming
fix/description— bug fixesfeature/description— new featuresdocs/description— documentation changestest/description— test improvements
Writing Tests
All tests must run with zero token usage — no real AI calls allowed.
// Use AiTool::fake() for test instances
$tool = AiTool::fake('claude');
// Suppress Console output in tests
ob_start();
// ... your test code
ob_end_clean();Test decision logic and state machines, not AI output quality. The AI output is unpredictable by nature — test the code that handles it.
# Run all tests
vendor/bin/phpunit
# Run a specific test file
vendor/bin/phpunit tests/Unit/MemoryTest.php
# Run a specific test method
vendor/bin/phpunit --filter=testResolveComplexDefaultsToClaudeOpusAdding a New Stack
- Create
src/Stacks/YourStack.phpimplementingStackInterface - Register it in
StackRegistry::init() - Implement the required methods:
| Method | Purpose |
|---|---|
name() | Short identifier (e.g. 'rails') |
label() | Display name (e.g. 'Ruby on Rails') |
description() | One-line description for AI context |
preflight() | Check that required tools are installed |
scaffold() | AI-driven build flow |
postSetup() | Run after build (migrations, seeding) |
completionInfo() | Show "your project is ready" info |
- Add tests in
tests/Unit/YourStackTest.php - Add a documentation page in the website repo
Key Design Decisions
These principles guide all contributions:
- Principle-based prompts — use 2-3 universal rules instead of long checklists. AI works better with principles than instructions.
- Version-agnostic — never hardcode framework versions. Read them from
vendor/orpackage.jsonat runtime. - Deterministic gates over AI grading — every meaningful step ends with a
gates:block in YAML. Preferexists_any/exists_all/command_passesover a second AI call to "review" the first. - Schema-versioned artefacts — every persistent file (
state.json,events.jsonl,plan.json) carriestessera.<artifact>/v<N>. Bump the version, never silently change the shape. - Atomic state — use temp file + rename for crash safety. Never write state directly. Memory writes happen before the matching audit event so resume stays correct on Ctrl+C.
- Minimal dependencies — runtime is PHP 8.4+ and
symfony/yaml. Adding a third dependency requires a strong reason.
What to Avoid
- Breaking changes without discussing in an issue first
- Large PRs that change many files — split them into smaller focused PRs
- Adding runtime dependencies — Tessera intentionally has zero runtime deps
- Hardcoding AI model names — use the routing system, not direct model references
- Tests that call real AI tools — all tests must work offline
Reporting Bugs
Open a GitHub issue with:
- Output of
tessera doctor— shows your system setup - Steps to reproduce — what command you ran, what you described
- Expected vs actual result — what went wrong
- OS and PHP version — from
php -vanduname -a
Environment Variables
Useful for testing different AI configurations:
| Variable | Values | Purpose |
|---|---|---|
TESSERA_CLAUDE_PLAN | max, pro, free | Override Claude plan detection |
TESSERA_CODEX_PLAN | plus, free | Override Codex plan detection |
TESSERA_GEMINI_PLAN | pro, free | Override Gemini plan detection |
TESSERA_TOOL_PREFERENCE | claude,gemini,codex | Custom tool order |
TESSERA_TOOL_EXCLUDE | codex | Tools to never use |
TESSERA_AI_TIMEOUT | 900 | AI step timeout in seconds (default 900) |
TESSERA_SAFE_AI | 1 | Claude only — strips --dangerously-skip-permissions, so Claude pauses on each action for approval. Does not affect Codex or Gemini. See Security Model. |
Related
- Getting Started — install Tessera and try it out before contributing
- AI Routing — understand how AI tools are orchestrated during builds
- Full CONTRIBUTING.md on GitHub — additional details