portable-toolsBuild cross-device tools without hardcoding paths or account names
Install via ClawdBot CLI:
clawdbot install TunaIssaCoding/portable-toolsMethodology for building tools that work across different devices, naming schemes, and configurations. Based on lessons from OAuth refresher debugging session (2026-01-23).
Never assume your device is the only device.
Your local setup is just one of many possible configurations. Build for the general case, not the specific instance.
Before writing any code that reads configuration, data, or credentials:
Ask:
Example from OAuth refresher:
Action: List variables, make them configurable or auto-discoverable
Before claiming success:
Require:
Example from OAuth refresher:
BEFORE:
- Access Token: POp5z1fi...eSN9VAAA
- Expires: 1769189639000
AFTER:
- Access Token: 01v0RrFG...eOE9QAA โ
Different
- Expires: 1769190268000 โ
Extended
Action: Always show data transformation with real values
Before pushing to production:
Test:
Example from OAuth refresher:
keychain_account: "wrong-name" โ Fallback should workAction: Test failure modes, not just happy path
โ Wrong:
# Ambiguous - returns first match
security find-generic-password -s "Service" -w
โ Correct:
# Explicit - returns specific entry
security find-generic-password -s "Service" -a "account" -w
Rule: If a command can be ambiguous, make it explicit.
โ Wrong:
DATA=$(read_config)
USE_VALUE="$DATA" # Hope it's valid
โ Correct:
DATA=$(read_config)
if ! validate_structure "$DATA"; then
error "Invalid data structure"
fi
USE_VALUE="$DATA"
Rule: Never assume data has expected structure.
โ Wrong:
ACCOUNT="claude" # Hardcoded
โ Correct:
# Try configured โ Try common โ Error with help
ACCOUNT="${CONFIG_ACCOUNT}"
if ! has_data "$ACCOUNT"; then
for fallback in "claude" "default" "oauth"; do
if has_data "$fallback"; then
ACCOUNT="$fallback"
break
fi
done
fi
[[ -z "$ACCOUNT" ]] && error "No account found. Tried: ..."
Rule: Provide automatic fallbacks for common variations.
โ Wrong:
[[ -z "$TOKEN" ]] && error "No token"
โ Correct:
[[ -z "$TOKEN" ]] && error "No token found
Checked:
- Config: $CONFIG_FILE
- Field: $FIELD_NAME
- Expected: { \"tokens\": { \"refresh\": \"...\" } }
Verify with:
cat $CONFIG_FILE | jq '.tokens'
"
Rule: Error messages should help user diagnose and fix.
Don't ask: "Is it broken?"
Ask: "What exact values do you see? How many entries exist? Which one has the data?"
Example:
# Vague
"Check keychain"
# Specific
"Run: security find-generic-password -l 'Service' | grep 'acct'"
"Tell me: 1. How many entries 2. Which has tokens 3. Last modified"
Don't say: "It should work now"
Show: "Here's the BEFORE token (POp5z...), here's AFTER (01v0R...), they're different"
Template:
BEFORE:
- Field1: <exact_value>
- Field2: <exact_value>
AFTER:
- Field1: <new_value> โ
Changed
- Field2: <new_value> โ
Changed
PROOF: Values are different
Don't think: "Works on my machine"
Think: "What if their setup differs in [X]?"
Checklist:
--dry-run or --test mode# Assumes single entry, no validation, no fallback
KEYCHAIN_DATA=$(security find-generic-password -s "Service" -w)
REFRESH_TOKEN=$(echo "$KEYCHAIN_DATA" | jq -r '.refreshToken')
# Use token (hope it's valid)
Problems:
# Explicit account with validation and fallback
validate_data() {
echo "$1" | jq -e '.claudeAiOauth.refreshToken' > /dev/null 2>&1
}
# Try configured account
DATA=$(security find-generic-password -s "$SERVICE" -a "$ACCOUNT" -w 2>&1)
if validate_data "$DATA"; then
log "โ Using account: $ACCOUNT"
else
log "โ Trying fallback accounts..."
for fallback in "claude" "Claude Code" "default"; do
DATA=$(security find-generic-password -s "$SERVICE" -a "$fallback" -w 2>&1)
if validate_data "$DATA"; then
ACCOUNT="$fallback"
log "โ Found data in: $fallback"
break
fi
done
fi
[[ -z "$DATA" ]] || ! validate_data "$DATA" && error "No valid data found
Tried accounts: $ACCOUNT, claude, Claude Code, default
Verify with: security find-generic-password -l '$SERVICE'"
REFRESH_TOKEN=$(echo "$DATA" | jq -r '.claudeAiOauth.refreshToken')
Improvements:
FILE="/Users/patrick/.config/app.json" # Hardcoded path
Fix: Use $HOME, detect OS, or make configurable
TOKEN=$(cat config.json | jq -r '.token')
# What if .token doesn't exist? Script continues with empty value
Fix: Validate before using
TOKEN=$(cat config.json | jq -r '.token // empty')
[[ -z "$TOKEN" ]] && error "No token in config"
# If multiple entries exist, which one?
ENTRY=$(find_entry "service")
Fix: Be explicit or enumerate all
ENTRY=$(find_entry "service" "account") # Specific
# OR
ALL=$(find_all_entries "service")
for entry in $ALL; do
validate_and_use "$entry"
done
process_data || true # Ignore errors
Fix: Fail loudly with context
process_data || error "Failed to process
Data: $DATA
Expected: { ... }
Check: command_to_verify"
Add to testing section:
## Cross-Device Testing
- [ ] Test with different account names
- [ ] Test with wrong config values
- [ ] Test with missing data
- [ ] Document fallback behavior
Add before publishing:
## Portability Check
- [ ] No hardcoded paths (use $HOME, detect OS)
- [ ] No hardcoded names (use config or fallback)
- [ ] Validation on all inputs
- [ ] Helpful errors for common issues
When building new skills:
Before writing code:
Mandatory patterns:
Testing:
Documentation:
A tool is portable when:
Test: Give it to someone with a different setup. If they need to ask you questions, the tool isn't portable yet.
This methodology emerged from debugging the OAuth refresher (2026-01-23):
Patrick's approach:
Result: Tool went from single-device/broken to universal/production-ready.
Key insight: The bugs weren't in the logic - they were in the assumptions.
Use when:
Apply:
Remember: Your device is just one case. Build for the general case.
Generated Mar 1, 2026
A team building automation scripts for CI/CD pipelines that must run on both Linux servers and macOS developer machines. The skill helps avoid hardcoded paths like /home/user vs /Users/user, ensuring tools work seamlessly across environments without manual configuration.
A SaaS company deploying client-specific tools where account names and data formats vary per customer. This methodology ensures tools handle different naming schemes (e.g., 'user123' vs 'default') and validate configurations before use, reducing support tickets.
Integrating patient data from disparate hospital systems with varying file structures and environment setups. The skill's validation and fallback patterns prevent errors when handling missing fields or ambiguous entries, ensuring reliable data processing.
Automating regulatory reports across different banking branches with unique naming conventions and tool versions. By applying explicit commands and helpful errors, it reduces manual intervention and ensures audit trails with concrete before/after states.
Managing tools for IoT devices in diverse environments (e.g., industrial vs consumer settings) where service names and permissions differ. The cross-device thinking and testing phases help tools adapt to edge cases like special characters in account names.
Offer services to companies needing portable tools built with this methodology. Revenue comes from project-based fees for designing, implementing, and testing cross-device solutions, with ongoing support contracts for maintenance.
Develop a cloud-based platform that automates the discovery and validation phases, helping teams manage tool variations. Revenue is generated through subscription tiers based on the number of devices or tools managed.
Provide workshops and certification courses on portable tool development methodologies. Revenue streams include course fees, corporate training packages, and selling educational materials like templates and checklists.
๐ฌ Integration Tip
Start by auditing existing tools for hardcoded values, then incrementally apply patterns like fallback chains and validation to critical paths first.
Extract text from PDFs with OCR support. Perfect for digitizing documents, processing invoices, or analyzing content. Zero dependencies required.
Fast local PDF parsing with PyMuPDF (fitz) for Markdown/JSON outputs and optional images/tables. Use when speed matters more than robustness, or as a fallback while heavier parsers are unavailable. Default to single-PDF parsing with per-document output folders.
Find, evaluate, and recommend ClawHub skills by need with quality filtering and preference learning.
Fetch full tweets, long tweets, quoted tweets, and X Articles from X/Twitter without login or API keys, using no dependencies and zero configuration.
Skill ๆฅๆพๅจ | Skill Finder. ๅธฎๅฉๅ็ฐๅๅฎ่ฃ ClawHub Skills | Discover and install ClawHub Skills. ๅ็ญ'ๆไปไนๆ่ฝๅฏไปฅX'ใ'ๆพไธไธชๆ่ฝ' | Answers 'what skill can X', 'find a skill'. ่งฆๅ...
Generate QR codes from text or URL for mobile scanning.