Contributing Guide
Thank you for your interest in contributing to Kuse Cowork! This guide will help you get started.
Ways to Contribute
- Bug Reports: Report issues you encounter
- Feature Requests: Suggest new features
- Code: Submit pull requests
- Documentation: Improve docs
- Testing: Help test new releases
- Community: Help others in discussions
Getting Started
1. Fork the Repository
- Go to github.com/kuse-ai/kuse_cowork
- Click "Fork"
- Clone your fork:
bash
git clone https://github.com/YOUR_USERNAME/kuse_cowork.git
cd kuse_cowork2. Set Up Development Environment
Follow the Development Setup guide.
3. Create a Branch
bash
# Create feature branch
git checkout -b feature/my-feature
# Or bugfix branch
git checkout -b fix/issue-123Development Workflow
Making Changes
- Make your changes
- Test locally with
pnpm tauri dev - Run linters and tests
bash
# Frontend
pnpm lint
pnpm test
# Backend
cd src-tauri
cargo fmt
cargo clippy
cargo testCommit Messages
Follow conventional commits:
type(scope): description
[optional body]
[optional footer]Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formattingrefactor: Code restructuringtest: Adding testschore: Maintenance
Examples:
feat(agent): add support for parallel tool execution
fix(docker): handle container cleanup on timeout
docs(readme): update installation instructionsPull Request Process
Push your branch:
bashgit push origin feature/my-featureCreate Pull Request:
- Go to your fork on GitHub
- Click "Compare & pull request"
- Fill out the PR template
PR Template:
markdown## Description Brief description of changes ## Type of Change - [ ] Bug fix - [ ] New feature - [ ] Documentation - [ ] Refactoring ## Testing How was this tested? ## Checklist - [ ] Code follows style guidelines - [ ] Tests pass locally - [ ] Documentation updatedReview Process:
- Maintainers will review your PR
- Address feedback
- Once approved, PR will be merged
Code Guidelines
TypeScript/SolidJS
typescript
// Use TypeScript types
interface Props {
title: string;
onClick: () => void;
}
// Functional components
const MyComponent: Component<Props> = (props) => {
// Use signals for state
const [count, setCount] = createSignal(0);
// Use createMemo for derived state
const doubled = createMemo(() => count() * 2);
return (
<div>
<h1>{props.title}</h1>
<button onClick={props.onClick}>
Count: {count()} (doubled: {doubled()})
</button>
</div>
);
};Rust
rust
// Use proper error handling
pub fn process(input: &str) -> Result<Output, Error> {
let data = parse(input)?;
let result = transform(data)?;
Ok(result)
}
// Document public APIs
/// Processes the input and returns transformed output.
///
/// # Arguments
/// * `input` - The input string to process
///
/// # Returns
/// The transformed output or an error
pub fn process(input: &str) -> Result<Output, Error> {
// ...
}
// Use meaningful names
let user_settings = load_settings()?; // Good
let us = load_settings()?; // AvoidCSS
css
/* Use component-scoped styles */
.my-component {
/* Layout */
display: flex;
flex-direction: column;
/* Spacing */
padding: 1rem;
margin: 0.5rem;
/* Appearance */
background: var(--background-color);
border-radius: 4px;
}
/* Use CSS variables for theming */
.my-component-title {
color: var(--text-color);
font-size: 1.25rem;
}Testing Guidelines
Unit Tests
typescript
// Frontend
import { render, screen } from "@solidjs/testing-library";
test("renders button with text", () => {
render(() => <Button>Click me</Button>);
expect(screen.getByText("Click me")).toBeInTheDocument();
});rust
// Backend
#[test]
fn test_parse_response() {
let input = r#"{"content": "hello"}"#;
let result = parse_response(input);
assert!(result.is_ok());
assert_eq!(result.unwrap().content, "hello");
}Integration Tests
rust
#[tokio::test]
async fn test_tool_execution() {
let executor = ToolExecutor::new(Some("/tmp/test".into()));
let result = executor.execute(&read_file_tool).await;
assert!(result.content.contains("expected content"));
}Documentation
Code Documentation
rust
/// Tool executor for running agent tools.
///
/// Handles execution of built-in tools and MCP tools,
/// managing the project context and permissions.
pub struct ToolExecutor {
/// Path to the project workspace
project_path: Option<String>,
/// MCP manager for external tools
mcp_manager: Option<Arc<MCPManager>>,
}User Documentation
- Use clear, concise language
- Include examples
- Add screenshots when helpful
- Keep docs up to date with code changes
Issue Guidelines
Bug Reports
Include:
- Description: What happened?
- Expected: What should happen?
- Steps: How to reproduce
- Environment: OS, version, etc.
- Logs: Error messages if any
Feature Requests
Include:
- Problem: What problem does this solve?
- Solution: Proposed solution
- Alternatives: Other options considered
- Context: Any additional info
Community Guidelines
Be Respectful
- Treat everyone with respect
- Be constructive in feedback
- Welcome newcomers
Be Helpful
- Answer questions when you can
- Share knowledge
- Help improve documentation
Be Patient
- Maintainers are volunteers
- Reviews take time
- Complex features need discussion
Recognition
Contributors are recognized in:
- GitHub contributors list
- Release notes
- Project README (for significant contributions)
Questions?
- Open a Discussion
- Check existing issues
- Read the documentation
Thank you for contributing!