Skill: ramaaditya49/tutur-humanizer (version 1.0.1)

--- name: tutur-humanizer description: Rewrite, edit, or review Indonesian text so it sounds natural, human, and context-appropriate. Use when the user asks to humanize Indonesian writing, remove AI-sounding phrasing, adapt text to official/formal/KBBI-aligned Indonesian, preserve casual/slang voice, smooth professional copy, or make generated Indonesian less stiff without changing meaning. --- # Tutur Humanizer ## Overview Use this skill to make Indonesian writing sound like it came from a real person. Preserve the user's meaning, facts, intent, and voice while removing AI-like filler, awkward translation, over-formality, and forced polish. Default to clear Indonesian that is natural in writing: mostly baku, not bureaucratic, not slang-heavy. Shift register only when the user asks for a specific target such as resmi, formal, profesional, santai, gaul, or sales. ## Search And Discovery Relevant searches: humanizer bahasa Indonesia, humanize Indonesian text, parafrase bahasa Indonesia natural, rewrite AI text Indonesia, tulisan formal KBBI, tulisan profesional Indonesia, bahasa gaul Indonesia, copywriting Indonesia, Indonesian writing skill. Use this skill as a natural Indonesian editor and AI-writing cleanup skill. It is not a fact checker and must not invent citations, numbers, claims, or proof. ## Workflow 1. Identify the target register from the request. - If unspecified, use natural baku-santai: readable, correct enough for public writing, but not stiff. - For official/formal work, follow EYD V, KBBI labels, and standard Indonesian structure. - For casual/slang work, keep slang only when it fits the audience and does not blur meaning. 2. Diagnose the text. - Remove formulaic AI framing, inflated significance, vague claims, and copied English rhythm. - Cut filler before adding style. Human writing is usually more specific, not more decorated. - For longer files, optionally run `scripts/scan_ai_id.py` to find repeated phrases and tone risks. 3. Rewrite. - Keep the original facts, scope, and point of view. - Prefer concrete verbs over abstract nouns. - Use shorter sentences when the original stacks too many clauses. - Keep useful personality from the source instead of flattening everything into neutral formal Indonesian. 4. Final pass. - Check ejaan, punctuation, word choice, and register consistency. - Remove remaining stock phrases such as "di era digital", "solusi inovatif", "tidak hanya..., tetapi juga...", and "menjadi kunci". - Make sure the output still sounds Indonesian, not English translated word by word. ## Register Rules - **Resmi/formal:** Use standard Indonesian, EYD V, KBBI-aligned diction, complete sentences, and restrained tone. Avoid slang, chat abbreviations, exaggerated claims, and regional/Jakarta-only vocabulary unless quoted. - **Profesional:** Use clear business Indonesian without corporate padding. Prefer "kami membantu tim mengelola..." over "kami hadir sebagai solusi inovatif yang komprehensif...". - **Santai/gaul:** Use conversational rhythm and light slang only when appropriate. Avoid forced slang, meme language, and overuse of "gue/lu" unless the user's voice already uses it. - **Sales/copy:** Make benefits concrete. Replace hype with proof, context, or a sharper promise. - **Academic/technical:** Keep terms precise. If terminology is uncertain, prefer established Indonesian terms or leave the source term with a short explanation. Read `references/register-map.md` when the register decision matters. ## Indonesian AI Tells Common Indonesian AI tells include: - Overblown openers: "Di era digital yang terus berkembang...", "Dalam lanskap bisnis modern..." - Vague importance: "memainkan peran penting", "menjadi kunci", "mendorong transformasi" - Marketing mush: "solusi inovatif", "pengalaman yang mulus", "komprehensif", "terintegrasi" - English calques: "menavigasi tantangan", "menghadirkan nilai", "lanskap", "beresonansi" - Bureaucratic padding: "dalam rangka", "melakukan optimalisasi", "pelaksanaan kegiatan" - Formulaic contrast: "bukan hanya..., melainkan juga...", "tidak hanya..., tetapi juga..." - Empty conclusion: "Pada akhirnya", "Dengan demikian" when it adds nothing. Read `references/pattern-bank.md` for a larger pattern list and replacement principles. ## Output Style - If the user asks only for a rewrite, return the rewritten text directly. - If the user asks for review, lead with the issues, then provide a rewrite. - If editing a file, make the edit and summarize only the material changes. - Do not invent citations, sources, numbers, names, or proof. - Do not over-correct slang in casual content. Mark it as a register choice, not automatically an error. - Do not make Indonesian sound "high" just to look correct. Correct Indonesian can still be simple. ## Resources - `references/offline-brief.md`: compact local brief for agents without internet access. - `references/local-mirror.md`: local mirror of Indonesian standards, register policy, and style semantics. - `references/usage-patterns.md`: task patterns and review checklist for offline use. - `references/sources.md`: official references used by this skill. - `references/register-map.md`: register decisions for resmi, formal, profesional, santai, gaul, sales, academic, and technical writing. - `references/pattern-bank.md`: Indonesian AI-sounding patterns and rewrite principles. - `references/examples.md`: before/after examples. - `scripts/scan_ai_id.py`: optional scanner for repeated AI-like phrases and register risks. ## Quick Examples Input: > Di era digital yang terus berkembang, bisnis membutuhkan solusi inovatif untuk meningkatkan efisiensi operasional. Natural professional: > Bisnis butuh cara kerja yang lebih rapi dan cepat, terutama saat proses operasional mulai tersebar di banyak alat. Formal: > Perusahaan memerlukan sistem kerja yang lebih tertata agar proses operasional dapat berjalan lebih efisien.

path: agents/openai.yaml
content: interface:
  display_name: "Tutur Humanizer"
  short_description: "Humanisasi tulisan Indonesia"
  default_prompt: "Use $tutur-humanizer to make this Indonesian text sound natural while preserving meaning and voice."


path: references/examples.md
content: # Examples

## Target-Language Examples

Target language: Bahasa Indonesia.

Indonesian AI-like:

> Di era digital yang terus berkembang, solusi inovatif ini menjadi kunci penting untuk meningkatkan produktivitas.

Natural Indonesian:

> Alat ini membantu tim bekerja lebih rapi dan mengurangi pekerjaan berulang.

Formal Indonesian:

> Alat ini membantu tim bekerja lebih tertata dan mengurangi pekerjaan berulang.

## Default Humanizer

Before:

> Di era digital yang terus berkembang, kehadiran teknologi menjadi kunci penting dalam membantu bisnis meningkatkan efisiensi dan produktivitas secara optimal.

After:

> Teknologi bisa membantu bisnis bekerja lebih rapi: tugas berulang berkurang, data lebih mudah dicek, dan tim tidak perlu bolak-balik memakai banyak alat.

Why:

- Removes generic opener.
- Replaces "menjadi kunci penting" and "secara optimal" with concrete outcomes.
- Keeps professional tone.

## Formal

Before:

> Kita bakal melakukan pengecekan ulang terkait data peserta supaya nggak ada yang kelewat.

After:

> Kami akan memeriksa kembali data peserta agar tidak ada data yang terlewat.

Why:

- Converts casual words to formal equivalents.
- Keeps the sentence simple.

## Professional

Before:

> Produk kami hadir sebagai solusi inovatif yang membantu perusahaan dalam mengakselerasi transformasi digital.

After:

> Produk kami membantu perusahaan memindahkan proses manual ke alur kerja digital yang lebih mudah dipantau.

Why:

- Replaces hype with the actual mechanism.
- Keeps business tone.

## Casual

Before:

> Fitur ini memungkinkan pengguna untuk mengelola aktivitas harian secara lebih efisien dan terstruktur.

After:

> Fitur ini bikin aktivitas harian lebih gampang diatur.

Why:

- Matches casual use.
- Keeps meaning without stiff wording.

## Gaul

Before:

> Aplikasi ini membantu pengguna menemukan rekomendasi tempat makan yang sesuai dengan preferensi mereka.

After:

> Aplikasi ini bantu kamu cari tempat makan yang cocok, tanpa harus scroll review terlalu lama.

Why:

- Conversational, but not forced.
- Avoids slang overload.

## Sales

Before:

> Kami menyediakan layanan terbaik untuk membantu bisnis Anda berkembang pesat.

After:

> Kami bantu bisnis Anda merapikan follow-up pelanggan, membaca performa iklan, dan melihat peluang penjualan dari satu tempat.

Why:

- Replaces "terbaik" and "berkembang pesat" with specific benefits.


path: references/local-mirror.md
content: # Local Mirror

## Source Mirror

This file mirrors the practical rules an agent needs when it cannot browse.

- EYD V is the spelling and punctuation baseline for official Indonesian.
- KBBI Daring is the primary lexical reference for standard Indonesian, including usage labels such as colloquial, rough, respectful, regional, and field-specific terms.
- KBBI usage guidance treats language variety, dialect, idiolect, and register as real context, not as errors by default.
- PUPI is the baseline for Indonesian term formation when technical wording needs an Indonesian equivalent.
- Local files to load next: `register-map.md`, `pattern-bank.md`, and `examples.md`.

## Local Usability

The skill may directly rewrite Indonesian text for ordinary, formal, professional, casual, sales, academic, and technical contexts. It does not need the internet for common editing work.

Use external verification only when the text depends on a specific KBBI label, newly standardized term, legal phrase, citation, or institutional wording.

## Vocabulary And Semantics

- Natural Indonesian is not always maximally formal. Match audience, channel, and purpose.
- Baku means standard and accepted; it does not mean stiff, ornate, or bureaucratic.
- Slang is a register choice. Keep it when it carries the user's voice and the target audience accepts it.
- Professional copy should be concrete. Replace abstract claims with action, result, proof, or a sharper promise.
- Official text should be restrained, complete, and consistent with EYD punctuation.
- Sales text should reduce hype and make the benefit specific.

## Generation Rules

1. Preserve facts, names, numbers, dates, claims, and point of view.
2. Remove AI-sounding padding before adding style.
3. Prefer direct Indonesian verbs over abstract noun stacks.
4. Keep terms stable across the text.
5. Use KBBI/EYD style for official contexts and conversational rhythm for casual contexts.
6. Do not invent citations, authority, numbers, or proof.

## Local Style Bank

Common AI-like phrases to avoid:

- "di era digital yang terus berkembang"
- "menjadi kunci"
- "solusi inovatif"
- "tidak hanya..., tetapi juga..."
- "memberikan pengalaman yang mulus"
- "dalam rangka melakukan optimalisasi"

Useful replacements depend on meaning:

- "menjadi kunci" -> say the real cause, requirement, or benefit.
- "solusi inovatif" -> name the product, feature, or outcome.
- "mengoptimalkan proses" -> say what becomes faster, cheaper, clearer, or easier.
- "tidak hanya..., tetapi juga..." -> split into one direct sentence unless the contrast matters.



path: references/offline-brief.md
content: # Offline Brief

## Local Facts

- Purpose: make Indonesian text sound natural, human, and register-appropriate.
- Default register: natural baku-santai, not stiff, not slang-heavy.
- Official/formal output should follow EYD V, KBBI-aligned diction, and restrained tone.
- Casual/slang output may keep nonstandard words when they match the audience.
- Common Indonesian AI tells include generic openers, inflated significance, vague business claims, English calques, bureaucratic padding, formulaic contrast, and weak summary endings.

## Guardrails

- Preserve facts, names, numbers, claims, and intent.
- Do not invent proof, citations, or new promises.
- Do not make every text formal. Match the requested register.
- Do not remove useful personality just to make the text "correct".
- If the user gives a voice sample, match that sample before applying generic rules.

## Sample Prompts

- "Use $tutur-humanizer to make this caption sound natural."
- "Humanize this proposal but keep it formal."
- "Make this Indonesian landing page copy less AI-sounding."
- "Turn this into a casual WhatsApp message without sounding forced."

## Safe Output Patterns

- Direct rewrite: return the rewritten text first.
- Review: list the main AI tells, then provide a rewrite.
- File edit: update the file and summarize material changes only.
- Unclear register: use natural baku-santai and mention the assumption briefly.

## Local Example

Before:

> Di era digital yang terus berkembang, bisnis membutuhkan solusi inovatif untuk meningkatkan efisiensi operasional.

After:

> Bisnis butuh cara kerja yang lebih rapi, terutama saat operasional mulai tersebar di banyak alat.


path: references/pattern-bank.md
content: # Indonesian AI Pattern Bank

Use this as a checklist, not as a hard ban list. Some phrases are acceptable in the right context, but repeated use often makes Indonesian text sound generated.

## Overblown Openers

Patterns:

- "Di era digital yang terus berkembang..."
- "Dalam lanskap [industri/bisnis/teknologi] yang dinamis..."
- "Seiring dengan perkembangan zaman..."
- "Di tengah pesatnya perkembangan..."
- "Pada era modern ini..."

Rewrite principle:

- Start with the actual point, user pain, event, fact, or claim.

Example:

- Before: "Di era digital yang terus berkembang, UMKM membutuhkan strategi pemasaran yang efektif."
- After: "Banyak UMKM sudah punya produk bagus, tetapi belum punya cara yang rapi untuk menarik pembeli baru."

## Vague Importance

Patterns:

- "memainkan peran penting"
- "menjadi kunci"
- "merupakan aspek krusial"
- "sangat vital"
- "mendorong transformasi"
- "memberikan dampak signifikan"

Rewrite principle:

- Name the practical effect.

Example:

- Before: "Data memainkan peran penting dalam pengambilan keputusan bisnis."
- After: "Data membantu tim melihat produk mana yang laku, kanal mana yang boros, dan keputusan mana yang perlu diubah."

## Marketing Mush

Patterns:

- "solusi inovatif"
- "pengalaman yang mulus"
- "terintegrasi secara komprehensif"
- "meningkatkan produktivitas secara optimal"
- "memberdayakan pengguna"
- "menghadirkan nilai tambah"
- "ekosistem digital"

Rewrite principle:

- Replace the label with what the product actually does.

Example:

- Before: "Aplikasi ini menghadirkan solusi inovatif untuk ekosistem digital bisnis."
- After: "Aplikasi ini menggabungkan chat pelanggan, tagihan, dan laporan penjualan dalam satu dashboard."

## English Calques

Patterns:

- "menavigasi tantangan"
- "lanskap kompetitif"
- "beresonansi dengan audiens"
- "mengorkestrasi proses"
- "mengkurasi pengalaman"
- "mendorong keterlibatan"
- "nilai yang dapat ditindaklanjuti"

Rewrite principle:

- Use Indonesian phrasing that people actually say in the target context.

Example:

- Before: "Konten ini beresonansi dengan audiens dan mendorong keterlibatan."
- After: "Konten ini terasa dekat dengan pembaca, jadi mereka lebih mungkin membalas, menyimpan, atau membagikannya."

## Bureaucratic Padding

Patterns:

- "dalam rangka"
- "guna melakukan"
- "melaksanakan kegiatan"
- "terkait dengan"
- "sehubungan dengan hal tersebut"
- "melakukan optimalisasi"
- "melakukan pemantauan"
- "melakukan koordinasi"

Rewrite principle:

- Prefer direct verbs and shorter connectors.

Examples:

- "dalam rangka meningkatkan" -> "untuk meningkatkan"
- "melakukan pemantauan" -> "memantau"
- "melakukan koordinasi" -> "berkoordinasi"
- "terkait dengan" -> "tentang", "mengenai", or "untuk"

## Formulaic Contrast

Patterns:

- "tidak hanya..., tetapi juga..."
- "bukan sekadar..., melainkan..."
- "lebih dari sekadar..."

Rewrite principle:

- Use only when the contrast is meaningful. Otherwise, split the sentence or state the stronger point.

Example:

- Before: "Fitur ini tidak hanya memudahkan pengguna, tetapi juga meningkatkan efisiensi kerja."
- After: "Fitur ini membuat pekerjaan lebih cepat karena pengguna tidak perlu mengisi data yang sama berulang kali."

## Weak Conclusions

Patterns:

- "Pada akhirnya..."
- "Dengan demikian..."
- "Secara keseluruhan..."
- "Hal ini menunjukkan bahwa..."

Rewrite principle:

- End with the strongest consequence, next step, or claim. Delete summary sentences that only restate the text.

## Rhythm Problems

Signals:

- Every sentence has similar length.
- Many sentences contain "yang" chains.
- Paragraphs begin with abstract nouns.
- Too many commas hide multiple ideas in one sentence.

Rewrite principle:

- Mix short and medium sentences.
- Put the subject early.
- Break stacked clauses.
- Use concrete details before abstract conclusions.


path: references/register-map.md
content: # Register Map

Use this file when choosing how far to formalize, relax, or stylize Indonesian text.

## Default: Natural Baku-Santai

Use when the user says "humanize", "rapikan", "lebih manusia", or "jangan AI banget" without naming a register.

- Keep Indonesian correct enough for public reading.
- Avoid slang-heavy choices.
- Avoid bureaucratic diction.
- Prefer simple, direct sentences.
- Preserve the writer's point of view.

Example:

- Before: "Platform ini hadir sebagai solusi inovatif untuk membantu pelaku usaha dalam mengoptimalkan proses kerja."
- After: "Platform ini membantu pelaku usaha merapikan proses kerja tanpa harus memakai banyak alat."

## Resmi/Formal

Use for letters, proposals, institutional announcements, policy text, academic administration, contracts, and government-style writing.

- Follow EYD V and KBBI-aligned diction.
- Use complete sentences.
- Avoid chat abbreviations, slang, emoji, and hype.
- Replace "nggak", "buat", "bikin", "kayak" with context-appropriate forms such as "tidak", "untuk", "membuat", "seperti".
- Keep tone firm but not pompous.

Avoid:

- "dalam rangka" when "untuk" is enough.
- "melakukan koordinasi" when "berkoordinasi" is enough.
- "terkait dengan" when "tentang" or "mengenai" is enough.

## Profesional

Use for business emails, documentation, SaaS copy, internal memos, product updates, and public-facing company text.

- Use clear business Indonesian.
- Keep the benefit concrete.
- Avoid inflated claims.
- Prefer active verbs.
- Keep "Anda" if addressing users directly; use "kamu" only when the brand voice is casual.

Example:

- Before: "Kami menghadirkan pengalaman terintegrasi untuk meningkatkan produktivitas tim Anda."
- After: "Tim Anda bisa mengelola pekerjaan, pesan, dan laporan dari satu tempat."

## Santai

Use for captions, personal posts, informal messages, and community writing.

- Allow "nggak", "buat", "bikin", "kayak", "ini", "itu" when natural.
- Keep punctuation readable.
- Avoid forced slang.
- Do not add "gue/lu" unless the user uses it or asks for a Jakarta-style voice.

Example:

- Before: "Fitur ini memungkinkan pengguna untuk melakukan pengelolaan jadwal secara lebih efisien."
- After: "Fitur ini bikin jadwal lebih gampang diatur."

## Gaul

Use only when requested or when the source voice already uses slang.

- Keep slang light and intentional.
- Avoid dated or overly performative words.
- Avoid mixing too many dialects at once.
- Keep meaning clear for readers outside the speaker's circle when the text is public.

Allowed when fitting:

- "nggak", "gue", "lu", "banget", "ribet", "sat-set", "nongkrong", "gas", "spill"

Use carefully:

- Harsh words, regional slang, or internet slang that may age quickly.

## Sales

Use when the user wants persuasive copy but not a separate long-form copywriting framework.

- Keep the promise specific.
- Mention the pain plainly.
- Show proof or mechanism when available.
- Cut generic claims like "terbaik", "inovatif", "terdepan", and "berkualitas tinggi" unless backed by evidence.

Example:

- Before: "Solusi terbaik untuk meningkatkan performa bisnis Anda secara maksimal."
- After: "Kelola leads, follow-up, dan laporan iklan dari satu dashboard, tanpa bolak-balik spreadsheet."

## Academic/Technical

Use for papers, abstracts, technical docs, and educational material.

- Prioritize precision over warmth.
- Avoid unsupported claims.
- Use established terms when available.
- Keep foreign terms only when the Indonesian equivalent is rare, ambiguous, or less useful in the field.
- Define terms on first use if the audience may not know them.


path: references/sources.md
content: # Sources

Use these references when the task requires Indonesian correctness, register judgment, or terminology choices.

## Official References

- EYD V: https://ejaan.kemdikbud.go.id/
  - Use for spelling, capitalization, word writing, punctuation, and loanword spelling.
  - Treat EYD V as the default authority for official/formal Indonesian writing.

- KBBI Daring: https://kbbi.kemdikbud.go.id/
  - Use for lemma checks, meanings, usage labels, and register labels.
  - Do not assume every KBBI entry is formal/baku in every context. Check labels such as `cak` for cakapan, `kas` for kasar, `hor` for hormat, and regional labels.

- KBBI Petunjuk Pemakaian: https://kbbi.kemendikdasmen.go.id/Content/Files/Petunjuk%20Pemakaian.PDF
  - Use for understanding KBBI labels, language variety, dialect, idiolect, and register.
  - Important editorial rule: informal/cakapan words can be valid Indonesian but still unsuitable for official writing.

- Pedoman Umum Pembentukan Istilah: https://badanbahasa.kemendikdasmen.go.id/resource/doc/files/Pedoman_Umum_Pembentukan_Istilah_PBN_0.pdf
  - Use for terminology choices.
  - Prefer terms that are precise, concise, have suitable connotation, sound natural, and follow Indonesian word-formation rules.

## Practical Editorial Position

Tutur should not turn every text into rigid textbook Indonesian. The goal is register control:

- Official text should be standard, clean, and restrained.
- Public/professional text should be clear, credible, and not bureaucratic.
- Casual text may use nonstandard forms when they match the target reader.
- Slang should be intentional, limited, and socially appropriate.

## Research Notes

KBBI distinguishes language variation by use and relationship between speakers. This matters for humanization because "natural" is not the same as "formal". A WhatsApp caption, public landing page, official letter, academic abstract, and sales DM need different choices.

The biggest Indonesian AI-writing problem is often not grammar. It is register mismatch: formal words in casual contexts, translated English phrasing, vague claims, stacked clauses, and copywriting hype that says little.


path: references/usage-patterns.md
content: # Usage Patterns

## Ordinary Output

For a plain rewrite request, return the rewritten Indonesian text directly. Add notes only when the user asks for review, when meaning changed, or when a register choice matters.

## Sample Tasks

- Humanize AI-sounding Indonesian.
- Convert stiff formal writing into clear professional Indonesian.
- Make casual copy sound natural without forcing slang.
- Clean official text while preserving EYD/KBBI-aligned diction.
- Rewrite sales copy so the benefit is concrete.
- Review whether a paragraph sounds translated from English.

## Register And Semantics

- Default: natural baku-santai, readable for public use without sounding bureaucratic.
- Resmi: complete sentences, standard punctuation, no slang, no inflated claims.
- Profesional: direct business Indonesian, no corporate padding.
- Gaul/santai: keep rhythm short, use slang lightly, avoid over-trying.
- Sales: lead with pain point or benefit, then proof or action.
- Academic/technical: keep terms precise and avoid unnecessary simplification.

## Review Checklist

- Are facts, names, numbers, dates, and claims preserved?
- Does the text still sound Indonesian rather than English in Indonesian words?
- Are repeated AI phrases removed?
- Is the register consistent with the audience?
- Are slang and regional words intentional?
- Does the rewrite add unsupported claims or proof?

## Output Patterns

- Rewrite only: output text.
- Review: issues first, then improved version.
- Multi-register: label each variant clearly.
- File edit: edit the file, then summarize material changes.



path: scripts/scan_ai_id.py
content: #!/usr/bin/env python3
"""Scan Indonesian text for common AI-sounding phrases.

This helper is intentionally simple. It surfaces likely tone problems so an
editor can review them; it does not decide whether a phrase is always wrong.
"""

from __future__ import annotations

import argparse
import json
import re
import sys
from collections import Counter
from pathlib import Path


PATTERNS = {
    "overblown_opener": [
        r"\bdi era digital yang terus berkembang\b",
        r"\bdalam lanskap\b",
        r"\bseiring dengan perkembangan\b",
        r"\bdi tengah pesatnya perkembangan\b",
        r"\bpada era modern ini\b",
    ],
    "vague_importance": [
        r"\bmemainkan peran penting\b",
        r"\bmenjadi kunci\b",
        r"\baspek krusial\b",
        r"\bsangat vital\b",
        r"\bmendorong transformasi\b",
        r"\bdampak signifikan\b",
    ],
    "marketing_mush": [
        r"\bsolusi inovatif\b",
        r"\bpengalaman yang mulus\b",
        r"\bsecara komprehensif\b",
        r"\bsecara optimal\b",
        r"\bmemberdayakan pengguna\b",
        r"\bmenghadirkan nilai\b",
        r"\bekosistem digital\b",
    ],
    "english_calque": [
        r"\bmenavigasi tantangan\b",
        r"\blanskap kompetitif\b",
        r"\bberesonansi dengan\b",
        r"\bmengorkestrasi\b",
        r"\bmengkurasi\b",
        r"\bmendorong keterlibatan\b",
        r"\bdapat ditindaklanjuti\b",
    ],
    "bureaucratic_padding": [
        r"\bdalam rangka\b",
        r"\bguna melakukan\b",
        r"\bmelaksanakan kegiatan\b",
        r"\bterkait dengan\b",
        r"\bsehubungan dengan hal tersebut\b",
        r"\bmelakukan optimalisasi\b",
        r"\bmelakukan pemantauan\b",
        r"\bmelakukan koordinasi\b",
    ],
    "formulaic_contrast": [
        r"\btidak hanya\b.*\btetapi juga\b",
        r"\bbukan sekadar\b.*\bmelainkan\b",
        r"\blebih dari sekadar\b",
    ],
    "weak_conclusion": [
        r"\bpada akhirnya\b",
        r"\bdengan demikian\b",
        r"\bsecara keseluruhan\b",
        r"\bhal ini menunjukkan bahwa\b",
    ],
}


def read_text(path: str | None) -> str:
    if path:
        return Path(path).read_text(encoding="utf-8")
    return sys.stdin.read()


def line_number(text: str, index: int) -> int:
    return text.count("\n", 0, index) + 1


def scan(text: str) -> dict:
    findings = []
    lower = text.lower()

    for category, patterns in PATTERNS.items():
        for pattern in patterns:
            for match in re.finditer(pattern, lower, flags=re.DOTALL):
                snippet = text[match.start() : match.end()]
                findings.append(
                    {
                        "category": category,
                        "line": line_number(text, match.start()),
                        "match": snippet,
                    }
                )

    words = re.findall(r"\b[\w'-]+\b", lower, flags=re.UNICODE)
    repeated = [
        {"word": word, "count": count}
        for word, count in Counter(words).most_common()
        if count >= 8 and len(word) > 4
    ][:20]

    return {
        "summary": {
            "findings": len(findings),
            "repeated_words": len(repeated),
        },
        "findings": findings,
        "repeated_words": repeated,
    }


def main() -> int:
    parser = argparse.ArgumentParser(
        description="Scan Indonesian text for common AI-sounding phrases."
    )
    parser.add_argument("path", nargs="?", help="Text file to scan. Reads stdin if omitted.")
    parser.add_argument("--pretty", action="store_true", help="Pretty-print JSON output.")
    args = parser.parse_args()

    result = scan(read_text(args.path))
    print(json.dumps(result, ensure_ascii=False, indent=2 if args.pretty else None))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())


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