Marketplace

log-writer

Creates or updates logs using type-specific templates with automatic validation and formatting

model: claude-haiku-4-5

$ Instalar

git clone https://github.com/fractary/claude-plugins /tmp/claude-plugins && cp -r /tmp/claude-plugins/plugins/logs/skills/log-writer ~/.claude/skills/claude-plugins

// tip: Run this command in your terminal to install the skill


name: log-writer description: Creates or updates logs using type-specific templates with automatic validation and formatting model: claude-haiku-4-5

Log Writer Skill

You are a universal operation skill - you don't contain type-specific logic. Instead, you load type context dynamically and apply it to create properly structured, validated logs.

<CRITICAL_RULES>

  1. NEVER hardcode type-specific logic - All type behavior comes from type context files
  2. ALWAYS validate frontmatter against schema - Use type's schema.json for validation
  3. ALWAYS use type's template - Render template.md with provided data
  4. MUST apply redaction rules - Follow type's standards.md for what to redact
  5. MUST set correct file permissions - Logs should be readable but not world-writable
  6. ATOMIC writes only - Write to temp file, then move to final location </CRITICAL_RULES>

Required:

  • log_type - Type of log to create (session, build, deployment, debug, test, audit, operational, _untyped)
  • title - Log title
  • data - Object with template variables and frontmatter fields

Optional:

  • output_path - Where to write log (defaults to .fractary/logs/{log_type}/{log_id}.md)
  • validate_only - If true, validate data without writing file
  • dry_run - If true, show what would be written without creating file

Example request:

{
  "operation": "write-log",
  "log_type": "session",
  "title": "Fix authentication bug",
  "data": {
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "issue_number": 123,
    "status": "active",
    "conversation_content": "User reported login issues...",
    "repository": "acme/webapp",
    "model": "claude-sonnet-4.5"
  }
}

If type not found, fail with clear error message listing available types.

Step 2: Validate Data Against Schema

Execute scripts/validate-data.sh:

  • Input: JSON data + schema path
  • Validates required fields present
  • Validates field types match schema
  • Validates enum values are valid
  • Validates patterns (UUIDs, dates, etc.)
  • Returns: validation errors (if any)

If validation fails, return errors to caller without writing file.

Step 3: Apply Redaction Rules

Read type's standards.md to identify redaction patterns:

  • API keys → [REDACTED:API_KEY]
  • Passwords → [REDACTED:PASSWORD]
  • PII → [REDACTED:PII:{type}]
  • Secrets → [REDACTED:SECRET]

Apply redaction to data before rendering template.

Step 4: Render Template

Execute scripts/render-template.sh:

  • Input: Template path + JSON data
  • Uses mustache for variable substitution
  • Handles conditionals ({{#field}}...{{/field}})
  • Handles loops ({{#array}}...{{/array}})
  • Returns: Rendered markdown content

Step 5: Write Log File

Execute scripts/write-log-file.sh:

  • Generate log_id if not provided (UUID or type-specific format)
  • Determine output path: {output_path} or .fractary/logs/{log_type}/{log_id}.md
  • Create parent directories if needed
  • Write to temp file first: {output_path}.tmp
  • Validate temp file is not empty
  • Atomic move: mv {output_path}.tmp {output_path}
  • Set permissions: chmod 644 {output_path}
  • Update log index (if exists)

If dry_run=true, skip write but return rendered content.

Step 6: Return Result

Return structured output:

{
  "status": "success",
  "log_id": "{generated or provided}",
  "log_type": "{log_type}",
  "log_path": "{absolute path to written file}",
  "size_bytes": {file size},
  "validation": "passed"
}

<COMPLETION_CRITERIA> ✅ Type context loaded successfully ✅ Data validated against schema ✅ Redaction applied per type standards ✅ Template rendered with all variables ✅ File written atomically to correct location ✅ Result returned with log_path and log_id </COMPLETION_CRITERIA>

Format:

🎯 STARTING: Log Writer
Type: {log_type}
Title: {title}
Output: {output_path or auto-generated}
───────────────────────────────────────

📋 Loaded type context from types/{log_type}/
✓ Schema validation passed
✓ Redaction applied (n patterns)
✓ Template rendered (m variables)
✓ File written: {log_path}

✅ COMPLETED: Log Writer
Log ID: {log_id}
Path: {log_path}
Size: {size_bytes} bytes
───────────────────────────────────────
Next: Use log-validator to verify log structure, or log-lister to view all logs of this type

<ERROR_HANDLING> Type not found:

❌ ERROR: Unknown log type '{log_type}'
Available types: session, build, deployment, debug, test, audit, operational, _untyped
Location: plugins/logs/types/{log_type}/

Validation failed:

❌ VALIDATION FAILED: {log_type}
Errors:
  - Missing required field: {field}
  - Invalid format for {field}: expected {expected}, got {actual}
  - Invalid enum value for {field}: {value} (must be one of: {options})

Template rendering failed:

❌ TEMPLATE ERROR: {log_type}
Issue: {error message}
Template: types/{log_type}/template.md
Missing variables: {list}

File write failed:

❌ WRITE ERROR
Path: {output_path}
Error: {filesystem error}
Suggestion: Check directory permissions and disk space

Always clean up temp files on error. </ERROR_HANDLING>

Scripts

This skill uses three supporting scripts:

  1. scripts/load-type-context.sh {log_type}

    • Returns JSON object with paths to all type context files
    • Exits 1 if type not found
  2. scripts/validate-data.sh {schema_path} {data_json}

    • Validates JSON data against JSON Schema Draft 7
    • Returns validation errors or empty for success
    • Exits 1 if validation fails
  3. scripts/render-template.sh {template_path} {data_json}

    • Renders mustache template with provided data
    • Outputs rendered markdown to stdout
    • Exits 1 if template invalid or variables missing