Wildcard matching
The Problem
Section titled “The Problem”SEACOW(r) is a meta-framework for organizing knowledge, not a specific structure. This means users can have entity-based structures where content is organized under different entities (people/teams), but each entity has its own OUTPUT structure.
Example Structure
Section titled “Example Structure”Cybersader/ 📁 01 - Projects/ 📁 02 - CyberNews/ 📁 03 - Curations, Stacks/
Username1/ 📁 01 - Projects/ 📁 02 - CyberNews/ 📁 03 - Curations, Stacks/The Challenge
Section titled “The Challenge”We need to support wildcard patterns like Cybersader/* where:
- The
*matches any remaining path depth - The matched content becomes tags bidirectionally
- The pattern works for multiple entities without duplicating rules
Current Limitations
Section titled “Current Limitations”Our current implementation requires explicit patterns:
tagPattern: "^--cybersader/projects"folderPattern: "^Cybersader/Projects"
This doesn’t scale when you have:
- Multiple entities
- Dynamic sub-structures under each entity
- Need to avoid rule explosion (1 rule per entity per subfolder)
Desired Behavior
Section titled “Desired Behavior”Folder to Tag
Section titled “Folder to Tag”File location: Cybersader/📁 01 - Projects/MyProject/note.md
Should create tags:
#--cybersader(entity)#--cybersader/01-projects(OUTPUT structure)#--cybersader/01-projects/myproject(specific project)
Tag to Folder
Section titled “Tag to Folder”File has tags:
#--username1/02-cybernews/security-breach
Should move to:
Username1/📁 02 - CyberNews/Security Breach/
Proposed Solution
Section titled “Proposed Solution”1. Wildcard Pattern Syntax
Section titled “1. Wildcard Pattern Syntax”Introduce * and ** wildcards in patterns:
{ "tagPattern": "^--{entity}/*", "folderPattern": "^{entity}/*"}Where:
{entity}is a captured group (matches any entity name)*matches one path level**matches multiple path levels recursively
2. Capture Groups
Section titled “2. Capture Groups”Use regex capture groups to extract and transform matched parts:
{ "tagPattern": "^--([^/]+)/(.*)", "folderPattern": "^([^/]+)/(.*)", "captures": { "1": "entity", "2": "path" }, "transforms": [ { "target": "path", "operations": ["removeEmoji", "removeNumberPrefix", "kebab-case"] } ]}Behavior:
- Capture group 1: Entity name (e.g., “cybersader”, “username1”)
- Capture group 2: Remaining path (e.g., ”📁 01 - Projects/MyProject”)
- Transform the path independently of the entity
3. Dynamic Rule Generation
Section titled “3. Dynamic Rule Generation”When a wildcard rule is defined, the engine:
- Scans the vault for matching entities
- Dynamically generates specific rules for each entity
- Caches generated rules for performance
- Regenerates when vault structure changes
Implementation Considerations
Section titled “Implementation Considerations”Performance
Section titled “Performance”Challenge: Scanning entire vault to detect entities Solutions:
- Cache entity list
- Only rescan on folder creation/deletion
- Lazy evaluation (generate rules on-demand)
Ambiguity Resolution
Section titled “Ambiguity Resolution”Challenge: Multiple wildcard rules matching the same file Solutions:
- Priority system (as we already have)
- Most specific pattern wins
- Explicit “wildcard priority” setting
UI Representation
Section titled “UI Representation”Challenge: How to show wildcard rules in settings Options:
- Show as single rule with “dynamic” badge
- Expand to show all generated rules (collapsible)
- Preview mode: “This rule will match X entities”
Validation
Section titled “Validation”Challenge: Validating wildcard patterns before applying Solutions:
- Pattern syntax validator
- Preview/dry-run mode
- Show matched files before confirming
Example Rule Configuration
Section titled “Example Rule Configuration”Simple Entity Wildcard
Section titled “Simple Entity Wildcard”{ "id": "entity-output-wildcard", "name": "Entity OUTPUT structures", "description": "Sync any entity's OUTPUT folder structure to tags", "wildcardEnabled": true, "direction": "bidirectional", "tagPattern": "^--(?<entity>[^/]+)/(?<path>.*)", "folderPattern": "^(?<entity>[^/]+)/(?<path>.*)", "transforms": { "entity": { "caseTransform": "lowercase" }, "path": { "caseTransform": "kebab-case", "emojiHandling": "strip", "numberPrefixHandling": "strip" } }, "options": { "createFolders": true, "addTags": true, "syncOnFileCreate": true }}Generated Rules (dynamic):
Cybersader/**↔#--cybersader/**Username1/**↔#--username1/**TeamA/**↔#--teama/**
Filtered Wildcard
Section titled “Filtered Wildcard”Only match certain subfolders:
{ "wildcardEnabled": true, "folderPattern": "^(?<entity>[^/]+)/📁 \\d+ - (?<section>[^/]+)/(?<path>.*)", "tagPattern": "^--(?<entity>[^/]+)/(?<section>[^/]+)/(?<path>.*)", "entityWhitelist": ["Cybersader", "Username1"], "pathFilter": "^📁 \\d+ -"}Matches:
- ✅
Cybersader/📁 01 - Projects/... - ✅
Username1/📁 02 - CyberNews/... - ❌
Cybersader/Random Folder/... - ❌
OtherEntity/📁 01 - Projects/...
Alternative Workarounds (Current System)
Section titled “Alternative Workarounds (Current System)”Until wildcard matching is implemented, users can:
Option 1: Explicit Entity Rules
Section titled “Option 1: Explicit Entity Rules”Create one rule per entity:
{ "id": "cybersader-output", "folderPattern": "^Cybersader/", "tagPattern": "^--cybersader/"}Pros: Works now Cons: Doesn’t scale with many entities
Option 2: Flat Entity Tag
Section titled “Option 2: Flat Entity Tag”Use entity as a single tag, structure separately:
Tags:
#--cybersader(flat, no nesting)#01-projects/myproject(structure tag)
Pros: Simpler rules Cons: Loses entity-path relationship
Option 3: Manual Tag Management
Section titled “Option 3: Manual Tag Management”Don’t auto-sync entity structures, manage manually:
- Entity folders for file organization
- Tags for cross-linking and filtering
- Use MoCs to bridge the two
Pros: Full control Cons: Manual work, defeats plugin purpose
Related Features
Section titled “Related Features”Entity Detection
Section titled “Entity Detection”The plugin could auto-detect entities by:
- Scanning top-level folders
- Looking for certain patterns (e.g., double-dash prefix)
- User-defined entity list in settings
Entity Management UI
Section titled “Entity Management UI”Settings panel for:
- List of detected entities
- Manually add/remove entities
- Set per-entity transformation rules
- Enable/disable entity sync
Template Variables
Section titled “Template Variables”Support template variables in patterns:
{ "folderPattern": "^{$ENTITY}/📁 {$NUMBER} - {$SECTION}/*", "tagPattern": "^--{$ENTITY}/{$SECTION}/*"}Where variables are:
- Defined by user in settings
- Auto-populated from vault structure
- Used in transformation rules
Priority for Implementation
Section titled “Priority for Implementation”Phase 1 (MVP)
Section titled “Phase 1 (MVP)”- Basic capture group support
- Static entity list (user-defined)
- Simple
*wildcard (one level)
Phase 2 (Enhanced)
Section titled “Phase 2 (Enhanced)”**recursive wildcard- Auto-detect entities
- Named capture groups
Phase 3 (Advanced)
Section titled “Phase 3 (Advanced)”- Template variables
- Entity management UI
- Dynamic rule generation with caching
Technical Design Notes
Section titled “Technical Design Notes”Regex Engine Extensions
Section titled “Regex Engine Extensions”Current: Basic pattern matching Needed: Named capture groups + transformations per group
interface WildcardPattern { pattern: string; // Regex with named groups captures: { [groupName: string]: { transform: TransformConfig; required: boolean; } };}
function applyWildcardPattern( path: string, pattern: WildcardPattern): TransformedPath | null { const match = path.match(pattern.pattern); if (!match) return null;
const transformed = {}; for (const [name, config] of Object.entries(pattern.captures)) { const captured = match.groups?.[name]; if (!captured && config.required) return null;
transformed[name] = applyTransforms(captured, config.transform); }
return transformed;}Caching Strategy
Section titled “Caching Strategy”class WildcardRuleCache { private cache: Map<string, GeneratedRule[]> = new Map();
getOrGenerate(wildcardRule: Rule, vault: Vault): GeneratedRule[] { const cacheKey = wildcardRule.id;
if (this.cache.has(cacheKey)) { return this.cache.get(cacheKey)!; }
const generated = this.generateRules(wildcardRule, vault); this.cache.set(cacheKey, generated); return generated; }
invalidate(wildcardRuleId: string) { this.cache.delete(wildcardRuleId); }}Questions to Resolve
Section titled “Questions to Resolve”- Syntax: Use regex capture groups or custom template syntax?
- Performance: Generate rules upfront or on-demand?
- UI: How to visualize wildcard rules and generated rules?
- Validation: How to validate wildcard patterns before saving?
- Conflicts: What happens when wildcard rules overlap with explicit rules?
- Entities: Auto-detect or manual configuration?
User Feedback Needed
Section titled “User Feedback Needed”- Is the proposed syntax intuitive?
- What edge cases are we missing?
- Which workaround is most acceptable short-term?
- Priority: Wildcard matching vs. other features?
Status
Section titled “Status”Current: Documented, not implemented Priority: High (blocks real-world usage for entity-based structures) Complexity: High (requires significant regex and caching logic) Dependencies: None (can implement independently)
Related Issues
Section titled “Related Issues”- Conditional UI fields (simpler, should do first)
- Rule filtering/search (simpler, should do first)
- Bulk operations (orthogonal, can do in parallel)
- Import/export (works with or without wildcards)