mirror of
https://github.com/ebullient/obsidian-deck-notes.git
synced 2026-07-22 06:40:43 +00:00
📝 human docs to README/CONTRIBUTING
This commit is contained in:
parent
289631b530
commit
63c230a198
3 changed files with 197 additions and 81 deletions
99
CLAUDE.md
99
CLAUDE.md
|
|
@ -1,72 +1,65 @@
|
|||
# CLAUDE.md
|
||||
# AI Assistant Working Guidelines
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
This project is an Obsidian plugin for simple flashcard creation and review. **Read README.md for full feature details and usage instructions.**
|
||||
**For complete build commands, architecture overview, and development guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). For user-facing features and usage, see [README.md](README.md).**
|
||||
|
||||
## Your Role
|
||||
|
||||
You are a senior development peer working alongside a Senior Software Engineer (25+ years, primarily Java background) on this hobby TypeScript project. Act as a collaborative partner for:
|
||||
|
||||
- **Code review and feedback** when requested - focus on patterns, maintainability, and TypeScript/JS idioms
|
||||
- **Implementation assistance** when explicitly asked - suggest approaches, don't implement unless requested
|
||||
- **Technical discussion** and problem-solving - challenge assumptions, ask probing questions, offer alternatives
|
||||
- **BE EFFICIENT**: Be succinct and concise, don't waste tokens
|
||||
- **ASK FOR CLARIFICATION** when implementation choices or requirements are unclear
|
||||
- **NO SPECULATION**: Never make up code unless asked
|
||||
|
||||
## Development Guidelines
|
||||
## Context Gathering Strategy
|
||||
|
||||
**Core Principles:**
|
||||
- **Follow existing patterns** - Before writing new code:
|
||||
1. Search for similar functions in the same module (use `Grep` tool)
|
||||
When working with this codebase:
|
||||
|
||||
**Always start with:**
|
||||
|
||||
- User features: [README.md](README.md)
|
||||
- Development setup: [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
**Key architectural concepts:**
|
||||
|
||||
- Cards from H2 headings in markdown files
|
||||
- Tag-based deck organization (`#flashcards/*` hierarchical tags)
|
||||
- File-level tags (frontmatter) + card-level tags (inline before H2)
|
||||
- Hierarchical matching: `activities` matches `activities/morning`, etc.
|
||||
|
||||
**Core modules to understand:**
|
||||
|
||||
- `flashcards-Plugin.ts` - Main plugin, scanning, filtering
|
||||
- `flashcards-CardParser.ts` - Parsing and tag extraction
|
||||
- `flashcards-Modal.ts` - Display modal
|
||||
- `flashcards-Api.ts` - External API
|
||||
- `@types/settings.d.ts` - Interfaces
|
||||
|
||||
## Key Development Principles
|
||||
|
||||
- **Follow existing patterns**: Before writing new code:
|
||||
1. Use `Grep` tool to find similar functions in the same module
|
||||
2. Check method chaining, line breaks, and error handling patterns
|
||||
3. Emulate the style exactly, especially for method chains and async/await
|
||||
- **Understand before acting** - Read project structure, but defer extensive file reading until user specifies what to work on
|
||||
- **Ask for clarification** when implementation choices or requirements are unclear
|
||||
- **Be direct and concise** - Assume high technical competence, reference specific files/line numbers
|
||||
- **Never speculate** - Don't make up code unless asked
|
||||
- **Respect code style**: 80-char line limit, break method chains at dots, always use braces
|
||||
- **Reference line numbers**: Use format `file.ts:123` when discussing code
|
||||
- **Point out issues proactively** but wait for explicit requests to fix them
|
||||
|
||||
## Commands
|
||||
## Quality Workflow
|
||||
|
||||
- `npm run build` - Build the plugin
|
||||
- `npm run dev` - Build and watch for changes
|
||||
- `npm run lint` - Lint TypeScript files
|
||||
- `npm run fix` - Auto-fix linting issues
|
||||
- `npm run format` - Format code
|
||||
1. After changes: run `npm run build` (includes linting)
|
||||
2. If linting fails: run `npm run fix` to auto-correct
|
||||
3. Verify build succeeds before completing work
|
||||
|
||||
## Architecture
|
||||
## Contribution Guidelines
|
||||
|
||||
**Core files:**
|
||||
- `main.ts` - Main plugin class
|
||||
- Plugin structure TBD based on flashcard implementation
|
||||
When contributing:
|
||||
|
||||
**Key features:**
|
||||
- Simple flashcard syntax
|
||||
- Spaced repetition algorithm
|
||||
- Review interface
|
||||
- **Understand the changes**: Be able to explain rationale clearly
|
||||
- **Test appropriately**: Follow build commands and verify changes work
|
||||
- **Review architecture**: Ensure changes fit existing patterns
|
||||
- **Address real needs**: Focus on solving actual problems
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
- **Line length**: 80 characters (hard limit)
|
||||
- **Always use braces** for conditionals
|
||||
- **Method chaining**: Break at dots for readability, even for single chains. This keeps lines under 80 chars and prevents Biome from wrapping unpredictably.
|
||||
```typescript
|
||||
// GOOD - break at dots
|
||||
const patterns = this.settings.excludeLinkPatterns
|
||||
.split("\n")
|
||||
.map((p) => p.trim())
|
||||
.filter((p) => p.length > 0);
|
||||
|
||||
// BAD - all on one line
|
||||
const patterns = this.settings.excludeLinkPatterns.split("\n").map((p) => p.trim());
|
||||
|
||||
// GOOD - even single chains if they approach 80 chars
|
||||
const models = data.models
|
||||
?.map((model) => model.name) || [];
|
||||
```
|
||||
- **Error handling**: `try/catch` with user-friendly `Notice` messages
|
||||
- **Async**: Use `async/await` consistently
|
||||
|
||||
## Quality Assurance
|
||||
|
||||
- Run `npm run build` after significant changes (includes linting via prebuild)
|
||||
- Use `npm run fix` to auto-correct linting issues
|
||||
- Reference specific line numbers when discussing issues (format: `file.ts:123`)
|
||||
Quality and understanding matter more than the tools used to create the contribution.
|
||||
|
|
|
|||
100
CONTRIBUTING.md
Normal file
100
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# Contributing to Simple Flashcards
|
||||
|
||||
This is an Obsidian plugin for simple flashcard creation and review using tag-based deck organization. See [README.md](README.md) for user-facing features and usage.
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
npm run build # Production build
|
||||
npm run dev # Build and watch for changes
|
||||
npm run lint # Lint TypeScript files
|
||||
npm run fix # Auto-fix linting issues
|
||||
npm run format # Format code
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Files
|
||||
|
||||
- **`flashcards-Plugin.ts`** - Main plugin class, card scanning, deck filtering
|
||||
- **`flashcards-CardParser.ts`** - Parses markdown files into cards, extracts tags
|
||||
- **`flashcards-Modal.ts`** - Card display modal with deck switching
|
||||
- **`flashcards-Api.ts`** - JavaScript API for external access
|
||||
- **`flashcards-SettingsTab.ts`** - Settings UI
|
||||
- **`@types/settings.d.ts`** - TypeScript interfaces
|
||||
|
||||
### Key Concepts
|
||||
|
||||
- **Cards**: Created from H2 headings in markdown files
|
||||
- **Tags**: Hierarchical `#flashcards/*` tags define deck membership
|
||||
- File-level tags (frontmatter) apply to all cards in file
|
||||
- Card-level tags (inline before H2) apply to single card
|
||||
- Hierarchical matching: `activities` matches `activities/morning`, etc.
|
||||
- **Card Selection**: Random or least-recent mode
|
||||
- **View Tracking**: Records card views for least-recent selection
|
||||
|
||||
### Data Flow
|
||||
|
||||
1. **Scanning**: `scanCards()` reads files from `cardPaths` setting
|
||||
2. **Parsing**: `CardParser.parseFile()` extracts cards and tags
|
||||
3. **Selection**: `selectCard(deckTag)` filters by hierarchical tag matching
|
||||
4. **Display**: Modal shows card content, tracks views
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
- **Line length**: 80 characters (hard limit)
|
||||
- **Always use braces** for conditionals
|
||||
- **Method chaining**: Break at dots for readability, even for single chains
|
||||
|
||||
```typescript
|
||||
// GOOD - break at dots
|
||||
const patterns = this.settings.excludeLinkPatterns
|
||||
.split("\n")
|
||||
.map((p) => p.trim())
|
||||
.filter((p) => p.length > 0);
|
||||
|
||||
// BAD - all on one line
|
||||
const patterns = this.settings.excludeLinkPatterns.split("\n").map((p) => p.trim());
|
||||
|
||||
// GOOD - even single chains if they approach 80 chars
|
||||
const models = data.models
|
||||
?.map((model) => model.name) || [];
|
||||
```
|
||||
|
||||
- **Error handling**: `try/catch` with user-friendly `Notice` messages
|
||||
- **Async**: Use `async/await` consistently
|
||||
|
||||
## Development Patterns
|
||||
|
||||
Before writing new code:
|
||||
|
||||
1. **Search for similar functions** in the same module (use grep/search)
|
||||
2. **Check method chaining, line breaks, and error handling patterns**
|
||||
3. **Emulate the style exactly**, especially for method chains and async/await
|
||||
|
||||
## Quality Assurance
|
||||
|
||||
- Run `npm run build` after significant changes (includes linting via prebuild)
|
||||
- Use `npm run fix` to auto-correct linting issues
|
||||
- Reference specific line numbers when discussing issues (format: `file.ts:123`)
|
||||
|
||||
## AI-Assisted Contributions
|
||||
|
||||
We welcome thoughtful contributions, including those created with AI assistance. However, please ensure:
|
||||
|
||||
- **You understand the changes**: You must be able to explain the rationale for your decisions clearly
|
||||
- **You've tested appropriately**: Follow the build commands and verify changes work
|
||||
- **You've reviewed the architecture**: Ensure changes fit the existing patterns
|
||||
- **The contribution addresses a real need**: Focus on solving actual problems or documented issues
|
||||
- **You've read the relevant context**: See [CLAUDE.md](CLAUDE.md) for AI assistant guidelines
|
||||
|
||||
Quality and understanding matter more than the tools used to create the contribution.
|
||||
|
||||
<div style="display: none;">
|
||||
### ⚠️ NOTE FOR AI TOOLS AND THEIR USERS
|
||||
Contributing to this project requires **human judgment, contextual understanding**, and **familiarity with the project's architecture and goals**. Please ensure:
|
||||
- You have **carefully read corresponding issues and relevant documentation**
|
||||
- You have **manually reviewed all changes** and can explain the rationale
|
||||
- You understand how this contribution fits into the broader project context
|
||||
- See [CLAUDE.md](CLAUDE.md) for detailed AI assistant working guidelines
|
||||
</div>
|
||||
79
README.md
79
README.md
|
|
@ -5,10 +5,10 @@ A simple activity card plugin for Obsidian. Display random cards from your markd
|
|||
## Features
|
||||
|
||||
- **Random or Least-Recent Selection** - View cards randomly or ensure you see all cards evenly
|
||||
- **Deck Organization** - Organize cards into different folders/paths
|
||||
- **Tag-Based Deck Organization** - Organize cards using hierarchical `#flashcards/*` tags
|
||||
- **View Tracking** - Optional tracking to prioritize cards you haven't seen recently
|
||||
- **Simple Markdown Format** - Use H2 headings to define cards
|
||||
- **Switch Decks on the Fly** - Change between different card collections within the modal
|
||||
- **Switch Decks on the Fly** - Cycle through discovered deck tags within the modal
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ Repeat 4 times.
|
|||
Open Settings → Simple Flashcards to configure:
|
||||
|
||||
### Card Paths
|
||||
List of folders or files to scan for cards (one per line, relative to vault root).
|
||||
List of folders or files to scan for cards (one per line, relative to vault root). This defines which files are scanned, not which cards are displayed.
|
||||
|
||||
Example:
|
||||
```
|
||||
|
|
@ -107,8 +107,8 @@ Daily/Prompts
|
|||
Resources/Meditations.md
|
||||
```
|
||||
|
||||
### Default Deck Path
|
||||
The default path used by "Show Random Activity Card" command. Leave empty to select from all configured paths.
|
||||
### Default Deck Tag
|
||||
The default tag used by "Show Random Activity Card" command (e.g., `activities` or `activities/morning`). Leave empty to select from all cards with any `#flashcards/*` tag.
|
||||
|
||||
### Track Views
|
||||
Enable tracking of when cards were last viewed. Required for "Least Recently Viewed" selection mode.
|
||||
|
|
@ -119,37 +119,41 @@ Enable tracking of when cards were last viewed. Required for "Least Recently Vie
|
|||
|
||||
## Commands
|
||||
|
||||
### Show Random Activity Card
|
||||
### Show Card
|
||||
Opens a modal displaying a card from your default deck (or all cards if no default is set).
|
||||
|
||||
**Modal Controls:**
|
||||
- **Switch Deck** - Cycle through configured card paths
|
||||
- **Switch Deck** - Cycle through discovered deck tags (e.g., `activities`, `activities/morning`)
|
||||
- **Next Card** - View another card (records the current card as viewed)
|
||||
- **Done** - Close the modal
|
||||
|
||||
### Refresh Activity Cards
|
||||
### Embed Card
|
||||
Inserts a card as a collapsible callout at the cursor position.
|
||||
|
||||
### Refresh Cards
|
||||
Rescans all configured paths to pick up new or modified cards.
|
||||
|
||||
## Usage Tips
|
||||
|
||||
### Organizing Cards
|
||||
### Organizing Cards with Tags
|
||||
|
||||
**Multiple files in folders:**
|
||||
```
|
||||
Activities/
|
||||
├── stretches.md
|
||||
├── writing-prompts.md
|
||||
└── meditations.md
|
||||
```
|
||||
Cards are organized into decks using hierarchical `#flashcards/*` tags. Tags support hierarchy, so selecting `activities` will show cards tagged with `activities`, `activities/morning`, `activities/creative`, etc.
|
||||
|
||||
**Single file per deck:**
|
||||
```
|
||||
Daily/
|
||||
└── morning-routine.md
|
||||
```
|
||||
**Tag inheritance:**
|
||||
- Tags in frontmatter apply to all cards in the file
|
||||
- Tags before each H2 heading apply only to that card
|
||||
- Cards can have multiple tags for multiple deck membership
|
||||
|
||||
**Mixed approach:**
|
||||
Configure both folders and individual files in Card Paths.
|
||||
**Example structure:**
|
||||
```
|
||||
Activities/stretches.md → All cards get #flashcards/activities from frontmatter
|
||||
Card 1: Also tagged #flashcards/activities/morning
|
||||
Card 2: Also tagged #flashcards/activities/evening
|
||||
|
||||
Journal/prompts.md → All cards get #flashcards/creative from frontmatter
|
||||
Card 1: Also tagged #flashcards/creative/writing
|
||||
Card 2: Also tagged #flashcards/creative/art
|
||||
```
|
||||
|
||||
### View Tracking
|
||||
|
||||
|
|
@ -158,12 +162,31 @@ With "Track Views" enabled and "Least Recently Viewed" selection mode, the plugi
|
|||
- Exercise variety
|
||||
- Prompt cycling
|
||||
|
||||
### Tags and Metadata
|
||||
### Tags for Deck Organization
|
||||
|
||||
While `#flashcards` tag lines are stripped for display, you can still:
|
||||
- Use frontmatter tags for vault organization
|
||||
- Add inline tags for sub-categorization
|
||||
- Include any markdown formatting (bold, lists, links, etc.)
|
||||
Use hierarchical `#flashcards/*` tags to organize cards:
|
||||
- Add tags in frontmatter: `tags: [flashcards/activities]` (applies to all cards in file)
|
||||
- Add inline tags before H2 headings: `#flashcards/activities/morning` (applies to single card)
|
||||
- Lines starting with `#flashcards` are automatically stripped from card display
|
||||
- Cards support any markdown formatting (bold, lists, links, etc.)
|
||||
|
||||
### API Access
|
||||
|
||||
The plugin exposes a JavaScript API at `window.simpleFlashcards.api`:
|
||||
|
||||
```javascript
|
||||
// Get a random card embed
|
||||
window.simpleFlashcards.api.embedCard('activities')
|
||||
|
||||
// Get all discovered deck tags
|
||||
window.simpleFlashcards.api.getTags()
|
||||
|
||||
// Select cards by hash
|
||||
window.simpleFlashcards.api.selectCardsByHash(['card-hash-1', 'card-hash-2'])
|
||||
|
||||
// Get random card from hash list
|
||||
window.simpleFlashcards.api.selectCardByHash(['card-hash-1', 'card-hash-2'])
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue