* Add contributing section for jan * Update CONTRIBUTING.md Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --------- Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
parent
a6e5273c7a
commit
b0eec07a01
262
CONTRIBUTING.md
262
CONTRIBUTING.md
@ -1,32 +1,266 @@
|
|||||||
# Contributing to jan
|
# Contributing to Jan
|
||||||
|
|
||||||
First off, thank you for considering contributing to jan. It's people like you that make jan such an amazing project.
|
First off, thank you for considering contributing to Jan. It's people like you that make Jan such an amazing project.
|
||||||
|
|
||||||
|
Jan is an AI assistant that can run 100% offline on your device. Think ChatGPT, but private, local, and under your complete control. If you're thinking about contributing, you're already awesome - let's make AI accessible to everyone, one commit at a time.
|
||||||
|
|
||||||
|
## Quick Links to Component Guides
|
||||||
|
|
||||||
|
- **[Web App](./web-app/CONTRIBUTING.md)** - React UI and logic
|
||||||
|
- **[Core SDK](./core/CONTRIBUTING.md)** - TypeScript SDK and extension system
|
||||||
|
- **[Extensions](./extensions/CONTRIBUTING.md)** - Supportive modules for the frontend
|
||||||
|
- **[Tauri Backend](./src-tauri/CONTRIBUTING.md)** - Rust native integration
|
||||||
|
- **[Tauri Plugins](./src-tauri/plugins/CONTRIBUTING.md)** - Hardware and system plugins
|
||||||
|
|
||||||
|
## How Jan Actually Works
|
||||||
|
|
||||||
|
Jan is a desktop app that runs local AI models. Here's how the components actually connect:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────────────┐
|
||||||
|
│ Web App (Frontend) │
|
||||||
|
│ (web-app/) │
|
||||||
|
│ • React UI │
|
||||||
|
│ • Chat Interface │
|
||||||
|
│ • Settings Pages │
|
||||||
|
│ • Model Hub │
|
||||||
|
└────────────┬─────────────────────────────┬───────────────┘
|
||||||
|
│ │
|
||||||
|
│ imports │ imports
|
||||||
|
▼ ▼
|
||||||
|
┌──────────────────────┐ ┌──────────────────────┐
|
||||||
|
│ Core SDK │ │ Extensions │
|
||||||
|
│ (core/) │ │ (extensions/) │
|
||||||
|
│ │ │ │
|
||||||
|
│ • TypeScript APIs │◄─────│ • Assistant Mgmt │
|
||||||
|
│ • Extension System │ uses │ • Conversations │
|
||||||
|
│ • Event Bus │ │ • Downloads │
|
||||||
|
│ • Type Definitions │ │ • LlamaCPP │
|
||||||
|
└──────────┬───────────┘ └───────────┬──────────┘
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────────┐ │
|
||||||
|
│ │ Web App │ │
|
||||||
|
│ └──────────┬───────────┘ │
|
||||||
|
│ │ │
|
||||||
|
└──────────────┼───────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Tauri IPC
|
||||||
|
(invoke commands)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌───────────────────────────────────────────────────────────┐
|
||||||
|
│ Tauri Backend (Rust) │
|
||||||
|
│ (src-tauri/) │
|
||||||
|
│ │
|
||||||
|
│ • Window Management • File System Access │
|
||||||
|
│ • Process Control • System Integration │
|
||||||
|
│ • IPC Command Handler • Security & Permissions │
|
||||||
|
└───────────────────────────┬───────────────────────────────┘
|
||||||
|
│
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌───────────────────────────────────────────────────────────┐
|
||||||
|
│ Tauri Plugins (Rust) │
|
||||||
|
│ (src-tauri/plugins/) │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ Hardware Plugin │ │ LlamaCPP Plugin │ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ │ • CPU/GPU Info │ │ • Process Mgmt │ │
|
||||||
|
│ │ • Memory Stats │ │ • Model Loading │ │
|
||||||
|
│ │ • System Info │ │ • Inference │ │
|
||||||
|
│ └──────────────────┘ └──────────────────┘ │
|
||||||
|
└───────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### The Communication Flow
|
||||||
|
|
||||||
|
1. **JavaScript Layer Relationships**:
|
||||||
|
- Web App imports Core SDK and Extensions as JavaScript modules
|
||||||
|
- Extensions use Core SDK for shared functionality
|
||||||
|
- All run in the browser/webview context
|
||||||
|
|
||||||
|
2. **All Three → Backend**: Through Tauri IPC
|
||||||
|
- **Web App** → Backend: `await invoke('app_command', data)`
|
||||||
|
- **Core SDK** → Backend: `await invoke('core_command', data)`
|
||||||
|
- **Extensions** → Backend: `await invoke('ext_command', data)`
|
||||||
|
- Each component can independently call backend commands
|
||||||
|
|
||||||
|
3. **Backend → Plugins**: Native Rust integration
|
||||||
|
- Backend loads plugins as Rust libraries
|
||||||
|
- Direct function calls, no IPC overhead
|
||||||
|
|
||||||
|
4. **Response Flow**:
|
||||||
|
- Plugin → Backend → IPC → Requester (Web App/Core/Extension) → UI updates
|
||||||
|
|
||||||
|
### Real-World Example: Loading a Model
|
||||||
|
|
||||||
|
Here's what actually happens when you click "Download Llama 3":
|
||||||
|
|
||||||
|
1. **Web App** (`web-app/`) - User clicks download button
|
||||||
|
2. **Extension** (`extensions/download-extension`) - Handles the download logic
|
||||||
|
3. **Tauri Backend** (`src-tauri/`) - Actually downloads the file to disk
|
||||||
|
4. **Extension** (`extensions/llamacpp-extension`) - Prepares model for loading
|
||||||
|
5. **Tauri Plugin** (`src-tauri/plugins/llamacpp`) - Starts llama.cpp process
|
||||||
|
6. **Hardware Plugin** (`src-tauri/plugins/hardware`) - Detects GPU, optimizes settings
|
||||||
|
7. **Model ready!** - User can start chatting
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
jan/
|
||||||
|
├── web-app/ # React frontend (what users see)
|
||||||
|
├── src-tauri/ # Rust backend (system integration)
|
||||||
|
│ ├── src/core/ # Core Tauri commands
|
||||||
|
│ └── plugins/ # Tauri plugins (hardware, llamacpp)
|
||||||
|
├── core/ # TypeScript SDK (API layer)
|
||||||
|
├── extensions/ # JavaScript extensions
|
||||||
|
│ ├── assistant-extension/
|
||||||
|
│ ├── conversational-extension/
|
||||||
|
│ ├── download-extension/
|
||||||
|
│ └── llamacpp-extension/
|
||||||
|
├── docs/ # Documentation website
|
||||||
|
├── website/ # Marketing website
|
||||||
|
├── autoqa/ # Automated testing
|
||||||
|
├── scripts/ # Build utilities
|
||||||
|
│
|
||||||
|
├── package.json # Root workspace configuration
|
||||||
|
├── Makefile # Build automation commands
|
||||||
|
├── mise.toml # Mise tool configuration
|
||||||
|
├── LICENSE # Apache 2.0 license
|
||||||
|
└── README.md # Project overview
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
### The Scenic Route (Build from Source)
|
||||||
|
|
||||||
|
**Prerequisites:**
|
||||||
|
- Node.js ≥ 20.0.0
|
||||||
|
- Yarn ≥ 1.22.0
|
||||||
|
- Rust (for Tauri)
|
||||||
|
- Make ≥ 3.81
|
||||||
|
|
||||||
|
**Option 1: The Easy Way (Make)**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/menloresearch/jan
|
||||||
|
cd jan
|
||||||
|
make dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: The Easier Way (Mise)**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/menloresearch/jan
|
||||||
|
cd jan
|
||||||
|
|
||||||
|
# Install mise
|
||||||
|
curl https://mise.run | sh
|
||||||
|
|
||||||
|
# Let mise handle everything
|
||||||
|
mise install # installs Node.js, Rust, and other tools
|
||||||
|
mise dev # runs the full development setup
|
||||||
|
```
|
||||||
|
|
||||||
## How Can I Contribute?
|
## How Can I Contribute?
|
||||||
|
|
||||||
### Reporting Bugs
|
### Reporting Bugs
|
||||||
|
|
||||||
- **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/menloresearch/jan/issues).
|
- **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/menloresearch/jan/issues)
|
||||||
- If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/menloresearch/jan/issues/new).
|
- If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/menloresearch/jan/issues/new)
|
||||||
|
- Include your system specs and error logs - it helps a ton
|
||||||
|
|
||||||
### Suggesting Enhancements
|
### Suggesting Enhancements
|
||||||
|
|
||||||
- Open a new issue with a clear title and description.
|
- Open a new issue with a clear title and description
|
||||||
|
- Explain why this enhancement would be useful
|
||||||
|
- Include mockups or examples if you can
|
||||||
|
|
||||||
### Your First Code Contribution
|
### Your First Code Contribution
|
||||||
|
|
||||||
- Fork the repo.
|
**Choose Your Adventure:**
|
||||||
- Create a new branch (`git checkout -b feature-name`).
|
- **Frontend UI and logic** → `web-app/`
|
||||||
- Commit your changes (`git commit -am 'Add some feature'`).
|
- **Shared API declarations** → `core/`
|
||||||
- Push to the branch (`git push origin feature-name`).
|
- **Backend system integration** → `src-tauri/`
|
||||||
- Open a new Pull Request.
|
- **Business logic features** → `extensions/`
|
||||||
|
- **Dedicated backend handler** → `src-tauri/plugins/`
|
||||||
|
|
||||||
## Styleguides
|
**The Process:**
|
||||||
|
1. Fork the repo
|
||||||
|
2. Create a new branch (`git checkout -b feature-name`)
|
||||||
|
3. Make your changes (and write tests!)
|
||||||
|
4. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
|
5. Push to the branch (`git push origin feature-name`)
|
||||||
|
6. Open a new Pull Request against `dev` branch
|
||||||
|
|
||||||
### Git Commit Messages
|
## Testing
|
||||||
|
|
||||||
- Use the present tense ("Add feature" not "Added feature").
|
```bash
|
||||||
|
yarn test # All tests
|
||||||
|
cd src-tauri && cargo test # Rust tests
|
||||||
|
cd autoqa && python main.py # End-to-end tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
### TypeScript/JavaScript
|
||||||
|
- TypeScript required (we're not animals)
|
||||||
|
- ESLint + Prettier
|
||||||
|
- Functional React components
|
||||||
|
- Proper typing (no `any` - seriously!)
|
||||||
|
|
||||||
|
### Rust
|
||||||
|
- `cargo fmt` + `cargo clippy`
|
||||||
|
- `Result<T, E>` for error handling
|
||||||
|
- Document public APIs
|
||||||
|
|
||||||
|
## Git Conventions
|
||||||
|
|
||||||
|
### Branches
|
||||||
|
- `main` - stable releases
|
||||||
|
- `dev` - development (target this for PRs)
|
||||||
|
- `feature/*` - new features
|
||||||
|
- `fix/*` - bug fixes
|
||||||
|
|
||||||
|
### Commit Messages
|
||||||
|
- Use the present tense ("Add feature" not "Added feature")
|
||||||
|
- Be descriptive but concise
|
||||||
|
- Reference issues when applicable
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
feat: add support for Qwen models
|
||||||
|
fix: resolve memory leak in model loading
|
||||||
|
docs: update installation instructions
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If things go sideways:
|
||||||
|
|
||||||
|
1. **Check our [troubleshooting docs](https://jan.ai/docs/troubleshooting)**
|
||||||
|
2. **Clear everything and start fresh:** `make clean` then `make dev`
|
||||||
|
3. **Copy your error logs and system specs**
|
||||||
|
4. **Ask for help in our [Discord](https://discord.gg/FTk2MvZwJH)** `#🆘|jan-help` channel
|
||||||
|
|
||||||
|
Common issues:
|
||||||
|
- **Build failures**: Check Node.js and Rust versions
|
||||||
|
- **Extension not loading**: Verify it's properly registered
|
||||||
|
- **Model not working**: Check hardware requirements and GPU drivers
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
- [Documentation](https://jan.ai/docs) - The manual you should read
|
||||||
|
- [Discord Community](https://discord.gg/jan) - Where the community lives
|
||||||
|
- [GitHub Issues](https://github.com/janhq/jan/issues) - Report bugs here
|
||||||
|
- [GitHub Discussions](https://github.com/janhq/jan/discussions) - Ask questions
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Apache 2.0 - Because sharing is caring. See [LICENSE](./LICENSE) for the legal stuff.
|
||||||
|
|
||||||
## Additional Notes
|
## Additional Notes
|
||||||
|
|
||||||
Thank you for contributing to jan!
|
We're building something pretty cool here - an AI assistant that respects your privacy and runs entirely on your machine. Every contribution, no matter how small, helps make AI more accessible to everyone.
|
||||||
|
|
||||||
|
Thanks for being part of the journey. Let's build the future of local AI together! 🚀
|
||||||
|
|||||||
71
core/CONTRIBUTING.md
Normal file
71
core/CONTRIBUTING.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Contributing to Jan Core
|
||||||
|
|
||||||
|
[← Back to Main Contributing Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
TypeScript SDK providing extension system, APIs, and type definitions for all Jan components.
|
||||||
|
|
||||||
|
## Key Directories
|
||||||
|
|
||||||
|
- **`/src/browser`** - Core APIs (events, extensions, file system)
|
||||||
|
- **`/src/browser/extensions`** - Built-in extensions (assistant, inference, conversational)
|
||||||
|
- **`/src/types`** - TypeScript type definitions
|
||||||
|
- **`/src/test`** - Testing utilities
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
|
||||||
|
1. **Platform Agnostic** - Works everywhere (browser, Node.js)
|
||||||
|
2. **Extension-Based** - New features = new extensions
|
||||||
|
3. **Type Everything** - TypeScript required
|
||||||
|
4. **Event-Driven** - Components communicate via events
|
||||||
|
|
||||||
|
### Building & Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the SDK
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
yarn test
|
||||||
|
|
||||||
|
# Watch mode
|
||||||
|
yarn test:watch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Event System
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Emit events
|
||||||
|
events.emit('model:loaded', { modelId: 'llama-3' })
|
||||||
|
|
||||||
|
// Listen for events
|
||||||
|
events.on('model:loaded', (data) => {
|
||||||
|
console.log('Model loaded:', data.modelId)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
describe('MyFeature', () => {
|
||||||
|
it('should do something', () => {
|
||||||
|
const result = doSomething()
|
||||||
|
expect(result).toBe('expected')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Keep it simple
|
||||||
|
- Use TypeScript fully (no `any`)
|
||||||
|
- Write tests for critical features
|
||||||
|
- Follow existing patterns
|
||||||
|
- Export new modules in index files
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **TypeScript** - Type safety
|
||||||
|
- **Rolldown** - Bundling
|
||||||
|
- **Vitest** - Testing
|
||||||
137
extensions/CONTRIBUTING.md
Normal file
137
extensions/CONTRIBUTING.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# Contributing to Jan Extensions
|
||||||
|
|
||||||
|
[← Back to Main Contributing Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
Extensions add specific features to Jan as self-contained modules.
|
||||||
|
|
||||||
|
## Current Extensions
|
||||||
|
|
||||||
|
### `/assistant-extension`
|
||||||
|
- Assistant CRUD operations
|
||||||
|
- `src/index.ts` - Main implementation
|
||||||
|
|
||||||
|
### `/conversational-extension`
|
||||||
|
- Message handling, conversation state
|
||||||
|
- `src/index.ts` - Chat logic
|
||||||
|
|
||||||
|
### `/download-extension`
|
||||||
|
- Model downloads with progress tracking
|
||||||
|
- `src/index.ts` - Download logic
|
||||||
|
- `settings.json` - Download settings
|
||||||
|
|
||||||
|
### `/llamacpp-extension`
|
||||||
|
- Local model inference via llama.cpp
|
||||||
|
- `src/index.ts` - Entry point
|
||||||
|
- `src/backend.ts` - llama.cpp integration
|
||||||
|
- `settings.json` - Model settings
|
||||||
|
|
||||||
|
## Creating Extensions
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir my-extension
|
||||||
|
cd my-extension
|
||||||
|
yarn init
|
||||||
|
```
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
my-extension/
|
||||||
|
├── package.json
|
||||||
|
├── rolldown.config.mjs
|
||||||
|
├── src/index.ts
|
||||||
|
└── settings.json (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Extension
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Extension } from '@janhq/core'
|
||||||
|
|
||||||
|
export default class MyExtension extends Extension {
|
||||||
|
async onLoad() {
|
||||||
|
// Extension initialization
|
||||||
|
}
|
||||||
|
|
||||||
|
async onUnload() {
|
||||||
|
// Cleanup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building & Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build extension
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
yarn test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Service Registration
|
||||||
|
```typescript
|
||||||
|
async onLoad() {
|
||||||
|
this.registerService('myService', {
|
||||||
|
doSomething: async () => 'result'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Event Handling
|
||||||
|
```typescript
|
||||||
|
async onLoad() {
|
||||||
|
this.on('model:loaded', (model) => {
|
||||||
|
console.log('Model loaded:', model.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extension Lifecycle
|
||||||
|
|
||||||
|
1. **Jan starts** → Discovers extensions
|
||||||
|
2. **Loading** → Calls `onLoad()` method
|
||||||
|
3. **Active** → Extension responds to events
|
||||||
|
4. **Unloading** → Calls `onUnload()` on shutdown
|
||||||
|
|
||||||
|
## Debugging Extensions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if extension loaded
|
||||||
|
console.log(window.core.extensions)
|
||||||
|
|
||||||
|
# Debug extension events
|
||||||
|
this.on('*', console.log)
|
||||||
|
|
||||||
|
# Check extension services
|
||||||
|
console.log(window.core.api)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues
|
||||||
|
|
||||||
|
**Extension not loading?**
|
||||||
|
- Check package.json format: `@janhq/extension-name`
|
||||||
|
- Ensure `onLoad()` doesn't throw errors
|
||||||
|
- Verify exports in index.ts
|
||||||
|
|
||||||
|
**Events not working?**
|
||||||
|
- Check event name spelling
|
||||||
|
- Ensure listeners are set up in `onLoad()`
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Keep extensions focused on one feature
|
||||||
|
- Use async/await for all operations
|
||||||
|
- Clean up resources in onUnload()
|
||||||
|
- Handle errors gracefully
|
||||||
|
- Don't depend on other extensions
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **@janhq/core** - Core SDK and extension system
|
||||||
|
- **TypeScript** - Type safety
|
||||||
|
- **Rolldown** - Bundling
|
||||||
111
src-tauri/CONTRIBUTING.md
Normal file
111
src-tauri/CONTRIBUTING.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# Contributing to Tauri Backend
|
||||||
|
|
||||||
|
[← Back to Main Contributing Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
Rust backend that handles native system integration, file operations, and process management.
|
||||||
|
|
||||||
|
## Key Modules
|
||||||
|
|
||||||
|
- **`/src/core/app`** - App state and commands
|
||||||
|
- **`/src/core/downloads`** - Model download management
|
||||||
|
- **`/src/core/filesystem`** - File system operations
|
||||||
|
- **`/src/core/mcp`** - Model Context Protocol
|
||||||
|
- **`/src/core/server`** - Local API server
|
||||||
|
- **`/src/core/system`** - System information and utilities
|
||||||
|
- **`/src/core/threads`** - Conversation management
|
||||||
|
- **`/utils`** - Shared utility crate (CLI, crypto, HTTP, path utils). Used by plugins and the main backend.
|
||||||
|
- **`/plugins`** - Native Tauri plugins ([see plugins guide](./plugins/CONTRIBUTING.md))
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Adding Tauri Commands
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
async fn my_command(param: String) -> Result<String, String> {
|
||||||
|
Ok(format!("Processed: {}", param))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register in lib.rs
|
||||||
|
tauri::Builder::default()
|
||||||
|
.invoke_handler(tauri::generate_handler![my_command])
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building & Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development
|
||||||
|
yarn tauri dev
|
||||||
|
|
||||||
|
# Build
|
||||||
|
yarn tauri build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Management
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
async fn get_data(state: State<'_, AppState>) -> Result<Data, Error> {
|
||||||
|
state.get_data().await
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum AppError {
|
||||||
|
#[error("IO error: {0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Enable debug logging
|
||||||
|
env::set_var("RUST_LOG", "debug");
|
||||||
|
|
||||||
|
// Debug print in commands
|
||||||
|
#[tauri::command]
|
||||||
|
async fn my_command() -> Result<String, String> {
|
||||||
|
println!("Command called"); // Shows in terminal
|
||||||
|
dbg!("Debug info");
|
||||||
|
Ok("result".to_string())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Platform-Specific Notes
|
||||||
|
|
||||||
|
**Windows**: Requires Visual Studio Build Tools
|
||||||
|
**macOS**: Needs Xcode command line tools
|
||||||
|
**Linux**: May need additional system packages
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues
|
||||||
|
|
||||||
|
**Build failures**: Check Rust toolchain version
|
||||||
|
**IPC errors**: Ensure command names match frontend calls
|
||||||
|
**Permission errors**: Update capabilities configuration
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Always use `Result<T, E>` for fallible operations
|
||||||
|
- Validate all input from frontend
|
||||||
|
- Use async for I/O operations
|
||||||
|
- Follow Rust naming conventions
|
||||||
|
- Document public APIs
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **Tauri** - Desktop app framework
|
||||||
|
- **Tokio** - Async runtime
|
||||||
|
- **Serde** - JSON serialization
|
||||||
|
- **thiserror** - Error handling
|
||||||
119
src-tauri/plugins/CONTRIBUTING.md
Normal file
119
src-tauri/plugins/CONTRIBUTING.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# Contributing to Tauri Plugins
|
||||||
|
|
||||||
|
[← Back to Main Contributing Guide](../../CONTRIBUTING.md) | [← Back to Tauri Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
Native Rust plugins for hardware access, process management, and system integration.
|
||||||
|
|
||||||
|
## Current Plugins
|
||||||
|
|
||||||
|
### `/tauri-plugin-hardware`
|
||||||
|
- Hardware detection (CPU, GPU, memory)
|
||||||
|
|
||||||
|
### `/tauri-plugin-llamacpp`
|
||||||
|
- llama.cpp process management and model inference
|
||||||
|
|
||||||
|
## Plugin Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
tauri-plugin-name/
|
||||||
|
├── Cargo.toml
|
||||||
|
├── src/lib.rs # Plugin entry point
|
||||||
|
├── src/commands.rs # Tauri commands
|
||||||
|
├── guest-js/index.ts # JavaScript API
|
||||||
|
└── permissions/default.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Creating Plugins
|
||||||
|
|
||||||
|
Assuming that your new plugin name is `my-plugin`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# with npx
|
||||||
|
npx @tauri-apps/cli plugin new my-plugin
|
||||||
|
|
||||||
|
# with cargo
|
||||||
|
cargo tauri plugin new my-plugin
|
||||||
|
|
||||||
|
cd tauri-plugin-my-plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plugin Registration
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use tauri::{plugin::{Builder, TauriPlugin}, Runtime};
|
||||||
|
|
||||||
|
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||||
|
Builder::new("my-plugin")
|
||||||
|
.invoke_handler(tauri::generate_handler![commands::my_command])
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commands & JavaScript API
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn my_command(param: String) -> Result<String, Error> {
|
||||||
|
Ok(format!("Result: {}", param))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
|
||||||
|
export async function myCommand(param: string): Promise<string> {
|
||||||
|
return await invoke('plugin:my-plugin|my_command', { param })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building & Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build # Build plugin
|
||||||
|
yarn build # Build JavaScript
|
||||||
|
cargo test # Run tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# permissions/default.toml - Be specific
|
||||||
|
[[permission]]
|
||||||
|
identifier = "allow-hardware-info"
|
||||||
|
description = "Read system hardware information"
|
||||||
|
|
||||||
|
# Never use wildcards in production
|
||||||
|
# ❌ identifier = "allow-*"
|
||||||
|
# ✅ identifier = "allow-specific-action"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Plugins
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test plugin in isolation
|
||||||
|
cd tauri-plugin-my-plugin
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# Test with main app
|
||||||
|
cd ../../
|
||||||
|
yarn tauri dev
|
||||||
|
|
||||||
|
# Test JavaScript API
|
||||||
|
yarn build && node -e "const plugin = require('./dist-js'); console.log(plugin)"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Use secure permission configurations
|
||||||
|
- Validate all command inputs
|
||||||
|
- Handle platform differences properly
|
||||||
|
- Clean up resources in Drop implementations
|
||||||
|
- Test on all target platforms
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **Tauri** - Plugin framework
|
||||||
|
- **Serde** - JSON serialization
|
||||||
|
- **Tokio** - Async runtime (if needed)
|
||||||
128
web-app/CONTRIBUTING.md
Normal file
128
web-app/CONTRIBUTING.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Contributing to Jan Web App
|
||||||
|
|
||||||
|
[← Back to Main Contributing Guide](../CONTRIBUTING.md)
|
||||||
|
|
||||||
|
React frontend using TypeScript, TanStack Router, Radix UI, and Tailwind CSS. State is managed by React State and Zustand.
|
||||||
|
|
||||||
|
## Key Directories
|
||||||
|
|
||||||
|
- **`/src/components/ui`** - UI components (buttons, dialogs, inputs)
|
||||||
|
- **`/src/containers`** - Complex feature components (ChatInput, ThreadContent)
|
||||||
|
- **`/src/hooks`** - Custom React hooks (useChat, useThreads, useAppState)
|
||||||
|
- **`/src/routes`** - TanStack Router pages
|
||||||
|
- **`/src/services`** - API layer for backend communication
|
||||||
|
- **`/src/types`** - TypeScript definitions
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Component Example
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
interface Props {
|
||||||
|
title: string
|
||||||
|
onAction?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MyComponent: React.FC<Props> = ({ title, onAction }) => {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<h2>{title}</h2>
|
||||||
|
<Button onClick={onAction}>Action</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Routing
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
export const Route = createFileRoute('/settings/general')({
|
||||||
|
component: GeneralSettings
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building & Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development
|
||||||
|
yarn dev
|
||||||
|
yarn build
|
||||||
|
yarn test
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Management
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// Local state
|
||||||
|
const [value, setValue] = useState<string>('')
|
||||||
|
|
||||||
|
// Global state (Zustand)
|
||||||
|
export const useAppState = create<AppState>((set) => ({
|
||||||
|
data: null,
|
||||||
|
setData: (data) => set({ data })
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tauri Integration
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { invoke } from '@tauri-apps/api/tauri'
|
||||||
|
|
||||||
|
const result = await invoke('command_name', { param: 'value' })
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// Use React.memo for expensive components
|
||||||
|
const ExpensiveComponent = React.memo(({ data }) => {
|
||||||
|
return <div>{processData(data)}</div>
|
||||||
|
})
|
||||||
|
|
||||||
|
// Debounce frequent updates
|
||||||
|
const debouncedValue = useDebounce(searchTerm, 300)
|
||||||
|
|
||||||
|
// Virtual scrolling for large lists
|
||||||
|
import { VariableSizeList } from 'react-window'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# React DevTools
|
||||||
|
# Install browser extension, then:
|
||||||
|
# - Inspect component tree
|
||||||
|
# - Debug hooks and state
|
||||||
|
# - Profile performance
|
||||||
|
|
||||||
|
# Debug Tauri commands
|
||||||
|
console.log(await window.__TAURI__.invoke('command_name'))
|
||||||
|
|
||||||
|
# Check for console errors
|
||||||
|
# Press F12 → Console tab
|
||||||
|
```
|
||||||
|
|
||||||
|
## Accessibility Guidelines
|
||||||
|
|
||||||
|
- Use semantic HTML (`<button>`, `<nav>`, `<main>`)
|
||||||
|
- Add ARIA labels: `aria-label`, `aria-describedby`
|
||||||
|
- Ensure keyboard navigation works
|
||||||
|
- Test with screen readers
|
||||||
|
- Maintain color contrast ratios
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- Keep components small and focused
|
||||||
|
- Use TypeScript fully (no `any`)
|
||||||
|
- Handle loading and error states
|
||||||
|
- Follow accessibility guidelines
|
||||||
|
- Extract business logic into hooks
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **React** - UI framework
|
||||||
|
- **TypeScript** - Type safety
|
||||||
|
- **TanStack Router** - Type-safe routing
|
||||||
|
- **Radix UI** - Accessible components
|
||||||
|
- **Tailwind CSS** - Utility-first styling
|
||||||
|
- **Zustand** - State management
|
||||||
Loading…
x
Reference in New Issue
Block a user