| name | text-message |
| description | Send text messages via Apple Messages app with automatic contact lookup and attachment support. This skill should be used when sending SMS/iMessage to contacts. Supports name-based recipient lookup via Google Contacts integration, image/file attachments, and handles missing recipient/message prompts. CRITICAL - Messages are ALWAYS sent individually to each recipient, NEVER as group messages. REQUIRES E.164 phone format (+1XXXXXXXXXX) for reliable delivery. Integrates Arlen's writing style guide for authentic messaging. |
| category | communication |
| version | 1.4.0 |
Text Message Agent Skill
🔴 CRITICAL MESSAGE DELIVERY RULE
MANDATORY: ALL text messages MUST be sent INDIVIDUALLY to each recipient
- ✅ CORRECT: Send same message to Rob → Send same message to Julie → Send same message to Mark
- ❌ FORBIDDEN: Send message to Rob, Julie, and Mark in a group chat
- NO EXCEPTIONS: This applies to ALL text message requests, regardless of how many recipients
Why This Matters:
- Email skill CAN send to multiple recipients simultaneously
- Text-message skill MUST NEVER create group conversations
- Each recipient receives an individual 1-on-1 message
- This is a fundamental behavioral difference between email and text messaging
Purpose
Send text messages (SMS/iMessage) via Apple Messages app on behalf of Arlen Greer with:
- Automatic contact lookup via Google Contacts for mobile numbers
- Accent-insensitive name matching (e.g., "Zoe" matches "Zoë", "Jose" matches "José")
- Image and file attachment support (photos, videos, documents, audio, etc.)
- Interactive prompts for missing recipient or message
- Support for both name-based and direct phone number recipients
- Integration with existing contacts skill
- Individual delivery to each recipient (never group messages)
- Read existing message threads and retrieve unread messages
When to Use This Skill
Use this skill when:
- User requests to send a text message or SMS
- Keywords detected: "text", "message", "SMS", "iMessage", "send to", "tell"
- User mentions contacting someone via text
- Mobile communication needs
- User asks to check messages, view unread messages, or read message threads
Trigger Patterns:
- "Text [name] [message]"
- "Send [name] a text saying [message]"
- "Message [name] that [message]"
- "Tell [name] [message]" ← NEW: Natural conversation pattern
- "iMessage [name] [message]"
- "Send [name] this photo/image/file" ← NEW: Attachment pattern
- "Text [name] [message] with attachment [path]" ← NEW: Message + attachment
Core Workflow
1. Recipient Resolution
🔴 CRITICAL - Multiple Recipients Handling: When user specifies multiple recipients (e.g., "Text Rob, Julie, and Mark"):
- Parse and identify ALL recipients from the request
- Resolve each recipient to a phone number (via contact lookup or direct number)
- Send the SAME message INDIVIDUALLY to EACH recipient (sequential sends)
- Confirm completion: "✅ Message sent individually to Rob, Julie, and Mark"
- NEVER create a group message or group chat
Single Recipient Flow:
Name-Based Recipients:
# Look up mobile number via contacts skill
~/.claude/skills/contacts/scripts/contacts_manager.rb --search "John Smith"
Extract mobile phone number from results:
- Prioritize phone numbers with type "mobile"
- Fall back to any phone number if no mobile type found
- Prompt user if no phone number exists
Direct Phone Number Recipients:
- Accept phone numbers in any format: (555) 123-4567, 555-123-4567, 5551234567
- Normalize to E.164 format if needed for Messages app
Missing Recipient:
- If no recipient specified, prompt user: "Who would you like to send a text message to?"
- Accept either name or phone number in response
- Process name through contact lookup
- If multiple names provided, prepare to send individually to each
2. Message Content
Missing Message:
- If no message specified, prompt user: "What message would you like to send?"
- Wait for user response before proceeding
Message Validation:
- No length restrictions (Messages app handles SMS vs iMessage)
- Preserve formatting and emoji
- No modifications to user's message content
3. Attachment Handling (NEW)
Attachment Support:
- Supported formats: Images (JPG, PNG, GIF, HEIC, etc.), Videos (MP4, MOV, etc.), Audio (MP3, M4A, etc.), Documents (PDF, DOC, etc.), Archives (ZIP, etc.)
- Path requirements: Provide absolute or relative file path
- Validation: Script validates file exists, is readable, and checks format
- Optional message: Can send attachment with or without text message
Attachment-only message:
~/.claude/skills/text-message/scripts/send_message.sh "PHONE_NUMBER" "" "/path/to/photo.jpg"
Message with attachment:
~/.claude/skills/text-message/scripts/send_message.sh "PHONE_NUMBER" "Check out this photo!" "/path/to/photo.jpg"
4. Send Message
Use AppleScript via Messages app:
# Text-only message
~/.claude/skills/text-message/scripts/send_message.sh "PHONE_NUMBER" "MESSAGE_TEXT"
# Message with attachment
~/.claude/skills/text-message/scripts/send_message.sh "PHONE_NUMBER" "MESSAGE_TEXT" "/path/to/file"
# Attachment-only (no text)
~/.claude/skills/text-message/scripts/send_message.sh "PHONE_NUMBER" "" "/path/to/file"
🔴 CRITICAL - Phone Number Format for Delivery:
For maximum delivery reliability, ALWAYS use E.164 format (+1XXXXXXXXXX) when sending via AppleScript:
- ✅ CORRECT:
+17604199142(full international format) - ⚠️ RISKY:
7604199142(may fail delivery, especially for SMS) - ❌ WRONG:
(760) 419-9142(formatted numbers may be rejected)
Why This Matters:
- AppleScript
send to buddyrequires consistent phone number format - Missing
+1country code can cause "Not Delivered" errors - Formatted numbers with parentheses/dashes may fail silently
- E.164 format works for both iMessage AND SMS delivery
Format Conversion:
# Remove all non-digits and add +1 for US numbers
PHONE=$(echo "$PHONE" | sed 's/[^0-9]//g' | sed 's/^1*//')
PHONE="+1${PHONE}"
🔴 CRITICAL - Special Character Handling: Messages with ANY apostrophes or single quotes can cause AppleScript failures:
- ✅ SAFE: "We just get hot, hotter, and why did I move here"
- ✅ SAFE: "I will not be there" (no contractions)
- ⚠️ FAILS: "We just get 'hot,' 'hotter,' and 'why did I move here again?'" (nested quotes)
- ⚠️ FAILS: "I won't be there" (contractions with apostrophes)
- ⚠️ FAILS: "It's time to go" (possessives and contractions)
- Solution: Remove ALL apostrophes - no contractions, no possessives, no nested quotes
- Root Cause: AppleScript string escaping fails with ANY apostrophe/single quote character, even after sed escaping
- Recommendation: Convert contractions to full words (won't → will not, it's → it is, can't → cannot)
The script will:
- Validate phone number format and convert to E.164 if needed
- Validate attachment file if provided (exists, readable, supported format)
- Open Messages app if not running
- Send message and/or attachment via AppleScript with proper phone format
- Return status confirmation with attachment info if applicable
- Note: May fail with ANY apostrophes/single quotes - remove all contractions and possessives if send fails
4. Read Messages (NEW)
Read existing message threads and unread messages:
~/.claude/skills/text-message/scripts/read_messages.sh [OPTIONS]
Common Operations:
# Get unread messages
~/.claude/skills/text-message/scripts/read_messages.sh --unread
# Get last 20 messages
~/.claude/skills/text-message/scripts/read_messages.sh --limit 20
# Get messages from specific contact
~/.claude/skills/text-message/scripts/read_messages.sh --from "Rob"
# Get unread messages from Julie
~/.claude/skills/text-message/scripts/read_messages.sh --unread --from "Julie"
Returns JSON with message text, sender phone number/iMessage ID, timestamp, read status, and conversation identifier.
🔴 CRITICAL - Sender Name Resolution Required: When presenting messages to the user, you MUST:
- Extract the phone number or iMessage ID from the
fromfield in the JSON response - Look up the sender's name via contacts skill:
~/.claude/skills/contacts/scripts/contacts_manager.rb --search "PHONE_NUMBER" - Display both the sender name (if found in contacts) and phone number/ID
- Format: "From: [Name] ([phone/ID]) - [timestamp]"
- If contact not found: "From: [phone/ID] (Unknown contact) - [timestamp]"
Example workflow:
# 1. Get messages
MESSAGES=$(~/.claude/skills/text-message/scripts/read_messages.sh --limit 3)
# 2. For each message, look up sender by phone number
PHONE=$(echo $MESSAGES | jq -r '.messages[0].from')
CONTACT=$(~/.claude/skills/contacts/scripts/contacts_manager.rb --search "$PHONE")
NAME=$(echo $CONTACT | jq -r '.contacts[0].name.display_name')
# 3. Present to user with name AND number
echo "From: $NAME ($PHONE) - Message text here"
Permission Required: Full Disk Access for Terminal in System Settings > Privacy & Security
Writing Style Integration
Arlen's Authentic Voice - This skill integrates Arlen's personal writing style for authentic text messaging.
Style Guide Reference: ~/.claude/skills/email/references/writing_style_guide.md
Key Texting Adaptations (adapted from email style guide):
- Conversational but clear - Texts are more casual than emails, but still professional
- Direct and brief - Get to the point quickly, texting favors brevity
- Natural contractions - Use "I'm", "I'll", "we're" freely in texts (BUT see apostrophe handling below)
- Friendly tone - Warm and approachable, less formal than email
- Emoji usage - Appropriate in texting contexts for tone and friendliness
Text Message Adaptations:
Email: "Hi Mark, I've successfully integrated the database connection..."
Text: "Hey! Got the database integrated 👍"
Email: "Let me know if you run into any issues."
Text: "Let me know if any issues come up"
Email: "Thank you, -Arlen"
Text: "Thanks!" or just the message without signature
🔴 CRITICAL - Apostrophe Handling Conflict: While Arlen's natural writing style uses contractions (I'm, I'll, won't, can't), AppleScript messaging has a technical limitation that causes ALL apostrophes to fail message delivery.
Resolution Strategy:
- First Priority: Natural voice preservation when possible
- Technical Constraint: Remove ALL apostrophes if send fails
- Adaptive Approach:
- Attempt natural message first (with contractions if user wrote them)
- If send fails, automatically remove apostrophes and retry
- Expand contractions: won't → will not, I'm → I am, can't → cannot
- Rephrase possessives: Tait's → the one Tait has
Best Practice: For critical or time-sensitive messages, proactively avoid apostrophes. For casual messages, attempt natural style first and adapt if needed.
Bundled Resources
Scripts
scripts/send_message.sh
- Send text message via Apple Messages app using AppleScript
- Handles phone number validation and normalization
- Opens Messages app if needed
- Returns JSON status response
scripts/read_messages.sh (NEW)
- Read existing message threads from Messages database
- Filter by read/unread status
- Filter by sender name or number
- Limit results and retrieve conversation history
- Returns JSON with message details
Usage:
~/.claude/skills/text-message/scripts/send_message.sh "+15551234567" "Hello, this is a test message"
Output:
- Success:
{"status": "success", "recipient": "+15551234567", "message": "Hello..."} - Error:
{"status": "error", "code": "ERROR_CODE", "message": "..."}
Exit Codes:
- 0: Success
- 1: Invalid arguments
- 2: Messages app error
- 3: AppleScript execution error
References
references/phone_number_formats.md
- Supported phone number formats
- Normalization rules
- International number handling
references/contact_integration.md
- Integration patterns with contacts skill
- Mobile number extraction logic
- Fallback strategies
references/reading_messages.md (NEW)
- Reading message threads from Messages database
- Filtering and querying messages
- Database schema reference
- Permission setup and troubleshooting
Integration with Contacts Skill
The text-message skill leverages the contacts skill for recipient lookup:
# 1. Search for contact by name
CONTACT=$(~/.claude/skills/contacts/scripts/contacts_manager.rb --search "Rob")
# 2. Extract mobile number (prioritize "mobile" type)
PHONE=$(echo $CONTACT | jq -r '.contacts[0].phones[] | select(.type == "mobile") | .value')
# 3. Fall back to first available phone if no mobile
if [ -z "$PHONE" ]; then
PHONE=$(echo $CONTACT | jq -r '.contacts[0].phones[0].value')
fi
# 4. Send message
~/.claude/skills/text-message/scripts/send_message.sh "$PHONE" "Your message here"
Workflow Examples
Example 1: Send to Named Contact
User: "Send Rob a text saying I'm running 10 minutes late"
Steps:
1. Look up "Rob" in contacts
2. Extract mobile number
3. Send message: "I'm running 10 minutes late"
4. Confirm: "✅ Message sent to Rob (+1-555-123-4567)"
Example 2: Multiple Recipients (Individual Sends)
User: "Text Rob, Julie, and Mark that the meeting is postponed"
🔴 CRITICAL WORKFLOW - Individual sends only:
Steps:
1. Parse recipients: ["Rob", "Julie", "Mark"]
2. Look up each contact and extract mobile numbers:
- Rob: +1-555-123-4567
- Julie: +1-555-234-5678
- Mark: +1-555-345-6789
3. Send INDIVIDUALLY to each recipient (one-by-one):
a. Send to Rob: "The meeting is postponed"
b. Send to Julie: "The meeting is postponed"
c. Send to Mark: "The meeting is postponed"
4. Confirm: "✅ Message sent individually to Rob, Julie, and Mark"
❌ FORBIDDEN: Creating group chat with all three recipients
✅ REQUIRED: Three separate 1-on-1 conversations
Example 3: Missing Recipient
User: "Send a text message"
Steps:
1. Prompt: "Who would you like to send a text message to?"
2. User responds: "Julie Whitney"
3. Look up Julie in contacts
4. Prompt: "What message would you like to send?"
5. User responds: "Meeting confirmed for tomorrow at 2pm"
6. Send message
7. Confirm: "✅ Message sent to Julie Whitney"
Example 4: Direct Phone Number
User: "Text (555) 123-4567 to confirm the appointment"
Steps:
1. Normalize phone number: +15551234567
2. Prompt: "What message would you like to send?"
3. User responds: "Confirming appointment"
4. Send message
5. Confirm: "✅ Message sent to (555) 123-4567"
Example 5: No Contact Found
User: "Send a text to John"
Steps:
1. Search contacts for "John"
2. No match found (or no phone number)
3. Prompt: "I couldn't find a phone number for John. Please provide a phone number."
4. User responds: "555-123-4567"
5. Send message with provided number
Example 5a: Send Image to Contact (NEW)
User: "Send Rob this photo: ~/Desktop/vacation.jpg"
Steps:
1. Look up "Rob" in contacts
2. Extract mobile number: +1-555-123-4567
3. Validate attachment file exists and is readable
4. Prompt: "What message would you like to include with the photo?" (or send without message)
5. User responds: "Check out our vacation!" (or "" for no message)
6. Send message with attachment:
~/.claude/skills/text-message/scripts/send_message.sh "+15551234567" "Check out our vacation!" "/Users/user/Desktop/vacation.jpg"
7. Confirm: "✅ Message and photo sent to Rob (+1-555-123-4567)"
Example 5b: Send Attachment Only (NEW)
User: "Text Julie this PDF: ~/Documents/report.pdf"
Steps:
1. Look up "Julie" in contacts
2. Extract mobile number: +1-555-234-5678
3. Validate PDF file exists
4. Send attachment without text message:
~/.claude/skills/text-message/scripts/send_message.sh "+15552345678" "" "/Users/user/Documents/report.pdf"
5. Confirm: "✅ PDF attachment sent to Julie (+1-555-234-5678)"
Example 5c: Send Video with Message (NEW)
User: "Send Mark this video with a message: ~/Movies/demo.mp4 - 'Here's the demo video we discussed'"
Steps:
1. Look up "Mark" in contacts
2. Extract mobile number: +1-555-345-6789
3. Validate video file exists and is readable
4. Send message with video attachment:
~/.claude/skills/text-message/scripts/send_message.sh "+15553456789" "Here's the demo video we discussed" "/Users/user/Movies/demo.mp4"
5. Confirm: "✅ Message and video sent to Mark (+1-555-345-6789)"
Example 6: Check Unread Messages
User: "Do I have any unread text messages?"
Steps:
1. Run: ~/.claude/skills/text-message/scripts/read_messages.sh --unread
2. Parse JSON response to extract phone numbers for each message
3. Look up each sender's name via contacts skill:
- Contact lookup for +15551234567 → Rob Lopez
- Contact lookup for +15552345678 → Julie Whitney
- Contact lookup for +15553456789 → Mark Davis
4. Display with names AND phone numbers:
"📱 You have 3 unread messages:
- **Rob Lopez** ((555) 123-4567): 'Hey, are you free for lunch?'
- **Julie Whitney** ((555) 234-5678): 'Meeting confirmed for 2pm'
- **Mark Davis** ((555) 345-6789): 'Thanks for the update'"
Example 7: Read Recent Conversation
User: "Show me my recent messages with Rob"
Steps:
1. Run: ~/.claude/skills/text-message/scripts/read_messages.sh --from "Rob" --limit 10
2. Parse JSON response
3. Display conversation thread with timestamps:
"💬 Recent conversation with Rob:
[2:30 PM] You: 'Sure! What time?'
[2:28 PM] Rob: 'Want to grab lunch?'
[11:45 AM] You: 'Thanks, see you then'
[11:42 AM] Rob: 'Meeting at 2pm confirmed'"
Example 8: Check and Reply to Unread
User: "Check my unread messages and reply to Rob"
Steps:
1. Run: ~/.claude/skills/text-message/scripts/read_messages.sh --unread --from "Rob"
2. Extract phone number from JSON and look up contact name
3. Display with name AND phone: "📱 Unread from **Rob Lopez** ((555) 123-4567): 'Are you free for lunch?'"
4. Prompt: "What would you like to reply?"
5. User responds: "Yes, 12:30 works for me"
6. Look up Rob's mobile number via contacts (if not already retrieved)
7. Send reply: ~/.claude/skills/text-message/scripts/send_message.sh "$PHONE" "Yes, 12:30 works for me"
8. Confirm: "✅ Reply sent to Rob Lopez"
Error Handling
Contact Lookup Fails:
- STOP messaging workflow immediately
- Display error: "❌ Contact lookup failed: No contact found for '[Name]'"
- PROMPT user: "Please provide a phone number for [Name] to continue."
- WAIT for user response - do not assume or guess
- Only proceed once valid phone number provided
No Phone Number in Contact:
- Display: "❌ [Name] doesn't have a phone number in contacts"
- PROMPT user: "Please provide a phone number to send the message."
- Wait for user response
- Proceed with provided number
Messages App Not Available:
- Check if Messages app exists on system
- If not available, display: "❌ Apple Messages app not found. This skill requires macOS with Messages app."
- Offer alternative: "Would you like me to help draft an email instead?"
AppleScript Permission Denied:
- Display: "❌ Permission denied to control Messages app"
- Instruct: "Please grant System Events permission in System Settings > Privacy & Security > Automation"
- Wait for user to grant permission before retrying
Attachment File Not Found (NEW):
- Display: "❌ Attachment file not found: [path]"
- PROMPT user: "Please verify the file path and try again."
- Wait for corrected path or user decision to proceed without attachment
Attachment File Not Readable (NEW):
- Display: "❌ Cannot read attachment file: [path]"
- Check file permissions
- Instruct: "Please check file permissions or try a different file."
Unsupported File Format (NEW):
- Display warning: "⚠️ File type '[extension]' may not be supported by Messages app"
- Ask user: "Would you like to try sending anyway?"
- Proceed based on user confirmation
Special Characters Causing Send Failure (NEW): When send_message.sh fails with SEND_FAILED error code:
Common Cause: ANY apostrophes or single quotes in message text
- Nested quotes: 'hot,' 'hotter,' or 'why did I move here?'
- Contractions: won't, can't, it's, don't, shouldn't
- Possessives: Tait's, Grace's, user's
Solution: Remove ALL apostrophes
- Remove nested quotes: 'hot' → hot
- Expand contractions: won't → will not, it's → it is, can't → cannot
- Rephrase possessives: Tait's candy → the candy Tait has, Grace's bag → the bag Grace has
- Keep emoji and other characters intact
Testing Strategy:
- First attempt with original message
- If fails, scan for ANY apostrophes (contractions, possessives, quotes)
- Remove/replace all apostrophes and retry
- Inform user of simplification made
Examples:
# Original (FAILS - nested quotes): "We get 'hot,' 'hotter,' and 'why did I move here again?'" # Fixed: "We get hot, hotter, and why did I move here again?" # Original (FAILS - contraction): "I won't be there at 2pm" # Fixed: "I will not be there at 2pm" # Original (FAILS - multiple apostrophes): "It's Grace's candy and she won't share" # Fixed: "It is the candy Grace has and she will not share"
Message Not Delivered (NEW): When Messages app shows "Not Delivered" with red exclamation mark:
Immediate Diagnosis:
- Check if message appears in Messages app conversation with "Not Delivered" indicator
- Verify phone number format used in failed attempt
Root Causes:
- Phone Number Format: Most common cause - missing
+1or improper formatting - iMessage/SMS Routing: Recipient's iMessage temporarily offline, SMS fallback failed
- Network Connectivity: Temporary cellular/internet connection issue
- Messages Service: Apple's messaging service experiencing issues
- Phone Number Format: Most common cause - missing
Resolution Steps:
# Step 1: Retry with E.164 format (fixes 80% of issues) osascript -e 'tell application "Messages" send "MESSAGE TEXT" to buddy "+1PHONENUMBER" end tell' # Step 2: If still fails, verify Messages app connectivity osascript -e 'tell application "Messages" get properties of service 1 end tell' # Step 3: Check for multiple delivery attempts in database ~/.claude/skills/text-message/scripts/read_messages.sh --limit 5Manual Fallback:
- If automated retry fails, instruct user to manually tap red exclamation mark in Messages app
- Select "Try Again" from the popup menu
- Or delete failed message and manually type/send
Success Indicators:
- Message shows "Delivered" (iMessage) or no error indicator (SMS)
- Message timestamp appears in conversation
- No red exclamation mark present
Pre-Send Checklist
🔴 CRITICAL - Multiple Recipients Check:
- ✅ If multiple recipients detected, verified they will receive INDIVIDUAL messages
- ✅ Confirmed NO group message will be created
- ✅ Each recipient will receive separate 1-on-1 message
Recipient Validation:
- ✅ All recipients resolved (name → phone number OR direct phone number)
- ✅ All phone numbers format validated
- ✅ Confirmation that recipients are correct
Message Validation:
- ✅ Message content provided (or intentionally empty for attachment-only)
- ✅ No modifications to user's intended message (except removing ALL apostrophes)
- ✅ Emoji and formatting preserved
- ✅ CRITICAL: ALL apostrophes removed (won't → will not, it's → it is, Grace's → the one Grace has)
Attachment Validation (NEW):
- ✅ File path validated if attachment provided
- ✅ File exists and is readable
- ✅ File format checked (warning given for unsupported types)
- ✅ Absolute path resolved for AppleScript
System Validation:
- ✅ Messages app available on system
- ✅ AppleScript permissions granted
- ✅ Script execution successful for each recipient
Quick Reference
Contact Lookup:
~/.claude/skills/contacts/scripts/contacts_manager.rb --search "First Last"
Send Message:
# Text only
~/.claude/skills/text-message/scripts/send_message.sh "PHONE" "MESSAGE"
# With attachment (NEW)
~/.claude/skills/text-message/scripts/send_message.sh "PHONE" "MESSAGE" "/path/to/file"
# Attachment only (NEW)
~/.claude/skills/text-message/scripts/send_message.sh "PHONE" "" "/path/to/file"
Read Messages:
# Get unread messages
~/.claude/skills/text-message/scripts/read_messages.sh --unread
# Get recent messages from specific contact
~/.claude/skills/text-message/scripts/read_messages.sh --from "Name" --limit 20
# Get all unread from specific contact
~/.claude/skills/text-message/scripts/read_messages.sh --unread --from "Name"
Phone Number Extraction (from contact JSON):
# Prioritize mobile
jq -r '.contacts[0].phones[] | select(.type == "mobile") | .value'
# Fall back to first phone
jq -r '.contacts[0].phones[0].value'
Best Practices
- Individual Messages Always: When multiple recipients, send individually (never group messages)
- Always Resolve Sender Names: When reading messages, ALWAYS look up sender names via contacts and display both name and phone/ID
- Always Confirm Recipients: Before sending, confirm all recipients with user
- Preserve Message Intent: Don't modify user's message unless asked (except removing ALL apostrophes to prevent failures)
- Handle Missing Info Gracefully: Use interactive prompts rather than assumptions
- Respect Privacy: Don't log message contents beyond what's needed for confirmation
- Error Recovery: Provide clear next steps when errors occur
- Rate Limiting: Add small delay between messages when sending to multiple recipients
- Attachment Validation (NEW): Always validate file exists and is readable before sending
- File Path Resolution (NEW): Convert relative paths to absolute paths for reliability
- Format Warnings (NEW): Warn users about potentially unsupported file formats
- Remove ALL Apostrophes (NEW): Remove contractions, possessives, and quotes to prevent AppleScript failures
Limitations
- macOS Only: Requires Apple Messages app (macOS)
- Contacts Access: Requires Google Contacts integration for name lookup
- Messages App Permissions: User must grant automation permissions
- iMessage vs SMS: Messages app determines delivery method (iMessage or SMS)
- No Group Messages: By design, cannot create group chats (individual messages only)
Version History
- 1.4.0 (2025-11-01) - WRITING STYLE INTEGRATION: Added comprehensive integration with Arlen's personal writing style guide from email skill. New "Writing Style Integration" section documents how to adapt email communication patterns to text messaging context. Includes key texting adaptations (conversational, brief, natural contractions), text message examples, and critical apostrophe handling conflict resolution strategy. Balances natural voice preservation with AppleScript technical limitations. Reference:
~/.claude/skills/email/references/writing_style_guide.md - 1.3.3 (2025-11-01) - CRITICAL UPDATE - ALL APOSTROPHES: Discovered AppleScript fails with ANY apostrophes/single quotes, not just nested ones. Updated documentation throughout to reflect that ALL apostrophes must be removed including: contractions (won't → will not, it's → it is, can't → cannot), possessives (Grace's → the one Grace has, Tait's → the one Tait has), and nested quotes ('hot' → hot). Updated Special Character Handling section, Error Handling examples, Pre-Send Checklist, and Best Practices #4 and #12. Root cause: AppleScript string escaping completely fails with ANY apostrophe character, even after sed escaping. Solution: Expand all contractions, rephrase all possessives, remove all quotes.
- 1.3.2 (2025-11-01) - SPECIAL CHARACTER HANDLING: Documented AppleScript failure when messages contain nested single quotes/apostrophes (e.g., 'hot,' 'hotter,'). Added error handling guidance, troubleshooting steps, and best practice to simplify punctuation in messages. Updated Pre-Send Checklist, Error Handling section with new "Special Characters Causing Send Failure" guidance, and Best Practices with recommendation #12. Root cause: AppleScript string escaping struggles with nested quotes even after sed escaping. Solution: Remove or replace nested quotes before sending. Includes example workflows and testing strategy.
- 1.3.1 (2025-11-01) - CRITICAL DELIVERY FIX: Added comprehensive phone number format requirements and delivery troubleshooting guidance. Documented that AppleScript
send to buddyREQUIRES E.164 format (+1XXXXXXXXXX) for reliable delivery to both iMessage and SMS recipients. Missing+1country code or formatted numbers with parentheses/dashes can cause "Not Delivered" errors. Added troubleshooting section for delivery failures with diagnosis steps, root cause analysis, resolution workflow, and manual fallback procedures. Includes format conversion examples and success indicators. This addresses 80% of message delivery failures. - 1.3.0 (2025-11-01) - MAJOR FEATURE: Added comprehensive attachment support for images, videos, audio, documents, and other file types. Enhanced
send_message.shto accept optional third parameter for file attachments. Includes file validation (existence, readability, format checking), absolute path resolution, and support for sending attachments with or without text messages. Updated SKILL.md with attachment workflows, error handling, and usage examples. Supports all common media formats supported by Apple Messages app. - 1.2.4 (2025-11-01) - CRITICAL FIX: Fixed SMS delivery issue. Previously, messages would only send successfully to iMessage users (iPhone/Mac). Updated AppleScript to allow Messages app to auto-route to either iMessage or SMS based on recipient capability. Now works correctly for both Apple users (iMessage) and non-Apple users (SMS). Changed from explicitly selecting iMessage service to using
send to buddywhich lets Messages app choose the appropriate delivery method. - 1.2.3 (2025-11-01) - CRITICAL UPDATE: Added mandatory sender name resolution when reading messages. When presenting messages to users, skill MUST look up sender names via contacts script and display both the contact name and phone number/iMessage ID. Updated workflow examples and best practices to enforce this requirement. Format: "From: [Name] ([phone/ID]) - [timestamp]" or "From: [phone/ID] (Unknown contact) - [timestamp]".
- 1.2.2 (2025-11-01) - Added accent-insensitive contact name matching to contacts script. Names with diacritics (ë, ñ, é, etc.) can now be searched without accents. For example, "Zoe" will match "Zoë", "Jose" matches "José", etc. Uses Unicode NFD normalization to decompose characters and strip combining marks for matching.
- 1.2.1 (2025-11-01) - Enhanced contacts script phone number search to support multiple formats including
+1country code prefix. Phone numbers are now normalized by removing all non-digit characters and stripping leading1for US numbers, enabling searches with formats like+1 (619) 846-1019,+16198461019,(619) 846-1019, or6198461019to all match contacts with619-846-1019. - 1.2.0 (2025-11-01) - Added ability to read existing message threads and retrieve unread messages via
read_messages.shscript. Includes SQLite database access to Messages chat.db, filtering by read/unread status, sender-based filtering, and conversation history retrieval. Added comprehensive reading_messages.md reference documentation and workflow examples for checking unread messages and replying to conversations. - 1.1.0 (2025-11-01) - CRITICAL UPDATE: Added mandatory individual message delivery for multiple recipients. Messages are NEVER sent as group chats. Each recipient receives a separate 1-on-1 message. Updated workflow examples, pre-send checklist, and best practices to enforce this behavior.
- 1.0.0 (2025-11-01) - Initial text-message skill creation with contact integration, interactive prompts, and AppleScript-based message sending
This skill enables seamless text messaging via Apple Messages with intelligent contact lookup and user-friendly prompts for missing information.