diff --git a/.cursor/.DS_Store b/.cursor/.DS_Store
new file mode 100644
index 0000000..149edce
Binary files /dev/null and b/.cursor/.DS_Store differ
diff --git a/.cursor/skills/1-Infrastructure/Data-Schema/SKILL.md b/.cursor/skills/1-Infrastructure/Data-Schema/SKILL.md
new file mode 100644
index 0000000..6f82f11
--- /dev/null
+++ b/.cursor/skills/1-Infrastructure/Data-Schema/SKILL.md
@@ -0,0 +1,618 @@
+---
+name: obsidian-bases
+description: Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
+---
+
+# Obsidian Bases Skill
+
+This skill enables skills-compatible agents to create and edit valid Obsidian Bases (`.base` files) including views, filters, formulas, and all related configurations.
+
+## Overview
+
+Obsidian Bases are YAML-based files that define dynamic views of notes in an Obsidian vault. A Base file can contain multiple views, global filters, formulas, property configurations, and custom summaries.
+
+## File Format
+
+Base files use the `.base` extension and contain valid YAML. They can also be embedded in Markdown code blocks.
+
+## Complete Schema
+
+```yaml
+# Global filters apply to ALL views in the base
+filters:
+ # Can be a single filter string
+ # OR a recursive filter object with and/or/not
+ and: []
+ or: []
+ not: []
+
+# Define formula properties that can be used across all views
+formulas:
+ formula_name: 'expression'
+
+# Configure display names and settings for properties
+properties:
+ property_name:
+ displayName: "Display Name"
+ formula.formula_name:
+ displayName: "Formula Display Name"
+ file.ext:
+ displayName: "Extension"
+
+# Define custom summary formulas
+summaries:
+ custom_summary_name: 'values.mean().round(3)'
+
+# Define one or more views
+views:
+ - type: table | cards | list | map
+ name: "View Name"
+ limit: 10 # Optional: limit results
+ groupBy: # Optional: group results
+ property: property_name
+ direction: ASC | DESC
+ filters: # View-specific filters
+ and: []
+ order: # Properties to display in order
+ - file.name
+ - property_name
+ - formula.formula_name
+ summaries: # Map properties to summary formulas
+ property_name: Average
+```
+
+## Filter Syntax
+
+Filters narrow down results. They can be applied globally or per-view.
+
+### Filter Structure
+
+```yaml
+# Single filter
+filters: 'status == "done"'
+
+# AND - all conditions must be true
+filters:
+ and:
+ - 'status == "done"'
+ - 'priority > 3'
+
+# OR - any condition can be true
+filters:
+ or:
+ - 'file.hasTag("book")'
+ - 'file.hasTag("article")'
+
+# NOT - exclude matching items
+filters:
+ not:
+ - 'file.hasTag("archived")'
+
+# Nested filters
+filters:
+ or:
+ - file.hasTag("tag")
+ - and:
+ - file.hasTag("book")
+ - file.hasLink("Textbook")
+ - not:
+ - file.hasTag("book")
+ - file.inFolder("Required Reading")
+```
+
+### Filter Operators
+
+| Operator | Description |
+|----------|-------------|
+| `==` | equals |
+| `!=` | not equal |
+| `>` | greater than |
+| `<` | less than |
+| `>=` | greater than or equal |
+| `<=` | less than or equal |
+| `&&` | logical and |
+| `\|\|` | logical or |
+| ! | logical not |
+
+## Properties
+
+### Three Types of Properties
+
+1. **Note properties** - From frontmatter: `note.author` or just `author`
+2. **File properties** - File metadata: `file.name`, `file.mtime`, etc.
+3. **Formula properties** - Computed values: `formula.my_formula`
+
+### File Properties Reference
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `file.name` | String | File name |
+| `file.basename` | String | File name without extension |
+| `file.path` | String | Full path to file |
+| `file.folder` | String | Parent folder path |
+| `file.ext` | String | File extension |
+| `file.size` | Number | File size in bytes |
+| `file.ctime` | Date | Created time |
+| `file.mtime` | Date | Modified time |
+| `file.tags` | List | All tags in file |
+| `file.links` | List | Internal links in file |
+| `file.backlinks` | List | Files linking to this file |
+| `file.embeds` | List | Embeds in the note |
+| `file.properties` | Object | All frontmatter properties |
+
+### The `this` Keyword
+
+- In main content area: refers to the base file itself
+- When embedded: refers to the embedding file
+- In sidebar: refers to the active file in main content
+
+## Formula Syntax
+
+Formulas compute values from properties. Defined in the `formulas` section.
+
+```yaml
+formulas:
+ # Simple arithmetic
+ total: "price * quantity"
+
+ # Conditional logic
+ status_icon: 'if(done, "✅", "⏳")'
+
+ # String formatting
+ formatted_price: 'if(price, price.toFixed(2) + " dollars")'
+
+ # Date formatting
+ created: 'file.ctime.format("YYYY-MM-DD")'
+
+ # Complex expressions
+ days_old: '((now() - file.ctime) / 86400000).round(0)'
+```
+
+## Functions Reference
+
+### Global Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `date()` | `date(string): date` | Parse string to date. Format: `YYYY-MM-DD HH:mm:ss` |
+| `duration()` | `duration(string): duration` | Parse duration string |
+| `now()` | `now(): date` | Current date and time |
+| `today()` | `today(): date` | Current date (time = 00:00:00) |
+| `if()` | `if(condition, trueResult, falseResult?)` | Conditional |
+| `min()` | `min(n1, n2, ...): number` | Smallest number |
+| `max()` | `max(n1, n2, ...): number` | Largest number |
+| `number()` | `number(any): number` | Convert to number |
+| `link()` | `link(path, display?): Link` | Create a link |
+| `list()` | `list(element): List` | Wrap in list if not already |
+| `file()` | `file(path): file` | Get file object |
+| `image()` | `image(path): image` | Create image for rendering |
+| `icon()` | `icon(name): icon` | Lucide icon by name |
+| `html()` | `html(string): html` | Render as HTML |
+| `escapeHTML()` | `escapeHTML(string): string` | Escape HTML characters |
+
+### Any Type Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `isTruthy()` | `any.isTruthy(): boolean` | Coerce to boolean |
+| `isType()` | `any.isType(type): boolean` | Check type |
+| `toString()` | `any.toString(): string` | Convert to string |
+
+### Date Functions & Fields
+
+**Fields:** `date.year`, `date.month`, `date.day`, `date.hour`, `date.minute`, `date.second`, `date.millisecond`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `date()` | `date.date(): date` | Remove time portion |
+| `format()` | `date.format(string): string` | Format with Moment.js pattern |
+| `time()` | `date.time(): string` | Get time as string |
+| `relative()` | `date.relative(): string` | Human-readable relative time |
+| `isEmpty()` | `date.isEmpty(): boolean` | Always false for dates |
+
+### Date Arithmetic
+
+```yaml
+# Duration units: y/year/years, M/month/months, d/day/days,
+# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
+
+# Add/subtract durations
+"date + \"1M\"" # Add 1 month
+"date - \"2h\"" # Subtract 2 hours
+"now() + \"1 day\"" # Tomorrow
+"today() + \"7d\"" # A week from today
+
+# Subtract dates for millisecond difference
+"now() - file.ctime"
+
+# Complex duration arithmetic
+"now() + (duration('1d') * 2)"
+```
+
+### String Functions
+
+**Field:** `string.length`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `contains()` | `string.contains(value): boolean` | Check substring |
+| `containsAll()` | `string.containsAll(...values): boolean` | All substrings present |
+| `containsAny()` | `string.containsAny(...values): boolean` | Any substring present |
+| `startsWith()` | `string.startsWith(query): boolean` | Starts with query |
+| `endsWith()` | `string.endsWith(query): boolean` | Ends with query |
+| `isEmpty()` | `string.isEmpty(): boolean` | Empty or not present |
+| `lower()` | `string.lower(): string` | To lowercase |
+| `title()` | `string.title(): string` | To Title Case |
+| `trim()` | `string.trim(): string` | Remove whitespace |
+| `replace()` | `string.replace(pattern, replacement): string` | Replace pattern |
+| `repeat()` | `string.repeat(count): string` | Repeat string |
+| `reverse()` | `string.reverse(): string` | Reverse string |
+| `slice()` | `string.slice(start, end?): string` | Substring |
+| `split()` | `string.split(separator, n?): list` | Split to list |
+
+### Number Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `abs()` | `number.abs(): number` | Absolute value |
+| `ceil()` | `number.ceil(): number` | Round up |
+| `floor()` | `number.floor(): number` | Round down |
+| `round()` | `number.round(digits?): number` | Round to digits |
+| `toFixed()` | `number.toFixed(precision): string` | Fixed-point notation |
+| `isEmpty()` | `number.isEmpty(): boolean` | Not present |
+
+### List Functions
+
+**Field:** `list.length`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `contains()` | `list.contains(value): boolean` | Element exists |
+| `containsAll()` | `list.containsAll(...values): boolean` | All elements exist |
+| `containsAny()` | `list.containsAny(...values): boolean` | Any element exists |
+| `filter()` | `list.filter(expression): list` | Filter by condition (uses `value`, `index`) |
+| `map()` | `list.map(expression): list` | Transform elements (uses `value`, `index`) |
+| `reduce()` | `list.reduce(expression, initial): any` | Reduce to single value (uses `value`, `index`, `acc`) |
+| `flat()` | `list.flat(): list` | Flatten nested lists |
+| `join()` | `list.join(separator): string` | Join to string |
+| `reverse()` | `list.reverse(): list` | Reverse order |
+| `slice()` | `list.slice(start, end?): list` | Sublist |
+| `sort()` | `list.sort(): list` | Sort ascending |
+| `unique()` | `list.unique(): list` | Remove duplicates |
+| `isEmpty()` | `list.isEmpty(): boolean` | No elements |
+
+### File Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `asLink()` | `file.asLink(display?): Link` | Convert to link |
+| `hasLink()` | `file.hasLink(otherFile): boolean` | Has link to file |
+| `hasTag()` | `file.hasTag(...tags): boolean` | Has any of the tags |
+| `hasProperty()` | `file.hasProperty(name): boolean` | Has property |
+| `inFolder()` | `file.inFolder(folder): boolean` | In folder or subfolder |
+
+### Link Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `asFile()` | `link.asFile(): file` | Get file object |
+| `linksTo()` | `link.linksTo(file): boolean` | Links to file |
+
+### Object Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `isEmpty()` | `object.isEmpty(): boolean` | No properties |
+| `keys()` | `object.keys(): list` | List of keys |
+| `values()` | `object.values(): list` | List of values |
+
+### Regular Expression Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `matches()` | `regexp.matches(string): boolean` | Test if matches |
+
+## View Types
+
+### Table View
+
+```yaml
+views:
+ - type: table
+ name: "My Table"
+ order:
+ - file.name
+ - status
+ - due_date
+ summaries:
+ price: Sum
+ count: Average
+```
+
+### Cards View
+
+```yaml
+views:
+ - type: cards
+ name: "Gallery"
+ order:
+ - file.name
+ - cover_image
+ - description
+```
+
+### List View
+
+```yaml
+views:
+ - type: list
+ name: "Simple List"
+ order:
+ - file.name
+ - status
+```
+
+### Map View
+
+Requires latitude/longitude properties and the Maps community plugin.
+
+```yaml
+views:
+ - type: map
+ name: "Locations"
+ # Map-specific settings for lat/lng properties
+```
+
+## Default Summary Formulas
+
+| Name | Input Type | Description |
+|------|------------|-------------|
+| `Average` | Number | Mathematical mean |
+| `Min` | Number | Smallest number |
+| `Max` | Number | Largest number |
+| `Sum` | Number | Sum of all numbers |
+| `Range` | Number | Max - Min |
+| `Median` | Number | Mathematical median |
+| `Stddev` | Number | Standard deviation |
+| `Earliest` | Date | Earliest date |
+| `Latest` | Date | Latest date |
+| `Range` | Date | Latest - Earliest |
+| `Checked` | Boolean | Count of true values |
+| `Unchecked` | Boolean | Count of false values |
+| `Empty` | Any | Count of empty values |
+| `Filled` | Any | Count of non-empty values |
+| `Unique` | Any | Count of unique values |
+
+## Complete Examples
+
+### Task Tracker Base
+
+```yaml
+filters:
+ and:
+ - file.hasTag("task")
+ - 'file.ext == "md"'
+
+formulas:
+ days_until_due: 'if(due, ((date(due) - today()) / 86400000).round(0), "")'
+ is_overdue: 'if(due, date(due) < today() && status != "done", false)'
+ priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'
+
+properties:
+ status:
+ displayName: Status
+ formula.days_until_due:
+ displayName: "Days Until Due"
+ formula.priority_label:
+ displayName: Priority
+
+views:
+ - type: table
+ name: "Active Tasks"
+ filters:
+ and:
+ - 'status != "done"'
+ order:
+ - file.name
+ - status
+ - formula.priority_label
+ - due
+ - formula.days_until_due
+ groupBy:
+ property: status
+ direction: ASC
+ summaries:
+ formula.days_until_due: Average
+
+ - type: table
+ name: "Completed"
+ filters:
+ and:
+ - 'status == "done"'
+ order:
+ - file.name
+ - completed_date
+```
+
+### Reading List Base
+
+```yaml
+filters:
+ or:
+ - file.hasTag("book")
+ - file.hasTag("article")
+
+formulas:
+ reading_time: 'if(pages, (pages * 2).toString() + " min", "")'
+ status_icon: 'if(status == "reading", "📖", if(status == "done", "✅", "📚"))'
+ year_read: 'if(finished_date, date(finished_date).year, "")'
+
+properties:
+ author:
+ displayName: Author
+ formula.status_icon:
+ displayName: ""
+ formula.reading_time:
+ displayName: "Est. Time"
+
+views:
+ - type: cards
+ name: "Library"
+ order:
+ - cover
+ - file.name
+ - author
+ - formula.status_icon
+ filters:
+ not:
+ - 'status == "dropped"'
+
+ - type: table
+ name: "Reading List"
+ filters:
+ and:
+ - 'status == "to-read"'
+ order:
+ - file.name
+ - author
+ - pages
+ - formula.reading_time
+```
+
+### Project Notes Base
+
+```yaml
+filters:
+ and:
+ - file.inFolder("Projects")
+ - 'file.ext == "md"'
+
+formulas:
+ last_updated: 'file.mtime.relative()'
+ link_count: 'file.links.length'
+
+summaries:
+ avgLinks: 'values.filter(value.isType("number")).mean().round(1)'
+
+properties:
+ formula.last_updated:
+ displayName: "Updated"
+ formula.link_count:
+ displayName: "Links"
+
+views:
+ - type: table
+ name: "All Projects"
+ order:
+ - file.name
+ - status
+ - formula.last_updated
+ - formula.link_count
+ summaries:
+ formula.link_count: avgLinks
+ groupBy:
+ property: status
+ direction: ASC
+
+ - type: list
+ name: "Quick List"
+ order:
+ - file.name
+ - status
+```
+
+### Daily Notes Index
+
+```yaml
+filters:
+ and:
+ - file.inFolder("Daily Notes")
+ - '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'
+
+formulas:
+ word_estimate: '(file.size / 5).round(0)'
+ day_of_week: 'date(file.basename).format("dddd")'
+
+properties:
+ formula.day_of_week:
+ displayName: "Day"
+ formula.word_estimate:
+ displayName: "~Words"
+
+views:
+ - type: table
+ name: "Recent Notes"
+ limit: 30
+ order:
+ - file.name
+ - formula.day_of_week
+ - formula.word_estimate
+ - file.mtime
+```
+
+## Embedding Bases
+
+Embed in Markdown files:
+
+```markdown
+![[MyBase.base]]
+
+
+![[MyBase.base#View Name]]
+```
+
+## YAML Quoting Rules
+
+- Use single quotes for formulas containing double quotes: `'if(done, "Yes", "No")'`
+- Use double quotes for simple strings: `"My View Name"`
+- Escape nested quotes properly in complex expressions
+
+## Common Patterns
+
+### Filter by Tag
+```yaml
+filters:
+ and:
+ - file.hasTag("project")
+```
+
+### Filter by Folder
+```yaml
+filters:
+ and:
+ - file.inFolder("Notes")
+```
+
+### Filter by Date Range
+```yaml
+filters:
+ and:
+ - 'file.mtime > now() - "7d"'
+```
+
+### Filter by Property Value
+```yaml
+filters:
+ and:
+ - 'status == "active"'
+ - 'priority >= 3'
+```
+
+### Combine Multiple Conditions
+```yaml
+filters:
+ or:
+ - and:
+ - file.hasTag("important")
+ - 'status != "done"'
+ - and:
+ - 'priority == 1'
+ - 'due != ""'
+```
+
+## References
+
+- [Bases Syntax](https://help.obsidian.md/bases/syntax)
+- [Functions](https://help.obsidian.md/bases/functions)
+- [Views](https://help.obsidian.md/bases/views)
+- [Formulas](https://help.obsidian.md/formulas)
diff --git a/.cursor/skills/1-Infrastructure/File-Organization/SKILL.md b/.cursor/skills/1-Infrastructure/File-Organization/SKILL.md
new file mode 100644
index 0000000..66762b8
--- /dev/null
+++ b/.cursor/skills/1-Infrastructure/File-Organization/SKILL.md
@@ -0,0 +1,433 @@
+---
+name: file-organizer
+description: Intelligently organizes your files and folders across your computer by understanding context, finding duplicates, suggesting better structures, and automating cleanup tasks. Reduces cognitive load and keeps your digital workspace tidy without manual effort.
+---
+
+# File Organizer
+
+This skill acts as your personal organization assistant, helping you maintain a clean, logical file structure across your computer without the mental overhead of constant manual organization.
+
+## When to Use This Skill
+
+- Your Downloads folder is a chaotic mess
+- You can't find files because they're scattered everywhere
+- You have duplicate files taking up space
+- Your folder structure doesn't make sense anymore
+- You want to establish better organization habits
+- You're starting a new project and need a good structure
+- You're cleaning up before archiving old projects
+
+## What This Skill Does
+
+1. **Analyzes Current Structure**: Reviews your folders and files to understand what you have
+2. **Finds Duplicates**: Identifies duplicate files across your system
+3. **Suggests Organization**: Proposes logical folder structures based on your content
+4. **Automates Cleanup**: Moves, renames, and organizes files with your approval
+5. **Maintains Context**: Makes smart decisions based on file types, dates, and content
+6. **Reduces Clutter**: Identifies old files you probably don't need anymore
+
+## How to Use
+
+### From Your Home Directory
+
+```
+cd ~
+```
+
+Then run Claude Code and ask for help:
+
+```
+Help me organize my Downloads folder
+```
+
+```
+Find duplicate files in my Documents folder
+```
+
+```
+Review my project directories and suggest improvements
+```
+
+### Specific Organization Tasks
+
+```
+Organize these downloads into proper folders based on what they are
+```
+
+```
+Find duplicate files and help me decide which to keep
+```
+
+```
+Clean up old files I haven't touched in 6+ months
+```
+
+```
+Create a better folder structure for my [work/projects/photos/etc]
+```
+
+## Instructions
+
+When a user requests file organization help:
+
+1. **Understand the Scope**
+
+ Ask clarifying questions:
+ - Which directory needs organization? (Downloads, Documents, entire home folder?)
+ - What's the main problem? (Can't find things, duplicates, too messy, no structure?)
+ - Any files or folders to avoid? (Current projects, sensitive data?)
+ - How aggressively to organize? (Conservative vs. comprehensive cleanup)
+
+2. **Analyze Current State**
+
+ Review the target directory:
+ ```bash
+ # Get overview of current structure
+ ls -la [target_directory]
+
+ # Check file types and sizes
+ find [target_directory] -type f -exec file {} \; | head -20
+
+ # Identify largest files
+ du -sh [target_directory]/* | sort -rh | head -20
+
+ # Count file types
+ find [target_directory] -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn
+ ```
+
+ Summarize findings:
+ - Total files and folders
+ - File type breakdown
+ - Size distribution
+ - Date ranges
+ - Obvious organization issues
+
+3. **Identify Organization Patterns**
+
+ Based on the files, determine logical groupings:
+
+ **By Type**:
+ - Documents (PDFs, DOCX, TXT)
+ - Images (JPG, PNG, SVG)
+ - Videos (MP4, MOV)
+ - Archives (ZIP, TAR, DMG)
+ - Code/Projects (directories with code)
+ - Spreadsheets (XLSX, CSV)
+ - Presentations (PPTX, KEY)
+
+ **By Purpose**:
+ - Work vs. Personal
+ - Active vs. Archive
+ - Project-specific
+ - Reference materials
+ - Temporary/scratch files
+
+ **By Date**:
+ - Current year/month
+ - Previous years
+ - Very old (archive candidates)
+
+4. **Find Duplicates**
+
+ When requested, search for duplicates:
+ ```bash
+ # Find exact duplicates by hash
+ find [directory] -type f -exec md5 {} \; | sort | uniq -d
+
+ # Find files with same name
+ find [directory] -type f -printf '%f\n' | sort | uniq -d
+
+ # Find similar-sized files
+ find [directory] -type f -printf '%s %p\n' | sort -n
+ ```
+
+ For each set of duplicates:
+ - Show all file paths
+ - Display sizes and modification dates
+ - Recommend which to keep (usually newest or best-named)
+ - **Important**: Always ask for confirmation before deleting
+
+5. **Propose Organization Plan**
+
+ Present a clear plan before making changes:
+
+ ```markdown
+ # Organization Plan for [Directory]
+
+ ## Current State
+ - X files across Y folders
+ - [Size] total
+ - File types: [breakdown]
+ - Issues: [list problems]
+
+ ## Proposed Structure
+
+ ```
+ [Directory]/
+ ├── Work/
+ │ ├── Projects/
+ │ ├── Documents/
+ │ └── Archive/
+ ├── Personal/
+ │ ├── Photos/
+ │ ├── Documents/
+ │ └── Media/
+ └── Downloads/
+ ├── To-Sort/
+ └── Archive/
+ ```
+
+ ## Changes I'll Make
+
+ 1. **Create new folders**: [list]
+ 2. **Move files**:
+ - X PDFs → Work/Documents/
+ - Y images → Personal/Photos/
+ - Z old files → Archive/
+ 3. **Rename files**: [any renaming patterns]
+ 4. **Delete**: [duplicates or trash files]
+
+ ## Files Needing Your Decision
+
+ - [List any files you're unsure about]
+
+ Ready to proceed? (yes/no/modify)
+ ```
+
+6. **Execute Organization**
+
+ After approval, organize systematically:
+
+ ```bash
+ # Create folder structure
+ mkdir -p "path/to/new/folders"
+
+ # Move files with clear logging
+ mv "old/path/file.pdf" "new/path/file.pdf"
+
+ # Rename files with consistent patterns
+ # Example: "YYYY-MM-DD - Description.ext"
+ ```
+
+ **Important Rules**:
+ - Always confirm before deleting anything
+ - Log all moves for potential undo
+ - Preserve original modification dates
+ - Handle filename conflicts gracefully
+ - Stop and ask if you encounter unexpected situations
+
+7. **Provide Summary and Maintenance Tips**
+
+ After organizing:
+
+ ```markdown
+ # Organization Complete! ✨
+
+ ## What Changed
+
+ - Created [X] new folders
+ - Organized [Y] files
+ - Freed [Z] GB by removing duplicates
+ - Archived [W] old files
+
+ ## New Structure
+
+ [Show the new folder tree]
+
+ ## Maintenance Tips
+
+ To keep this organized:
+
+ 1. **Weekly**: Sort new downloads
+ 2. **Monthly**: Review and archive completed projects
+ 3. **Quarterly**: Check for new duplicates
+ 4. **Yearly**: Archive old files
+
+ ## Quick Commands for You
+
+ ```bash
+ # Find files modified this week
+ find . -type f -mtime -7
+
+ # Sort downloads by type
+ [custom command for their setup]
+
+ # Find duplicates
+ [custom command]
+ ```
+
+ Want to organize another folder?
+ ```
+
+## Examples
+
+### Example 1: Organizing Downloads (From Justin Dielmann)
+
+**User**: "My Downloads folder is a mess with 500+ files. Help me organize it."
+
+**Process**:
+1. Analyzes Downloads folder
+2. Finds patterns: work docs, personal photos, installers, random PDFs
+3. Proposes structure:
+ - Downloads/
+ - Work/
+ - Personal/
+ - Installers/ (DMG, PKG files)
+ - Archive/
+ - ToSort/ (things needing decisions)
+4. Asks for confirmation
+5. Moves files intelligently based on content and names
+6. Results: 500 files → 5 organized folders
+
+### Example 2: Finding and Removing Duplicates
+
+**User**: "Find duplicate files in my Documents and help me decide which to keep."
+
+**Output**:
+```markdown
+# Found 23 Sets of Duplicates (156 MB total)
+
+## Duplicate Set 1: "proposal.pdf"
+- `/Documents/proposal.pdf` (2.3 MB, modified: 2024-03-15)
+- `/Documents/old/proposal.pdf` (2.3 MB, modified: 2024-03-15)
+- `/Desktop/proposal.pdf` (2.3 MB, modified: 2024-03-10)
+
+**Recommendation**: Keep `/Documents/proposal.pdf` (most recent in correct location)
+Delete the other 2 copies?
+
+[Continue for all duplicates...]
+```
+
+### Example 3: Restructuring Projects Folder
+
+**User**: "Review my ~/Projects directory and suggest improvements."
+
+**Output**:
+```markdown
+# Analysis of ~/Projects
+
+## Current Structure Issues
+- Mix of active and archived projects (3+ years old)
+- No consistent naming convention
+- Some projects at root, others in random subfolders
+- Duplicate folders (project-name, project-name-old, project-name-v2)
+
+## Proposed Structure
+
+```
+Projects/
+├── Active/
+│ ├── client-work/
+│ ├── side-projects/
+│ └── learning/
+├── Archive/
+│ ├── 2022/
+│ ├── 2023/
+│ └── 2024/
+└── Templates/
+```
+
+## Specific Changes
+1. Move 12 projects not touched since 2022 → Archive/
+2. Consolidate 4 duplicate project folders
+3. Rename projects to consistent format: "client-name-project-name"
+4. Create Archive for old work
+
+Want me to implement this?
+```
+
+### Example 4: Organizing Photos by Date
+
+**User**: "Organize my photo folders by year and month."
+
+**Output**: Creates structure like:
+```
+Photos/
+├── 2023/
+│ ├── 01-January/
+│ ├── 02-February/
+│ └── ...
+├── 2024/
+│ ├── 01-January/
+│ └── ...
+└── Unsorted/
+```
+
+Then moves photos based on EXIF data or file modification dates.
+
+## Common Organization Tasks
+
+### Downloads Cleanup
+```
+Organize my Downloads folder - move documents to Documents,
+images to Pictures, keep installers separate, and archive files
+older than 3 months.
+```
+
+### Project Organization
+```
+Review my Projects folder structure and help me separate active
+projects from old ones I should archive.
+```
+
+### Duplicate Removal
+```
+Find all duplicate files in my Documents folder and help me
+decide which ones to keep.
+```
+
+### Desktop Cleanup
+```
+My Desktop is covered in files. Help me organize everything into
+my Documents folder properly.
+```
+
+### Photo Organization
+```
+Organize all photos in this folder by date (year/month) based
+on when they were taken.
+```
+
+### Work/Personal Separation
+```
+Help me separate my work files from personal files across my
+Documents folder.
+```
+
+## Pro Tips
+
+1. **Start Small**: Begin with one messy folder (like Downloads) to build trust
+2. **Regular Maintenance**: Run weekly cleanup on Downloads
+3. **Consistent Naming**: Use "YYYY-MM-DD - Description" format for important files
+4. **Archive Aggressively**: Move old projects to Archive instead of deleting
+5. **Keep Active Separate**: Maintain clear boundaries between active and archived work
+6. **Trust the Process**: Let Claude handle the cognitive load of where things go
+
+## Best Practices
+
+### Folder Naming
+- Use clear, descriptive names
+- Avoid spaces (use hyphens or underscores)
+- Be specific: "client-proposals" not "docs"
+- Use prefixes for ordering: "01-current", "02-archive"
+
+### File Naming
+- Include dates: "2024-10-17-meeting-notes.md"
+- Be descriptive: "q3-financial-report.xlsx"
+- Avoid version numbers in names (use version control instead)
+- Remove download artifacts: "document-final-v2 (1).pdf" → "document.pdf"
+
+### When to Archive
+- Projects not touched in 6+ months
+- Completed work that might be referenced later
+- Old versions after migration to new systems
+- Files you're hesitant to delete (archive first)
+
+## Related Use Cases
+
+- Setting up organization for a new computer
+- Preparing files for backup/archiving
+- Cleaning up before storage cleanup
+- Organizing shared team folders
+- Structuring new project directories
+
diff --git a/.cursor/skills/2-Execution/Communication-Standards/LICENSE.txt b/.cursor/skills/2-Execution/Communication-Standards/LICENSE.txt
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/.cursor/skills/2-Execution/Communication-Standards/SKILL.md b/.cursor/skills/2-Execution/Communication-Standards/SKILL.md
new file mode 100644
index 0000000..56ea935
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/SKILL.md
@@ -0,0 +1,32 @@
+---
+name: internal-comms
+description: A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
+license: Complete terms in LICENSE.txt
+---
+
+## When to use this skill
+To write internal communications, use this skill for:
+- 3P updates (Progress, Plans, Problems)
+- Company newsletters
+- FAQ responses
+- Status reports
+- Leadership updates
+- Project updates
+- Incident reports
+
+## How to use this skill
+
+To write any internal communication:
+
+1. **Identify the communication type** from the request
+2. **Load the appropriate guideline file** from the `examples/` directory:
+ - `examples/3p-updates.md` - For Progress/Plans/Problems team updates
+ - `examples/company-newsletter.md` - For company-wide newsletters
+ - `examples/faq-answers.md` - For answering frequently asked questions
+ - `examples/general-comms.md` - For anything else that doesn't explicitly match one of the above
+3. **Follow the specific instructions** in that file for formatting, tone, and content gathering
+
+If the communication type doesn't match any existing guideline, ask for clarification or more context about the desired format.
+
+## Keywords
+3P updates, company newsletter, company comms, weekly update, faqs, common questions, updates, internal comms
diff --git a/.cursor/skills/2-Execution/Communication-Standards/examples/3p-updates.md b/.cursor/skills/2-Execution/Communication-Standards/examples/3p-updates.md
new file mode 100644
index 0000000..5329bfb
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/examples/3p-updates.md
@@ -0,0 +1,47 @@
+## Instructions
+You are being asked to write a 3P update. 3P updates stand for "Progress, Plans, Problems." The main audience is for executives, leadership, other teammates, etc. They're meant to be very succinct and to-the-point: think something you can read in 30-60sec or less. They're also for people with some, but not a lot of context on what the team does.
+
+3Ps can cover a team of any size, ranging all the way up to the entire company. The bigger the team, the less granular the tasks should be. For example, "mobile team" might have "shipped feature" or "fixed bugs," whereas the company might have really meaty 3Ps, like "hired 20 new people" or "closed 10 new deals."
+
+They represent the work of the team across a time period, almost always one week. They include three sections:
+1) Progress: what the team has accomplished over the next time period. Focus mainly on things shipped, milestones achieved, tasks created, etc.
+2) Plans: what the team plans to do over the next time period. Focus on what things are top-of-mind, really high priority, etc. for the team.
+3) Problems: anything that is slowing the team down. This could be things like too few people, bugs or blockers that are preventing the team from moving forward, some deal that fell through, etc.
+
+Before writing them, make sure that you know the team name. If it's not specified, you can ask explicitly what the team name you're writing for is.
+
+
+## Tools Available
+Whenever possible, try to pull from available sources to get the information you need:
+- Slack: posts from team members with their updates - ideally look for posts in large channels with lots of reactions
+- Google Drive: docs written from critical team members with lots of views
+- Email: emails with lots of responses of lots of content that seems relevant
+- Calendar: non-recurring meetings that have a lot of importance, like product reviews, etc.
+
+
+Try to gather as much context as you can, focusing on the things that covered the time period you're writing for:
+- Progress: anything between a week ago and today
+- Plans: anything from today to the next week
+- Problems: anything between a week ago and today
+
+
+If you don't have access, you can ask the user for things they want to cover. They might also include these things to you directly, in which case you're mostly just formatting for this particular format.
+
+## Workflow
+
+1. **Clarify scope**: Confirm the team name and time period (usually past week for Progress/Problems, next
+week for Plans)
+2. **Gather information**: Use available tools or ask the user directly
+3. **Draft the update**: Follow the strict formatting guidelines
+4. **Review**: Ensure it's concise (30-60 seconds to read) and data-driven
+
+## Formatting
+
+The format is always the same, very strict formatting. Never use any formatting other than this. Pick an emoji that is fun and captures the vibe of the team and update.
+
+[pick an emoji] [Team Name] (Dates Covered, usually a week)
+Progress: [1-3 sentences of content]
+Plans: [1-3 sentences of content]
+Problems: [1-3 sentences of content]
+
+Each section should be no more than 1-3 sentences: clear, to the point. It should be data-driven, and generally include metrics where possible. The tone should be very matter-of-fact, not super prose-heavy.
\ No newline at end of file
diff --git a/.cursor/skills/2-Execution/Communication-Standards/examples/company-newsletter.md b/.cursor/skills/2-Execution/Communication-Standards/examples/company-newsletter.md
new file mode 100644
index 0000000..4997a07
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/examples/company-newsletter.md
@@ -0,0 +1,65 @@
+## Instructions
+You are being asked to write a company-wide newsletter update. You are meant to summarize the past week/month of a company in the form of a newsletter that the entire company will read. It should be maybe ~20-25 bullet points long. It will be sent via Slack and email, so make it consumable for that.
+
+Ideally it includes the following attributes:
+- Lots of links: pulling documents from Google Drive that are very relevant, linking to prominent Slack messages in announce channels and from executives, perhgaps referencing emails that went company-wide, highlighting significant things that have happened in the company.
+- Short and to-the-point: each bullet should probably be no longer than ~1-2 sentences
+- Use the "we" tense, as you are part of the company. Many of the bullets should say "we did this" or "we did that"
+
+## Tools to use
+If you have access to the following tools, please try to use them. If not, you can also let the user know directly that their responses would be better if they gave them access.
+
+- Slack: look for messages in channels with lots of people, with lots of reactions or lots of responses within the thread
+- Email: look for things from executives that discuss company-wide announcements
+- Calendar: if there were meetings with large attendee lists, particularly things like All-Hands meetings, big company announcements, etc. If there were documents attached to those meetings, those are great links to include.
+- Documents: if there were new docs published in the last week or two that got a lot of attention, you can link them. These should be things like company-wide vision docs, plans for the upcoming quarter or half, things authored by critical executives, etc.
+- External press: if you see references to articles or press we've received over the past week, that could be really cool too.
+
+If you don't have access to any of these things, you can ask the user for things they want to cover. In this case, you'll mostly just be polishing up and fitting to this format more directly.
+
+## Sections
+The company is pretty big: 1000+ people. There are a variety of different teams and initiatives going on across the company. To make sure the update works well, try breaking it into sections of similar things. You might break into clusters like {product development, go to market, finance} or {recruiting, execution, vision}, or {external news, internal news} etc. Try to make sure the different areas of the company are highlighted well.
+
+## Prioritization
+Focus on:
+- Company-wide impact (not team-specific details)
+- Announcements from leadership
+- Major milestones and achievements
+- Information that affects most employees
+- External recognition or press
+
+Avoid:
+- Overly granular team updates (save those for 3Ps)
+- Information only relevant to small groups
+- Duplicate information already communicated
+
+## Example Formats
+
+:megaphone: Company Announcements
+- Announcement 1
+- Announcement 2
+- Announcement 3
+
+:dart: Progress on Priorities
+- Area 1
+ - Sub-area 1
+ - Sub-area 2
+ - Sub-area 3
+- Area 2
+ - Sub-area 1
+ - Sub-area 2
+ - Sub-area 3
+- Area 3
+ - Sub-area 1
+ - Sub-area 2
+ - Sub-area 3
+
+:pillar: Leadership Updates
+- Post 1
+- Post 2
+- Post 3
+
+:thread: Social Updates
+- Update 1
+- Update 2
+- Update 3
diff --git a/.cursor/skills/2-Execution/Communication-Standards/examples/faq-answers.md b/.cursor/skills/2-Execution/Communication-Standards/examples/faq-answers.md
new file mode 100644
index 0000000..395262a
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/examples/faq-answers.md
@@ -0,0 +1,30 @@
+## Instructions
+You are an assistant for answering questions that are being asked across the company. Every week, there are lots of questions that get asked across the company, and your goal is to try to summarize what those questions are. We want our company to be well-informed and on the same page, so your job is to produce a set of frequently asked questions that our employees are asking and attempt to answer them. Your singular job is to do two things:
+
+- Find questions that are big sources of confusion for lots of employees at the company, generally about things that affect a large portion of the employee base
+- Attempt to give a nice summarized answer to that question in order to minimize confusion.
+
+Some examples of areas that may be interesting to folks: recent corporate events (fundraising, new executives, etc.), upcoming launches, hiring progress, changes to vision or focus, etc.
+
+
+## Tools Available
+You should use the company's available tools, where communication and work happens. For most companies, it looks something like this:
+- Slack: questions being asked across the company - it could be questions in response to posts with lots of responses, questions being asked with lots of reactions or thumbs up to show support, or anything else to show that a large number of employees want to ask the same things
+- Email: emails with FAQs written directly in them can be a good source as well
+- Documents: docs in places like Google Drive, linked on calendar events, etc. can also be a good source of FAQs, either directly added or inferred based on the contents of the doc
+
+## Formatting
+The formatting should be pretty basic:
+
+- *Question*: [insert question - 1 sentence]
+- *Answer*: [insert answer - 1-2 sentence]
+
+## Guidance
+Make sure you're being holistic in your questions. Don't focus too much on just the user in question or the team they are a part of, but try to capture the entire company. Try to be as holistic as you can in reading all the tools available, producing responses that are relevant to all at the company.
+
+## Answer Guidelines
+- Base answers on official company communications when possible
+- If information is uncertain, indicate that clearly
+- Link to authoritative sources (docs, announcements, emails)
+- Keep tone professional but approachable
+- Flag if a question requires executive input or official response
\ No newline at end of file
diff --git a/.cursor/skills/2-Execution/Communication-Standards/examples/general-comms.md b/.cursor/skills/2-Execution/Communication-Standards/examples/general-comms.md
new file mode 100644
index 0000000..0ea9770
--- /dev/null
+++ b/.cursor/skills/2-Execution/Communication-Standards/examples/general-comms.md
@@ -0,0 +1,16 @@
+ ## Instructions
+ You are being asked to write internal company communication that doesn't fit into the standard formats (3P
+ updates, newsletters, or FAQs).
+
+ Before proceeding:
+ 1. Ask the user about their target audience
+ 2. Understand the communication's purpose
+ 3. Clarify the desired tone (formal, casual, urgent, informational)
+ 4. Confirm any specific formatting requirements
+
+ Use these general principles:
+ - Be clear and concise
+ - Use active voice
+ - Put the most important information first
+ - Include relevant links and references
+ - Match the company's communication style
\ No newline at end of file
diff --git a/.cursor/skills/2-Execution/Document-Governance/SKILL.md b/.cursor/skills/2-Execution/Document-Governance/SKILL.md
new file mode 100644
index 0000000..6646638
--- /dev/null
+++ b/.cursor/skills/2-Execution/Document-Governance/SKILL.md
@@ -0,0 +1,197 @@
+---
+name: docx
+description: "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks"
+license: Proprietary. LICENSE.txt has complete terms
+---
+
+# DOCX creation, editing, and analysis
+
+## Overview
+
+A user may ask you to create, edit, or analyze the contents of a .docx file. A .docx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.
+
+## Workflow Decision Tree
+
+### Reading/Analyzing Content
+Use "Text extraction" or "Raw XML access" sections below
+
+### Creating New Document
+Use "Creating a new Word document" workflow
+
+### Editing Existing Document
+- **Your own document + simple changes**
+ Use "Basic OOXML editing" workflow
+
+- **Someone else's document**
+ Use **"Redlining workflow"** (recommended default)
+
+- **Legal, academic, business, or government docs**
+ Use **"Redlining workflow"** (required)
+
+## Reading and analyzing content
+
+### Text extraction
+If you just need to read the text contents of a document, you should convert the document to markdown using pandoc. Pandoc provides excellent support for preserving document structure and can show tracked changes:
+
+```bash
+# Convert document to markdown with tracked changes
+pandoc --track-changes=all path-to-file.docx -o output.md
+# Options: --track-changes=accept/reject/all
+```
+
+### Raw XML access
+You need raw XML access for: comments, complex formatting, document structure, embedded media, and metadata. For any of these features, you'll need to unpack a document and read its raw XML contents.
+
+#### Unpacking a file
+`python ooxml/scripts/unpack.py `
+
+#### Key file structures
+* `word/document.xml` - Main document contents
+* `word/comments.xml` - Comments referenced in document.xml
+* `word/media/` - Embedded images and media files
+* Tracked changes use `` (insertions) and `` (deletions) tags
+
+## Creating a new Word document
+
+When creating a new Word document from scratch, use **docx-js**, which allows you to create Word documents using JavaScript/TypeScript.
+
+### Workflow
+1. **MANDATORY - READ ENTIRE FILE**: Read [`docx-js.md`](docx-js.md) (~500 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Read the full file content for detailed syntax, critical formatting rules, and best practices before proceeding with document creation.
+2. Create a JavaScript/TypeScript file using Document, Paragraph, TextRun components (You can assume all dependencies are installed, but if not, refer to the dependencies section below)
+3. Export as .docx using Packer.toBuffer()
+
+## Editing an existing Word document
+
+When editing an existing Word document, use the **Document library** (a Python library for OOXML manipulation). The library automatically handles infrastructure setup and provides methods for document manipulation. For complex scenarios, you can access the underlying DOM directly through the library.
+
+### Workflow
+1. **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~600 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Read the full file content for the Document library API and XML patterns for directly editing document files.
+2. Unpack the document: `python ooxml/scripts/unpack.py `
+3. Create and run a Python script using the Document library (see "Document Library" section in ooxml.md)
+4. Pack the final document: `python ooxml/scripts/pack.py `
+
+The Document library provides both high-level methods for common operations and direct DOM access for complex scenarios.
+
+## Redlining workflow for document review
+
+This workflow allows you to plan comprehensive tracked changes using markdown before implementing them in OOXML. **CRITICAL**: For complete tracked changes, you must implement ALL changes systematically.
+
+**Batching Strategy**: Group related changes into batches of 3-10 changes. This makes debugging manageable while maintaining efficiency. Test each batch before moving to the next.
+
+**Principle: Minimal, Precise Edits**
+When implementing tracked changes, only mark text that actually changes. Repeating unchanged text makes edits harder to review and appears unprofessional. Break replacements into: [unchanged text] + [deletion] + [insertion] + [unchanged text]. Preserve the original run's RSID for unchanged text by extracting the `` element from the original and reusing it.
+
+Example - Changing "30 days" to "60 days" in a sentence:
+```python
+# BAD - Replaces entire sentence
+'The term is 30 days.The term is 60 days.'
+
+# GOOD - Only marks what changed, preserves original for unchanged text
+'The term is 3060 days.'
+```
+
+### Tracked changes workflow
+
+1. **Get markdown representation**: Convert document to markdown with tracked changes preserved:
+ ```bash
+ pandoc --track-changes=all path-to-file.docx -o current.md
+ ```
+
+2. **Identify and group changes**: Review the document and identify ALL changes needed, organizing them into logical batches:
+
+ **Location methods** (for finding changes in XML):
+ - Section/heading numbers (e.g., "Section 3.2", "Article IV")
+ - Paragraph identifiers if numbered
+ - Grep patterns with unique surrounding text
+ - Document structure (e.g., "first paragraph", "signature block")
+ - **DO NOT use markdown line numbers** - they don't map to XML structure
+
+ **Batch organization** (group 3-10 related changes per batch):
+ - By section: "Batch 1: Section 2 amendments", "Batch 2: Section 5 updates"
+ - By type: "Batch 1: Date corrections", "Batch 2: Party name changes"
+ - By complexity: Start with simple text replacements, then tackle complex structural changes
+ - Sequential: "Batch 1: Pages 1-3", "Batch 2: Pages 4-6"
+
+3. **Read documentation and unpack**:
+ - **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~600 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Pay special attention to the "Document Library" and "Tracked Change Patterns" sections.
+ - **Unpack the document**: `python ooxml/scripts/unpack.py `
+ - **Note the suggested RSID**: The unpack script will suggest an RSID to use for your tracked changes. Copy this RSID for use in step 4b.
+
+4. **Implement changes in batches**: Group changes logically (by section, by type, or by proximity) and implement them together in a single script. This approach:
+ - Makes debugging easier (smaller batch = easier to isolate errors)
+ - Allows incremental progress
+ - Maintains efficiency (batch size of 3-10 changes works well)
+
+ **Suggested batch groupings:**
+ - By document section (e.g., "Section 3 changes", "Definitions", "Termination clause")
+ - By change type (e.g., "Date changes", "Party name updates", "Legal term replacements")
+ - By proximity (e.g., "Changes on pages 1-3", "Changes in first half of document")
+
+ For each batch of related changes:
+
+ **a. Map text to XML**: Grep for text in `word/document.xml` to verify how text is split across `` elements.
+
+ **b. Create and run script**: Use `get_node` to find nodes, implement changes, then `doc.save()`. See **"Document Library"** section in ooxml.md for patterns.
+
+ **Note**: Always grep `word/document.xml` immediately before writing a script to get current line numbers and verify text content. Line numbers change after each script run.
+
+5. **Pack the document**: After all batches are complete, convert the unpacked directory back to .docx:
+ ```bash
+ python ooxml/scripts/pack.py unpacked reviewed-document.docx
+ ```
+
+6. **Final verification**: Do a comprehensive check of the complete document:
+ - Convert final document to markdown:
+ ```bash
+ pandoc --track-changes=all reviewed-document.docx -o verification.md
+ ```
+ - Verify ALL changes were applied correctly:
+ ```bash
+ grep "original phrase" verification.md # Should NOT find it
+ grep "replacement phrase" verification.md # Should find it
+ ```
+ - Check that no unintended changes were introduced
+
+
+## Converting Documents to Images
+
+To visually analyze Word documents, convert them to images using a two-step process:
+
+1. **Convert DOCX to PDF**:
+ ```bash
+ soffice --headless --convert-to pdf document.docx
+ ```
+
+2. **Convert PDF pages to JPEG images**:
+ ```bash
+ pdftoppm -jpeg -r 150 document.pdf page
+ ```
+ This creates files like `page-1.jpg`, `page-2.jpg`, etc.
+
+Options:
+- `-r 150`: Sets resolution to 150 DPI (adjust for quality/size balance)
+- `-jpeg`: Output JPEG format (use `-png` for PNG if preferred)
+- `-f N`: First page to convert (e.g., `-f 2` starts from page 2)
+- `-l N`: Last page to convert (e.g., `-l 5` stops at page 5)
+- `page`: Prefix for output files
+
+Example for specific range:
+```bash
+pdftoppm -jpeg -r 150 -f 2 -l 5 document.pdf page # Converts only pages 2-5
+```
+
+## Code Style Guidelines
+**IMPORTANT**: When generating code for DOCX operations:
+- Write concise code
+- Avoid verbose variable names and redundant operations
+- Avoid unnecessary print statements
+
+## Dependencies
+
+Required dependencies (install if not available):
+
+- **pandoc**: `sudo apt-get install pandoc` (for text extraction)
+- **docx**: `npm install -g docx` (for creating new documents)
+- **LibreOffice**: `sudo apt-get install libreoffice` (for PDF conversion)
+- **Poppler**: `sudo apt-get install poppler-utils` (for pdftoppm to convert PDF to images)
+- **defusedxml**: `pip install defusedxml` (for secure XML parsing)
\ No newline at end of file
diff --git a/.cursor/skills/2-Execution/Visual-Workflows/SKILL.md b/.cursor/skills/2-Execution/Visual-Workflows/SKILL.md
new file mode 100644
index 0000000..e0611fe
--- /dev/null
+++ b/.cursor/skills/2-Execution/Visual-Workflows/SKILL.md
@@ -0,0 +1,642 @@
+---
+name: json-canvas
+description: Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections. Use when working with .canvas files, creating visual canvases, mind maps, flowcharts, or when the user mentions Canvas files in Obsidian.
+---
+
+# JSON Canvas Skill
+
+This skill enables skills-compatible agents to create and edit valid JSON Canvas files (`.canvas`) used in Obsidian and other applications.
+
+## Overview
+
+JSON Canvas is an open file format for infinite canvas data. Canvas files use the `.canvas` extension and contain valid JSON following the [JSON Canvas Spec 1.0](https://jsoncanvas.org/spec/1.0/).
+
+## File Structure
+
+A canvas file contains two top-level arrays:
+
+```json
+{
+ "nodes": [],
+ "edges": []
+}
+```
+
+- `nodes` (optional): Array of node objects
+- `edges` (optional): Array of edge objects connecting nodes
+
+## Nodes
+
+Nodes are objects placed on the canvas. There are four node types:
+- `text` - Text content with Markdown
+- `file` - Reference to files/attachments
+- `link` - External URL
+- `group` - Visual container for other nodes
+
+### Z-Index Ordering
+
+Nodes are ordered by z-index in the array:
+- First node = bottom layer (displayed below others)
+- Last node = top layer (displayed above others)
+
+### Generic Node Attributes
+
+All nodes share these attributes:
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `id` | Yes | string | Unique identifier for the node |
+| `type` | Yes | string | Node type: `text`, `file`, `link`, or `group` |
+| `x` | Yes | integer | X position in pixels |
+| `y` | Yes | integer | Y position in pixels |
+| `width` | Yes | integer | Width in pixels |
+| `height` | Yes | integer | Height in pixels |
+| `color` | No | canvasColor | Node color (see Color section) |
+
+### Text Nodes
+
+Text nodes contain Markdown content.
+
+```json
+{
+ "id": "6f0ad84f44ce9c17",
+ "type": "text",
+ "x": 0,
+ "y": 0,
+ "width": 400,
+ "height": 200,
+ "text": "# Hello World\n\nThis is **Markdown** content."
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `text` | Yes | string | Plain text with Markdown syntax |
+
+### File Nodes
+
+File nodes reference files or attachments (images, videos, PDFs, notes, etc.).
+
+```json
+{
+ "id": "a1b2c3d4e5f67890",
+ "type": "file",
+ "x": 500,
+ "y": 0,
+ "width": 400,
+ "height": 300,
+ "file": "Attachments/diagram.png"
+}
+```
+
+```json
+{
+ "id": "b2c3d4e5f6789012",
+ "type": "file",
+ "x": 500,
+ "y": 400,
+ "width": 400,
+ "height": 300,
+ "file": "Notes/Project Overview.md",
+ "subpath": "#Implementation"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `file` | Yes | string | Path to file within the system |
+| `subpath` | No | string | Link to heading or block (starts with `#`) |
+
+### Link Nodes
+
+Link nodes display external URLs.
+
+```json
+{
+ "id": "c3d4e5f678901234",
+ "type": "link",
+ "x": 1000,
+ "y": 0,
+ "width": 400,
+ "height": 200,
+ "url": "https://obsidian.md"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `url` | Yes | string | External URL |
+
+### Group Nodes
+
+Group nodes are visual containers for organizing other nodes.
+
+```json
+{
+ "id": "d4e5f6789012345a",
+ "type": "group",
+ "x": -50,
+ "y": -50,
+ "width": 1000,
+ "height": 600,
+ "label": "Project Overview",
+ "color": "4"
+}
+```
+
+```json
+{
+ "id": "e5f67890123456ab",
+ "type": "group",
+ "x": 0,
+ "y": 700,
+ "width": 800,
+ "height": 500,
+ "label": "Resources",
+ "background": "Attachments/background.png",
+ "backgroundStyle": "cover"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `label` | No | string | Text label for the group |
+| `background` | No | string | Path to background image |
+| `backgroundStyle` | No | string | Background rendering style |
+
+#### Background Styles
+
+| Value | Description |
+|-------|-------------|
+| `cover` | Fills entire width and height of node |
+| `ratio` | Maintains aspect ratio of background image |
+| `repeat` | Repeats image as pattern in both directions |
+
+## Edges
+
+Edges are lines connecting nodes.
+
+```json
+{
+ "id": "f67890123456789a",
+ "fromNode": "6f0ad84f44ce9c17",
+ "toNode": "a1b2c3d4e5f67890"
+}
+```
+
+```json
+{
+ "id": "0123456789abcdef",
+ "fromNode": "6f0ad84f44ce9c17",
+ "fromSide": "right",
+ "fromEnd": "none",
+ "toNode": "b2c3d4e5f6789012",
+ "toSide": "left",
+ "toEnd": "arrow",
+ "color": "1",
+ "label": "leads to"
+}
+```
+
+| Attribute | Required | Type | Default | Description |
+|-----------|----------|------|---------|-------------|
+| `id` | Yes | string | - | Unique identifier for the edge |
+| `fromNode` | Yes | string | - | Node ID where connection starts |
+| `fromSide` | No | string | - | Side where edge starts |
+| `fromEnd` | No | string | `none` | Shape at edge start |
+| `toNode` | Yes | string | - | Node ID where connection ends |
+| `toSide` | No | string | - | Side where edge ends |
+| `toEnd` | No | string | `arrow` | Shape at edge end |
+| `color` | No | canvasColor | - | Line color |
+| `label` | No | string | - | Text label for the edge |
+
+### Side Values
+
+| Value | Description |
+|-------|-------------|
+| `top` | Top edge of node |
+| `right` | Right edge of node |
+| `bottom` | Bottom edge of node |
+| `left` | Left edge of node |
+
+### End Shapes
+
+| Value | Description |
+|-------|-------------|
+| `none` | No endpoint shape |
+| `arrow` | Arrow endpoint |
+
+## Colors
+
+The `canvasColor` type can be specified in two ways:
+
+### Hex Colors
+
+```json
+{
+ "color": "#FF0000"
+}
+```
+
+### Preset Colors
+
+```json
+{
+ "color": "1"
+}
+```
+
+| Preset | Color |
+|--------|-------|
+| `"1"` | Red |
+| `"2"` | Orange |
+| `"3"` | Yellow |
+| `"4"` | Green |
+| `"5"` | Cyan |
+| `"6"` | Purple |
+
+Note: Specific color values for presets are intentionally undefined, allowing applications to use their own brand colors.
+
+## Complete Examples
+
+### Simple Canvas with Text and Connections
+
+```json
+{
+ "nodes": [
+ {
+ "id": "8a9b0c1d2e3f4a5b",
+ "type": "text",
+ "x": 0,
+ "y": 0,
+ "width": 300,
+ "height": 150,
+ "text": "# Main Idea\n\nThis is the central concept."
+ },
+ {
+ "id": "1a2b3c4d5e6f7a8b",
+ "type": "text",
+ "x": 400,
+ "y": -100,
+ "width": 250,
+ "height": 100,
+ "text": "## Supporting Point A\n\nDetails here."
+ },
+ {
+ "id": "2b3c4d5e6f7a8b9c",
+ "type": "text",
+ "x": 400,
+ "y": 100,
+ "width": 250,
+ "height": 100,
+ "text": "## Supporting Point B\n\nMore details."
+ }
+ ],
+ "edges": [
+ {
+ "id": "3c4d5e6f7a8b9c0d",
+ "fromNode": "8a9b0c1d2e3f4a5b",
+ "fromSide": "right",
+ "toNode": "1a2b3c4d5e6f7a8b",
+ "toSide": "left"
+ },
+ {
+ "id": "4d5e6f7a8b9c0d1e",
+ "fromNode": "8a9b0c1d2e3f4a5b",
+ "fromSide": "right",
+ "toNode": "2b3c4d5e6f7a8b9c",
+ "toSide": "left"
+ }
+ ]
+}
+```
+
+### Project Board with Groups
+
+```json
+{
+ "nodes": [
+ {
+ "id": "5e6f7a8b9c0d1e2f",
+ "type": "group",
+ "x": 0,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "To Do",
+ "color": "1"
+ },
+ {
+ "id": "6f7a8b9c0d1e2f3a",
+ "type": "group",
+ "x": 350,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "In Progress",
+ "color": "3"
+ },
+ {
+ "id": "7a8b9c0d1e2f3a4b",
+ "type": "group",
+ "x": 700,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "Done",
+ "color": "4"
+ },
+ {
+ "id": "8b9c0d1e2f3a4b5c",
+ "type": "text",
+ "x": 20,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 1\n\nImplement feature X"
+ },
+ {
+ "id": "9c0d1e2f3a4b5c6d",
+ "type": "text",
+ "x": 370,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 2\n\nReview PR #123",
+ "color": "2"
+ },
+ {
+ "id": "0d1e2f3a4b5c6d7e",
+ "type": "text",
+ "x": 720,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 3\n\n~~Setup CI/CD~~"
+ }
+ ],
+ "edges": []
+}
+```
+
+### Research Canvas with Files and Links
+
+```json
+{
+ "nodes": [
+ {
+ "id": "1e2f3a4b5c6d7e8f",
+ "type": "text",
+ "x": 300,
+ "y": 200,
+ "width": 400,
+ "height": 200,
+ "text": "# Research Topic\n\n## Key Questions\n\n- How does X affect Y?\n- What are the implications?",
+ "color": "5"
+ },
+ {
+ "id": "2f3a4b5c6d7e8f9a",
+ "type": "file",
+ "x": 0,
+ "y": 0,
+ "width": 250,
+ "height": 150,
+ "file": "Literature/Paper A.pdf"
+ },
+ {
+ "id": "3a4b5c6d7e8f9a0b",
+ "type": "file",
+ "x": 0,
+ "y": 200,
+ "width": 250,
+ "height": 150,
+ "file": "Notes/Meeting Notes.md",
+ "subpath": "#Key Insights"
+ },
+ {
+ "id": "4b5c6d7e8f9a0b1c",
+ "type": "link",
+ "x": 0,
+ "y": 400,
+ "width": 250,
+ "height": 100,
+ "url": "https://example.com/research"
+ },
+ {
+ "id": "5c6d7e8f9a0b1c2d",
+ "type": "file",
+ "x": 750,
+ "y": 150,
+ "width": 300,
+ "height": 250,
+ "file": "Attachments/diagram.png"
+ }
+ ],
+ "edges": [
+ {
+ "id": "6d7e8f9a0b1c2d3e",
+ "fromNode": "2f3a4b5c6d7e8f9a",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "label": "supports"
+ },
+ {
+ "id": "7e8f9a0b1c2d3e4f",
+ "fromNode": "3a4b5c6d7e8f9a0b",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "label": "informs"
+ },
+ {
+ "id": "8f9a0b1c2d3e4f5a",
+ "fromNode": "4b5c6d7e8f9a0b1c",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "toEnd": "arrow",
+ "color": "6"
+ },
+ {
+ "id": "9a0b1c2d3e4f5a6b",
+ "fromNode": "1e2f3a4b5c6d7e8f",
+ "fromSide": "right",
+ "toNode": "5c6d7e8f9a0b1c2d",
+ "toSide": "left",
+ "label": "visualized by"
+ }
+ ]
+}
+```
+
+### Flowchart
+
+```json
+{
+ "nodes": [
+ {
+ "id": "a0b1c2d3e4f5a6b7",
+ "type": "text",
+ "x": 200,
+ "y": 0,
+ "width": 150,
+ "height": 60,
+ "text": "**Start**",
+ "color": "4"
+ },
+ {
+ "id": "b1c2d3e4f5a6b7c8",
+ "type": "text",
+ "x": 200,
+ "y": 100,
+ "width": 150,
+ "height": 60,
+ "text": "Step 1:\nGather data"
+ },
+ {
+ "id": "c2d3e4f5a6b7c8d9",
+ "type": "text",
+ "x": 200,
+ "y": 200,
+ "width": 150,
+ "height": 80,
+ "text": "**Decision**\n\nIs data valid?",
+ "color": "3"
+ },
+ {
+ "id": "d3e4f5a6b7c8d9e0",
+ "type": "text",
+ "x": 400,
+ "y": 200,
+ "width": 150,
+ "height": 60,
+ "text": "Process data"
+ },
+ {
+ "id": "e4f5a6b7c8d9e0f1",
+ "type": "text",
+ "x": 0,
+ "y": 200,
+ "width": 150,
+ "height": 60,
+ "text": "Request new data",
+ "color": "1"
+ },
+ {
+ "id": "f5a6b7c8d9e0f1a2",
+ "type": "text",
+ "x": 400,
+ "y": 320,
+ "width": 150,
+ "height": 60,
+ "text": "**End**",
+ "color": "4"
+ }
+ ],
+ "edges": [
+ {
+ "id": "a6b7c8d9e0f1a2b3",
+ "fromNode": "a0b1c2d3e4f5a6b7",
+ "fromSide": "bottom",
+ "toNode": "b1c2d3e4f5a6b7c8",
+ "toSide": "top"
+ },
+ {
+ "id": "b7c8d9e0f1a2b3c4",
+ "fromNode": "b1c2d3e4f5a6b7c8",
+ "fromSide": "bottom",
+ "toNode": "c2d3e4f5a6b7c8d9",
+ "toSide": "top"
+ },
+ {
+ "id": "c8d9e0f1a2b3c4d5",
+ "fromNode": "c2d3e4f5a6b7c8d9",
+ "fromSide": "right",
+ "toNode": "d3e4f5a6b7c8d9e0",
+ "toSide": "left",
+ "label": "Yes",
+ "color": "4"
+ },
+ {
+ "id": "d9e0f1a2b3c4d5e6",
+ "fromNode": "c2d3e4f5a6b7c8d9",
+ "fromSide": "left",
+ "toNode": "e4f5a6b7c8d9e0f1",
+ "toSide": "right",
+ "label": "No",
+ "color": "1"
+ },
+ {
+ "id": "e0f1a2b3c4d5e6f7",
+ "fromNode": "e4f5a6b7c8d9e0f1",
+ "fromSide": "top",
+ "fromEnd": "none",
+ "toNode": "b1c2d3e4f5a6b7c8",
+ "toSide": "left",
+ "toEnd": "arrow"
+ },
+ {
+ "id": "f1a2b3c4d5e6f7a8",
+ "fromNode": "d3e4f5a6b7c8d9e0",
+ "fromSide": "bottom",
+ "toNode": "f5a6b7c8d9e0f1a2",
+ "toSide": "top"
+ }
+ ]
+}
+```
+
+## ID Generation
+
+Node and edge IDs must be unique strings. Obsidian generates 16-character hexadecimal IDs:
+
+```json
+"id": "6f0ad84f44ce9c17"
+"id": "a3b2c1d0e9f8g7h6"
+"id": "1234567890abcdef"
+```
+
+This format is a 16-character lowercase hex string (64-bit random value).
+
+## Layout Guidelines
+
+### Positioning
+
+- Coordinates can be negative (canvas extends infinitely)
+- `x` increases to the right
+- `y` increases downward
+- Position refers to top-left corner of node
+
+### Recommended Sizes
+
+| Node Type | Suggested Width | Suggested Height |
+|-----------|-----------------|------------------|
+| Small text | 200-300 | 80-150 |
+| Medium text | 300-450 | 150-300 |
+| Large text | 400-600 | 300-500 |
+| File preview | 300-500 | 200-400 |
+| Link preview | 250-400 | 100-200 |
+| Group | Varies | Varies |
+
+### Spacing
+
+- Leave 20-50px padding inside groups
+- Space nodes 50-100px apart for readability
+- Align nodes to grid (multiples of 10 or 20) for cleaner layouts
+
+## Validation Rules
+
+1. All `id` values must be unique across nodes and edges
+2. `fromNode` and `toNode` must reference existing node IDs
+3. Required fields must be present for each node type
+4. `type` must be one of: `text`, `file`, `link`, `group`
+5. `backgroundStyle` must be one of: `cover`, `ratio`, `repeat`
+6. `fromSide`, `toSide` must be one of: `top`, `right`, `bottom`, `left`
+7. `fromEnd`, `toEnd` must be one of: `none`, `arrow`
+8. Color presets must be `"1"` through `"6"` or valid hex color
+
+## References
+
+- [JSON Canvas Spec 1.0](https://jsoncanvas.org/spec/1.0/)
+- [JSON Canvas GitHub](https://github.com/obsidianmd/jsoncanvas)
diff --git a/.cursor/skills/2-Execution/Writing-Standards/SKILL.md b/.cursor/skills/2-Execution/Writing-Standards/SKILL.md
new file mode 100644
index 0000000..2fb45c5
--- /dev/null
+++ b/.cursor/skills/2-Execution/Writing-Standards/SKILL.md
@@ -0,0 +1,620 @@
+---
+name: obsidian-markdown
+description: Create and edit Obsidian Flavored Markdown with wikilinks, embeds, callouts, properties, and other Obsidian-specific syntax. Use when working with .md files in Obsidian, or when the user mentions wikilinks, callouts, frontmatter, tags, embeds, or Obsidian notes.
+---
+
+# Obsidian Flavored Markdown Skill
+
+This skill enables skills-compatible agents to create and edit valid Obsidian Flavored Markdown, including all Obsidian-specific syntax extensions.
+
+## Overview
+
+Obsidian uses a combination of Markdown flavors:
+- [CommonMark](https://commonmark.org/)
+- [GitHub Flavored Markdown](https://github.github.com/gfm/)
+- [LaTeX](https://www.latex-project.org/) for math
+- Obsidian-specific extensions (wikilinks, callouts, embeds, etc.)
+
+## Basic Formatting
+
+### Paragraphs and Line Breaks
+
+```markdown
+This is a paragraph.
+
+This is another paragraph (blank line between creates separate paragraphs).
+
+For a line break within a paragraph, add two spaces at the end
+or use Shift+Enter.
+```
+
+### Headings
+
+```markdown
+# Heading 1
+## Heading 2
+### Heading 3
+#### Heading 4
+##### Heading 5
+###### Heading 6
+```
+
+### Text Formatting
+
+| Style | Syntax | Example | Output |
+|-------|--------|---------|--------|
+| Bold | `**text**` or `__text__` | `**Bold**` | **Bold** |
+| Italic | `*text*` or `_text_` | `*Italic*` | *Italic* |
+| Bold + Italic | `***text***` | `***Both***` | ***Both*** |
+| Strikethrough | `~~text~~` | `~~Striked~~` | ~~Striked~~ |
+| Highlight | `==text==` | `==Highlighted==` | ==Highlighted== |
+| Inline code | `` `code` `` | `` `code` `` | `code` |
+
+### Escaping Formatting
+
+Use backslash to escape special characters:
+```markdown
+\*This won't be italic\*
+\#This won't be a heading
+1\. This won't be a list item
+```
+
+Common characters to escape: `\*`, `\_`, `\#`, `` \` ``, `\|`, `\~`
+
+## Internal Links (Wikilinks)
+
+### Basic Links
+
+```markdown
+[[Note Name]]
+[[Note Name.md]]
+[[Note Name|Display Text]]
+```
+
+### Link to Headings
+
+```markdown
+[[Note Name#Heading]]
+[[Note Name#Heading|Custom Text]]
+[[#Heading in same note]]
+[[##Search all headings in vault]]
+```
+
+### Link to Blocks
+
+```markdown
+[[Note Name#^block-id]]
+[[Note Name#^block-id|Custom Text]]
+```
+
+Define a block ID by adding `^block-id` at the end of a paragraph:
+```markdown
+This is a paragraph that can be linked to. ^my-block-id
+```
+
+For lists and quotes, add the block ID on a separate line:
+```markdown
+> This is a quote
+> With multiple lines
+
+^quote-id
+```
+
+### Search Links
+
+```markdown
+[[##heading]] Search for headings containing "heading"
+[[^^block]] Search for blocks containing "block"
+```
+
+## Markdown-Style Links
+
+```markdown
+[Display Text](Note%20Name.md)
+[Display Text](Note%20Name.md#Heading)
+[Display Text](https://example.com)
+[Note](obsidian://open?vault=VaultName&file=Note.md)
+```
+
+Note: Spaces must be URL-encoded as `%20` in Markdown links.
+
+## Embeds
+
+### Embed Notes
+
+```markdown
+![[Note Name]]
+![[Note Name#Heading]]
+![[Note Name#^block-id]]
+```
+
+### Embed Images
+
+```markdown
+![[image.png]]
+![[image.png|640x480]] Width x Height
+![[image.png|300]] Width only (maintains aspect ratio)
+```
+
+### External Images
+
+```markdown
+
+
+```
+
+### Embed Audio
+
+```markdown
+![[audio.mp3]]
+![[audio.ogg]]
+```
+
+### Embed PDF
+
+```markdown
+![[document.pdf]]
+![[document.pdf#page=3]]
+![[document.pdf#height=400]]
+```
+
+### Embed Lists
+
+```markdown
+![[Note#^list-id]]
+```
+
+Where the list has been defined with a block ID:
+```markdown
+- Item 1
+- Item 2
+- Item 3
+
+^list-id
+```
+
+### Embed Search Results
+
+````markdown
+```query
+tag:#project status:done
+```
+````
+
+## Callouts
+
+### Basic Callout
+
+```markdown
+> [!note]
+> This is a note callout.
+
+> [!info] Custom Title
+> This callout has a custom title.
+
+> [!tip] Title Only
+```
+
+### Foldable Callouts
+
+```markdown
+> [!faq]- Collapsed by default
+> This content is hidden until expanded.
+
+> [!faq]+ Expanded by default
+> This content is visible but can be collapsed.
+```
+
+### Nested Callouts
+
+```markdown
+> [!question] Outer callout
+> > [!note] Inner callout
+> > Nested content
+```
+
+### Supported Callout Types
+
+| Type | Aliases | Description |
+|------|---------|-------------|
+| `note` | - | Blue, pencil icon |
+| `abstract` | `summary`, `tldr` | Teal, clipboard icon |
+| `info` | - | Blue, info icon |
+| `todo` | - | Blue, checkbox icon |
+| `tip` | `hint`, `important` | Cyan, flame icon |
+| `success` | `check`, `done` | Green, checkmark icon |
+| `question` | `help`, `faq` | Yellow, question mark |
+| `warning` | `caution`, `attention` | Orange, warning icon |
+| `failure` | `fail`, `missing` | Red, X icon |
+| `danger` | `error` | Red, zap icon |
+| `bug` | - | Red, bug icon |
+| `example` | - | Purple, list icon |
+| `quote` | `cite` | Gray, quote icon |
+
+### Custom Callouts (CSS)
+
+```css
+.callout[data-callout="custom-type"] {
+ --callout-color: 255, 0, 0;
+ --callout-icon: lucide-alert-circle;
+}
+```
+
+## Lists
+
+### Unordered Lists
+
+```markdown
+- Item 1
+- Item 2
+ - Nested item
+ - Another nested
+- Item 3
+
+* Also works with asterisks
++ Or plus signs
+```
+
+### Ordered Lists
+
+```markdown
+1. First item
+2. Second item
+ 1. Nested numbered
+ 2. Another nested
+3. Third item
+
+1) Alternative syntax
+2) With parentheses
+```
+
+### Task Lists
+
+```markdown
+- [ ] Incomplete task
+- [x] Completed task
+- [ ] Task with sub-tasks
+ - [ ] Subtask 1
+ - [x] Subtask 2
+```
+
+## Quotes
+
+```markdown
+> This is a blockquote.
+> It can span multiple lines.
+>
+> And include multiple paragraphs.
+>
+> > Nested quotes work too.
+```
+
+## Code
+
+### Inline Code
+
+```markdown
+Use `backticks` for inline code.
+Use double backticks for ``code with a ` backtick inside``.
+```
+
+### Code Blocks
+
+````markdown
+```
+Plain code block
+```
+
+```javascript
+// Syntax highlighted code block
+function hello() {
+ console.log("Hello, world!");
+}
+```
+
+```python
+# Python example
+def greet(name):
+ print(f"Hello, {name}!")
+```
+````
+
+### Nesting Code Blocks
+
+Use more backticks or tildes for the outer block:
+
+`````markdown
+````markdown
+Here's how to create a code block:
+```js
+console.log("Hello")
+```
+````
+`````
+
+## Tables
+
+```markdown
+| Header 1 | Header 2 | Header 3 |
+|----------|----------|----------|
+| Cell 1 | Cell 2 | Cell 3 |
+| Cell 4 | Cell 5 | Cell 6 |
+```
+
+### Alignment
+
+```markdown
+| Left | Center | Right |
+|:---------|:--------:|---------:|
+| Left | Center | Right |
+```
+
+### Using Pipes in Tables
+
+Escape pipes with backslash:
+```markdown
+| Column 1 | Column 2 |
+|----------|----------|
+| [[Link\|Display]] | ![[Image\|100]] |
+```
+
+## Math (LaTeX)
+
+### Inline Math
+
+```markdown
+This is inline math: $e^{i\pi} + 1 = 0$
+```
+
+### Block Math
+
+```markdown
+$$
+\begin{vmatrix}
+a & b \\
+c & d
+\end{vmatrix} = ad - bc
+$$
+```
+
+### Common Math Syntax
+
+```markdown
+$x^2$ Superscript
+$x_i$ Subscript
+$\frac{a}{b}$ Fraction
+$\sqrt{x}$ Square root
+$\sum_{i=1}^{n}$ Summation
+$\int_a^b$ Integral
+$\alpha, \beta$ Greek letters
+```
+
+## Diagrams (Mermaid)
+
+````markdown
+```mermaid
+graph TD
+ A[Start] --> B{Decision}
+ B -->|Yes| C[Do this]
+ B -->|No| D[Do that]
+ C --> E[End]
+ D --> E
+```
+````
+
+### Sequence Diagrams
+
+````markdown
+```mermaid
+sequenceDiagram
+ Alice->>Bob: Hello Bob
+ Bob-->>Alice: Hi Alice
+```
+````
+
+### Linking in Diagrams
+
+````markdown
+```mermaid
+graph TD
+ A[Biology]
+ B[Chemistry]
+ A --> B
+ class A,B internal-link;
+```
+````
+
+## Footnotes
+
+```markdown
+This sentence has a footnote[^1].
+
+[^1]: This is the footnote content.
+
+You can also use named footnotes[^note].
+
+[^note]: Named footnotes still appear as numbers.
+
+Inline footnotes are also supported.^[This is an inline footnote.]
+```
+
+## Comments
+
+```markdown
+This is visible %%but this is hidden%% text.
+
+%%
+This entire block is hidden.
+It won't appear in reading view.
+%%
+```
+
+## Horizontal Rules
+
+```markdown
+---
+***
+___
+- - -
+* * *
+```
+
+## Properties (Frontmatter)
+
+Properties use YAML frontmatter at the start of a note:
+
+```yaml
+---
+title: My Note Title
+date: 2024-01-15
+tags:
+ - project
+ - important
+aliases:
+ - My Note
+ - Alternative Name
+cssclasses:
+ - custom-class
+status: in-progress
+rating: 4.5
+completed: false
+due: 2024-02-01T14:30:00
+---
+```
+
+### Property Types
+
+| Type | Example |
+|------|---------|
+| Text | `title: My Title` |
+| Number | `rating: 4.5` |
+| Checkbox | `completed: true` |
+| Date | `date: 2024-01-15` |
+| Date & Time | `due: 2024-01-15T14:30:00` |
+| List | `tags: [one, two]` or YAML list |
+| Links | `related: "[[Other Note]]"` |
+
+### Default Properties
+
+- `tags` - Note tags
+- `aliases` - Alternative names for the note
+- `cssclasses` - CSS classes applied to the note
+
+## Tags
+
+```markdown
+#tag
+#nested/tag
+#tag-with-dashes
+#tag_with_underscores
+
+In frontmatter:
+---
+tags:
+ - tag1
+ - nested/tag2
+---
+```
+
+Tags can contain:
+- Letters (any language)
+- Numbers (not as first character)
+- Underscores `_`
+- Hyphens `-`
+- Forward slashes `/` (for nesting)
+
+## HTML Content
+
+Obsidian supports HTML within Markdown:
+
+```markdown
+
+ Colored text
+
+
+
+ Click to expand
+ Hidden content here.
+
+
+Ctrl + C
+```
+
+## Complete Example
+
+````markdown
+---
+title: Project Alpha
+date: 2024-01-15
+tags:
+ - project
+ - active
+status: in-progress
+priority: high
+---
+
+# Project Alpha
+
+## Overview
+
+This project aims to [[improve workflow]] using modern techniques.
+
+> [!important] Key Deadline
+> The first milestone is due on ==January 30th==.
+
+## Tasks
+
+- [x] Initial planning
+- [x] Resource allocation
+- [ ] Development phase
+ - [ ] Backend implementation
+ - [ ] Frontend design
+- [ ] Testing
+- [ ] Deployment
+
+## Technical Notes
+
+The main algorithm uses the formula $O(n \log n)$ for sorting.
+
+```python
+def process_data(items):
+ return sorted(items, key=lambda x: x.priority)
+```
+
+## Architecture
+
+```mermaid
+graph LR
+ A[Input] --> B[Process]
+ B --> C[Output]
+ B --> D[Cache]
+```
+
+## Related Documents
+
+- ![[Meeting Notes 2024-01-10#Decisions]]
+- [[Budget Allocation|Budget]]
+- [[Team Members]]
+
+## References
+
+For more details, see the official documentation[^1].
+
+[^1]: https://example.com/docs
+
+%%
+Internal notes:
+- Review with team on Friday
+- Consider alternative approaches
+%%
+````
+
+## References
+
+- [Basic formatting syntax](https://help.obsidian.md/syntax)
+- [Advanced formatting syntax](https://help.obsidian.md/advanced-syntax)
+- [Obsidian Flavored Markdown](https://help.obsidian.md/obsidian-flavored-markdown)
+- [Internal links](https://help.obsidian.md/links)
+- [Embed files](https://help.obsidian.md/embeds)
+- [Callouts](https://help.obsidian.md/callouts)
+- [Properties](https://help.obsidian.md/properties)
diff --git a/.cursor/skills/3-Output/Note-Templates/SKILL.md b/.cursor/skills/3-Output/Note-Templates/SKILL.md
new file mode 100644
index 0000000..d251c8a
--- /dev/null
+++ b/.cursor/skills/3-Output/Note-Templates/SKILL.md
@@ -0,0 +1,84 @@
+---
+name: obsidian-note-output
+description: This is a new rule
+---
+
+---
+name: obsidian-note-output
+description: Format Claude's output as Obsidian-compatible markdown notes. Trigger when user says "输出成Obsidian格式", "Obsidian笔记", "输出Obsidian", "转成Obsidian格式" or similar requests to export content for Obsidian. Use for summarizing conversations, capturing good outputs, or any content the user wants to save to their Obsidian vault.
+---
+
+# Obsidian Note Output
+
+将对话内容或Claude输出格式化为可直接复制到Obsidian的笔记格式。
+
+## 输出规范
+
+### 整体结构
+
+使用四个反引号包裹完整输出(不加语言标识),确保用户可整块复制:
+
+````
+---
+YAML frontmatter
+---
+
+正文内容
+````
+
+### YAML Frontmatter(必须)
+
+根据内容智能生成元数据,放在笔记最前面:
+
+```yaml
+---
+tags: [tag1, tag2, tag3]
+created: YYYY-MM-DD
+updated: YYYY-MM-DD
+source: Claude对话
+type: note/summary/tutorial/reference/guide/analysis
+status: draft/complete
+aliases: [别名1, 别名2]
+---
+```
+
+YAML字段生成规则:
+- `tags`: 从内容提取3-5个关键词,使用行内格式
+- `type`: 根据内容性质判断(教程用tutorial,分析用analysis,参考资料用reference等)
+- `aliases`: 笔记的其他称呼,便于搜索和链接
+- `source`: 标注来源
+- 笔记标题由用户自己命名文件,不在YAML中设置
+
+### 数学公式
+
+Obsidian专用语法:
+- 行内公式: `$...$`
+- 块级公式:
+```
+$$
+...
+$$
+```
+
+禁止使用 `\[` `\]` 语法。
+
+### 代码块
+
+- 必须完整闭合,结尾有 ```
+- 标注语言类型(python/bash/json等)
+- 禁止截断或不完整的代码块
+
+### 正文格式
+
+- 使用 `#` / `##` / `###` 标题层级
+- 自然段落,避免过度格式化
+- 标准Markdown语法,不使用非必要扩展语法
+- 内部链接使用 `[[]]` 格式(如适用)
+
+## 输出流程
+
+1. 分析用户指定的内容(上一轮输出/对话总结/指定内容)
+2. 生成符合内容的YAML元数据
+3. 整理正文为清晰结构
+4. 用四反引号包裹完整输出
+5. 不添加额外解释,直接输出可复制内容
\ No newline at end of file
diff --git a/.cursor/skills/3-Output/Release-Management/SKILL.md b/.cursor/skills/3-Output/Release-Management/SKILL.md
new file mode 100644
index 0000000..72919de
--- /dev/null
+++ b/.cursor/skills/3-Output/Release-Management/SKILL.md
@@ -0,0 +1,104 @@
+---
+name: changelog-generator
+description: Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
+---
+
+# Changelog Generator
+
+This skill transforms technical git commits into polished, user-friendly changelogs that your customers and users will actually understand and appreciate.
+
+## When to Use This Skill
+
+- Preparing release notes for a new version
+- Creating weekly or monthly product update summaries
+- Documenting changes for customers
+- Writing changelog entries for app store submissions
+- Generating update notifications
+- Creating internal release documentation
+- Maintaining a public changelog/product updates page
+
+## What This Skill Does
+
+1. **Scans Git History**: Analyzes commits from a specific time period or between versions
+2. **Categorizes Changes**: Groups commits into logical categories (features, improvements, bug fixes, breaking changes, security)
+3. **Translates Technical → User-Friendly**: Converts developer commits into customer language
+4. **Formats Professionally**: Creates clean, structured changelog entries
+5. **Filters Noise**: Excludes internal commits (refactoring, tests, etc.)
+6. **Follows Best Practices**: Applies changelog guidelines and your brand voice
+
+## How to Use
+
+### Basic Usage
+
+From your project repository:
+
+```
+Create a changelog from commits since last release
+```
+
+```
+Generate changelog for all commits from the past week
+```
+
+```
+Create release notes for version 2.5.0
+```
+
+### With Specific Date Range
+
+```
+Create a changelog for all commits between March 1 and March 15
+```
+
+### With Custom Guidelines
+
+```
+Create a changelog for commits since v2.4.0, using my changelog
+guidelines from CHANGELOG_STYLE.md
+```
+
+## Example
+
+**User**: "Create a changelog for commits from the past 7 days"
+
+**Output**:
+```markdown
+# Updates - Week of March 10, 2024
+
+## ✨ New Features
+
+- **Team Workspaces**: Create separate workspaces for different
+ projects. Invite team members and keep everything organized.
+
+- **Keyboard Shortcuts**: Press ? to see all available shortcuts.
+ Navigate faster without touching your mouse.
+
+## 🔧 Improvements
+
+- **Faster Sync**: Files now sync 2x faster across devices
+- **Better Search**: Search now includes file contents, not just titles
+
+## 🐛 Fixes
+
+- Fixed issue where large images wouldn't upload
+- Resolved timezone confusion in scheduled posts
+- Corrected notification badge count
+```
+
+**Inspired by:** Manik Aggarwal's use case from Lenny's Newsletter
+
+## Tips
+
+- Run from your git repository root
+- Specify date ranges for focused changelogs
+- Use your CHANGELOG_STYLE.md for consistent formatting
+- Review and adjust the generated changelog before publishing
+- Save output directly to CHANGELOG.md
+
+## Related Use Cases
+
+- Creating GitHub release notes
+- Writing app store update descriptions
+- Generating email updates for users
+- Creating social media announcement posts
+
diff --git a/.cursor/skills/README.md b/.cursor/skills/README.md
new file mode 100644
index 0000000..f44608d
--- /dev/null
+++ b/.cursor/skills/README.md
@@ -0,0 +1,28 @@
+# Product & Project Management Knowledge Base
+
+Welcome to your structured knowledge base for non-code project management. This directory is organized to support the lifecycle of product development, from infrastructure setup to execution and final output.
+
+## 📂 1-Infrastructure (Foundations)
+Skills for organizing your workspace and defining how data is structured.
+
+- **[File-Organization](./1-Infrastructure/File-Organization/SKILL.md)**: Rules for folder structures, file naming, and archiving lifecycle.
+- **[Data-Schema](./1-Infrastructure/Data-Schema/SKILL.md)**: Definitions for project properties, status tags, and metadata (based on Obsidian bases).
+
+## 🚀 2-Execution (Process & Standards)
+Templates and guidelines for daily project work.
+
+- **[Communication-Standards](./2-Execution/Communication-Standards/SKILL.md)**: Templates for Status Reports, Meeting Minutes, FAQs, and Newsletters.
+- **[Document-Governance](./2-Execution/Document-Governance/SKILL.md)**: Workflows for document review, redlining/revision tracking, and version control.
+- **[Visual-Workflows](./2-Execution/Visual-Workflows/SKILL.md)**: Standards for process mapping and diagrams (JSON Canvas format).
+- **[Writing-Standards](./2-Execution/Writing-Standards/SKILL.md)**: Markdown syntax guide for rich text formatting, callouts, and tables.
+
+## 📢 3-Output (Delivery)
+Skills for packaging and releasing your work to stakeholders/users.
+
+- **[Release-Management](./3-Output/Release-Management/SKILL.md)**: Guidelines for writing Release Notes and Changelogs (categorizing features vs. fixes).
+- **[Note-Templates](./3-Output/Note-Templates/SKILL.md)**: Standardized formats for exporting notes and summaries.
+
+---
+
+## 📦 Archive
+Technical tools and scripts that are less relevant for general management are moved to the `Dev-Tools-Archive` folder.
diff --git a/.cursor/skills/json-canvas/SKILL.md b/.cursor/skills/json-canvas/SKILL.md
new file mode 100644
index 0000000..e0611fe
--- /dev/null
+++ b/.cursor/skills/json-canvas/SKILL.md
@@ -0,0 +1,642 @@
+---
+name: json-canvas
+description: Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections. Use when working with .canvas files, creating visual canvases, mind maps, flowcharts, or when the user mentions Canvas files in Obsidian.
+---
+
+# JSON Canvas Skill
+
+This skill enables skills-compatible agents to create and edit valid JSON Canvas files (`.canvas`) used in Obsidian and other applications.
+
+## Overview
+
+JSON Canvas is an open file format for infinite canvas data. Canvas files use the `.canvas` extension and contain valid JSON following the [JSON Canvas Spec 1.0](https://jsoncanvas.org/spec/1.0/).
+
+## File Structure
+
+A canvas file contains two top-level arrays:
+
+```json
+{
+ "nodes": [],
+ "edges": []
+}
+```
+
+- `nodes` (optional): Array of node objects
+- `edges` (optional): Array of edge objects connecting nodes
+
+## Nodes
+
+Nodes are objects placed on the canvas. There are four node types:
+- `text` - Text content with Markdown
+- `file` - Reference to files/attachments
+- `link` - External URL
+- `group` - Visual container for other nodes
+
+### Z-Index Ordering
+
+Nodes are ordered by z-index in the array:
+- First node = bottom layer (displayed below others)
+- Last node = top layer (displayed above others)
+
+### Generic Node Attributes
+
+All nodes share these attributes:
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `id` | Yes | string | Unique identifier for the node |
+| `type` | Yes | string | Node type: `text`, `file`, `link`, or `group` |
+| `x` | Yes | integer | X position in pixels |
+| `y` | Yes | integer | Y position in pixels |
+| `width` | Yes | integer | Width in pixels |
+| `height` | Yes | integer | Height in pixels |
+| `color` | No | canvasColor | Node color (see Color section) |
+
+### Text Nodes
+
+Text nodes contain Markdown content.
+
+```json
+{
+ "id": "6f0ad84f44ce9c17",
+ "type": "text",
+ "x": 0,
+ "y": 0,
+ "width": 400,
+ "height": 200,
+ "text": "# Hello World\n\nThis is **Markdown** content."
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `text` | Yes | string | Plain text with Markdown syntax |
+
+### File Nodes
+
+File nodes reference files or attachments (images, videos, PDFs, notes, etc.).
+
+```json
+{
+ "id": "a1b2c3d4e5f67890",
+ "type": "file",
+ "x": 500,
+ "y": 0,
+ "width": 400,
+ "height": 300,
+ "file": "Attachments/diagram.png"
+}
+```
+
+```json
+{
+ "id": "b2c3d4e5f6789012",
+ "type": "file",
+ "x": 500,
+ "y": 400,
+ "width": 400,
+ "height": 300,
+ "file": "Notes/Project Overview.md",
+ "subpath": "#Implementation"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `file` | Yes | string | Path to file within the system |
+| `subpath` | No | string | Link to heading or block (starts with `#`) |
+
+### Link Nodes
+
+Link nodes display external URLs.
+
+```json
+{
+ "id": "c3d4e5f678901234",
+ "type": "link",
+ "x": 1000,
+ "y": 0,
+ "width": 400,
+ "height": 200,
+ "url": "https://obsidian.md"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `url` | Yes | string | External URL |
+
+### Group Nodes
+
+Group nodes are visual containers for organizing other nodes.
+
+```json
+{
+ "id": "d4e5f6789012345a",
+ "type": "group",
+ "x": -50,
+ "y": -50,
+ "width": 1000,
+ "height": 600,
+ "label": "Project Overview",
+ "color": "4"
+}
+```
+
+```json
+{
+ "id": "e5f67890123456ab",
+ "type": "group",
+ "x": 0,
+ "y": 700,
+ "width": 800,
+ "height": 500,
+ "label": "Resources",
+ "background": "Attachments/background.png",
+ "backgroundStyle": "cover"
+}
+```
+
+| Attribute | Required | Type | Description |
+|-----------|----------|------|-------------|
+| `label` | No | string | Text label for the group |
+| `background` | No | string | Path to background image |
+| `backgroundStyle` | No | string | Background rendering style |
+
+#### Background Styles
+
+| Value | Description |
+|-------|-------------|
+| `cover` | Fills entire width and height of node |
+| `ratio` | Maintains aspect ratio of background image |
+| `repeat` | Repeats image as pattern in both directions |
+
+## Edges
+
+Edges are lines connecting nodes.
+
+```json
+{
+ "id": "f67890123456789a",
+ "fromNode": "6f0ad84f44ce9c17",
+ "toNode": "a1b2c3d4e5f67890"
+}
+```
+
+```json
+{
+ "id": "0123456789abcdef",
+ "fromNode": "6f0ad84f44ce9c17",
+ "fromSide": "right",
+ "fromEnd": "none",
+ "toNode": "b2c3d4e5f6789012",
+ "toSide": "left",
+ "toEnd": "arrow",
+ "color": "1",
+ "label": "leads to"
+}
+```
+
+| Attribute | Required | Type | Default | Description |
+|-----------|----------|------|---------|-------------|
+| `id` | Yes | string | - | Unique identifier for the edge |
+| `fromNode` | Yes | string | - | Node ID where connection starts |
+| `fromSide` | No | string | - | Side where edge starts |
+| `fromEnd` | No | string | `none` | Shape at edge start |
+| `toNode` | Yes | string | - | Node ID where connection ends |
+| `toSide` | No | string | - | Side where edge ends |
+| `toEnd` | No | string | `arrow` | Shape at edge end |
+| `color` | No | canvasColor | - | Line color |
+| `label` | No | string | - | Text label for the edge |
+
+### Side Values
+
+| Value | Description |
+|-------|-------------|
+| `top` | Top edge of node |
+| `right` | Right edge of node |
+| `bottom` | Bottom edge of node |
+| `left` | Left edge of node |
+
+### End Shapes
+
+| Value | Description |
+|-------|-------------|
+| `none` | No endpoint shape |
+| `arrow` | Arrow endpoint |
+
+## Colors
+
+The `canvasColor` type can be specified in two ways:
+
+### Hex Colors
+
+```json
+{
+ "color": "#FF0000"
+}
+```
+
+### Preset Colors
+
+```json
+{
+ "color": "1"
+}
+```
+
+| Preset | Color |
+|--------|-------|
+| `"1"` | Red |
+| `"2"` | Orange |
+| `"3"` | Yellow |
+| `"4"` | Green |
+| `"5"` | Cyan |
+| `"6"` | Purple |
+
+Note: Specific color values for presets are intentionally undefined, allowing applications to use their own brand colors.
+
+## Complete Examples
+
+### Simple Canvas with Text and Connections
+
+```json
+{
+ "nodes": [
+ {
+ "id": "8a9b0c1d2e3f4a5b",
+ "type": "text",
+ "x": 0,
+ "y": 0,
+ "width": 300,
+ "height": 150,
+ "text": "# Main Idea\n\nThis is the central concept."
+ },
+ {
+ "id": "1a2b3c4d5e6f7a8b",
+ "type": "text",
+ "x": 400,
+ "y": -100,
+ "width": 250,
+ "height": 100,
+ "text": "## Supporting Point A\n\nDetails here."
+ },
+ {
+ "id": "2b3c4d5e6f7a8b9c",
+ "type": "text",
+ "x": 400,
+ "y": 100,
+ "width": 250,
+ "height": 100,
+ "text": "## Supporting Point B\n\nMore details."
+ }
+ ],
+ "edges": [
+ {
+ "id": "3c4d5e6f7a8b9c0d",
+ "fromNode": "8a9b0c1d2e3f4a5b",
+ "fromSide": "right",
+ "toNode": "1a2b3c4d5e6f7a8b",
+ "toSide": "left"
+ },
+ {
+ "id": "4d5e6f7a8b9c0d1e",
+ "fromNode": "8a9b0c1d2e3f4a5b",
+ "fromSide": "right",
+ "toNode": "2b3c4d5e6f7a8b9c",
+ "toSide": "left"
+ }
+ ]
+}
+```
+
+### Project Board with Groups
+
+```json
+{
+ "nodes": [
+ {
+ "id": "5e6f7a8b9c0d1e2f",
+ "type": "group",
+ "x": 0,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "To Do",
+ "color": "1"
+ },
+ {
+ "id": "6f7a8b9c0d1e2f3a",
+ "type": "group",
+ "x": 350,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "In Progress",
+ "color": "3"
+ },
+ {
+ "id": "7a8b9c0d1e2f3a4b",
+ "type": "group",
+ "x": 700,
+ "y": 0,
+ "width": 300,
+ "height": 500,
+ "label": "Done",
+ "color": "4"
+ },
+ {
+ "id": "8b9c0d1e2f3a4b5c",
+ "type": "text",
+ "x": 20,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 1\n\nImplement feature X"
+ },
+ {
+ "id": "9c0d1e2f3a4b5c6d",
+ "type": "text",
+ "x": 370,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 2\n\nReview PR #123",
+ "color": "2"
+ },
+ {
+ "id": "0d1e2f3a4b5c6d7e",
+ "type": "text",
+ "x": 720,
+ "y": 50,
+ "width": 260,
+ "height": 80,
+ "text": "## Task 3\n\n~~Setup CI/CD~~"
+ }
+ ],
+ "edges": []
+}
+```
+
+### Research Canvas with Files and Links
+
+```json
+{
+ "nodes": [
+ {
+ "id": "1e2f3a4b5c6d7e8f",
+ "type": "text",
+ "x": 300,
+ "y": 200,
+ "width": 400,
+ "height": 200,
+ "text": "# Research Topic\n\n## Key Questions\n\n- How does X affect Y?\n- What are the implications?",
+ "color": "5"
+ },
+ {
+ "id": "2f3a4b5c6d7e8f9a",
+ "type": "file",
+ "x": 0,
+ "y": 0,
+ "width": 250,
+ "height": 150,
+ "file": "Literature/Paper A.pdf"
+ },
+ {
+ "id": "3a4b5c6d7e8f9a0b",
+ "type": "file",
+ "x": 0,
+ "y": 200,
+ "width": 250,
+ "height": 150,
+ "file": "Notes/Meeting Notes.md",
+ "subpath": "#Key Insights"
+ },
+ {
+ "id": "4b5c6d7e8f9a0b1c",
+ "type": "link",
+ "x": 0,
+ "y": 400,
+ "width": 250,
+ "height": 100,
+ "url": "https://example.com/research"
+ },
+ {
+ "id": "5c6d7e8f9a0b1c2d",
+ "type": "file",
+ "x": 750,
+ "y": 150,
+ "width": 300,
+ "height": 250,
+ "file": "Attachments/diagram.png"
+ }
+ ],
+ "edges": [
+ {
+ "id": "6d7e8f9a0b1c2d3e",
+ "fromNode": "2f3a4b5c6d7e8f9a",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "label": "supports"
+ },
+ {
+ "id": "7e8f9a0b1c2d3e4f",
+ "fromNode": "3a4b5c6d7e8f9a0b",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "label": "informs"
+ },
+ {
+ "id": "8f9a0b1c2d3e4f5a",
+ "fromNode": "4b5c6d7e8f9a0b1c",
+ "fromSide": "right",
+ "toNode": "1e2f3a4b5c6d7e8f",
+ "toSide": "left",
+ "toEnd": "arrow",
+ "color": "6"
+ },
+ {
+ "id": "9a0b1c2d3e4f5a6b",
+ "fromNode": "1e2f3a4b5c6d7e8f",
+ "fromSide": "right",
+ "toNode": "5c6d7e8f9a0b1c2d",
+ "toSide": "left",
+ "label": "visualized by"
+ }
+ ]
+}
+```
+
+### Flowchart
+
+```json
+{
+ "nodes": [
+ {
+ "id": "a0b1c2d3e4f5a6b7",
+ "type": "text",
+ "x": 200,
+ "y": 0,
+ "width": 150,
+ "height": 60,
+ "text": "**Start**",
+ "color": "4"
+ },
+ {
+ "id": "b1c2d3e4f5a6b7c8",
+ "type": "text",
+ "x": 200,
+ "y": 100,
+ "width": 150,
+ "height": 60,
+ "text": "Step 1:\nGather data"
+ },
+ {
+ "id": "c2d3e4f5a6b7c8d9",
+ "type": "text",
+ "x": 200,
+ "y": 200,
+ "width": 150,
+ "height": 80,
+ "text": "**Decision**\n\nIs data valid?",
+ "color": "3"
+ },
+ {
+ "id": "d3e4f5a6b7c8d9e0",
+ "type": "text",
+ "x": 400,
+ "y": 200,
+ "width": 150,
+ "height": 60,
+ "text": "Process data"
+ },
+ {
+ "id": "e4f5a6b7c8d9e0f1",
+ "type": "text",
+ "x": 0,
+ "y": 200,
+ "width": 150,
+ "height": 60,
+ "text": "Request new data",
+ "color": "1"
+ },
+ {
+ "id": "f5a6b7c8d9e0f1a2",
+ "type": "text",
+ "x": 400,
+ "y": 320,
+ "width": 150,
+ "height": 60,
+ "text": "**End**",
+ "color": "4"
+ }
+ ],
+ "edges": [
+ {
+ "id": "a6b7c8d9e0f1a2b3",
+ "fromNode": "a0b1c2d3e4f5a6b7",
+ "fromSide": "bottom",
+ "toNode": "b1c2d3e4f5a6b7c8",
+ "toSide": "top"
+ },
+ {
+ "id": "b7c8d9e0f1a2b3c4",
+ "fromNode": "b1c2d3e4f5a6b7c8",
+ "fromSide": "bottom",
+ "toNode": "c2d3e4f5a6b7c8d9",
+ "toSide": "top"
+ },
+ {
+ "id": "c8d9e0f1a2b3c4d5",
+ "fromNode": "c2d3e4f5a6b7c8d9",
+ "fromSide": "right",
+ "toNode": "d3e4f5a6b7c8d9e0",
+ "toSide": "left",
+ "label": "Yes",
+ "color": "4"
+ },
+ {
+ "id": "d9e0f1a2b3c4d5e6",
+ "fromNode": "c2d3e4f5a6b7c8d9",
+ "fromSide": "left",
+ "toNode": "e4f5a6b7c8d9e0f1",
+ "toSide": "right",
+ "label": "No",
+ "color": "1"
+ },
+ {
+ "id": "e0f1a2b3c4d5e6f7",
+ "fromNode": "e4f5a6b7c8d9e0f1",
+ "fromSide": "top",
+ "fromEnd": "none",
+ "toNode": "b1c2d3e4f5a6b7c8",
+ "toSide": "left",
+ "toEnd": "arrow"
+ },
+ {
+ "id": "f1a2b3c4d5e6f7a8",
+ "fromNode": "d3e4f5a6b7c8d9e0",
+ "fromSide": "bottom",
+ "toNode": "f5a6b7c8d9e0f1a2",
+ "toSide": "top"
+ }
+ ]
+}
+```
+
+## ID Generation
+
+Node and edge IDs must be unique strings. Obsidian generates 16-character hexadecimal IDs:
+
+```json
+"id": "6f0ad84f44ce9c17"
+"id": "a3b2c1d0e9f8g7h6"
+"id": "1234567890abcdef"
+```
+
+This format is a 16-character lowercase hex string (64-bit random value).
+
+## Layout Guidelines
+
+### Positioning
+
+- Coordinates can be negative (canvas extends infinitely)
+- `x` increases to the right
+- `y` increases downward
+- Position refers to top-left corner of node
+
+### Recommended Sizes
+
+| Node Type | Suggested Width | Suggested Height |
+|-----------|-----------------|------------------|
+| Small text | 200-300 | 80-150 |
+| Medium text | 300-450 | 150-300 |
+| Large text | 400-600 | 300-500 |
+| File preview | 300-500 | 200-400 |
+| Link preview | 250-400 | 100-200 |
+| Group | Varies | Varies |
+
+### Spacing
+
+- Leave 20-50px padding inside groups
+- Space nodes 50-100px apart for readability
+- Align nodes to grid (multiples of 10 or 20) for cleaner layouts
+
+## Validation Rules
+
+1. All `id` values must be unique across nodes and edges
+2. `fromNode` and `toNode` must reference existing node IDs
+3. Required fields must be present for each node type
+4. `type` must be one of: `text`, `file`, `link`, `group`
+5. `backgroundStyle` must be one of: `cover`, `ratio`, `repeat`
+6. `fromSide`, `toSide` must be one of: `top`, `right`, `bottom`, `left`
+7. `fromEnd`, `toEnd` must be one of: `none`, `arrow`
+8. Color presets must be `"1"` through `"6"` or valid hex color
+
+## References
+
+- [JSON Canvas Spec 1.0](https://jsoncanvas.org/spec/1.0/)
+- [JSON Canvas GitHub](https://github.com/obsidianmd/jsoncanvas)
diff --git a/.cursor/skills/obsidian-bases/SKILL.md b/.cursor/skills/obsidian-bases/SKILL.md
new file mode 100644
index 0000000..6f82f11
--- /dev/null
+++ b/.cursor/skills/obsidian-bases/SKILL.md
@@ -0,0 +1,618 @@
+---
+name: obsidian-bases
+description: Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
+---
+
+# Obsidian Bases Skill
+
+This skill enables skills-compatible agents to create and edit valid Obsidian Bases (`.base` files) including views, filters, formulas, and all related configurations.
+
+## Overview
+
+Obsidian Bases are YAML-based files that define dynamic views of notes in an Obsidian vault. A Base file can contain multiple views, global filters, formulas, property configurations, and custom summaries.
+
+## File Format
+
+Base files use the `.base` extension and contain valid YAML. They can also be embedded in Markdown code blocks.
+
+## Complete Schema
+
+```yaml
+# Global filters apply to ALL views in the base
+filters:
+ # Can be a single filter string
+ # OR a recursive filter object with and/or/not
+ and: []
+ or: []
+ not: []
+
+# Define formula properties that can be used across all views
+formulas:
+ formula_name: 'expression'
+
+# Configure display names and settings for properties
+properties:
+ property_name:
+ displayName: "Display Name"
+ formula.formula_name:
+ displayName: "Formula Display Name"
+ file.ext:
+ displayName: "Extension"
+
+# Define custom summary formulas
+summaries:
+ custom_summary_name: 'values.mean().round(3)'
+
+# Define one or more views
+views:
+ - type: table | cards | list | map
+ name: "View Name"
+ limit: 10 # Optional: limit results
+ groupBy: # Optional: group results
+ property: property_name
+ direction: ASC | DESC
+ filters: # View-specific filters
+ and: []
+ order: # Properties to display in order
+ - file.name
+ - property_name
+ - formula.formula_name
+ summaries: # Map properties to summary formulas
+ property_name: Average
+```
+
+## Filter Syntax
+
+Filters narrow down results. They can be applied globally or per-view.
+
+### Filter Structure
+
+```yaml
+# Single filter
+filters: 'status == "done"'
+
+# AND - all conditions must be true
+filters:
+ and:
+ - 'status == "done"'
+ - 'priority > 3'
+
+# OR - any condition can be true
+filters:
+ or:
+ - 'file.hasTag("book")'
+ - 'file.hasTag("article")'
+
+# NOT - exclude matching items
+filters:
+ not:
+ - 'file.hasTag("archived")'
+
+# Nested filters
+filters:
+ or:
+ - file.hasTag("tag")
+ - and:
+ - file.hasTag("book")
+ - file.hasLink("Textbook")
+ - not:
+ - file.hasTag("book")
+ - file.inFolder("Required Reading")
+```
+
+### Filter Operators
+
+| Operator | Description |
+|----------|-------------|
+| `==` | equals |
+| `!=` | not equal |
+| `>` | greater than |
+| `<` | less than |
+| `>=` | greater than or equal |
+| `<=` | less than or equal |
+| `&&` | logical and |
+| `\|\|` | logical or |
+| ! | logical not |
+
+## Properties
+
+### Three Types of Properties
+
+1. **Note properties** - From frontmatter: `note.author` or just `author`
+2. **File properties** - File metadata: `file.name`, `file.mtime`, etc.
+3. **Formula properties** - Computed values: `formula.my_formula`
+
+### File Properties Reference
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `file.name` | String | File name |
+| `file.basename` | String | File name without extension |
+| `file.path` | String | Full path to file |
+| `file.folder` | String | Parent folder path |
+| `file.ext` | String | File extension |
+| `file.size` | Number | File size in bytes |
+| `file.ctime` | Date | Created time |
+| `file.mtime` | Date | Modified time |
+| `file.tags` | List | All tags in file |
+| `file.links` | List | Internal links in file |
+| `file.backlinks` | List | Files linking to this file |
+| `file.embeds` | List | Embeds in the note |
+| `file.properties` | Object | All frontmatter properties |
+
+### The `this` Keyword
+
+- In main content area: refers to the base file itself
+- When embedded: refers to the embedding file
+- In sidebar: refers to the active file in main content
+
+## Formula Syntax
+
+Formulas compute values from properties. Defined in the `formulas` section.
+
+```yaml
+formulas:
+ # Simple arithmetic
+ total: "price * quantity"
+
+ # Conditional logic
+ status_icon: 'if(done, "✅", "⏳")'
+
+ # String formatting
+ formatted_price: 'if(price, price.toFixed(2) + " dollars")'
+
+ # Date formatting
+ created: 'file.ctime.format("YYYY-MM-DD")'
+
+ # Complex expressions
+ days_old: '((now() - file.ctime) / 86400000).round(0)'
+```
+
+## Functions Reference
+
+### Global Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `date()` | `date(string): date` | Parse string to date. Format: `YYYY-MM-DD HH:mm:ss` |
+| `duration()` | `duration(string): duration` | Parse duration string |
+| `now()` | `now(): date` | Current date and time |
+| `today()` | `today(): date` | Current date (time = 00:00:00) |
+| `if()` | `if(condition, trueResult, falseResult?)` | Conditional |
+| `min()` | `min(n1, n2, ...): number` | Smallest number |
+| `max()` | `max(n1, n2, ...): number` | Largest number |
+| `number()` | `number(any): number` | Convert to number |
+| `link()` | `link(path, display?): Link` | Create a link |
+| `list()` | `list(element): List` | Wrap in list if not already |
+| `file()` | `file(path): file` | Get file object |
+| `image()` | `image(path): image` | Create image for rendering |
+| `icon()` | `icon(name): icon` | Lucide icon by name |
+| `html()` | `html(string): html` | Render as HTML |
+| `escapeHTML()` | `escapeHTML(string): string` | Escape HTML characters |
+
+### Any Type Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `isTruthy()` | `any.isTruthy(): boolean` | Coerce to boolean |
+| `isType()` | `any.isType(type): boolean` | Check type |
+| `toString()` | `any.toString(): string` | Convert to string |
+
+### Date Functions & Fields
+
+**Fields:** `date.year`, `date.month`, `date.day`, `date.hour`, `date.minute`, `date.second`, `date.millisecond`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `date()` | `date.date(): date` | Remove time portion |
+| `format()` | `date.format(string): string` | Format with Moment.js pattern |
+| `time()` | `date.time(): string` | Get time as string |
+| `relative()` | `date.relative(): string` | Human-readable relative time |
+| `isEmpty()` | `date.isEmpty(): boolean` | Always false for dates |
+
+### Date Arithmetic
+
+```yaml
+# Duration units: y/year/years, M/month/months, d/day/days,
+# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
+
+# Add/subtract durations
+"date + \"1M\"" # Add 1 month
+"date - \"2h\"" # Subtract 2 hours
+"now() + \"1 day\"" # Tomorrow
+"today() + \"7d\"" # A week from today
+
+# Subtract dates for millisecond difference
+"now() - file.ctime"
+
+# Complex duration arithmetic
+"now() + (duration('1d') * 2)"
+```
+
+### String Functions
+
+**Field:** `string.length`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `contains()` | `string.contains(value): boolean` | Check substring |
+| `containsAll()` | `string.containsAll(...values): boolean` | All substrings present |
+| `containsAny()` | `string.containsAny(...values): boolean` | Any substring present |
+| `startsWith()` | `string.startsWith(query): boolean` | Starts with query |
+| `endsWith()` | `string.endsWith(query): boolean` | Ends with query |
+| `isEmpty()` | `string.isEmpty(): boolean` | Empty or not present |
+| `lower()` | `string.lower(): string` | To lowercase |
+| `title()` | `string.title(): string` | To Title Case |
+| `trim()` | `string.trim(): string` | Remove whitespace |
+| `replace()` | `string.replace(pattern, replacement): string` | Replace pattern |
+| `repeat()` | `string.repeat(count): string` | Repeat string |
+| `reverse()` | `string.reverse(): string` | Reverse string |
+| `slice()` | `string.slice(start, end?): string` | Substring |
+| `split()` | `string.split(separator, n?): list` | Split to list |
+
+### Number Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `abs()` | `number.abs(): number` | Absolute value |
+| `ceil()` | `number.ceil(): number` | Round up |
+| `floor()` | `number.floor(): number` | Round down |
+| `round()` | `number.round(digits?): number` | Round to digits |
+| `toFixed()` | `number.toFixed(precision): string` | Fixed-point notation |
+| `isEmpty()` | `number.isEmpty(): boolean` | Not present |
+
+### List Functions
+
+**Field:** `list.length`
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `contains()` | `list.contains(value): boolean` | Element exists |
+| `containsAll()` | `list.containsAll(...values): boolean` | All elements exist |
+| `containsAny()` | `list.containsAny(...values): boolean` | Any element exists |
+| `filter()` | `list.filter(expression): list` | Filter by condition (uses `value`, `index`) |
+| `map()` | `list.map(expression): list` | Transform elements (uses `value`, `index`) |
+| `reduce()` | `list.reduce(expression, initial): any` | Reduce to single value (uses `value`, `index`, `acc`) |
+| `flat()` | `list.flat(): list` | Flatten nested lists |
+| `join()` | `list.join(separator): string` | Join to string |
+| `reverse()` | `list.reverse(): list` | Reverse order |
+| `slice()` | `list.slice(start, end?): list` | Sublist |
+| `sort()` | `list.sort(): list` | Sort ascending |
+| `unique()` | `list.unique(): list` | Remove duplicates |
+| `isEmpty()` | `list.isEmpty(): boolean` | No elements |
+
+### File Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `asLink()` | `file.asLink(display?): Link` | Convert to link |
+| `hasLink()` | `file.hasLink(otherFile): boolean` | Has link to file |
+| `hasTag()` | `file.hasTag(...tags): boolean` | Has any of the tags |
+| `hasProperty()` | `file.hasProperty(name): boolean` | Has property |
+| `inFolder()` | `file.inFolder(folder): boolean` | In folder or subfolder |
+
+### Link Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `asFile()` | `link.asFile(): file` | Get file object |
+| `linksTo()` | `link.linksTo(file): boolean` | Links to file |
+
+### Object Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `isEmpty()` | `object.isEmpty(): boolean` | No properties |
+| `keys()` | `object.keys(): list` | List of keys |
+| `values()` | `object.values(): list` | List of values |
+
+### Regular Expression Functions
+
+| Function | Signature | Description |
+|----------|-----------|-------------|
+| `matches()` | `regexp.matches(string): boolean` | Test if matches |
+
+## View Types
+
+### Table View
+
+```yaml
+views:
+ - type: table
+ name: "My Table"
+ order:
+ - file.name
+ - status
+ - due_date
+ summaries:
+ price: Sum
+ count: Average
+```
+
+### Cards View
+
+```yaml
+views:
+ - type: cards
+ name: "Gallery"
+ order:
+ - file.name
+ - cover_image
+ - description
+```
+
+### List View
+
+```yaml
+views:
+ - type: list
+ name: "Simple List"
+ order:
+ - file.name
+ - status
+```
+
+### Map View
+
+Requires latitude/longitude properties and the Maps community plugin.
+
+```yaml
+views:
+ - type: map
+ name: "Locations"
+ # Map-specific settings for lat/lng properties
+```
+
+## Default Summary Formulas
+
+| Name | Input Type | Description |
+|------|------------|-------------|
+| `Average` | Number | Mathematical mean |
+| `Min` | Number | Smallest number |
+| `Max` | Number | Largest number |
+| `Sum` | Number | Sum of all numbers |
+| `Range` | Number | Max - Min |
+| `Median` | Number | Mathematical median |
+| `Stddev` | Number | Standard deviation |
+| `Earliest` | Date | Earliest date |
+| `Latest` | Date | Latest date |
+| `Range` | Date | Latest - Earliest |
+| `Checked` | Boolean | Count of true values |
+| `Unchecked` | Boolean | Count of false values |
+| `Empty` | Any | Count of empty values |
+| `Filled` | Any | Count of non-empty values |
+| `Unique` | Any | Count of unique values |
+
+## Complete Examples
+
+### Task Tracker Base
+
+```yaml
+filters:
+ and:
+ - file.hasTag("task")
+ - 'file.ext == "md"'
+
+formulas:
+ days_until_due: 'if(due, ((date(due) - today()) / 86400000).round(0), "")'
+ is_overdue: 'if(due, date(due) < today() && status != "done", false)'
+ priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'
+
+properties:
+ status:
+ displayName: Status
+ formula.days_until_due:
+ displayName: "Days Until Due"
+ formula.priority_label:
+ displayName: Priority
+
+views:
+ - type: table
+ name: "Active Tasks"
+ filters:
+ and:
+ - 'status != "done"'
+ order:
+ - file.name
+ - status
+ - formula.priority_label
+ - due
+ - formula.days_until_due
+ groupBy:
+ property: status
+ direction: ASC
+ summaries:
+ formula.days_until_due: Average
+
+ - type: table
+ name: "Completed"
+ filters:
+ and:
+ - 'status == "done"'
+ order:
+ - file.name
+ - completed_date
+```
+
+### Reading List Base
+
+```yaml
+filters:
+ or:
+ - file.hasTag("book")
+ - file.hasTag("article")
+
+formulas:
+ reading_time: 'if(pages, (pages * 2).toString() + " min", "")'
+ status_icon: 'if(status == "reading", "📖", if(status == "done", "✅", "📚"))'
+ year_read: 'if(finished_date, date(finished_date).year, "")'
+
+properties:
+ author:
+ displayName: Author
+ formula.status_icon:
+ displayName: ""
+ formula.reading_time:
+ displayName: "Est. Time"
+
+views:
+ - type: cards
+ name: "Library"
+ order:
+ - cover
+ - file.name
+ - author
+ - formula.status_icon
+ filters:
+ not:
+ - 'status == "dropped"'
+
+ - type: table
+ name: "Reading List"
+ filters:
+ and:
+ - 'status == "to-read"'
+ order:
+ - file.name
+ - author
+ - pages
+ - formula.reading_time
+```
+
+### Project Notes Base
+
+```yaml
+filters:
+ and:
+ - file.inFolder("Projects")
+ - 'file.ext == "md"'
+
+formulas:
+ last_updated: 'file.mtime.relative()'
+ link_count: 'file.links.length'
+
+summaries:
+ avgLinks: 'values.filter(value.isType("number")).mean().round(1)'
+
+properties:
+ formula.last_updated:
+ displayName: "Updated"
+ formula.link_count:
+ displayName: "Links"
+
+views:
+ - type: table
+ name: "All Projects"
+ order:
+ - file.name
+ - status
+ - formula.last_updated
+ - formula.link_count
+ summaries:
+ formula.link_count: avgLinks
+ groupBy:
+ property: status
+ direction: ASC
+
+ - type: list
+ name: "Quick List"
+ order:
+ - file.name
+ - status
+```
+
+### Daily Notes Index
+
+```yaml
+filters:
+ and:
+ - file.inFolder("Daily Notes")
+ - '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'
+
+formulas:
+ word_estimate: '(file.size / 5).round(0)'
+ day_of_week: 'date(file.basename).format("dddd")'
+
+properties:
+ formula.day_of_week:
+ displayName: "Day"
+ formula.word_estimate:
+ displayName: "~Words"
+
+views:
+ - type: table
+ name: "Recent Notes"
+ limit: 30
+ order:
+ - file.name
+ - formula.day_of_week
+ - formula.word_estimate
+ - file.mtime
+```
+
+## Embedding Bases
+
+Embed in Markdown files:
+
+```markdown
+![[MyBase.base]]
+
+
+![[MyBase.base#View Name]]
+```
+
+## YAML Quoting Rules
+
+- Use single quotes for formulas containing double quotes: `'if(done, "Yes", "No")'`
+- Use double quotes for simple strings: `"My View Name"`
+- Escape nested quotes properly in complex expressions
+
+## Common Patterns
+
+### Filter by Tag
+```yaml
+filters:
+ and:
+ - file.hasTag("project")
+```
+
+### Filter by Folder
+```yaml
+filters:
+ and:
+ - file.inFolder("Notes")
+```
+
+### Filter by Date Range
+```yaml
+filters:
+ and:
+ - 'file.mtime > now() - "7d"'
+```
+
+### Filter by Property Value
+```yaml
+filters:
+ and:
+ - 'status == "active"'
+ - 'priority >= 3'
+```
+
+### Combine Multiple Conditions
+```yaml
+filters:
+ or:
+ - and:
+ - file.hasTag("important")
+ - 'status != "done"'
+ - and:
+ - 'priority == 1'
+ - 'due != ""'
+```
+
+## References
+
+- [Bases Syntax](https://help.obsidian.md/bases/syntax)
+- [Functions](https://help.obsidian.md/bases/functions)
+- [Views](https://help.obsidian.md/bases/views)
+- [Formulas](https://help.obsidian.md/formulas)
diff --git a/.cursor/skills/obsidian-markdown/SKILL.md b/.cursor/skills/obsidian-markdown/SKILL.md
new file mode 100644
index 0000000..2fb45c5
--- /dev/null
+++ b/.cursor/skills/obsidian-markdown/SKILL.md
@@ -0,0 +1,620 @@
+---
+name: obsidian-markdown
+description: Create and edit Obsidian Flavored Markdown with wikilinks, embeds, callouts, properties, and other Obsidian-specific syntax. Use when working with .md files in Obsidian, or when the user mentions wikilinks, callouts, frontmatter, tags, embeds, or Obsidian notes.
+---
+
+# Obsidian Flavored Markdown Skill
+
+This skill enables skills-compatible agents to create and edit valid Obsidian Flavored Markdown, including all Obsidian-specific syntax extensions.
+
+## Overview
+
+Obsidian uses a combination of Markdown flavors:
+- [CommonMark](https://commonmark.org/)
+- [GitHub Flavored Markdown](https://github.github.com/gfm/)
+- [LaTeX](https://www.latex-project.org/) for math
+- Obsidian-specific extensions (wikilinks, callouts, embeds, etc.)
+
+## Basic Formatting
+
+### Paragraphs and Line Breaks
+
+```markdown
+This is a paragraph.
+
+This is another paragraph (blank line between creates separate paragraphs).
+
+For a line break within a paragraph, add two spaces at the end
+or use Shift+Enter.
+```
+
+### Headings
+
+```markdown
+# Heading 1
+## Heading 2
+### Heading 3
+#### Heading 4
+##### Heading 5
+###### Heading 6
+```
+
+### Text Formatting
+
+| Style | Syntax | Example | Output |
+|-------|--------|---------|--------|
+| Bold | `**text**` or `__text__` | `**Bold**` | **Bold** |
+| Italic | `*text*` or `_text_` | `*Italic*` | *Italic* |
+| Bold + Italic | `***text***` | `***Both***` | ***Both*** |
+| Strikethrough | `~~text~~` | `~~Striked~~` | ~~Striked~~ |
+| Highlight | `==text==` | `==Highlighted==` | ==Highlighted== |
+| Inline code | `` `code` `` | `` `code` `` | `code` |
+
+### Escaping Formatting
+
+Use backslash to escape special characters:
+```markdown
+\*This won't be italic\*
+\#This won't be a heading
+1\. This won't be a list item
+```
+
+Common characters to escape: `\*`, `\_`, `\#`, `` \` ``, `\|`, `\~`
+
+## Internal Links (Wikilinks)
+
+### Basic Links
+
+```markdown
+[[Note Name]]
+[[Note Name.md]]
+[[Note Name|Display Text]]
+```
+
+### Link to Headings
+
+```markdown
+[[Note Name#Heading]]
+[[Note Name#Heading|Custom Text]]
+[[#Heading in same note]]
+[[##Search all headings in vault]]
+```
+
+### Link to Blocks
+
+```markdown
+[[Note Name#^block-id]]
+[[Note Name#^block-id|Custom Text]]
+```
+
+Define a block ID by adding `^block-id` at the end of a paragraph:
+```markdown
+This is a paragraph that can be linked to. ^my-block-id
+```
+
+For lists and quotes, add the block ID on a separate line:
+```markdown
+> This is a quote
+> With multiple lines
+
+^quote-id
+```
+
+### Search Links
+
+```markdown
+[[##heading]] Search for headings containing "heading"
+[[^^block]] Search for blocks containing "block"
+```
+
+## Markdown-Style Links
+
+```markdown
+[Display Text](Note%20Name.md)
+[Display Text](Note%20Name.md#Heading)
+[Display Text](https://example.com)
+[Note](obsidian://open?vault=VaultName&file=Note.md)
+```
+
+Note: Spaces must be URL-encoded as `%20` in Markdown links.
+
+## Embeds
+
+### Embed Notes
+
+```markdown
+![[Note Name]]
+![[Note Name#Heading]]
+![[Note Name#^block-id]]
+```
+
+### Embed Images
+
+```markdown
+![[image.png]]
+![[image.png|640x480]] Width x Height
+![[image.png|300]] Width only (maintains aspect ratio)
+```
+
+### External Images
+
+```markdown
+
+
+```
+
+### Embed Audio
+
+```markdown
+![[audio.mp3]]
+![[audio.ogg]]
+```
+
+### Embed PDF
+
+```markdown
+![[document.pdf]]
+![[document.pdf#page=3]]
+![[document.pdf#height=400]]
+```
+
+### Embed Lists
+
+```markdown
+![[Note#^list-id]]
+```
+
+Where the list has been defined with a block ID:
+```markdown
+- Item 1
+- Item 2
+- Item 3
+
+^list-id
+```
+
+### Embed Search Results
+
+````markdown
+```query
+tag:#project status:done
+```
+````
+
+## Callouts
+
+### Basic Callout
+
+```markdown
+> [!note]
+> This is a note callout.
+
+> [!info] Custom Title
+> This callout has a custom title.
+
+> [!tip] Title Only
+```
+
+### Foldable Callouts
+
+```markdown
+> [!faq]- Collapsed by default
+> This content is hidden until expanded.
+
+> [!faq]+ Expanded by default
+> This content is visible but can be collapsed.
+```
+
+### Nested Callouts
+
+```markdown
+> [!question] Outer callout
+> > [!note] Inner callout
+> > Nested content
+```
+
+### Supported Callout Types
+
+| Type | Aliases | Description |
+|------|---------|-------------|
+| `note` | - | Blue, pencil icon |
+| `abstract` | `summary`, `tldr` | Teal, clipboard icon |
+| `info` | - | Blue, info icon |
+| `todo` | - | Blue, checkbox icon |
+| `tip` | `hint`, `important` | Cyan, flame icon |
+| `success` | `check`, `done` | Green, checkmark icon |
+| `question` | `help`, `faq` | Yellow, question mark |
+| `warning` | `caution`, `attention` | Orange, warning icon |
+| `failure` | `fail`, `missing` | Red, X icon |
+| `danger` | `error` | Red, zap icon |
+| `bug` | - | Red, bug icon |
+| `example` | - | Purple, list icon |
+| `quote` | `cite` | Gray, quote icon |
+
+### Custom Callouts (CSS)
+
+```css
+.callout[data-callout="custom-type"] {
+ --callout-color: 255, 0, 0;
+ --callout-icon: lucide-alert-circle;
+}
+```
+
+## Lists
+
+### Unordered Lists
+
+```markdown
+- Item 1
+- Item 2
+ - Nested item
+ - Another nested
+- Item 3
+
+* Also works with asterisks
++ Or plus signs
+```
+
+### Ordered Lists
+
+```markdown
+1. First item
+2. Second item
+ 1. Nested numbered
+ 2. Another nested
+3. Third item
+
+1) Alternative syntax
+2) With parentheses
+```
+
+### Task Lists
+
+```markdown
+- [ ] Incomplete task
+- [x] Completed task
+- [ ] Task with sub-tasks
+ - [ ] Subtask 1
+ - [x] Subtask 2
+```
+
+## Quotes
+
+```markdown
+> This is a blockquote.
+> It can span multiple lines.
+>
+> And include multiple paragraphs.
+>
+> > Nested quotes work too.
+```
+
+## Code
+
+### Inline Code
+
+```markdown
+Use `backticks` for inline code.
+Use double backticks for ``code with a ` backtick inside``.
+```
+
+### Code Blocks
+
+````markdown
+```
+Plain code block
+```
+
+```javascript
+// Syntax highlighted code block
+function hello() {
+ console.log("Hello, world!");
+}
+```
+
+```python
+# Python example
+def greet(name):
+ print(f"Hello, {name}!")
+```
+````
+
+### Nesting Code Blocks
+
+Use more backticks or tildes for the outer block:
+
+`````markdown
+````markdown
+Here's how to create a code block:
+```js
+console.log("Hello")
+```
+````
+`````
+
+## Tables
+
+```markdown
+| Header 1 | Header 2 | Header 3 |
+|----------|----------|----------|
+| Cell 1 | Cell 2 | Cell 3 |
+| Cell 4 | Cell 5 | Cell 6 |
+```
+
+### Alignment
+
+```markdown
+| Left | Center | Right |
+|:---------|:--------:|---------:|
+| Left | Center | Right |
+```
+
+### Using Pipes in Tables
+
+Escape pipes with backslash:
+```markdown
+| Column 1 | Column 2 |
+|----------|----------|
+| [[Link\|Display]] | ![[Image\|100]] |
+```
+
+## Math (LaTeX)
+
+### Inline Math
+
+```markdown
+This is inline math: $e^{i\pi} + 1 = 0$
+```
+
+### Block Math
+
+```markdown
+$$
+\begin{vmatrix}
+a & b \\
+c & d
+\end{vmatrix} = ad - bc
+$$
+```
+
+### Common Math Syntax
+
+```markdown
+$x^2$ Superscript
+$x_i$ Subscript
+$\frac{a}{b}$ Fraction
+$\sqrt{x}$ Square root
+$\sum_{i=1}^{n}$ Summation
+$\int_a^b$ Integral
+$\alpha, \beta$ Greek letters
+```
+
+## Diagrams (Mermaid)
+
+````markdown
+```mermaid
+graph TD
+ A[Start] --> B{Decision}
+ B -->|Yes| C[Do this]
+ B -->|No| D[Do that]
+ C --> E[End]
+ D --> E
+```
+````
+
+### Sequence Diagrams
+
+````markdown
+```mermaid
+sequenceDiagram
+ Alice->>Bob: Hello Bob
+ Bob-->>Alice: Hi Alice
+```
+````
+
+### Linking in Diagrams
+
+````markdown
+```mermaid
+graph TD
+ A[Biology]
+ B[Chemistry]
+ A --> B
+ class A,B internal-link;
+```
+````
+
+## Footnotes
+
+```markdown
+This sentence has a footnote[^1].
+
+[^1]: This is the footnote content.
+
+You can also use named footnotes[^note].
+
+[^note]: Named footnotes still appear as numbers.
+
+Inline footnotes are also supported.^[This is an inline footnote.]
+```
+
+## Comments
+
+```markdown
+This is visible %%but this is hidden%% text.
+
+%%
+This entire block is hidden.
+It won't appear in reading view.
+%%
+```
+
+## Horizontal Rules
+
+```markdown
+---
+***
+___
+- - -
+* * *
+```
+
+## Properties (Frontmatter)
+
+Properties use YAML frontmatter at the start of a note:
+
+```yaml
+---
+title: My Note Title
+date: 2024-01-15
+tags:
+ - project
+ - important
+aliases:
+ - My Note
+ - Alternative Name
+cssclasses:
+ - custom-class
+status: in-progress
+rating: 4.5
+completed: false
+due: 2024-02-01T14:30:00
+---
+```
+
+### Property Types
+
+| Type | Example |
+|------|---------|
+| Text | `title: My Title` |
+| Number | `rating: 4.5` |
+| Checkbox | `completed: true` |
+| Date | `date: 2024-01-15` |
+| Date & Time | `due: 2024-01-15T14:30:00` |
+| List | `tags: [one, two]` or YAML list |
+| Links | `related: "[[Other Note]]"` |
+
+### Default Properties
+
+- `tags` - Note tags
+- `aliases` - Alternative names for the note
+- `cssclasses` - CSS classes applied to the note
+
+## Tags
+
+```markdown
+#tag
+#nested/tag
+#tag-with-dashes
+#tag_with_underscores
+
+In frontmatter:
+---
+tags:
+ - tag1
+ - nested/tag2
+---
+```
+
+Tags can contain:
+- Letters (any language)
+- Numbers (not as first character)
+- Underscores `_`
+- Hyphens `-`
+- Forward slashes `/` (for nesting)
+
+## HTML Content
+
+Obsidian supports HTML within Markdown:
+
+```markdown
+
+ Colored text
+
+
+
+ Click to expand
+ Hidden content here.
+
+
+Ctrl + C
+```
+
+## Complete Example
+
+````markdown
+---
+title: Project Alpha
+date: 2024-01-15
+tags:
+ - project
+ - active
+status: in-progress
+priority: high
+---
+
+# Project Alpha
+
+## Overview
+
+This project aims to [[improve workflow]] using modern techniques.
+
+> [!important] Key Deadline
+> The first milestone is due on ==January 30th==.
+
+## Tasks
+
+- [x] Initial planning
+- [x] Resource allocation
+- [ ] Development phase
+ - [ ] Backend implementation
+ - [ ] Frontend design
+- [ ] Testing
+- [ ] Deployment
+
+## Technical Notes
+
+The main algorithm uses the formula $O(n \log n)$ for sorting.
+
+```python
+def process_data(items):
+ return sorted(items, key=lambda x: x.priority)
+```
+
+## Architecture
+
+```mermaid
+graph LR
+ A[Input] --> B[Process]
+ B --> C[Output]
+ B --> D[Cache]
+```
+
+## Related Documents
+
+- ![[Meeting Notes 2024-01-10#Decisions]]
+- [[Budget Allocation|Budget]]
+- [[Team Members]]
+
+## References
+
+For more details, see the official documentation[^1].
+
+[^1]: https://example.com/docs
+
+%%
+Internal notes:
+- Review with team on Friday
+- Consider alternative approaches
+%%
+````
+
+## References
+
+- [Basic formatting syntax](https://help.obsidian.md/syntax)
+- [Advanced formatting syntax](https://help.obsidian.md/advanced-syntax)
+- [Obsidian Flavored Markdown](https://help.obsidian.md/obsidian-flavored-markdown)
+- [Internal links](https://help.obsidian.md/links)
+- [Embed files](https://help.obsidian.md/embeds)
+- [Callouts](https://help.obsidian.md/callouts)
+- [Properties](https://help.obsidian.md/properties)