Skill: nollio/writing-coach-pro (version 1.0.0)

# Writing Coach Pro — Agent Skill > Your writing gets better every session. Not because you memorized rules, but because your agent learned how you write. ## Description Writing Coach Pro turns your OpenClaw agent into a persistent writing coach that analyzes, improves, and learns from your writing over time. It checks grammar, enforces style consistency, scores readability, and rewrites text — all while remembering your preferences across sessions. ## Trigger Phrases Use when the user asks to: - Review, edit, proofread, or polish writing - Check grammar, style, or tone - Rewrite or rephrase text - Score readability or grade level - Check document consistency - Set writing preferences or style guide - View writing stats or improvement trends - "Coach me on this" or "explain why this is wrong" Do NOT use for: - Generating content from scratch (that's content creation, not coaching) - Translation - Plagiarism detection - Summarization (use summarize skill) --- ## 1. Style Profile System The style profile is what makes Writing Coach Pro different from every other writing tool. It persists across sessions and evolves as the user writes. ### Profile Location Store the active profile at: `~/.openclaw/skills/writing-coach-pro/config/settings.json` ### Profile Structure The profile tracks these dimensions: **Style Guide**: Which authority governs mechanical choices. - Options: `ap` (AP Stylebook), `chicago` (Chicago Manual of Style), `apa` (APA 7th Edition), `custom` - Default: `ap` - Affects: serial comma usage, title capitalization, number formatting, abbreviation rules, date formatting **Tone**: The user's preferred voice. - Scale: `formal` → `professional` → `conversational` → `casual` - Default: `professional` - Per-context overrides supported (e.g., emails = conversational, reports = formal) **Vocabulary Level**: Complexity of word choice. - Scale: `simple` (6th grade) → `standard` (10th grade) → `advanced` (college) → `technical` (domain-specific) - Default: `standard` **Sentence Length Target**: Average words per sentence. - Range: 10-30 words - Default: 18 - Agent tracks actual average and nudges toward target **Active Voice Preference**: How aggressively to flag passive constructions. - Options: `strict` (flag all), `moderate` (flag when active is clearer), `relaxed` (only flag when passive obscures meaning) - Default: `moderate` **Custom Rules**: User-specific preferences the agent has learned. - Stored as an array of rule objects: `{ "rule": "description", "source": "learned|manual", "confidence": 0.0-1.0 }` - Example: `{ "rule": "Always use Oxford comma", "source": "learned", "confidence": 0.95 }` - Example: `{ "rule": "Prefer 'use' over 'utilize'", "source": "manual", "confidence": 1.0 }` ### Profile Discovery When a new user has no profile, run a discovery flow: 1. Ask: "What kind of writing do you do most? (emails, reports, blog posts, creative, academic, technical)" 2. Ask: "Do you follow a style guide? (AP, Chicago, APA, or none/custom)" 3. Ask: "How would you describe your tone? (formal, professional, conversational, casual)" 4. Set defaults based on answers and save to `settings.json` 5. Tell the user: "Got it. I'll refine these as we work together — the more you write, the better I get." If the user skips discovery, use defaults and learn from their first few submissions. ### Profile Updates The profile updates through two mechanisms: **Explicit**: User says "I prefer Oxford commas" or "Stop flagging my sentence fragments" → update immediately with `confidence: 1.0`. **Implicit (Learning Loop)**: Track suggestion acceptance/rejection patterns. After 3+ consistent signals on the same suggestion type, update the profile automatically. See Section 6 for the full learning loop. --- ## 2. Analysis Pipeline Every piece of text runs through a multi-pass pipeline. Each pass is independent and produces its own findings. The agent assembles findings into a unified report. ### Pass 1: Grammar & Mechanics Check for: - Spelling errors (context-aware — "their/there/they're" resolved by meaning) - Punctuation errors (missing commas, incorrect semicolons, misused apostrophes) - Subject-verb agreement - Pronoun-antecedent agreement - Run-on sentences and comma splices - Sentence fragments (flag only if style profile has `fragments: "flag"`) - Misplaced or dangling modifiers - Incorrect word usage (affect/effect, fewer/less, who/whom) Output format per finding: ``` [GRAMMAR] Line/location → Issue description → Suggested fix ``` ### Pass 2: Style & Word Choice Check for: - Wordiness: "in order to" → "to", "at this point in time" → "now", "due to the fact that" → "because" - Redundancies: "absolutely essential" → "essential", "past history" → "history" - Clichés: "think outside the box", "at the end of the day", "low-hanging fruit" - Weak verbs: overuse of "is/was/are/were" when stronger verbs exist - Nominalization: "make a decision" → "decide", "give consideration to" → "consider" - Adverb overuse: flag adverbs that weaken rather than strengthen ("very", "really", "quite", "actually") - Jargon level: flag if vocabulary doesn't match the profile's vocabulary level setting - Sentence variety: flag if 3+ consecutive sentences start the same way or follow the same structure Apply the user's style guide rules from their profile. For example: - AP style: numbers under 10 spelled out, no Oxford comma (unless user overrides), "%" not "percent" in most contexts - Chicago: numbers under 100 spelled out, Oxford comma required - APA: numbers under 10 spelled out, specific heading formats Output format per finding: ``` [STYLE] Location → Current text → Suggested revision → Rule/reason ``` ### Pass 3: Tone Analysis Evaluate the overall tone and flag mismatches with the user's profile: - Detect: confident, tentative, aggressive, friendly, neutral, formal, casual, passive-aggressive - Flag tone shifts within a document (paragraph 2 is formal, paragraph 5 is suddenly casual) - Flag tone mismatches with stated context (a professional email that reads as too casual) - Identify hedging language: "I think maybe we could possibly consider..." - Identify overly aggressive phrasing: "You need to do this immediately" in a peer email Output: ``` [TONE] Overall tone: [detected] | Target tone: [from profile] | Mismatches: [list] ``` ### Pass 4: Readability Scoring Calculate all metrics (see Section 4 for formulas and interpretation): - Flesch-Kincaid Grade Level - Flesch Reading Ease - Average sentence length (words) - Average word length (syllables) - Passive voice percentage - Adverb density (adverbs per 100 words) - Sentence complexity distribution (simple, compound, complex, compound-complex) Compare against the user's target readability from their profile. Output: ``` [READABILITY] Grade Level: X | Reading Ease: Y | Avg Sentence: Z words Passive Voice: N% | Adverb Density: N per 100 words Target: [user's target] | Status: [on target / above / below] ``` ### Pass 5: Document Consistency Only runs on texts longer than 200 words. Checks for: - Terminology shifts (see Section 5 for full list) - Capitalization inconsistencies - Hyphenation inconsistencies ("e-mail" vs "email" within same doc) - Number formatting ("10" vs "ten" within same context) - Tense shifts (past → present without clear reason) - Voice shifts (active → passive patterns) Output: ``` [CONSISTENCY] Issue type → First usage → Conflicting usage → Recommendation ``` --- ## 3. Feedback Modes The agent operates in one of four modes based on user request. Default to Quick Review unless the user specifies otherwise. ### Quick Review **Trigger**: "check this", "proofread this", "quick review", or any short text (<300 words) without mode specification. **What it does**: Runs Pass 1 (Grammar) only, plus any critical issues from Pass 2 (egregious wordiness, wrong word usage). Skips tone, readability, and consistency. **Output format**: Concise, inline corrections. No scores, no metrics. Just fixes. Example output: ``` Found 3 issues: 1. "their" → "there" (paragraph 2) — wrong word 2. "me and John" → "John and I" (paragraph 1) — pronoun case 3. "very unique" → "unique" (paragraph 3) — unique is absolute, no degree modifier needed ``` ### Full Review **Trigger**: "full review", "review this thoroughly", "analyze my writing", or any text >500 words without mode specification. **What it does**: Runs all 5 passes. Produces a structured report with scores. **Output format**: ``` ## Writing Analysis Report ### Summary [2-3 sentence overall assessment] ### Readability - Grade Level: X (target: Y) - Reading Ease: Z/100 - Avg Sentence Length: N words - Passive Voice: N% - Adverb Density: N/100 words ### Grammar & Mechanics (N issues) [List each issue with fix] ### Style (N suggestions) [List each suggestion with before/after] ### Tone [Overall assessment, any mismatches] ### Consistency (N issues) [List any inconsistencies found] ### Top 3 Priorities [The three most impactful changes to make] ``` Always end with "Top 3 Priorities" — the user's attention is finite. Surface what matters most. ### Rewrite Mode **Trigger**: "rewrite this", "polish this", "make this better", "clean this up". **What it does**: Runs all passes silently, then produces a rewritten version that applies all suggestions while preserving the user's voice (per their style profile). **Output format**: 1. The full rewritten text 2. A brief summary of what changed and why (collapsed/below the rewrite) 3. If multiple options exist for a section, present 2-3 alternatives **Rules for rewrites**: - Never change the meaning or core message - Preserve the user's vocabulary level and tone preferences from their profile - Don't make everything sound the same — preserve stylistic choices that are intentional - When in doubt about whether something is a stylistic choice or an error, ask ### Coach Mode **Trigger**: "coach me", "explain this", "teach me", "why is this wrong", "writing lesson". **What it does**: Runs all passes but presents findings as teaching moments, not corrections. Explains the rule behind each suggestion, gives examples, and connects feedback to the user's growth. **Output format per issue**: ``` ### [Issue Title] **What I found:** [the text in question] **The principle:** [explain the grammar/style rule and why it matters] **The fix:** [suggested revision] **Example in the wild:** [a published example of this principle done well] **Your pattern:** [if this is a recurring issue, note that — "I've seen this in your last 3 reviews"] ``` Coach Mode is designed to make the user a better writer, not just produce better text. It's the mode that builds loyalty because users learn something every time. --- ## 4. Readability Scoring ### Flesch-Kincaid Grade Level Formula: `0.39 × (total words / total sentences) + 11.8 × (total syllables / total words) - 15.59` Ranges: 5-6 (elementary) → 7-8 (middle school) → 9-10 (high school) → 11-12 (college prep) → 13-16 (college) → 17+ (professional) ### Flesch Reading Ease Formula: `206.835 - 1.015 × (total words / total sentences) - 84.6 × (total syllables / total words)` Ranges: 90-100 (very easy, 5th grade) → 60-69 (standard, 8th-9th) → 30-49 (difficult, college) → 0-29 (professional) ### Target Recommendations by Context - **Marketing copy**: Grade 6-8, Reading Ease 70-80 - **Blog posts**: Grade 7-9, Reading Ease 60-70 - **Business emails**: Grade 8-10, Reading Ease 55-65 - **Technical docs**: Grade 10-12, Reading Ease 40-55 - **Academic papers**: Grade 12-16, Reading Ease 30-50 - **Legal writing**: Grade 14+, Reading Ease 20-40 ### Additional Metrics **Passive Voice Percentage**: Count sentences with passive constructions / total sentences × 100. Target: below 15% for most writing. Academic writing may tolerate 20-25%. **Adverb Density**: Count adverbs / total words × 100. Target: below 5%. Above 8% is excessive for any context. **Sentence Length Distribution**: Categorize every sentence: - Short: 1-10 words - Medium: 11-20 words - Long: 21-35 words - Very long: 36+ words Healthy distribution has variety. Flag if >40% of sentences fall in any single bucket. --- ## 5. Document Consistency Checks ### Terminology Build a term map as you read the document. Flag when: - The same concept uses different words: client/customer, app/application, use/utilize - Proper nouns change capitalization: "internet" vs "Internet" - Acronyms are used before being defined, or defined multiple times - Product names are inconsistent: "macOS" vs "MacOS" vs "Mac OS" ### Capitalization Check for: - Title case vs. sentence case in headings (should be consistent throughout) - Inconsistent capitalization of terms: "Agile" vs "agile" (pick one per document) - Proper noun handling ### Hyphenation Flag inconsistencies: - "e-mail" vs "email" - "on-line" vs "online" - Compound modifiers: "well-known fact" but "the fact is well known" (hyphenation rules) ### Number Formatting Per the user's style guide: - Spell out vs. numerals threshold (AP: under 10, Chicago: under 100) - Percentages: "50%" vs "50 percent" vs "fifty percent" - Currency: "$1,000" vs "$1000" vs "one thousand dollars" - Dates: "March 11, 2026" vs "3/11/2026" vs "11 March 2026" ### Tense Consistency Track the dominant tense per section. Flag shifts that appear unintentional: - Past tense narrative suddenly switching to present - Mixing "will" (future) with "would" (conditional) without clear reason ### Voice Consistency Track active vs. passive ratio per section. Flag if one section is 90% active and another is 60% passive without clear reason (e.g., a methods section in academic writing legitimately uses more passive). --- ## 6. Learning Loop The learning loop is what makes Writing Coach Pro improve over time. It tracks patterns in user behavior and adapts the style profile. ### What Gets Tracked Store in `~/.openclaw/skills/writing-coach-pro/data/learning-log.json`: ```json { "suggestions": [ { "date": "2026-03-11", "type": "style", "rule": "oxford_comma", "suggestion": "Add comma before 'and'", "accepted": false, "context": "email" } ], "sessions": [ { "date": "2026-03-11", "wordCount": 450, "issuesFound": 7, "issuesAccepted": 5, "mode": "full_review", "readabilityScore": 62 } ] } ``` ### Acceptance Detection How to know if a suggestion was accepted or rejected: - **Accepted**: User says "fix it", "yes", "apply that", "good catch", uses the rewritten version, or doesn't object - **Rejected**: User says "no", "ignore that", "I meant to write it that way", "skip", or re-submits text without the suggested change - **Unclear**: If the user doesn't respond to a specific suggestion, don't count it either way ### Profile Update Rules - After 3 rejections of the same rule type → reduce that rule's priority (add to custom rules with `"action": "suppress"`) - After 5 acceptances of the same suggestion type → increase confidence, reinforce in profile - After 10+ sessions → generate a "style fingerprint" summary: "You tend to write at a 9th grade level with a conversational tone. You prefer active voice and short sentences. Your most common issues are comma splices and adverb overuse." - Never fully remove a grammar rule — only suppress style preferences. "Their/there" is always wrong regardless of preference. ### Feedback to User Every 10 sessions (or on request), offer a progress report: ``` ## Your Writing Progress Sessions analyzed: 47 Total words reviewed: 23,400 ### Trends - Your average readability has improved from grade 12 to grade 9 - Passive voice usage dropped from 22% to 11% - You've eliminated most adverb overuse — down from 8.2 to 3.1 per 100 words ### Consistent Strengths - Strong active voice - Good sentence variety - Effective use of transitional phrases ### Areas to Watch - Comma splices still appear (flagged in 6 of last 10 sessions) - Tendency toward nominalizations in formal writing ### Your Style Profile [Display current profile settings] ``` --- ## 7. Dashboard Integration Writing Coach Pro feeds data to the NormieClaw dashboard (if installed). The dashboard kit is in `dashboard-kit/`. ### Data Tables Three tables (full schemas in `dashboard-kit/manifest.json`): - **`wc_sessions`**: One row per review session — date, mode, word count, issues found/accepted, readability metrics, context type - **`wc_issues`**: Individual issues across all sessions — linked to session, categorized by pass (grammar/style/tone/consistency), tracks acceptance - **`wc_profile_history`**: Style profile change log — what changed, old/new values, whether learned or manual ### Dashboard Route & Sync Route: `/writing-coach` — displays stat cards (sessions, words, grade level, acceptance rate), readability trend line, issue category breakdown, acceptance rate over time, and a recent sessions table. After each review session, write a summary row to `wc_sessions` and individual findings to `wc_issues`. Update `wc_profile_history` whenever the style profile changes. See `dashboard-kit/DASHBOARD-SPEC.md` for full layout. --- ## 8. Commands Reference - `review [text]` — Quick Review (default) - `full review [text]` — Full 5-pass analysis - `rewrite [text]` — Produce improved version - `coach [text]` — Teaching mode with explanations - `set style [ap|chicago|apa|custom]` — Change style guide - `set tone [formal|professional|conversational|casual]` — Change tone preference - `set readability [grade level]` — Set target readability - `show profile` — Display current style profile - `edit profile` — Interactively modify profile settings - `show progress` — Display writing improvement stats - `export report` — Generate analysis report (runs `export-report.sh`) - `style check [file]` — Consistency scan on a file (runs `style-check.sh`) --- ## 9. Output Formatting Rules ### For Telegram/Discord/WhatsApp - No markdown tables — use bullet lists - Keep responses under 4000 characters when possible - Use bold for issue types, regular text for details - Collapse detailed analysis behind a summary ### For Terminal/CLI - Markdown tables are fine - Use code blocks for before/after comparisons - Color coding via terminal formatting if supported ### Universal - Always lead with a summary count: "Found 7 issues (3 grammar, 2 style, 1 tone, 1 consistency)" - Always end Full Review with "Top 3 Priorities" - In Rewrite Mode, present the rewrite first, explanation second - In Coach Mode, present the teaching point first, the fix second --- ## 10. Edge Cases ### Very Short Text (<20 words) - Skip readability scoring (not meaningful for short text) - Skip consistency checks - Only run grammar pass - Don't run discovery flow on a one-liner ### Very Long Text (>5000 words) - Warn the user: "This is a long document — full analysis will take a moment." - Run consistency checks with higher priority (long docs have more drift) - Break the report into sections rather than one massive output - Offer to analyze section by section ### Code Mixed with Prose - Detect code blocks (```, indented blocks) and skip them for grammar/style analysis - Still analyze comments within code blocks - Readability scores should exclude code ### User Disagrees with a Suggestion - Accept gracefully: "Got it — I'll remember that preference." - Update the learning log with a rejection - If the user explains why, capture the reasoning in custom rules - Never argue or repeat a dismissed suggestion in the same session ### No Style Profile Exists - Use sensible defaults (AP style, professional tone, standard vocabulary, 18-word sentences) - Run the discovery flow at the end of the first review, not before — let the user see value first - Say: "I used default settings for this review. Want to customize your style profile for better results next time?" --- ## 11. Integration with Other Skills Writing Coach Pro works well alongside: - **Content Creation skills**: Run content through Writing Coach after drafting - **Email skills**: Auto-review outgoing emails before sending (if user opts in) - **Report generation**: Apply style consistency to generated reports The agent should suggest Writing Coach review when it detects the user is working on writing-heavy tasks, but never force it. A gentle "Want me to run this through Writing Coach before you send it?" is appropriate. --- ## 12. File Locations | Path | Purpose | |------|---------| | `~/.openclaw/skills/writing-coach-pro/config/settings.json` | Style profile | | `~/.openclaw/skills/writing-coach-pro/data/learning-log.json` | Learning loop data | | `~/.openclaw/skills/writing-coach-pro/data/session-history/` | Per-session detailed logs | | `~/.openclaw/skills/writing-coach-pro/reports/` | Exported analysis reports |

path: README.md
content: # Writing Coach Pro

An agent-native writing coach for OpenClaw. Checks grammar, enforces your style, scores readability, and gets smarter every time you use it.

## What It Does

- **Grammar & Mechanics**: Catches errors, suggests fixes
- **Style Enforcement**: AP, Chicago, APA, or your own custom rules
- **Readability Scoring**: Flesch-Kincaid grade level, reading ease, passive voice %, adverb density
- **Document Consistency**: Flags terminology shifts, capitalization drift, tense changes across long documents
- **Smart Rewrites**: Produces improved versions that sound like you, not a robot
- **Persistent Style Memory**: Learns your preferences over time — the only writing tool that does this
- **Coach Mode**: Teaches you *why* something should change, not just *what*

## Why This Over Grammarly/ProWritingAid

| | Writing Coach Pro | Grammarly Pro | ProWritingAid |
|---|---|---|---|
| **Price** | $9.99 one-time | $144/year | $120/year |
| **Learns your style** | Yes, automatically | No | No |
| **Agent-native** | Yes, works in chat | No, browser extension | No, browser extension |
| **Document consistency** | Full cross-document | Basic | Basic |
| **Teaching mode** | Yes (Coach Mode) | No | No |

## Install

1. Drop `writing-coach-pro/` into `~/.openclaw/skills/`
2. Run `bash ~/.openclaw/skills/writing-coach-pro/scripts/setup.sh`
3. Say "review this" to your agent with any text

Full setup instructions: [SETUP-PROMPT.md](SETUP-PROMPT.md)

## Compatibility

- **OpenClaw**: v1.0+
- **Models**: Works with any LLM backend (Claude, GPT-4, Gemini, local models)
- **Platforms**: macOS, Linux, Windows (WSL)
- **Channels**: Telegram, Discord, Slack, CLI — anywhere your agent runs

## What's Included

```
writing-coach-pro/
├── SKILL.md              # The agent skill (core logic)
├── SETUP-PROMPT.md       # Setup guide
├── README.md             # This file
├── SECURITY.md           # Security information
├── config/settings.json  # Default style profile
├── scripts/              # Setup, export, and style-check scripts
├── examples/             # Before/after examples
└── dashboard-kit/        # Dashboard integration (optional)
```

## License

Included with NormieClaw Pro ($9.99) or The Full Stack ($49). See [normieclaw.ai](https://normieclaw.ai) for terms.


path: SECURITY.md
content: # Writing Coach Pro — Security

## How Text Is Processed

Writing Coach Pro runs as an agent skill inside your OpenClaw instance. When you submit text for review, it is processed by whatever LLM backend your agent is configured to use (Claude, GPT-4, Gemini, a local model, etc.).

**Your text goes wherever your LLM calls go.** If your agent uses a cloud-hosted model (most do), your text is sent to that model's API. If your agent uses a local model (Ollama, llama.cpp), your text stays on your machine.

We do not operate any servers that receive, store, or process your text. Writing Coach Pro is a set of instructions and scripts that your agent executes locally.

## What Gets Stored Locally

Writing Coach Pro stores the following files on your machine:

- **Style profile** (`config/settings.json`): Your writing preferences — style guide, tone, vocabulary level, custom rules. Contains no actual text you've submitted.
- **Learning log** (`data/learning-log.json`): Metadata about past sessions — dates, word counts, issue counts, acceptance rates. Contains issue descriptions but not your original text.
- **Session history** (`data/session-history/`): Per-session analysis summaries. May contain excerpts from your submitted text alongside suggested corrections.
- **Exported reports** (`reports/`): Analysis reports you explicitly generate. Contain excerpts and analysis of your text.

## What We Can and Cannot Guarantee

**We can tell you:**
- Writing Coach Pro does not phone home, ping any NormieClaw server, or transmit data anywhere
- The skill files are readable plaintext — you can audit every line
- No analytics, telemetry, or tracking is built into this skill

**We cannot guarantee:**
- How your LLM provider handles text sent via API calls (review their privacy policies)
- The security of your local filesystem or OpenClaw installation
- That future OpenClaw updates won't change how skills interact with external services

## Recommendations

- Review your LLM provider's data handling policies if you process sensitive documents
- Use a local model (Ollama, llama.cpp) if you need text to stay on your machine
- The `data/` directory contains analysis metadata — protect it like any personal file
- Run `rm -rf ~/.openclaw/skills/writing-coach-pro/data` to delete all stored analysis data

## Reporting Issues

If you discover a security concern with Writing Coach Pro, email [REDACTED_SECRET].


path: SETUP-PROMPT.md
content: # Writing Coach Pro — Setup Guide

Welcome! This guide gets Writing Coach Pro running in about 5 minutes. No technical knowledge required.

---

## Step 1: Install the Skill

Copy the `writing-coach-pro` folder into your OpenClaw skills directory:

```
~/.openclaw/skills/writing-coach-pro/
```

If you purchased The Full Stack bundle, you already have this folder in your download. Just drag it in.

If you purchased Writing Coach Pro individually, unzip the download and move the folder to the path above.

## Step 2: Run Setup

Open your terminal and run:

```bash
bash ~/.openclaw/skills/writing-coach-pro/scripts/setup.sh
```

This creates the data directories and a default style profile. You'll see a confirmation message when it's done.

## Step 3: Talk to Your Agent

That's it. Your agent now knows how to coach your writing. Try these to get started:

- **Quick check**: Paste any text and say "review this"
- **Deep analysis**: Paste text and say "full review"
- **Get a rewrite**: Paste text and say "rewrite this"
- **Learn something**: Paste text and say "coach me on this"

## Step 4: Set Your Preferences (Optional but Recommended)

Tell your agent your preferences. You can do this conversationally:

- "I follow AP style"
- "I write in a conversational tone"
- "Set my target readability to 8th grade"
- "I always use the Oxford comma"
- "Show my profile"

Or say "set up my writing profile" and the agent will walk you through it interactively.

## Step 5: Keep Writing

Writing Coach Pro gets smarter every time you use it. It tracks which suggestions you accept and reject, and adjusts its feedback to match your style. After about 10 sessions, you'll notice the suggestions feel dialed in.

---

## What the Scripts Do

You don't need to run these manually — the agent handles it. But if you're curious:

| Script | What It Does |
|--------|-------------|
| `setup.sh` | Creates data folders and default config. Run once after install. |
| `export-report.sh` | Generates a writing analysis report as markdown or PDF. |
| `style-check.sh` | Scans a file for style inconsistencies from the command line. |

---

## Dashboard (Optional)

If you have the NormieClaw Dashboard installed, Writing Coach Pro automatically feeds it your writing stats. Check the `/writing-coach` route on your dashboard for trends and progress charts.

No dashboard? No problem. Say "show progress" to your agent anytime.

---

## Troubleshooting

**Agent doesn't recognize Writing Coach commands**
Make sure the folder is at `~/.openclaw/skills/writing-coach-pro/` (exact name matters). Restart your OpenClaw session.

**"No style profile found" messages**
Run the setup script again: `bash ~/.openclaw/skills/writing-coach-pro/scripts/setup.sh`

**Suggestions feel generic**
You probably haven't set your preferences yet. Say "set up my writing profile" or just keep using it — it learns automatically after a few sessions.

**Want to start fresh**
Delete the data folder and re-run setup:
```bash
rm -rf ~/.openclaw/skills/writing-coach-pro/data
bash ~/.openclaw/skills/writing-coach-pro/scripts/setup.sh
```

---

## Need Help?

- Visit [normieclaw.ai/support](https://normieclaw.ai/support)
- Email: [REDACTED_SECRET]
- Community: Join the NormieClaw Discord for tips and templates


path: config/settings.json
content: {
  "profile": {
    "style_guide": "ap",
    "tone": "professional",
    "vocabulary_level": "standard",
    "sentence_length_target": 18,
    "active_voice_preference": "moderate",
    "context_overrides": {
      "email": { "tone": "conversational" },
      "report": { "tone": "formal" },
      "blog": { "tone": "conversational", "vocabulary_level": "simple" },
      "academic": { "tone": "formal", "vocabulary_level": "advanced" }
    },
    "custom_rules": []
  },
  "readability_targets": {
    "default_grade_level": 9,
    "default_reading_ease": 60,
    "max_passive_voice_pct": 15,
    "max_adverb_density": 5,
    "max_sentence_length": 35
  },
  "feedback": {
    "default_mode": "quick_review",
    "auto_review_outgoing_email": false,
    "show_readability_on_quick": false,
    "max_suggestions_per_review": 20,
    "suppress_after_rejections": 3
  },
  "dashboard": {
    "enabled": true,
    "sync_after_each_session": true,
    "progress_report_interval_sessions": 10
  },
  "learning": {
    "enabled": true,
    "min_signals_to_learn": 3,
    "style_fingerprint_after_sessions": 10,
    "track_acceptance_rates": true
  }
}


path: dashboard-kit/DASHBOARD-SPEC.md
content: # Writing Coach Pro — Dashboard Integration Spec

## Overview

Writing Coach Pro integrates with the NormieClaw Dashboard to display writing analysis trends, style profile evolution, and improvement tracking over time.

## Requirements

- NormieClaw Dashboard v1.0+
- Dashboard must support the standard manifest format (see `manifest.json`)
- Tables auto-created on first data sync if using Supabase backend

## Route

**Path:** `/writing-coach`
**Nav label:** Writing Coach
**Icon:** `pencil-line` (Lucide icon set)

## Data Flow

1. After each Writing Coach Pro review session, the agent writes a summary row to `wc_sessions`
2. Individual findings are written to `wc_issues` with a foreign key to the session
3. Any style profile changes are logged to `wc_profile_history`
4. Dashboard reads these tables to render widgets

## Page Layout

### Top Row: Key Stats
Four stat cards in a horizontal row:
- **Total Sessions**: Count of all review sessions
- **Words Reviewed**: Sum of all word counts
- **Current Grade Level**: Readability grade from the most recent session
- **Acceptance Rate**: Overall percentage of accepted suggestions (measures agent learning quality)

### Chart Row 1: Readability Trend
Line chart showing Flesch-Kincaid grade level over time. One data point per day (averaged if multiple sessions). Helps users see if their writing complexity is converging on their target.

### Chart Row 2: Side by Side
- **Left — Issues by Category**: Bar chart breaking down grammar vs. style vs. tone vs. consistency issues. Shows where the user's writing needs the most work.
- **Right — Acceptance Rate Over Time**: Line chart tracking what percentage of suggestions the user accepts. A rising line means the agent is learning the user's preferences. A flat or falling line means the profile needs tuning.

### Table: Recent Sessions
Sortable table showing the last 20 sessions with columns:
- Date
- Mode (Quick/Full/Rewrite/Coach)
- Word Count
- Issues Found
- Issues Accepted
- Readability Grade
- Context Type

Click a row to drill into the session detail (if session logs are stored).

## Table Schemas

See `manifest.json` for complete column definitions. Key relationships:

- `wc_issues.session_id` → `wc_sessions.id`
- All tables use text primary keys (UUIDs generated by the agent)
- Timestamps are `timestamptz` for timezone-safe queries

## Data Retention

No automatic purging. Users can clear their data by:
- Deleting `~/.openclaw/skills/writing-coach-pro/data/` (local logs)
- Running `DELETE FROM wc_sessions` / `wc_issues` / `wc_profile_history` (dashboard tables)

## Future Enhancements

- Style profile visualization (radar chart of tone/vocabulary/complexity settings)
- "Most improved" metric highlighting biggest gains
- Comparison view: this month vs. last month
- Export dashboard data as CSV


path: dashboard-kit/manifest.json
content: {
  "skill": "writing-coach-pro",
  "version": "1.0.0",
  "prefix": "wc_",
  "display_name": "Writing Coach",
  "icon": "pencil-line",
  "route": "/writing-coach",
  "description": "Writing analysis trends, style profile, and improvement tracking",
  "tables": [
    {
      "name": "wc_sessions",
      "description": "One row per writing review session",
      "columns": [
        { "name": "id", "type": "text", "primary": true },
        { "name": "date", "type": "timestamptz", "index": true },
        { "name": "mode", "type": "text" },
        { "name": "word_count", "type": "integer" },
        { "name": "issues_found", "type": "integer" },
        { "name": "issues_accepted", "type": "integer" },
        { "name": "readability_grade", "type": "real" },
        { "name": "reading_ease", "type": "real" },
        { "name": "passive_voice_pct", "type": "real" },
        { "name": "adverb_density", "type": "real" },
        { "name": "context_type", "type": "text" }
      ]
    },
    {
      "name": "wc_issues",
      "description": "Individual issues detected across sessions",
      "columns": [
        { "name": "id", "type": "text", "primary": true },
        { "name": "session_id", "type": "text", "references": "wc_sessions.id" },
        { "name": "pass", "type": "text" },
        { "name": "rule", "type": "text", "index": true },
        { "name": "description", "type": "text" },
        { "name": "accepted", "type": "boolean" }
      ]
    },
    {
      "name": "wc_profile_history",
      "description": "Style profile change log",
      "columns": [
        { "name": "id", "type": "text", "primary": true },
        { "name": "date", "type": "timestamptz", "index": true },
        { "name": "field", "type": "text" },
        { "name": "old_value", "type": "text" },
        { "name": "new_value", "type": "text" },
        { "name": "trigger", "type": "text" }
      ]
    }
  ],
  "widgets": [
    {
      "type": "stat_row",
      "items": [
        { "label": "Total Sessions", "query": "SELECT COUNT(*) FROM wc_sessions" },
        { "label": "Words Reviewed", "query": "SELECT COALESCE(SUM(word_count), 0) FROM wc_sessions" },
        { "label": "Current Grade Level", "query": "SELECT ROUND(readability_grade, 1) FROM wc_sessions ORDER BY date DESC LIMIT 1" },
        { "label": "Acceptance Rate", "query": "SELECT ROUND(SUM(issues_accepted)::numeric / NULLIF(SUM(issues_found), 0) * 100, 1) FROM wc_sessions" }
      ]
    },
    {
      "type": "line_chart",
      "title": "Readability Trend",
      "query": "SELECT date::date, AVG(readability_grade) as grade_level FROM wc_sessions GROUP BY date::date ORDER BY date::date",
      "x": "date",
      "y": "grade_level"
    },
    {
      "type": "bar_chart",
      "title": "Issues by Category",
      "query": "SELECT pass, COUNT(*) as count FROM wc_issues GROUP BY pass ORDER BY count DESC",
      "x": "pass",
      "y": "count"
    },
    {
      "type": "line_chart",
      "title": "Acceptance Rate Over Time",
      "query": "SELECT s.date::date, ROUND(SUM(s.issues_accepted)::numeric / NULLIF(SUM(s.issues_found), 0) * 100, 1) as rate FROM wc_sessions s GROUP BY s.date::date ORDER BY s.date::date",
      "x": "date",
      "y": "rate"
    }
  ]
}


path: examples/example-blog-review.md
content: # Example: Blog Post Full Review

## Context
A SaaS founder is writing a blog post about customer onboarding. Targeting potential customers — mid-market ops managers. Goal: thought leadership, not a sales pitch.

## Submitted Text

> # Why Your Onboarding Process is Broken (And How to Fix It)
>
> If you're like most SaaS companies, you've probably spent a lot of time and money building an amazing product. But here's the thing — none of that matters if your users can't figure out how to use it in the first few days.
>
> The truth is, most onboarding processes are fundamentally broken. They're either too complex, too generic, or too hands-off. And the result is that users churn before they ever experience the real value of your product.
>
> ## The Problem with Traditional Onboarding
>
> Traditional onboarding usually looks something like this: you sign up, you get a welcome email, maybe you get a product tour that shows you every single feature whether you need it or not, and then you're basically on your own.
>
> This approach has several really big problems. First of all, it treats every user the same. A technical power user and a non-technical casual user get the exact same experience. That makes absolutely no sense whatsoever. Second, it front-loads information. Nobody can absorb 47 features in their first session. Third, it's passive. Users are expected to figure things out on their own with no guidance.
>
> ## What Good Onboarding Actually Looks Like
>
> Good onboarding is personalized, progressive, and proactive. Let me explain what I mean by each of these.
>
> Personalized means understanding who your user is and what they're trying to accomplish. Are they a project manager who needs to set up team workflows? Or are they a developer who wants API access? The onboarding path should be different for each.
>
> Progressive means revealing features gradually. Don't show everything on day one. Show users what they need right now, then introduce more advanced features as they become relevant. This is sometimes called "progressive disclosure" and it's been a best practice in UX design for decades.
>
> Proactive means reaching out before users get stuck. Monitor usage patterns and send targeted nudges when you see signs of confusion or disengagement. Don't wait for a support ticket — by then it's often too late.
>
> ## The Metrics That Matter
>
> If you want to know whether your onboarding is working, track these metrics: time-to-value (how long until users hit their "aha moment"), activation rate (percentage of signups who complete key actions), Day 7 and Day 30 retention, and support ticket volume during the first two weeks.
>
> These numbers will tell you more about your onboarding quality than any user survey ever could.

## Full Review Output

### Summary
Solid structure and clear thinking. The post reads at a 9th-grade level — right on target for your audience. Main issues: wordiness in several passages, some filler phrases that dilute your authority, and a handful of style inconsistencies. Fifteen suggestions total — five are high-impact.

### Readability
- **Grade Level:** 8.7 (target: 8-10 ✓)
- **Reading Ease:** 63/100 (standard range ✓)
- **Avg Sentence Length:** 19.2 words
- **Passive Voice:** 8% (healthy ✓)
- **Adverb Density:** 4.1/100 words (within target ✓)

### Grammar & Mechanics (2 issues)

1. **Title casing**: "is" should be capitalized in the title → "Why Your Onboarding Process Is Broken" (all verbs are capitalized in title case, including "is")
2. **Comma splice**: "Don't show everything on day one. Show users what they need right now, then introduce more advanced features" → technically a run-on since the second clause after "then" is independent. Add a period or semicolon, or restructure.

### Style (9 suggestions)

1. **"a lot of time and money"** → "heavily" or give a specific figure — "a lot of" is vague
2. **"here's the thing"** → cut — filler that delays your point
3. **"The truth is"** → cut — if it's the truth, just state it. Throat-clearing undermines confidence.
4. **"several really big problems"** → "three problems" — you list exactly three, so say so. "Really big" is imprecise.
5. **"That makes absolutely no sense whatsoever"** → "That doesn't work." — three intensifiers stacked ("absolutely", "no", "whatsoever") reads as ranting, not authority
6. **"Let me explain what I mean by each of these"** → cut — the subheadings explain themselves. This sentence is a bridge to nowhere.
7. **"sometimes called 'progressive disclosure'"** → make this a strength, not a hedge: "This is progressive disclosure — a UX principle that's been validated for decades."
8. **"These numbers will tell you more about your onboarding quality than any user survey ever could"** → strong closer, but "ever could" is slightly hyperbolic. Consider: "These numbers reveal more about onboarding quality than surveys."
9. **"basically on your own"** → "on your own" — "basically" adds nothing

### Tone
- **Overall tone:** Conversational, confident, slightly informal
- **Target match:** Good. Appropriate for a blog aimed at ops managers.
- **Flag:** The "That makes absolutely no sense whatsoever" line tips from confident into frustrated. Pull it back one notch.

### Consistency (2 issues)

1. **Number formatting**: "47 features" (numeral) but "first two weeks" (spelled out). Pick a threshold and stick with it. For a blog, AP style says spell out under 10, use numerals for 10+.
2. **Terminology**: "users" (8 occurrences) and "signups" (1 occurrence) — both refer to the same people. Stick with "users" throughout since that's your dominant term.

### Top 3 Priorities

1. **Cut the filler phrases** ("here's the thing", "the truth is", "let me explain") — they undermine the confident voice you've built. This is the single biggest improvement.
2. **Tighten "The Problem" section** — the ideas are strong but the phrasing is loose. Tighter writing = more authority.
3. **Fix the number formatting inconsistency** — small thing, but editors and careful readers notice it.


path: examples/example-email-polish.md
content: # Example: Email Polish

## Context
A project manager needs to send a status update to their VP. The draft is wordy, wishy-washy, and buries the lead.

## Before

> Subject: Update on Q2 project stuff
>
> Hi Jennifer,
>
> I wanted to reach out and give you a quick update on where things stand with the Q2 website redesign project. We have been making progress on various aspects of the project and I think we are in a pretty good place overall, although there are definitely some areas where we could potentially be doing better.
>
> The design team has been working really hard on the new homepage mockups and they were completed last Friday. I think they look very nice. The development team has started implementing the frontend components and they are estimated to be done by the end of next week hopefully.
>
> One thing I should mention is that we have been experiencing some delays with the content migration due to the fact that the legacy CMS has a lot of formatting issues that need to be cleaned up manually. This is taking longer than we originally anticipated. We're currently exploring some options to try to speed this up.
>
> In terms of the budget, we are currently tracking at about $12,000 against our $15000 budget which I think is reasonable at this point in time.
>
> Please let me know if you have any questions or if there's anything else you need from me.
>
> Best,
> Marcus

## Agent Review (Quick Review Mode)

Found 6 issues:

1. **"wanted to reach out and give you"** → "Here's" — remove throat-clearing. Get to the point.
2. **"due to the fact that"** → "because" — wordy phrase
3. **"at this point in time"** → "currently" or cut entirely — filler
4. **"very nice"** → cut or replace with specific feedback — "very" weakens the sentence
5. **"$15000"** → "$15,000" — inconsistent number formatting (you wrote "$12,000" with a comma earlier)
6. **"they are estimated to be done by the end of next week hopefully"** → "they should finish by end of next week" — passive construction + hedging

## After (Rewrite Mode)

> Subject: Q2 Website Redesign — Status Update
>
> Hi Jennifer,
>
> Here's where we stand on the Q2 website redesign.
>
> **On track:** Homepage mockups are done (completed Friday). The dev team is building frontend components now and should finish by end of next week.
>
> **Risk:** Content migration is behind schedule. The legacy CMS has formatting issues that require manual cleanup — more than we scoped. We're evaluating tools to speed this up and I'll have a revised timeline by Thursday.
>
> **Budget:** Tracking at $12,000 against our $15,000 budget. On target.
>
> Happy to jump on a call if you want to discuss the migration delay.
>
> Marcus

## What Changed

- **Cut word count by 52%** (186 → 89 words). Same information, half the reading time.
- **Led with structure**: bolded section headers make it scannable
- **Eliminated hedging**: "I think we are in a pretty good place overall, although there are definitely some areas where we could potentially be doing better" → cut entirely (says nothing)
- **Named the risk clearly**: instead of burying delays in paragraph 3, flagged it explicitly
- **Added a commitment**: "I'll have a revised timeline by Thursday" gives the VP something concrete
- **Fixed number formatting**: consistent comma usage in dollar amounts
- **Removed filler phrases**: "I wanted to reach out", "in terms of", "at this point in time"


path: examples/example-resume-rewrite.md
content: # Example: Resume Bullet Improvement

## Context
A marketing manager updating their resume for a senior role. The bullets are duty-based, not achievement-based. Writing Coach Pro rewrites them to lead with impact.

## Before

> **Marketing Manager — Bright Signal, Inc. (2022–2025)**
>
> - Responsible for managing the company's social media accounts including Facebook, Instagram, LinkedIn, and Twitter
> - Worked on developing and implementing email marketing campaigns for various product launches
> - Helped to increase website traffic through SEO optimization and content strategy efforts
> - Was in charge of coordinating with the design team to create marketing collateral for trade shows and events
> - Managed a marketing budget and ensured that spending was within approved limits
> - Participated in weekly meetings with the sales team to align marketing and sales strategies

## Agent Review (Coach Mode)

### The Core Problem: Duty Descriptions vs. Impact Statements

**What I found:** All six bullets describe what you were responsible for, not what you accomplished. Hiring managers skim resumes in 6-8 seconds. Duties tell them your role. Achievements tell them your value.

**The principle:** Strong resume bullets follow the **CAR formula**: **C**hallenge or context → **A**ction you took → **R**esult you delivered. Every bullet should answer: "So what? What happened because you did this?"

**Your pattern:** Every bullet starts with a weak verb or passive construction: "Responsible for", "Worked on", "Helped to", "Was in charge of", "Managed", "Participated in." These are duty-starters that bury your impact.

---

### Bullet-by-Bullet Rewrite

**Original:** "Responsible for managing the company's social media accounts including Facebook, Instagram, LinkedIn, and Twitter"

**The fix:** What did managing those accounts achieve? Did followers grow? Did engagement improve? Did social drive leads?

**Rewrite:** "Grew social media following from 12K to 41K across four platforms in 18 months, generating 340+ qualified leads through organic content"

**Why this works:** Starts with a power verb ("Grew"), includes specific numbers, and connects the activity to a business outcome (leads).

---

**Original:** "Worked on developing and implementing email marketing campaigns for various product launches"

**The fix:** "Worked on" is invisible. How many campaigns? What were the results?

**Rewrite:** "Launched 15 email campaigns for 4 product releases, averaging 32% open rates and driving $280K in attributed pipeline"

**Why this works:** Quantifies the scope (15 campaigns, 4 products) and the outcome ($280K pipeline). "Launched" is stronger than "worked on."

---

**Original:** "Helped to increase website traffic through SEO optimization and content strategy efforts"

**The fix:** "Helped to" dilutes your ownership. If you did the work, own it. By how much did traffic increase?

**Rewrite:** "Increased organic traffic 3.2x (18K → 58K monthly sessions) through keyword strategy overhaul and 40-article content program"

**Why this works:** "3.2x" is more compelling than "increased." The specifics (18K → 58K, 40 articles) make it credible.

---

**Original:** "Was in charge of coordinating with the design team to create marketing collateral for trade shows and events"

**The fix:** "Was in charge of coordinating" is five words to say "led." What did the collateral help achieve?

**Rewrite:** "Led collateral production for 8 trade shows, contributing to 22% increase in booth-generated leads year over year"

**Why this works:** Ties the activity to a measurable business result. "Led" beats "was in charge of coordinating with."

---

**Original:** "Managed a marketing budget and ensured that spending was within approved limits"

**The fix:** Staying within budget is the bare minimum — not an achievement. Did you optimize spending? Find savings? Reallocate to higher-performing channels?

**Rewrite:** "Managed $350K annual marketing budget, reallocating 20% from underperforming paid channels to organic programs that delivered 2x higher ROI"

**Why this works:** Shows strategic thinking, not just compliance. The reallocation story demonstrates business judgment.

---

**Original:** "Participated in weekly meetings with the sales team to align marketing and sales strategies"

**The fix:** "Participated in meetings" is not a resume bullet. What came out of that alignment? If nothing measurable, cut this bullet entirely and use the space for a real achievement.

**Rewrite:** "Built marketing-sales feedback loop that reduced lead-to-close cycle from 47 to 31 days, earning cross-functional collaboration award"

**Why this works:** Transforms a process description into an outcome. If you don't have a specific result from sales alignment, drop this bullet.

---

## After

> **Marketing Manager — Bright Signal, Inc. (2022–2025)**
>
> - Grew social media following from 12K to 41K across four platforms in 18 months, generating 340+ qualified leads through organic content
> - Launched 15 email campaigns for 4 product releases, averaging 32% open rates and driving $280K in attributed pipeline
> - Increased organic traffic 3.2x (18K → 58K monthly sessions) through keyword strategy overhaul and 40-article content program
> - Led collateral production for 8 trade shows, contributing to 22% increase in booth-generated leads year over year
> - Managed $350K annual marketing budget, reallocating 20% from underperforming paid channels to organic programs that delivered 2x higher ROI
> - Built marketing-sales feedback loop that reduced lead-to-close cycle from 47 to 31 days

## Key Lesson

**Every bullet should make the reader think "I want that person on my team."** If a bullet could describe anyone in the role, it's not specific enough. Numbers, outcomes, and power verbs are the difference between a resume that gets interviews and one that gets skimmed.

**Note:** The numbers in the rewrite are illustrative. Replace them with your real metrics. Even approximate numbers ("~3x growth") beat no numbers at all.


path: scripts/export-report.sh
content: #!/usr/bin/env bash
set -euo pipefail

# Writing Coach Pro — Export Report
# Generates a writing analysis summary from session history

SKILL_DIR="${HOME}/.openclaw/skills/writing-coach-pro"
DATA_DIR="${SKILL_DIR}/data"
REPORTS_DIR="${SKILL_DIR}/reports"
LEARNING_LOG="${DATA_DIR}/learning-log.json"

usage() {
    echo "Usage: export-report.sh [--format md|pdf] [--last N]"
    echo ""
    echo "Options:"
    echo "  --format md|pdf   Output format (default: md)"
    echo "  --last N          Include only the last N sessions (default: all)"
    echo ""
    echo "Generates a writing progress report from your session history."
    exit 0
}

FORMAT="md"
LAST_N=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        --format)
            FORMAT="${2:-md}"
            if [[ "${FORMAT}" != "md" && "${FORMAT}" != "pdf" ]]; then
                echo "Error: Format must be 'md' or 'pdf'"
                exit 1
            fi
            shift 2
            ;;
        --last)
            LAST_N="${2:-}"
            if ! [[ "${LAST_N}" =~ ^[0-9]+$ ]]; then
                echo "Error: --last requires a positive number"
                exit 1
            fi
            shift 2
            ;;
        --help|-h)
            usage
            ;;
        *)
            echo "Unknown option: $1"
            usage
            ;;
    esac
done

# Verify data exists
if [ ! -f "${LEARNING_LOG}" ]; then
    echo "Error: No learning log found at ${LEARNING_LOG}"
    echo "Have you run any writing reviews yet?"
    echo "Run setup.sh first if you haven't: bash scripts/setup.sh"
    exit 1
fi

# Check for jq
if ! command -v jq &>/dev/null; then
    echo "Error: jq is required for report generation"
    echo "Install it: brew install jq (macOS) or apt install jq (Linux)"
    exit 1
fi

mkdir -p "${REPORTS_DIR}"

TIMESTAMP=$(date +"%Y-%m-%d_%H%M%S")
REPORT_FILE="${REPORTS_DIR}/writing-report-${TIMESTAMP}.md"

echo "Generating writing report..."

# Extract stats from learning log
TOTAL_SESSIONS=$(jq '.sessions | length' "${LEARNING_LOG}")
TOTAL_SUGGESTIONS=$(jq '.suggestions | length' "${LEARNING_LOG}")

if [ "${TOTAL_SESSIONS}" -eq 0 ]; then
    echo "No sessions found in learning log. Use Writing Coach Pro a few times first."
    exit 0
fi

# Apply --last filter
if [ -n "${LAST_N}" ]; then
    SESSIONS_FILTER="(.sessions | sort_by(.date) | .[-${LAST_N}:])"
    SCOPE_NOTE="Last ${LAST_N} sessions"
else
    SESSIONS_FILTER="(.sessions)"
    SCOPE_NOTE="All ${TOTAL_SESSIONS} sessions"
fi

TOTAL_WORDS=$(jq "${SESSIONS_FILTER} | map(.wordCount) | add // 0" "${LEARNING_LOG}")
AVG_ISSUES=$(jq "${SESSIONS_FILTER} | map(.issuesFound) | if length > 0 then (add / length | . * 10 | round / 10) else 0 end" "${LEARNING_LOG}")
ACCEPTED=$(jq '.suggestions | map(select(.accepted == true)) | length' "${LEARNING_LOG}")
REJECTED=$(jq '.suggestions | map(select(.accepted == false)) | length' "${LEARNING_LOG}")

if [ "${TOTAL_SUGGESTIONS}" -gt 0 ]; then
    ACCEPT_RATE=$(echo "scale=1; ${ACCEPTED} * 100 / ${TOTAL_SUGGESTIONS}" | bc 2>/dev/null || echo "N/A")
else
    ACCEPT_RATE="N/A"
fi

# Build the report
cat > "${REPORT_FILE}" << EOF
# Writing Coach Pro — Progress Report

**Generated:** $(date +"%B %d, %Y at %I:%M %p")
**Scope:** ${SCOPE_NOTE}

---

## Summary

- **Total sessions:** ${TOTAL_SESSIONS}
- **Total words reviewed:** ${TOTAL_WORDS}
- **Average issues per session:** ${AVG_ISSUES}
- **Suggestions accepted:** ${ACCEPTED}
- **Suggestions rejected:** ${REJECTED}
- **Acceptance rate:** ${ACCEPT_RATE}%

## Session Breakdown

| Date | Mode | Words | Issues Found | Issues Accepted | Readability |
|------|------|-------|-------------|----------------|-------------|
EOF

# Add session rows
jq -r "${SESSIONS_FILTER} | sort_by(.date) | reverse | .[] | \"| \(.date) | \(.mode) | \(.wordCount) | \(.issuesFound) | \(.issuesAccepted) | \(.readabilityScore) |\"" "${LEARNING_LOG}" >> "${REPORT_FILE}"

cat >> "${REPORT_FILE}" << 'EOF'

## Top Suggestion Categories

EOF

# Count suggestions by type
jq -r '.suggestions | group_by(.type) | map({type: .[0].type, count: length}) | sort_by(-.count) | .[] | "- **\(.type)**: \(.count) suggestions"' "${LEARNING_LOG}" >> "${REPORT_FILE}"

cat >> "${REPORT_FILE}" << 'EOF'

---

*Report generated by Writing Coach Pro for NormieClaw*
EOF

echo "Report saved to: ${REPORT_FILE}"

# Convert to PDF if requested
if [ "${FORMAT}" = "pdf" ]; then
    PDF_FILE="${REPORTS_DIR}/writing-report-${TIMESTAMP}.pdf"
    if command -v pandoc &>/dev/null; then
        pandoc "${REPORT_FILE}" -o "${PDF_FILE}" --pdf-engine=wkhtmltopdf 2>/dev/null || \
        pandoc "${REPORT_FILE}" -o "${PDF_FILE}" 2>/dev/null || {
            echo "PDF conversion failed. Markdown report is still available at: ${REPORT_FILE}"
            exit 0
        }
        echo "PDF saved to: ${PDF_FILE}"
    else
        echo "pandoc not found — PDF conversion skipped."
        echo "Install pandoc for PDF export: brew install pandoc (macOS) or apt install pandoc (Linux)"
        echo "Markdown report is available at: ${REPORT_FILE}"
    fi
fi


path: scripts/setup.sh
content: #!/usr/bin/env bash
set -euo pipefail

# Writing Coach Pro — Setup Script
# Creates data directories and initializes default config

SKILL_DIR="${HOME}/.openclaw/skills/writing-coach-pro"
CONFIG_DIR="${SKILL_DIR}/config"
DATA_DIR="${SKILL_DIR}/data"
SESSION_DIR="${DATA_DIR}/session-history"
REPORTS_DIR="${SKILL_DIR}/reports"

echo "Writing Coach Pro — Setup"
echo "========================="
echo ""

# Check that the skill directory exists
if [ ! -d "${SKILL_DIR}" ]; then
    echo "Error: Skill directory not found at ${SKILL_DIR}"
    echo "Make sure you've copied writing-coach-pro/ into ~/.openclaw/skills/"
    exit 1
fi

# Create data directories
echo "Creating data directories..."
mkdir -p "${DATA_DIR}"
mkdir -p "${SESSION_DIR}"
mkdir -p "${REPORTS_DIR}"

# Set permissions — owner only
chmod 700 "${DATA_DIR}"
chmod 700 "${SESSION_DIR}"
chmod 700 "${REPORTS_DIR}"

# Initialize learning log if it doesn't exist
LEARNING_LOG="${DATA_DIR}/learning-log.json"
if [ ! -f "${LEARNING_LOG}" ]; then
    echo "Initializing learning log..."
    cat > "${LEARNING_LOG}" << 'EOF'
{
  "suggestions": [],
  "sessions": [],
  "created": "TIMESTAMP",
  "version": "1.0.0"
}
EOF
    # Replace timestamp
    if command -v date &>/dev/null; then
        TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
        if [[ "$OSTYPE" == "darwin"* ]]; then
            sed -i '' "s/TIMESTAMP/${TIMESTAMP}/" "${LEARNING_LOG}"
        else
            sed -i "s/TIMESTAMP/${TIMESTAMP}/" "${LEARNING_LOG}"
        fi
    fi
    chmod 600 "${LEARNING_LOG}"
    echo "  → Created ${LEARNING_LOG}"
else
    echo "  → Learning log already exists, skipping"
fi

# Check that settings.json exists
if [ ! -f "${CONFIG_DIR}/settings.json" ]; then
    echo ""
    echo "Warning: settings.json not found in ${CONFIG_DIR}/"
    echo "Your style profile may need to be re-created."
    echo "Tell your agent: 'set up my writing profile'"
else
    echo "  → Style profile found at ${CONFIG_DIR}/settings.json"
fi

echo ""
echo "Setup complete."
echo ""
echo "Next steps:"
echo "  1. Start (or restart) your OpenClaw session"
echo "  2. Paste some text and say 'review this'"
echo "  3. Say 'set up my writing profile' to customize preferences"
echo ""
echo "For full instructions, see SETUP-PROMPT.md"


path: scripts/style-check.sh
content: #!/usr/bin/env bash
set -euo pipefail

# Writing Coach Pro — Style Consistency Check
# Quick scan for common style inconsistencies in a text file

usage() {
    echo "Usage: style-check.sh <file> [--style ap|chicago|apa] [--verbose]"
    echo ""
    echo "Scans a file for common style inconsistencies:"
    echo "  - Mixed number formatting (spelled out vs numerals)"
    echo "  - Inconsistent capitalization"
    echo "  - Hyphenation inconsistencies"
    echo "  - Oxford comma usage (mixed)"
    echo "  - Terminology shifts"
    echo ""
    echo "Options:"
    echo "  --style ap|chicago|apa   Style guide to check against (default: ap)"
    echo "  --verbose                Show line numbers for each finding"
    exit 0
}

if [ $# -lt 1 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
    usage
fi

FILE="$1"
shift

if [ ! -f "${FILE}" ]; then
    echo "Error: File not found: ${FILE}"
    exit 1
fi

if [ ! -r "${FILE}" ]; then
    echo "Error: Cannot read file: ${FILE}"
    exit 1
fi

STYLE="ap"
VERBOSE=false

while [[ $# -gt 0 ]]; do
    case "$1" in
        --style)
            STYLE="${2:-ap}"
            if [[ "${STYLE}" != "ap" && "${STYLE}" != "chicago" && "${STYLE}" != "apa" ]]; then
                echo "Error: Style must be 'ap', 'chicago', or 'apa'"
                exit 1
            fi
            shift 2
            ;;
        --verbose)
            VERBOSE=true
            shift
            ;;
        *)
            echo "Unknown option: $1"
            usage
            ;;
    esac
done

ISSUES=0
CONTENT=$(cat "${FILE}")
WORD_COUNT=$(echo "${CONTENT}" | wc -w | tr -d ' ')

echo "Writing Coach Pro — Style Check"
echo "================================"
echo "File: ${FILE}"
echo "Words: ${WORD_COUNT}"
echo "Style guide: ${STYLE}"
echo ""

# Check 1: Mixed number formatting
# Look for both spelled-out small numbers and digit small numbers
HAS_SPELLED=$(echo "${CONTENT}" | grep -ciE '\b(one|two|three|four|five|six|seven|eight|nine)\b' || true)
HAS_DIGITS=$(echo "${CONTENT}" | grep -cE '\b[1-9]\b' || true)

if [ "${HAS_SPELLED}" -gt 0 ] && [ "${HAS_DIGITS}" -gt 0 ]; then
    echo "⚠ NUMBERS: Mixed formatting — some small numbers spelled out, some as digits"
    if [ "${VERBOSE}" = true ]; then
        echo "  Spelled out:"
        grep -niE '\b(one|two|three|four|five|six|seven|eight|nine)\b' "${FILE}" | head -5 | sed 's/^/    /'
        echo "  As digits:"
        grep -nE '\b[1-9]\b' "${FILE}" | head -5 | sed 's/^/    /'
    fi
    ISSUES=$((ISSUES + 1))
fi

# Check 2: Inconsistent hyphenation of common words
for PAIR in "e-mail:email" "on-line:online" "web-site:website" "co-operate:cooperate"; do
    HYPHENATED="${PAIR%%:*}"
    UNHYPHENATED="${PAIR##*:}"
    HAS_H=$(echo "${CONTENT}" | grep -ci "${HYPHENATED}" || true)
    HAS_U=$(echo "${CONTENT}" | grep -ci "${UNHYPHENATED}" || true)
    if [ "${HAS_H}" -gt 0 ] && [ "${HAS_U}" -gt 0 ]; then
        echo "⚠ HYPHENATION: Mixed usage of '${HYPHENATED}' and '${UNHYPHENATED}'"
        ISSUES=$((ISSUES + 1))
    fi
done

# Check 3: Oxford comma inconsistency
# Look for "X, Y, and Z" vs "X, Y and Z" patterns
OXFORD=$(echo "${CONTENT}" | grep -cE ', and ' || true)
NO_OXFORD=$(echo "${CONTENT}" | grep -cE '[a-z], [a-z]+ and ' || true)

if [ "${OXFORD}" -gt 0 ] && [ "${NO_OXFORD}" -gt 0 ]; then
    if [ "${STYLE}" = "ap" ]; then
        echo "⚠ COMMAS: Oxford comma used inconsistently (AP style omits it)"
    elif [ "${STYLE}" = "chicago" ]; then
        echo "⚠ COMMAS: Oxford comma used inconsistently (Chicago style requires it)"
    else
        echo "⚠ COMMAS: Oxford comma used inconsistently"
    fi
    ISSUES=$((ISSUES + 1))
fi

# Check 4: Percent formatting
HAS_SYMBOL=$(echo "${CONTENT}" | grep -cE '[0-9]+%' || true)
HAS_WORD=$(echo "${CONTENT}" | grep -ci '[0-9]+ percent' || true)

if [ "${HAS_SYMBOL}" -gt 0 ] && [ "${HAS_WORD}" -gt 0 ]; then
    echo "⚠ FORMATTING: Mixed '%' symbol and 'percent' spelling"
    ISSUES=$((ISSUES + 1))
fi

# Check 5: Heading capitalization consistency (markdown files)
if [[ "${FILE}" == *.md ]]; then
    TITLE_CASE=$(grep -cE '^#{1,3} ([A-Z][a-z]+ ){2,}[A-Z]' "${FILE}" || true)
    SENTENCE_CASE=$(grep -cE '^#{1,3} [A-Z][a-z]+ [a-z]' "${FILE}" || true)
    if [ "${TITLE_CASE}" -gt 0 ] && [ "${SENTENCE_CASE}" -gt 0 ]; then
        echo "⚠ HEADINGS: Mixed title case and sentence case in headings"
        ISSUES=$((ISSUES + 1))
    fi
fi

# Check 6: Common terminology pairs
for PAIR in "client:customer" "app:application" "user:end-user" "setup:set up"; do
    TERM_A="${PAIR%%:*}"
    TERM_B="${PAIR##*:}"
    HAS_A=$(echo "${CONTENT}" | grep -ciw "${TERM_A}" || true)
    HAS_B=$(echo "${CONTENT}" | grep -ciw "${TERM_B}" || true)
    if [ "${HAS_A}" -gt 2 ] && [ "${HAS_B}" -gt 2 ]; then
        echo "⚠ TERMINOLOGY: Both '${TERM_A}' (${HAS_A}x) and '${TERM_B}' (${HAS_B}x) used — pick one"
        ISSUES=$((ISSUES + 1))
    fi
done

# Check 7: Passive voice density (rough heuristic)
PASSIVE_MARKERS=$(echo "${CONTENT}" | grep -ciE '\b(is|was|were|are|been|being) [a-z]+ed\b' || true)
SENTENCE_COUNT=$(echo "${CONTENT}" | grep -cE '[.!?]' || true)
if [ "${SENTENCE_COUNT}" -gt 0 ]; then
    # Rough passive percentage
    PASSIVE_PCT=$((PASSIVE_MARKERS * 100 / SENTENCE_COUNT))
    if [ "${PASSIVE_PCT}" -gt 25 ]; then
        echo "⚠ VOICE: High passive voice density (~${PASSIVE_PCT}% of sentences)"
    fi
fi

echo ""
if [ "${ISSUES}" -eq 0 ]; then
    echo "✓ No style inconsistencies detected. Looking clean."
else
    echo "Found ${ISSUES} style inconsistency issue(s)."
    echo "For a full analysis, paste the text to your agent and say 'full review'."
fi


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)