mirror of
https://github.com/taskgenius/taskgenius-plugin.git
synced 2026-07-22 06:40:25 +00:00
- Remove experimental TaskViewV2 and related CSS - Fix DEVELOPMENT.md formatting and remove outdated license reference - Clean up accidentally committed experimental code
9 KiB
9 KiB
Task Genius Development Guide
Comprehensive guide for developers contributing to the Task Genius plugin for Obsidian
Table of Contents
Getting Started
Prerequisites
- Node.js: Version 18.x or higher
- pnpm: Version 8.x or higher (preferred) or npm
- Git: Latest version
- Obsidian: Version 1.9.0 or higher
- IDE: VS Code (recommended) with TypeScript support
Initial Setup
# Clone the repository into your Obsidian vault's plugin folder
cd {YOUR_OBSIDIAN_VAULT_PATH}/.obsidian/plugins
git clone https://github.com/Quorafind/Obsidian-Task-Genius.git
cd Obsidian-Task-Genius
# Install dependencies
pnpm install
# Start development with hot reload
pnpm run dev
Quick Start Checklist
- Fork the repository
- Clone your fork locally
- Install dependencies with
pnpm install - Create symbolic link to Obsidian vault
- Run
pnpm run devfor development mode - Enable "Task Genius" plugin in Obsidian settings
- Open Developer Console (Ctrl/Cmd + Shift + I)
Project Architecture
Directory Structure
SRC
├─cache # Cache system used for caching data from Fluent view
├─commands # Commands for the plugin
├─common # Common files for the plugin
│ └─task-status # Task statuses marks like `[x]` and `[ ]`
├─components # Components for the plugin
│ ├─features # Contains all features related components
│ │ ├─calendar
│ │ │ ├─rendering
│ │ │ └─views
│ │ ├─fluent
│ │ │ ├─components
│ │ │ ├─events
│ │ │ └─managers
│ │ ├─gantt
│ │ ├─habit
│ │ │ ├─components
│ │ │ ├─habitcard
│ │ │ └─modals
│ │ ├─kanban
│ │ ├─on-completion
│ │ ├─onboarding
│ │ │ ├─modals
│ │ │ ├─previews
│ │ │ ├─steps
│ │ │ │ ├─guide
│ │ │ │ ├─intro
│ │ │ │ └─preview
│ │ │ └─ui
│ │ ├─quadrant
│ │ ├─quick-capture
│ │ │ ├─components
│ │ │ ├─modals
│ │ │ └─suggest
│ │ ├─read-mode
│ │ ├─settings
│ │ │ ├─components
│ │ │ ├─core
│ │ │ └─tabs
│ │ ├─table
│ │ ├─task
│ │ │ ├─edit
│ │ │ ├─filter
│ │ │ │ └─in-view
│ │ │ │ └─custom
│ │ │ └─view
│ │ │ └─modals
│ │ ├─timeline-sidebar
│ │ └─workflow
│ │ ├─modals
│ │ └─widgets
│ └─ui # UI components for the plugin
│ ├─behavior
│ ├─date-picker
│ ├─feedback
│ ├─inputs
│ ├─menus
│ ├─modals
│ ├─popovers
│ ├─renderers
│ ├─suggest
│ └─tree
├─core # Main core files for the plugin
│ └─goal
├─dataflow # Dataflow architecture(focused on performance and scalability)
│ ├─api
│ ├─augment
│ ├─core
│ ├─events
│ ├─indexer
│ ├─parsers
│ ├─persistence
│ ├─project
│ ├─sources
│ └─workers
├─editor-extensions # Editor extensions for Obsidian
│ ├─autocomplete
│ ├─core
│ ├─date-time
│ ├─task-operations
│ ├─ui-widgets
│ └─workflow
├─executors # Action executors when task is completed/archived/duplicated/moved/etc.
│ └─completion
├─managers # Some data/task managers
├─mcp # MCP server for Agentic task management
│ ├─auth
│ ├─bridge
│ └─types
├─pages # All views created by the plugin
│ └─bases # Bases view support
├─parsers # Task parsers
├─patches # Patches for Obsidian
├─services # Task related services
├─styles # All styles for the plugin
│ ├─calendar
│ ├─fluent
│ ├─gantt
│ ├─kanban
│ └─quadrant
├─translations # All translations for the plugin
│ └─locale
├─types # All types for the plugin
├─utils # All utils for the plugin
│ ├─date
│ ├─file
│ ├─task
│ └─ui
├─__mocks__
└─__tests__
├─file-source
├─file-task-manager
└─integration
Feature Development Flow
-
Create Feature Branch
git checkout -b feature/your-feature-name -
Development Cycle
# Make changes pnpm run dev # Watch mode # Run tests pnpm test # Lint code pnpm run lint -
Commit Changes
git add . git commit -m "feat: add new feature" git push origin feature/your-feature-name -
Submit Pull Request
- Push to your fork
- Create PR against
masterbranch - Ensure CI passes
- Request review
Conventional Commits
Format: <type>(<scope>): <subject>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changesrefactor: Code refactoringperf: Performance improvementstest: Test additions/changeschore: Build/tooling changes
Examples:
feat(kanban): add drag-and-drop support
fix(parser): handle edge case in task parsing
docs(api): update TaskManager documentation
perf(indexer): optimize file scanning algorithm
Code Style Guide
TypeScript Guidelines
// 1. Use explicit types for function parameters and returns
function calculateProgress(completed: number, total: number): number {
return (completed / total) * 100;
}
// 2. Use interfaces for object shapes
interface TaskConfig {
enableWorker: boolean;
maxConcurrency: number;
cacheTimeout: number;
}
// 3. Prefer const assertions for literals
const TASK_STATUSES = ['todo', 'in-progress', 'done'] as const;
type TaskStatus = typeof TASK_STATUSES[number];
// 4. Use optional chaining and nullish coalescing
const title = task?.metadata?.title ?? 'Untitled';
// 5. Async/await over promises
async function loadTasks(): Promise<Task[]> {
const files = await this.getTaskFiles();
return this.parseTasks(files);
}
Component Guidelines
// 1. Extract complex logic to separate methods
export class TaskList extends Component {
private async renderTasks(): Promise<void> {
const tasks = await this.fetchTasks();
const filtered = this.applyFilters(tasks);
const sorted = this.sortTasks(filtered);
this.display(sorted);
}
private applyFilters(tasks: Task[]): Task[] {
// Filter logic
}
private sortTasks(tasks: Task[]): Task[] {
// Sort logic
}
}
// 2. Use descriptive names
// Bad: const d = new Date();
// Good: const currentDate = new Date();
// 3. Document complex algorithms
/**
* Calculates task priority score based on multiple factors
* @param task - The task to score
* @returns Priority score (0-100)
*/
function calculatePriorityScore(task: Task): number {
// Implementation
}
CSS/Styling Guidelines
/* Use BEM naming convention */
.task-genius-view task-card {
/* Block */
}
.task-genius-view task-card__header {
/* Element */
}
.task-genius-view task-card--completed {
/* Modifier */
}
/* Use CSS variables for theming */
.task-genius-view {
--primary-color: var(--interactive-accent);
--spacing-sm: 4px;
--spacing-md: 8px;
--spacing-lg: 16px;
}
/* Scope styles to prevent conflicts */
.workspace-leaf-content[data-type="task-genius"] {
/* Plugin-specific styles */
}
Testing Strategy
Test Structure
// src/__tests__/unit/TaskParser.test.ts
describe('TaskParser', () => {
let parser: TaskParser;
beforeEach(() => {
parser = new TaskParser();
});
describe('parseTask', () => {
it('should parse basic task syntax', () => {
const input = '- [ ] Sample task';
const result = parser.parseTask(input);
expect(result).toMatchObject({
content: 'Sample task',
completed: false
});
});
it('should handle task with metadata', () => {
// Test implementation
});
});
});
Testing Commands
# Run all tests
pnpm test
# Run tests in watch mode
pnpm run test:watch
# Run specific test file
pnpm test src/__tests__/unit/TaskParser.test.ts
Mock Strategies
// Mock Obsidian API
jest.mock('obsidian', () => ({
Plugin: class MockPlugin {
// Mock implementation
},
TFile: class MockTFile {
// Mock implementation
}
}));
Getting Help
- Check existing issues on GitHub
- Search Discord plugin-dev channel
- Create detailed issue with:
- Environment details
- Steps to reproduce
- Expected vs actual behavior
- Console logs
Questions?
If you have questions not covered here:
- Open a discussion on GitHub
- Ask in the Obsidian Discord
- Contact the maintainers
Happy coding! 🚀