Contributing Guide
Thank you for your interest in contributing to Helix Agents! This guide covers development setup, testing, and the contribution process.
Development Setup
Prerequisites
- Node.js 18+
- npm 9+
- Git
- Docker (for integration tests)
Clone and Install
bash
git clone https://github.com/your-org/helix-agents.git
cd helix-agents
npm installBuild
bash
# Build all packages
npm run build
# Watch mode for development
npm run devProject Structure
helix-agents/
├── packages/
│ ├── core/ # Core types and logic
│ ├── sdk/ # Umbrella package
│ ├── runtime-js/ # JavaScript runtime
│ ├── runtime-temporal/ # Temporal runtime
│ ├── runtime-cloudflare/ # Cloudflare runtime
│ ├── store-memory/ # In-memory stores
│ ├── store-redis/ # Redis stores
│ ├── store-cloudflare/ # Cloudflare stores
│ ├── llm-vercel/ # Vercel AI SDK adapter
│ ├── ai-sdk/ # Frontend integration
│ └── e2e/ # End-to-end tests
├── examples/
│ ├── research-assistant/
│ ├── research-assistant-temporal/
│ └── research-assistant-cloudflare/
├── docs/ # Documentation (VitePress)
└── turbo.json # Turborepo configurationCommands
Building
bash
npm run build # Build all packages
npm run build:core # Build specific package
npm run dev # Watch modeTesting
bash
npm run test # Unit tests
npm run test:watch # Watch mode
npm run test:integration # Integration tests (requires services)
npm run test:e2e # End-to-end testsCode Quality
bash
npm run typecheck # TypeScript type checking
npm run lint # ESLint
npm run lint:fix # Auto-fix lint issues
npm run format # Prettier formattingDocumentation
bash
npm run docs:dev # Start dev server
npm run docs:build # Production build
npm run docs:preview # Preview buildTesting
Unit Tests
Located in src/__tests__/*.test.ts:
typescript
// packages/core/src/__tests__/step-processor.test.ts
import { describe, it, expect } from 'vitest';
import { planStepProcessing } from '../orchestration/step-processor.js';
describe('planStepProcessing', () => {
it('handles text response', () => {
const plan = planStepProcessing({
type: 'text',
content: 'Hello',
shouldStop: false,
});
expect(plan.isTerminal).toBe(false);
expect(plan.assistantMessagePlan?.content).toBe('Hello');
});
});Run unit tests:
bash
npm run test
npm run test -- --coverageIntegration Tests
Located in src/__tests__/*.integ.test.ts. Require external services:
bash
# Start services
docker-compose up -d
# Run integration tests
npm run test:integrationEnd-to-End Tests
Located in packages/e2e/:
bash
npm run test:e2eAdding a New Package
1. Create Directory
bash
mkdir packages/my-package
cd packages/my-package2. Initialize Package
json
// packages/my-package/package.json
{
"name": "@helix-agents/my-package",
"version": "0.0.1",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"files": ["dist"],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@helix-agents/core": "workspace:*"
},
"devDependencies": {
"tsup": "^8.0.0",
"typescript": "^5.3.0",
"vitest": "^1.0.0"
},
"publishConfig": {
"access": "public"
}
}3. Add TypeScript Config
json
// packages/my-package/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}4. Add Build Config
typescript
// packages/my-package/tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
sourcemap: true,
});5. Create Source Files
typescript
// packages/my-package/src/index.ts
export function myFunction() {
return 'hello';
}6. Update Turborepo
Add to turbo.json if special build requirements.
Code Style
TypeScript
- Strict mode enabled
- Explicit return types on public APIs
- Use
readonlyfor immutable properties - Prefer
interfaceovertypefor objects
typescript
// Good
interface MyConfig {
readonly name: string;
count: number;
}
export function processConfig(config: MyConfig): ProcessResult {
// ...
}
// Avoid
type MyConfig = {
name: string;
count: number;
};
export const processConfig = (config) => {
// ...
};Imports
- Use explicit
.jsextensions for local imports - Group imports: external, then internal, then relative
typescript
// External
import { z } from 'zod';
import type { Draft } from 'immer';
// Internal workspace
import { defineAgent } from '@helix-agents/core';
// Relative
import { helper } from './utils.js';
import type { MyType } from './types.js';Exports
- Export types separately with
export type - Use barrel exports in
index.ts
typescript
// types.ts
export interface MyInterface { ... }
export type MyType = { ... };
// index.ts
export type { MyInterface, MyType } from './types.js';
export { myFunction } from './functions.js';Comments
- JSDoc for public APIs
- Inline comments for complex logic
- No comments for self-explanatory code
typescript
/**
* Process an agent step and determine next actions.
*
* @param stepResult - The result from the LLM adapter
* @param options - Processing options
* @returns A plan describing what operations to perform
*/
export function planStepProcessing<TOutput>(
stepResult: StepResult<TOutput>,
options?: PlanStepProcessingOptions<TOutput>
): StepProcessingPlan<TOutput> {
// Check for __finish__ tool call (signals completion)
const finishCall = findFinishToolCall(stepResult);
// ...
}Pull Request Process
1. Create a Branch
bash
git checkout -b feature/my-feature
# or
git checkout -b fix/bug-description2. Make Changes
- Write code
- Add tests
- Update documentation if needed
3. Run Checks
bash
npm run typecheck
npm run lint
npm run test
npm run build4. Add Changeset
For changes that affect published packages:
bash
npx changesetSelect affected packages and describe changes.
5. Commit
bash
git add .
git commit -m "feat: add new feature"Commit message format:
feat:New featurefix:Bug fixdocs:Documentationrefactor:Code refactoringtest:Test changeschore:Build/tooling changes
6. Push and Create PR
bash
git push -u origin feature/my-featureCreate PR with:
- Clear description
- Link to related issues
- Test instructions if applicable
Changesets
We use Changesets for versioning.
Adding a Changeset
bash
npx changeset- Select affected packages
- Choose bump type (patch/minor/major)
- Write description
Changeset File
Creates .changeset/random-name.md:
markdown
---
'@helix-agents/core': minor
'@helix-agents/runtime-js': patch
---
Add new orchestration function for step processingRelease Process
Maintainers handle releases:
bash
# Consume changesets and update versions
npx changeset version
# Review changes
git diff
# Commit and create release PR
git add .
git commit -m "chore: version packages"
git push
# After merge, publish
npm run publishGetting Help
- Open an issue for bugs or feature requests
- Discussions for questions
- Check existing issues before creating new ones
Code of Conduct
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
License
Contributions are licensed under the project's license (see LICENSE file).