From jaan-to
Extracts writing system specs from codebases using multi-signal analysis: NNg tone dimensions, UI copy classification, i18n maturity, terminology consistency. Use for auditing content systems.
npx claudepluginhub parhumm/jaan-to --plugin jaan-toThis skill is limited to using the following tools:
> Detect the current writing system using multi-signal extraction and output a canonical writing-system spec.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Detect the current writing system using multi-signal extraction and output a canonical writing-system spec.
$JAAN_LEARN_DIR/jaan-to-detect-writing.learn.md - Past lessons (loaded in Pre-Execution)$JAAN_CONTEXT_DIR/tech.md - Tech stack (for framework-aware i18n scanning)$JAAN_TEMPLATES_DIR/jaan-to-detect-writing.template.md - Output template${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md - Language resolution protocolOutput path: $JAAN_OUTPUTS_DIR/detect/writing/ — flat files, overwritten each run (no IDs).
Arguments: $ARGUMENTS — parsed in Step 0.0. Repository path and mode determined there.
MANDATORY — Read and execute ALL steps in: ${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md
Skill name: detect-writing
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
Read and apply language protocol: ${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md
Override field for this skill: language_detect-writing
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-shared-reference.mdfor Evidence Format (SARIF), Evidence ID Generation, Confidence Levels, Frontmatter Schema, Platform Detection, Document Structure, and Codebase Content Safety.
This skill's namespace: E-WRT-* (e.g., E-WRT-001, E-WRT-WEB-001)
Tool name in frontmatter: detect-writing
Arguments: $ARGUMENTS
| Argument | Effect |
|---|---|
| (none) | Light mode (default): String inventory + i18n maturity, single summary file |
[repo] | Scan specified repo (applies to both modes) |
--full | Full mode: All detection steps, 6 output files (current behavior) |
Mode determination:
$ARGUMENTS contains --full as a standalone token → set run_depth = "full"run_depth = "light"Strip --full token from arguments. Set repo_path to remaining arguments (or current working directory if empty).
If run_depth == "full": ultrathink
If run_depth == "light": megathink
Use extended reasoning for:
Purpose: Auto-detect platform structure and determine analysis scope (full vs partial).
Use Glob and Bash to identify platform folders:
(Same as detect-dev - see detect-dev Step 0 for full patterns table)
pnpm-workspace.yaml, lerna.json, nx.json, turbo.jsonls -d */ | grep -Ev "node_modules|\.git|dist|build|\.next"platforms = [{ name: 'all', path: '.' }]For each platform, determine analysis scope:
| Platform Type | Analysis Scope | Rationale |
|---|---|---|
| web, mobile, androidtv, ios, android, desktop | Full | UI copy, error messages, tone, localization |
| backend, api, services | Partial | Error messages only (API errors, logs, validation messages) |
| cli, cmd | Partial | Error messages + CLI help text only |
Partial analysis includes:
# Check for UI component files
ui_files=$(find {platform.path} -type f \( -name "*.jsx" -o -name "*.tsx" -o -name "*.vue" -o -name "*.svelte" \) 2>/dev/null | head -n 1)
if [ -z "$ui_files" ]; then
# No UI files - partial analysis mode
analysis_mode = "partial" # Error messages only
else
analysis_mode = "full" # Full writing system analysis
fi
For each platform in platforms:
current_platform = platform.namebase_path = platform.pathrun_depth and analysis_mode:
run_depth == "full" AND analysis_mode == "full": Run Steps 1-7run_depth == "full" AND analysis_mode == "partial": Run Steps 1, 3 (reduced), 4, 5, 6 (reduced). Skip Step 2, 7 unless content linting detected.run_depth == "light" AND analysis_mode == "full": Run Steps 1, 5 only (skip Steps 2, 3, 4, 6, 7)run_depth == "light" AND analysis_mode == "partial": Run Steps 1, 4, 5 only (skip Steps 2, 3, 6, 7)Partial Analysis Output Notes:
writing-system.md: Tone dimensions based on error messages only, with note about scope limitationui-copy.md: Minimal "Not Applicable" file with informational findingsamples.md: Minimal "Not Applicable" file or error message samples onlyNote: If single-platform mode (platform.name == 'all'), output paths have NO suffix. If multi-platform mode, output paths include -{platform} suffix.
Use framework-specific glob patterns:
| Framework | Glob Patterns |
|---|---|
| React i18next | **/locales/**/*.json, **/i18n/**/*.json, **/public/locales/**/*.json |
| Vue i18n | **/locales/*.json, **/i18n/**/*.json, **/lang/**/*.{json,yml} |
| Angular | **/src/locale/messages.*.xlf |
| Next.js | **/public/locales/**/*.json, **/messages/*.json |
| Flutter/Dart | **/lib/l10n/*.arb, **/l10n/app_*.arb |
| Android | **/res/values/strings.xml, **/res/values-*/strings.xml |
| iOS/macOS | **/*.lproj/Localizable.strings |
| Rails | **/config/locales/**/*.yml |
| Django | **/locale/*/LC_MESSAGES/django.po |
| Java | **/resources/messages*.properties |
| .NET | **/Resources/*.resx |
| PHP/Laravel | **/resources/lang/**/*.php, **/lang/**/*.php |
| GNU gettext | **/po/*.po, **/po/*.pot |
label, title, message, description, placeholder, helperText, errorMessageIf run_depth == "light" AND analysis_mode == "full": Skip Steps 2-4, 6-7. Proceed directly to Step 5 (i18n Maturity Assessment).
If run_depth == "light" AND analysis_mode == "partial": Skip Steps 2-3. Proceed directly to Step 4 (Error Message Quality Scoring), then Step 5, then skip Steps 6-7.
Classify discovered strings into 8 categories (Buttons/CTAs, Error messages, Empty states, Confirmation dialogs, Notifications/toasts, Onboarding, Form labels/helper, Loading states) using component-name glob patterns and variant/severity props.
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "UI Copy Classification" for category detection patterns and props to extract.
Score strings across 4 primary dimensions (Formality, Humor, Respectfulness, Enthusiasm) and 5 extended dimensions (Technical complexity, Verbosity, Directness, Empathy, Confidence), each on a 1-5 scale. Calculate consistency scores via standard deviation per dimension; flag outliers deviating >1.5 standard deviations.
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "NNg Tone Dimension Scoring" for dimension scales, detection signals, and consistency calculation.
Apply 5-dimension weighted rubric (Clarity 25%, Specificity 20%, Actionability 25%, Tone 15%, Accessibility 15%) to each error message found. Flag messages matching automated heuristic thresholds (complexity, length, passive voice, blame language, visible error codes, missing action verbs).
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "Error Message Quality Scoring" for rubric details and heuristic flag criteria.
Use the glob patterns from Step 1 to identify which i18n framework is in use. Assess ICU MessageFormat usage, RTL support, hardcoded string prevalence, string interpolation quality, and centralization. Rate maturity on a 0-5 scale (None through Excellence).
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "i18n Maturity Assessment" for ICU regex patterns, RTL detection methods, hardcoded string grep patterns, interpolation quality levels, centralization scoring rules, and the 0-5 maturity scale.
If run_depth == "light": Skip Steps 6-7. Proceed directly to Step 8 (Present Detection Summary).
Build a glossary using ISO-704-inspired methodology. Discover terms via TF-IDF and C-value analysis, detect semantic/syntactic/frequency-based inconsistencies, and output entries with preferred/admitted/deprecated statuses.
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "Terminology Extraction" for term discovery methods, inconsistency detection rules, and glossary entry YAML format.
Check for content governance signals: CODEOWNERS locale ownership, content linting tools, i18n keywords in PR templates, and CI translation checks.
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-writing-reference.md— "Content Governance Detection" for specific tools and patterns to check.
If run_depth == "light":
WRITING SYSTEM DETECTION COMPLETE (Light Mode)
-------------------------------------------------
PLATFORM: {platform_name or 'all'}
ANALYSIS MODE: {Full/Partial (error messages only)}
STRING CORPUS: {n} strings analyzed across {n} files
LOCALES DETECTED: {list}
i18n MATURITY: Level {0-5} ({name})
{if analysis_mode == "partial":}
ERROR MESSAGE SCORE: {avg_score}/10
SEVERITY SUMMARY
Critical: {n} | High: {n} | Medium: {n} | Low: {n} | Info: {n}
OVERALL SCORE: {score}/10
OUTPUT FILE (1):
$JAAN_OUTPUTS_DIR/detect/writing/summary{-platform}.md
Note: Run with --full for NNg tone dimensions, UI copy classification,
glossary, and governance analysis (6 output files).
"Proceed with writing summary to $JAAN_OUTPUTS_DIR/detect/writing/? [y/n]"
If run_depth == "full":
WRITING SYSTEM DETECTION COMPLETE
-----------------------------------
PLATFORM: {platform_name or 'all'}
ANALYSIS MODE: {Full/Partial (error messages only)}
STRING CORPUS: {n} strings analyzed across {n} files
LOCALES DETECTED: {list}
TONE DIMENSIONS (NNg) {scope note if partial: "based on error messages only"}
Formality: {score}/5 Consistency: {stddev}
Humor: {score}/5 Consistency: {stddev}
Respectfulness: {score}/5 Consistency: {stddev}
Enthusiasm: {score}/5 Consistency: {stddev}
UI COPY COVERAGE {show "N/A" if partial analysis}
Buttons: {n} strings Error messages: {n} strings
Empty states: {n} strings Dialogs: {n} strings
Toasts: {n} strings Onboarding: {n} strings
Form labels: {n} strings Loading: {n} strings
i18n MATURITY: Level {0-5} ({name})
ERROR MESSAGE SCORE: {avg_score}/10
SEVERITY SUMMARY
Critical: {n} | High: {n} | Medium: {n} | Low: {n} | Info: {n}
OVERALL SCORE: {score}/10
OUTPUT FILES (6):
$JAAN_OUTPUTS_DIR/detect/writing/writing-system{-platform}.md - Voice + tone + consistency
$JAAN_OUTPUTS_DIR/detect/writing/glossary{-platform}.md - Terminology glossary
$JAAN_OUTPUTS_DIR/detect/writing/ui-copy{-platform}.md - UI copy classification {or "N/A" if partial}
$JAAN_OUTPUTS_DIR/detect/writing/error-messages{-platform}.md - Error message audit
$JAAN_OUTPUTS_DIR/detect/writing/localization{-platform}.md - i18n maturity assessment
$JAAN_OUTPUTS_DIR/detect/writing/samples{-platform}.md - Representative samples {or "N/A" if partial}
Note: {-platform} suffix only if multi-platform mode (e.g., -web, -backend). Single-platform mode has no suffix.
Partial analysis mode (backend/cli) produces minimal "Not Applicable" files for ui-copy.md and samples.md.
"Proceed with writing 6 output files to $JAAN_OUTPUTS_DIR/detect/writing/? [y/n]"
Do NOT proceed to Phase 2 without explicit approval.
Create directory $JAAN_OUTPUTS_DIR/detect/writing/ if it does not exist.
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/detect-shared-reference.mdsections "Output Path Logic" and "Stale File Cleanup" for platform-specific suffix convention and run_depth cleanup rules.
run_depth == "light": Write Single Summary FileWrite one file: $JAAN_OUTPUTS_DIR/detect/writing/summary{suffix}.md
Contents:
platform field, findings_summary, and overall_scoreanalysis_mode == "partial": Error Message Quality Scores — rubric scoring results (from Step 4)--full for NNg tone dimensions, UI copy classification, glossary, and governance analysis (6 output files)."run_depth == "full": Write 6 Output FilesWrite 6 output files:
| File | Content | Partial Analysis Handling |
|---|---|---|
$JAAN_OUTPUTS_DIR/detect/writing/writing-system{suffix}.md | Voice definition, tone spectrum (NNg dimensions), consistency score | If partial: Note scope limitation ("based on error messages only") |
$JAAN_OUTPUTS_DIR/detect/writing/glossary{suffix}.md | Terminology glossary with ISO-704 statuses | If partial: Error terminology only |
$JAAN_OUTPUTS_DIR/detect/writing/ui-copy{suffix}.md | UI copy classification across 8 categories | If partial: Minimal "Not Applicable" file |
$JAAN_OUTPUTS_DIR/detect/writing/error-messages{suffix}.md | Error message quality audit with rubric scoring | Always included (core finding) |
$JAAN_OUTPUTS_DIR/detect/writing/localization{suffix}.md | i18n maturity assessment (0-5) with evidence | If partial: Error message i18n only |
$JAAN_OUTPUTS_DIR/detect/writing/samples{suffix}.md | Representative string samples per category | If partial: Minimal "Not Applicable" or error samples only |
Note: {suffix} is empty for single-platform mode, or -{platform} for multi-platform mode.
Partial Analysis "Not Applicable" Files:
For platforms with analysis_mode == "partial" (backend/cli), create minimal files for ui-copy.md and samples.md:
---
findings_summary:
informational: 1
overall_score: 10.0 # Nothing to assess
---
## Executive Summary
Platform '{platform}' does not contain UI components. Full writing system analysis is not applicable. This audit focuses on error messages only.
## Findings
### E-WRT-{PLATFORM}-001: UI Copy Analysis Not Applicable
**Severity**: Informational
**Confidence**: Confirmed (1.0)
**Description**: Platform type '{platform}' (backend/CLI) does not have UI copy. Writing system analysis is limited to error messages, validation strings, and API responses.
Each file MUST include:
platform field and findings_summary/overall_scoreReference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/seed-reconciliation-reference.mdfor comparison rules, discrepancy format, and auto-update protocol.
$JAAN_CONTEXT_DIR/tone-of-voice.template.md, $JAAN_CONTEXT_DIR/localization.template.md[y/n]/jaan-to:learn-add commands for patterns worth documenting"Any feedback on the writing system detection? [y/n]"
If yes:
/jaan-to:learn-add detect-writing "{feedback}"context: fork)$JAAN_OUTPUTS_DIR pathIf run_depth == "light":
$JAAN_OUTPUTS_DIR/detect/writing/summary{suffix}.mdoverall_scoreIf run_depth == "full":
$JAAN_OUTPUTS_DIR/detect/writing/platform field in every file