skills/specs/001-screenshot-analysis/data-model.md
dan 5fea49b7c0 feat(tufte-press): evolve skill to complete workflow with JSON generation and build automation
- Transform tufte-press from reference guide to conversation-aware generator
- Add JSON generation from conversation context following strict schema
- Create build automation scripts with Nix environment handling
- Integrate CUPS printing with duplex support
- Add comprehensive workflow documentation

Scripts added:
- skills/tufte-press/scripts/generate-and-build.sh (242 lines)
- skills/tufte-press/scripts/build-card.sh (23 lines)

Documentation:
- Updated SKILL.md with complete workflow instructions (370 lines)
- Updated README.md with usage examples (340 lines)
- Created SKILL-DEVELOPMENT-STRATEGY-tufte-press.md (450 lines)
- Added worklog: 2025-11-10-tufte-press-skill-evolution.org

Features:
- Agent generates valid JSON from conversation
- Schema validation before build (catches errors early)
- Automatic Nix shell entry for dependencies
- PDF build via tufte-press toolchain
- Optional print with duplex support
- Self-contained margin notes enforced
- Complete end-to-end testing

Workflow: Conversation → JSON → Validate → Build → Print

Related: niri-window-capture, screenshot-latest, worklog skills
2025-11-10 15:03:44 -08:00

7.5 KiB

Data Model: Screenshot Analysis Skill

Feature: 001-screenshot-analysis
Date: 2025-11-08

Overview

This skill has a minimal data model focused on configuration and file metadata. There are no persistent data structures or databases - all data is ephemeral (file system state) or configuration (JSON file).

Entities

Screenshot File

Description: A screenshot image file discovered in the configured directory

Attributes:

  • path (string, absolute): Full filesystem path to the screenshot file
    • Example: /home/user/Pictures/Screenshots/screenshot-2025-11-08-143022.png
    • Validation: Must be absolute path, must exist, must be readable
  • modification_time (timestamp, Unix epoch): File modification time in seconds since epoch
    • Example: 1731078622 (2025-11-08 14:30:22 UTC)
    • Used for: Sorting files by recency
    • Source: stat -c '%Y'
  • format (enum): Image file format
    • Allowed values: PNG, JPG, JPEG
    • Validation: Case-insensitive match on file extension
    • Used for: Filtering non-screenshot files

Lifecycle: Ephemeral (discovered on each invocation, not persisted)

Relationships: None (standalone file, no references)

State Transitions: N/A (stateless)


Screenshot Directory

Description: Location where screenshots are stored

Attributes:

  • path (string, absolute): Full filesystem path to the directory
    • Default: ~/Pictures/Screenshots (expanded to absolute)
    • Custom: Loaded from config file screenshot_dir field
    • Validation: Must be absolute, must exist, must be readable
  • exists (boolean, derived): Whether the directory exists
    • Computed: [[ -d "$path" ]]
  • readable (boolean, derived): Whether the directory is readable
    • Computed: [[ -r "$path" ]]

Lifecycle: Checked on each skill invocation

Relationships: Contains zero or more Screenshot Files


Skill Configuration

Description: Optional user configuration stored in JSON file

Storage Location (precedence order):

  1. ~/.config/opencode/skills/screenshot-analysis/config.json (OpenCode)
  2. ~/.claude/skills/screenshot-analysis/config.json (Claude Code)

Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "screenshot_dir": {
      "type": "string",
      "description": "Custom screenshot directory path (absolute or ~-expanded)",
      "examples": [
        "/home/user/Pictures/Screenshots",
        "~/Screenshots",
        "/mnt/storage/screenshots"
      ]
    }
  },
  "additionalProperties": false
}

Attributes:

  • screenshot_dir (string, optional): Custom directory path
    • Default: ~/Pictures/Screenshots if omitted or file doesn't exist
    • Validation: Must resolve to valid directory path after tilde expansion

Lifecycle: Loaded once per skill invocation

Validation Rules:

  • If config file missing → Use default, no error
  • If config file malformed JSON → Log warning, use default
  • If screenshot_dir present but invalid path → Error with actionable message
  • If screenshot_dir omitted → Use default

Example Valid Configs:

// Minimal (use all defaults)
{}

// Custom directory
{
  "screenshot_dir": "/home/user/Documents/Screenshots"
}

// Tilde expansion supported
{
  "screenshot_dir": "~/Pictures/MyScreenshots"
}

Example Invalid Configs:

// Invalid: not an object
"~/Pictures"

// Invalid: wrong type
{
  "screenshot_dir": 12345
}

// Invalid: extra fields (allowed but ignored per additionalProperties: false)
{
  "screenshot_dir": "~/Pictures/Screenshots",
  "unknown_field": "value"
}

Data Flow

1. Skill Invoked
   ↓
2. Load Configuration
   - Check ~/.config/opencode/skills/screenshot-analysis/config.json
   - Check ~/.claude/skills/screenshot-analysis/config.json
   - Parse JSON (jq)
   - Extract screenshot_dir or use default
   ↓
3. Validate Directory
   - Expand tilde (~) to absolute path
   - Check directory exists ([[ -d ]])
   - Check directory readable ([[ -r ]])
   ↓
4. Discover Screenshot Files
   - Find regular files (exclude symlinks)
   - Filter by extension (.png, .jpg, .jpeg)
   - Get modification times (stat -c '%Y %n')
   ↓
5. Sort by Recency
   - Primary: modification time (newest first)
   - Tiebreaker: lexicographic filename (Z > A)
   ↓
6. Select File(s)
   - Latest: First result (head -1)
   - Nth: Nth result (sed -n "${N}p")
   - Time-filtered: All matching time constraint
   ↓
7. Return File Path(s)
   - Absolute path(s) to agent
   - Agent passes to image analysis

Validation Rules Summary

Entity Field Validation Error Behavior
Config File JSON format Valid JSON Warn + use default
Config File screenshot_dir Absolute/expandable path Error if invalid
Screenshot Dir path Exists + readable Error with message
Screenshot File path Regular file (not symlink) Skip (filter)
Screenshot File format PNG/JPG/JPEG extension Skip (filter)
Screenshot File modification_time Valid Unix timestamp Skip (malformed)

Edge Cases

Empty Directory

  • Scenario: Screenshot directory exists but contains no screenshot files
  • Behavior: Return empty result (not an error)
  • Message: "No screenshots found in {directory}"

Permission Denied

  • Scenario: Screenshot directory exists but is not readable
  • Behavior: Error with actionable message
  • Message: "Directory not readable (permission denied): {directory}"
  • Scenario: Directory contains symlinks to screenshot files
  • Behavior: Symlinks are filtered out (skip)
  • Validation: find -type f excludes symlinks automatically

Same Timestamp

  • Scenario: Multiple files have identical modification times
  • Behavior: Use lexicographic filename ordering as tiebreaker
  • Example: Given a.png and z.png both at timestamp 1731078622, z.png is selected (Z > A)

Malformed Config

  • Scenario: config.json exists but contains invalid JSON
  • Behavior: Log warning, fall back to default directory
  • Message: "Warning: Failed to parse config.json, using default directory"

Missing jq

  • Scenario: jq command not found on system
  • Behavior: Log warning, fall back to default directory
  • Message: "Warning: jq not found, using default directory"

Constraints

Performance:

  • File discovery must complete in <1 second for 1000 files (SC-002)
  • Config loading must be negligible (<10ms)

Storage:

  • No persistent storage (stateless skill)
  • Config file size limited to 1KB (reasonable for JSON with single path field)

Scalability:

  • Tested up to 1000 files (requirement)
  • Degrades gracefully beyond 10,000 files (acceptable for screenshot directories)

Assumptions

  1. Screenshot files are regular files (not symlinks, special files, or directories)
  2. Modification time accurately reflects screenshot recency (OS maintains mtime correctly)
  3. File extensions (.png, .jpg, .jpeg) reliably indicate image format (case-insensitive)
  4. Config file is user-managed (skill doesn't create or modify it)
  5. Users won't have more than ~10,000 screenshots in a single directory

Future Enhancements (Out of Scope for v1)

  • Screenshot Metadata Database: Index screenshots for faster queries (>10k files)
  • Tag/Label Support: Add metadata field for user-defined tags
  • Multi-Directory Search: Support searching multiple directories
  • Format Conversion: Support additional formats (WebP, BMP, TIFF)
  • Content-Based Search: OCR text extraction, visual similarity