From baf9b3813b2110b71a2336c70724908b0a2ea32d Mon Sep 17 00:00:00 2001 From: Camille Simon Date: Wed, 29 Jul 2026 09:38:59 -0700 Subject: [PATCH 1/3] Add write-prose --- .../.agents/skills/write-prose | 1 + .../.agents/skills/write-prose/SKILL.md | 84 ++++++++++ .../write-prose/references/audiences.md | 118 +++++++++++++ .../write-prose/references/standards.md | 143 ++++++++++++++++ .../write-prose/scripts/analyze_prose.py | 157 ++++++++++++++++++ .../skill-repos/gspencergoog/skills-lock.json | 11 ++ 6 files changed, 514 insertions(+) create mode 120000 packages/camera/camera_android_camerax/.agents/skills/write-prose create mode 100644 third_party/skill-repos/gspencergoog/.agents/skills/write-prose/SKILL.md create mode 100644 third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/audiences.md create mode 100644 third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/standards.md create mode 100755 third_party/skill-repos/gspencergoog/.agents/skills/write-prose/scripts/analyze_prose.py create mode 100644 third_party/skill-repos/gspencergoog/skills-lock.json diff --git a/packages/camera/camera_android_camerax/.agents/skills/write-prose b/packages/camera/camera_android_camerax/.agents/skills/write-prose new file mode 120000 index 00000000000..ab1fcc87330 --- /dev/null +++ b/packages/camera/camera_android_camerax/.agents/skills/write-prose @@ -0,0 +1 @@ +./write-prose \ No newline at end of file diff --git a/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/SKILL.md b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/SKILL.md new file mode 100644 index 00000000000..eaa8dbcc37f --- /dev/null +++ b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/SKILL.md @@ -0,0 +1,84 @@ +--- +name: write-prose +description: Master prose writing and orchestration skill for creating clear, plain, accessible, and natural human writing. Synthesizes ISO 24495-1:2023, W3C Cognitive Accessibility Guidance, Plain Writing Act, and Simplified Technical English (STE) standards. Use when writing, drafting, editing, or reviewing reports, PR descriptions, commit messages, API docstrings, READMEs, architecture documents, user guides, prompts, or general technical prose. +--- + +# Master Prose Writing & Orchestration (`write-prose`) + +> [!CAUTION] +> **MANDATORY LINGUISTIC AUDIT** +> Language models naturally default to pre-trained "AI-isms" (*delve, leverage, seamless, robust, pivotal, testament, not only... but also*). You MUST actively execute the Two-Pass Drafting Protocol below to audit and replace machine-generated fluff before producing final output. + +> [!IMPORTANT] +> **WORKSPACE HYGIENE & FILE LOCATION RULES** +> - **No Repo Pollution**: Never create temporary draft files or scratch markdown in the project repository root or source directories. +> - **Temporary Drafts**: Store intermediate drafts, multi-pass review files, or scratch notes in the conversation scratch directory: `/brain//scratch/`. +> - **Final Artifacts**: Write persistent, user-facing markdown reports or documents to the conversation artifacts directory: `/brain//`. + +This skill serves as the central source of truth for clear, plain, accessible, and natural human writing across all technical and non-technical documents. + +## Procedural Workflow + +### Step 1: Context & Audience Inference +Determine the target audience and document format: +1. **Pull Requests / Commits**: Engineering peers $\rightarrow$ Focus on "Why" over "How", factual tone, no fluff. +2. **API Documentation / Docstrings**: API consumers $\rightarrow$ Third-person singular verbs, concise summaries, clear parameter prose. +3. **User Guides / Tutorials**: End users $\rightarrow$ Direct second-person ("you"), short critical paths, explicit step-by-step instructions. +4. **Architecture / Design RFCs**: Team leads & stakeholders $\rightarrow$ Clear tradeoffs, decision-first layout, plain language. +5. **Prompts & System Instructions**: AI Agents / LLMs $\rightarrow$ Imperative tone, XML tags, positive directives, assume high baseline knowledge (name concepts without explaining them). + +> [!NOTE] +> If the target audience or document context is ambiguous, use `ask_question` to clarify before drafting. + +For detailed audience templates and tone matrices, see [references/audiences.md](references/audiences.md). + +--- + +### Mode A: Writing & Drafting New Prose + +#### Step 2: Sub-Skill Coordination +For specialized document types, delegate content gathering to domain skills while enforcing `write-prose` quality standards: +- **Pull Request Descriptions**: Refer to [`write-pr-description`](../write-pr-description/SKILL.md) for diff structure and testing steps. +- **Commit Messages**: Refer to [`commit-changes`](../commit-changes/SKILL.md) for conventional commit formatting. +- **Code & API Documentation**: Refer to [`code-documentation`](../code-documentation/SKILL.md) for docstring and tag conventions. +- **AI Prompts & Skill Instructions**: Refer to Section 7 in [`references/standards.md`](references/standards.md#7-prompt-design-standards-for-llm-audiences) for XML tagging, primacy placement, and token conservation. + +#### Step 3: Apply Plain Writing & Accessibility Standards +Before writing, consult [references/standards.md](references/standards.md) to apply core principles from: +- **ISO 24495-1:2023**: Ensure content is relevant, findable, understandable, and usable. +- **W3C Cognitive Accessibility (COGA)**: Use clear words, literal language, short text, separate steps, short critical paths, and no reliance on memory. +- **Plain Writing Act**: Ensure immediate first-reading clarity using active voice and short sentences (15–20 words max). +- **Simplified Technical English (STE / ASD-STE100)**: Use controlled vocabulary, explicit sequential steps, max 3 nouns per cluster, and warnings before actions. + +#### Step 4: Two-Pass Drafting & Anti-AI-ism Self-Correction +Execute this mandatory two-pass procedure before finalizing output: + +1. **Pass 1 (Content Draft)**: Draft the response focusing on technical accuracy, structure, and domain content. +2. **Pass 2 (Linguistic Inspection & Rewrite)**: + - Scan the draft line-by-line against the **Positive Replacement Pairs** in [references/standards.md](references/standards.md#61-positive-replacement-pairs-banned-words-mappings). + - Flag and replace any banned verbs (*delve, leverage, foster, cultivate, maximize, democratize, resonate, encompass, bridge, underscore*). + - Replace vague adjectives (*robust, seamless, pivotal, crucial, holistic, intuitive*) with **specific physical/technical behaviors** (e.g. replace *"robust error handling"* with *"retries failed HTTP requests up to 3 times"*). + - Eliminate copula substitutions (*"serves as"* $\rightarrow$ *"is"*), negative parallelism (*"not only... but also"*), and rule-of-three lists. +3. **Output**: Present only the polished, post-audit prose. + +--- + +### Mode B: Reviewing & Auditing Existing Prose + +When the user asks to review, audit, or critique an existing document, PR description, or prompt: + +1. **Run the Statistical Analyzer**: + Execute the analyzer script on the target file: + ```bash + python3 /usr/local/google/home/gspencer/.gemini/config/skills/write-prose/scripts/analyze_prose.py + ``` +2. **Evaluate Output Metrics**: + - Check total word count, sentence count, median sentence length, and paragraph stats. + - Note any sentences exceeding **25 words**, paragraphs exceeding **4 sentences**, or **banned AI words** returned by the script. +3. **Generate Audit Report Table**: + Output a clear feedback report detailing findings and concrete fixes: + + | Line / Location | Issue / Violation | Standard Violated | Suggested Plain Language Fix | + | :--- | :--- | :--- | :--- | + | Line 12 | *"serves as a robust framework"* | Anti-AI-ism / Copula Sub | *"is a framework that retries HTTP requests"* | + | Line 34 | Sentence length (42 words) | STE / Plain Language | Split into two sentences ($\le 20$ words each). | diff --git a/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/audiences.md b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/audiences.md new file mode 100644 index 00000000000..3cab47e9491 --- /dev/null +++ b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/audiences.md @@ -0,0 +1,118 @@ +# Audience & Voice Matrix (`audiences.md`) + +This guide provides concrete matrices and **one-shot reference examples** demonstrating how the same technical concept is adapted across 5 distinct audiences. + +--- + +## 1. Audience Matrix & Rule Adaptations + +| Audience | Primary Goal | Voice / Person | Verb & Tense Style | Structural Focus | +| :--- | :--- | :--- | :--- | :--- | +| **Peer Engineers** | PR descriptions, commit logs, code reviews | Factual / Impersonal | Past-tense for changes (*"Added"*, *"Fixed"*); Present for logic intent (*"Why"* over *"How"*). | Summary $\rightarrow$ Logic Changes $\rightarrow$ Impact $\rightarrow$ Testing Steps. | +| **API Consumers** | Library docs, docstrings, SDK references | Third-person neutral | 3rd-person singular present (*"Calculates..."*, *"Retries..."*); Booleans start with *"Whether..."*. | 1-Sentence Summary $\rightarrow$ Parameter Prose $\rightarrow$ Usage Code Sample. | +| **End Users / Devs** | Tutorials, user guides, setup docs | Direct second-person ("you") | Imperative action verbs (*"Open"*, *"Configure"*); 1 action per step. | Prerequisites $\rightarrow$ Numbered Steps $\rightarrow$ Expected Result. | +| **Leadership / RFCs** | System designs, RFCs, technical proposals | Objective / Analytical | Present tense; decision-first layout. | Executive Summary $\rightarrow$ Proposal $\rightarrow$ Trade-offs Table $\rightarrow$ Migration. | +| **AI Agents / LLMs** | System prompts, agent skills, tool directives | Imperative / Unambiguous | Direct imperative commands (*"Execute"*, *"Return"*); positive action directives. | Role Anchor $\rightarrow$ XML Delimiters $\rightarrow$ Guardrails $\rightarrow$ Examples. | + +--- + +## 2. One-Shot Reference Examples (Same Topic, 5 Audiences) + +**Scenario**: Adding exponential backoff retry logic to an HTTP network service client. + +### Example A: Peer Engineers (PR Description) + +```markdown +## Summary +Adds automatic HTTP retry logic with exponential backoff to `HttpClient` to prevent transient network dropouts from failing user requests. + +## Changes +* Wrapped `HttpClient.send()` in a retry loop using `ExponentialBackoff`. +* Added `maxRetries` (default: 3) and `initialDelayMs` (default: 200ms) parameters to `HttpClientConfig`. +* Retries only on HTTP 502, 503, 504, and socket timeout exceptions. + +## Testing +* Added unit tests in `test/http_client_test.dart` verifying backoff delays: 200ms, 400ms, 800ms. +* Verified that HTTP 4xx errors fail immediately without retrying. +``` + +--- + +### Example B: API Consumers (Docstrings / API Reference) + +```dart +/// Sends an HTTP request and retries transient failures using exponential backoff. +/// +/// Retries up to [HttpClientConfig.maxRetries] times when encountering HTTP 502, +/// 503, or 504 status codes, or network socket timeouts. Throws [HttpException] +/// if all retries fail or if a non-retriable error (e.g. 4xx) occurs. +/// +/// Usage: +/// ```dart +/// final response = await client.send(request); +/// ``` +Future send(HttpRequest request); +``` + +--- + +### Example C: End Users / Developers (User Guide / Setup Doc) + +```markdown +## Configuring Automatic Retries + +You can configure the client to retry failed requests automatically when temporary network errors occur. + +1. Open your project configuration file (`config.yaml`). +2. Add the `retry_policy` block to your network settings: + +```yaml +network: + max_retries: 3 + initial_delay_ms: 200 +``` + +3. Save the file and restart your application service. +``` + +--- + +### Example D: Leadership / RFCs (System Design / RFC) + +```markdown +# RFC: Network Client Resilience & Transient Failure Handling + +## Executive Summary +We propose introducing exponential backoff retries to the core HTTP client. This will reduce user-facing network error spikes by an estimated 80% during transient cloud gateway dropouts. + +## Proposed Design & Trade-offs + +| Option | Implementation Cost | Latency Impact | Resilience | +| :--- | :--- | :--- | :--- | +| **1. No Retries (Current)** | Zero | 0ms added | Poor (Errors surface immediately) | +| **2. Exponential Retries (Proposed)** | Low (2 days) | +200ms–1400ms on transient failures | High (Recovers from transient outages) | + +## Migration & Risk +This change is non-breaking. Default retry values (3 attempts, 200ms initial delay) apply automatically without configuration changes. +``` + +--- + +### Example E: AI Agents / LLMs (System Prompt Directive) + +```markdown + +You are an expert networking engineer assisting with HTTP client resilience. + + + +When configuring retry logic, enforce exponential backoff using these parameters: +1. Set initial delay to 200ms with a multiplier of 2.0. +2. Limit retries strictly to HTTP 502, 503, 504, and socket timeouts. +3. Fail non-retriable HTTP 4xx status codes immediately. + + + +Return client configuration as a YAML block formatted inside ```yaml code fences. + +``` diff --git a/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/standards.md b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/standards.md new file mode 100644 index 00000000000..225ece0563b --- /dev/null +++ b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/references/standards.md @@ -0,0 +1,143 @@ +# Foundational Writing Standards (`standards.md`) + +This document synthesizes international writing standards (ISO 24495-1:2023, W3C Cognitive Accessibility, Plain Writing Act, Simplified Technical English) and natural writing controls to eliminate "AI-isms" and structural fluff. + +--- + +## 1. Quantitative Targets & Measurement Limits + +When writing or auditing text, aim for these quantitative thresholds: + +| Metric | Target / Limit | Rule | +| :--- | :--- | :--- | +| **Sentence Length (Procedural)** | $\le \mathbf{20\text{ words}}$ | Procedural steps must be short and direct (1 action per step). | +| **Sentence Length (Descriptive)**| $\le \mathbf{25\text{ words}}$ (15–20 average) | Flag and split any sentence over 25 words. | +| **Paragraph Length** | $\le \mathbf{4\text{ sentences}}$ (40–80 words) | Keep paragraphs focused on a single concept. | +| **Word Length** | $\le \mathbf{5\text{ characters}}$ median | Prefer simple words (*use* vs *utilize*, *check* vs *investigate*). | +| **Noun Clusters** | $\le \mathbf{3\text{ consecutive nouns}}$ | Avoid heavy noun stacks (e.g., write *"system for monitoring engine temperature"*, not *"engine temperature monitoring system"*). | + +Run `python3 /usr/local/google/home/gspencer/.gemini/config/skills/write-prose/scripts/analyze_prose.py ` to measure these stats automatically. + +--- + +## 2. Technical Markup & Markdown Link Rules + +To ensure technical clarity and prevent UI rendering breakage: +- **Code Symbols & Paths**: Enclose variable names, function names, CLI flags, and file paths in backticks: `` `my_function()` ``, `` `--verbose` ``, `` `src/main.ts` ``. +- **Code Blocks**: Always specify a language specifier for code blocks (`python`, `bash`, `json`, `markdown`). +- **Markdown Links (CRITICAL RULE)**: **NEVER** wrap Markdown link text in backticks. Wrapping a link in backticks breaks clickable formatting in IDEs and web views: + - ❌ **Incorrect**: ``[`main.ts`](file:///path/to/main.ts)`` or ``[`MyClass`](file:///path/to/main.ts#L10)`` + - ✅ **Correct**: `[main.ts](file:///path/to/main.ts)` or `[MyClass](file:///path/to/main.ts#L10)` + +--- + +## 3. ISO 24495-1:2023 (Plain Language Principles) + +Content must satisfy four core principles: +1. **Relevant**: Include only information the reader needs to achieve their goal. Eliminate filler and background tangents. +2. **Findable**: Structure document with descriptive, sentence-case headings (`## Header`), bulleted lists, and logical ordering so information is easily scannable. +3. **Understandable**: Use familiar words, short sentences (15–20 words on average), and simple sentence structures. +4. **Usable**: Provide clear, actionable instructions that enable the reader to perform their task without re-reading. + +--- + +## 4. W3C Cognitive Accessibility Guidance (COGA) + +To support cognitive accessibility and reduce mental load: +- **Clear & Literal Language**: Avoid metaphors, idioms, hyperbole, and abstract expressions. +- **Short Text & Paragraphs**: Limit paragraphs to 2–4 sentences focusing on a single idea. +- **Separate Steps**: Present multi-step instructions as numbered lists (`1.`, `2.`, `3.`) with one action per step. +- **Short Critical Paths**: Put the most important action or decision first. +- **No Memory Reliance**: Do not expect the reader to remember details from earlier sections; repeat critical parameters or link directly. + +--- + +## 5. Plain Writing Act & STE Standards + +- **Active Voice**: Make the actor the subject of the sentence (*"The server rejected the request"* instead of *"The request was rejected by the server"*). +- **Direct Address**: Use second-person pronouns ("you", "your") for user-facing instructions and guides. +- **Subject-Verb Proximity**: Keep subjects and their main verbs close together. +- **No Nominalizations**: Do not turn verbs into heavy nouns (use *"decide"* instead of *"make a decision"*). +- **Sequential Safety/Context**: Always state prerequisites, warnings, or conditions *before* the action verb. + +--- + +## 6. Natural Writing & Anti-AI-ism Controls + +### 6.1 Positive Replacement Pairs (Banned Words Mappings) + +Do NOT use high-probability AI filler words. Replace them using this direct mapping table during **Pass 2** self-correction: + +| Banned Word / Phrase | Recommended Direct Alternative(s) | +| :--- | :--- | +| **leverage** | *use*, *apply*, *build on* | +| **delve / delve into** | *examine*, *study*, *check*, *look at* | +| **foster / cultivate** | *support*, *encourage*, *build*, *develop* | +| **utilize** | *use* | +| **seamless / seamlessly** | *without extra setup*, *automatically*, *directly* | +| **robust** | State exact behavior: *handles errors*, *retries up to 3 times* | +| **intuitive** | State exact design: *uses standard defaults*, *requires no configuration* | +| **pivotal / crucial** | State facts directly: *important*, *key*, or state why it matters | +| **tapestry / landscape / realm** | *context*, *area*, *environment*, *system* | +| **testament to / serves as** | *is*, *shows*, *demonstrates* | +| **holistic / comprehensive** | *complete*, *full*, or list the specific parts | +| **in order to** | *to* | +| **at this point in time** | *now*, *currently* | + +--- + +### 6.2 Side-by-Side Contrastive Examples + +Use these contrastive pairs to calibrate self-correction during drafting: + +| ❌ Machine-Generated Fluff (AI-ism) | ✅ Human Plain Language | +| :--- | :--- | +| *"The library serves as a robust framework for leveraging telemetry data."* | *"The library collects telemetry data and retries on failure."* | +| *"This pull request marks a pivotal moment in streamlining database queries..."* | *"This pull request reduces database query latency by indexing the user ID column."* | +| *"The team continues to foster innovation while seamlessly navigating challenges."* | *"The team resolved 5 open issues and added unit test coverage."* | +| *"Nestled in the architecture, this module acts as a cornerstone..."* | *"This module handles authentication."* | +| *"It is not only a caching layer, but also a security boundary."* | *"It caches data and enforces access controls."* | +| *"Despite initial hurdles, the pipeline continues to thrive..."* | *"The build pipeline passed all checks."* | +| *"Certainly! I would be happy to delve into this robust solution for you."* | *"Here is the design breakdown."* | + +--- + +### 6.3 Converting Vague Adjectives into Concrete Technical Behaviors + +Never use vague praise adjectives (*robust, seamless, intuitive, frictionless, scalable*). Replace them with the actual technical mechanism: + +- ❌ *"Implements robust error handling."* + $\rightarrow$ ✅ *"Catches `NetworkException` and retries failed requests up to 3 times before timing out."* +- ❌ *"Provides a seamless user experience."* + $\rightarrow$ ✅ *"Saves user settings automatically without requiring a manual save button."* +- ❌ *"Highly scalable architecture."* + $\rightarrow$ ✅ *"Distributes requests across worker isolates using a round-robin pool."* + +--- + +## 7. Prompt Design Standards for LLM Audiences + +When writing system prompts, agent skills, tool guidelines, or automated prompts: + +1. **Token Conservation Principles**: + - **Treat Context as a Finite Resource**: Every token consumed in a prompt reduces attention efficiency and limits remaining history/code space. + - **Eliminate Polite & Conversational Filler**: Omit phrases like *"Please make sure to..."*, *"It would be appreciated if you..."*, *"As an AI assistant, you should..."*. Use direct imperative verbs (*"Extract parameters..."*, *"Return JSON format..."*). + - **Use High-Density Delimiters**: Use brief XML tags (``, ``) or Markdown bullet points instead of prose paragraphs to delineate sections. + - **Modular Depth & Context Layering**: Where supported (such as agent skills), use progressive disclosure by separating core instructions from deep reference files (`references/`). For standalone prompts where multi-file loading is not feasible, keep the primary directive concise at the top and relegate large reference data or schemas to distinct, clearly delimited sections at the end of the prompt. + +2. **Assume High Baseline Knowledge**: + - **Do NOT explain basic concepts**: Models already have extensive pre-trained knowledge about ASTs, REST APIs, Conventional Commits, or ISO standards. Name the concept directly without writing explanatory paragraphs. + - **Only explain specific constraints**: Elaborate only when defining a non-standard rule, custom domain schema, or project-specific edge case. + +3. **Semantic Delimiters**: + - Use XML tags (``, ``, ``, ``) or Markdown headers (`#`) to bound prompt components. Delimiters help the model's attention mechanism distinguish instructions from user input. + +4. **Primacy & Recency Placement**: + - Place role definition, primary objective, and core callouts at the **very top** (`> [!CAUTION]`). + - Place critical output formatting constraints at the **very bottom** (immediately before the response threshold). + +5. **Positive Action Directives**: + - Frame instructions as direct, positive actions (*"Format the output as a 3-column table with headers X, Y, Z"*) rather than vague negative prohibitions (*"Don't generate bad tables"*). + +6. **Few-Shot Concrete Examples**: + - Provide 1–2 exact `Input -> Output` pairs for complex output formats. Examples communicate format requirements more effectively than token-heavy prose explanations. diff --git a/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/scripts/analyze_prose.py b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/scripts/analyze_prose.py new file mode 100755 index 00000000000..1579c97b6dd --- /dev/null +++ b/third_party/skill-repos/gspencergoog/.agents/skills/write-prose/scripts/analyze_prose.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +""" +analyze_prose.py - Statistical analysis and anti-AI-ism compliance scanner for text/markdown documents. +""" + +import sys +import os +import re +import json +import statistics + +BANNED_WORDS = [ + "delve", "leverage", "foster", "cultivate", "maximize", "democratize", + "resonate", "encompass", "bridge", "underscore", "utilize", "seamless", + "seamlessly", "robust", "pivotal", "crucial", "vibrant", "intricate", + "nuanced", "unwavering", "indelible", "uncharted", "transformative", + "breathtaking", "nestled", "dynamic", "comprehensive", "intuitive", + "holistic", "frictionless", "scalable", "synergistic", "tapestry", + "landscape", "realm", "testament", "interplay", "synergy", "cornerstone" +] + +def split_into_sentences(text): + """Splits text into sentences while ignoring common abbreviations.""" + # Simple regex sentence splitting on .!? followed by whitespace + raw_sentences = re.split(r'(?<=[.!?])\s+', text) + cleaned = [] + for s in raw_sentences: + s_strip = s.strip() + # Ignore markdown headers, bullet points markers, or code fences + if s_strip and not s_strip.startswith('#') and not s_strip.startswith('```') and not s_strip.startswith('|'): + cleaned.append(s_strip) + return cleaned + +def analyze_prose(file_path): + if not os.path.exists(file_path): + return {"error": f"File not found: {file_path}"} + + with open(file_path, 'r', encoding='utf-8') as f: + lines = f.readlines() + + full_text = "".join(lines) + + # Extract plain text paragraphs (ignoring headers, tables, code blocks) + in_code_block = False + paragraphs = [] + current_para = [] + + for line in lines: + line_str = line.strip() + if line_str.startswith('```'): + in_code_block = not in_code_block + continue + if in_code_block: + continue + if not line_str or line_str.startswith('#') or line_str.startswith('|'): + if current_para: + paragraphs.append("\n".join(current_para)) + current_para = [] + continue + current_para.append(line_str) + if current_para: + paragraphs.append("\n".join(current_para)) + + # All words in body + words = re.findall(r'\b[a-zA-Z0-9_\'-]+\b', full_text) + total_words = len(words) + + # Word lengths + word_lengths = [len(w) for w in words] if words else [0] + median_word_length = statistics.median(word_lengths) if word_lengths else 0 + + # Sentences analysis + sentences = split_into_sentences(full_text) + total_sentences = len(sentences) + + sentence_word_counts = [] + long_sentences = [] + + for idx, s in enumerate(sentences, 1): + s_words = re.findall(r'\b[a-zA-Z0-9_\'-]+\b', s) + w_count = len(s_words) + if w_count > 0: + sentence_word_counts.append(w_count) + if w_count > 25: + long_sentences.append({ + "index": idx, + "word_count": w_count, + "text": s[:100] + ("..." if len(s) > 100 else "") + }) + + median_words_per_sentence = statistics.median(sentence_word_counts) if sentence_word_counts else 0 + + # Paragraph analysis + para_sentence_counts = [] + para_word_counts = [] + long_paragraphs = [] + + for idx, p in enumerate(paragraphs, 1): + p_sentences = split_into_sentences(p) + p_words = re.findall(r'\b[a-zA-Z0-9_\'-]+\b', p) + num_s = len(p_sentences) + num_w = len(p_words) + + para_sentence_counts.append(num_s) + para_word_counts.append(num_w) + + if num_s > 4: + long_paragraphs.append({ + "paragraph_index": idx, + "sentence_count": num_s, + "snippet": p[:80] + ("..." if len(p) > 80 else "") + }) + + median_sentences_per_para = statistics.median(para_sentence_counts) if para_sentence_counts else 0 + median_words_per_para = statistics.median(para_word_counts) if para_word_counts else 0 + + # Banned words scanning with line numbers + banned_matches = [] + for line_idx, line in enumerate(lines, 1): + # Skip code blocks + if line.strip().startswith('```') or line.strip().startswith('|'): + continue + line_words = re.findall(r'\b[a-zA-Z0-9_\'-]+\b', line.lower()) + for bw in BANNED_WORDS: + if bw in line_words: + banned_matches.append({ + "line": line_idx, + "banned_word": bw, + "line_snippet": line.strip()[:90] + }) + + return { + "file_path": file_path, + "summary": { + "total_words": total_words, + "total_sentences": total_sentences, + "total_paragraphs": len(paragraphs), + "median_word_length_chars": round(median_word_length, 1), + "median_words_per_sentence": round(median_words_per_sentence, 1), + "median_sentences_per_paragraph": round(median_sentences_per_para, 1), + "median_words_per_paragraph": round(median_words_per_para, 1) + }, + "violations": { + "banned_ai_words_found": banned_matches, + "sentences_exceeding_25_words": long_sentences, + "paragraphs_exceeding_4_sentences": long_paragraphs + } + } + +if __name__ == "__main__": + if len(sys.argv) < 2: + print(json.dumps({"error": "Usage: analyze_prose.py "})) + sys.exit(1) + + target_file = sys.argv[1] + result = analyze_prose(target_file) + print(json.dumps(result, indent=2)) diff --git a/third_party/skill-repos/gspencergoog/skills-lock.json b/third_party/skill-repos/gspencergoog/skills-lock.json new file mode 100644 index 00000000000..1c36fffe6fb --- /dev/null +++ b/third_party/skill-repos/gspencergoog/skills-lock.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "skills": { + "write-prose": { + "source": "gspencergoog/skills", + "sourceType": "github", + "skillPath": "skills/write-prose/SKILL.md", + "computedHash": "266b4bdb6e03459b7a1990e34174f843dfcdea959d872122ba424e1806e7a0a4" + } + } +} From 85ae103b503b46b4222a149e3b1dfa009305446c Mon Sep 17 00:00:00 2001 From: Camille Simon Date: Wed, 29 Jul 2026 09:43:11 -0700 Subject: [PATCH 2/3] correct symlink --- .../camera/camera_android_camerax/.agents/skills/write-prose | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_android_camerax/.agents/skills/write-prose b/packages/camera/camera_android_camerax/.agents/skills/write-prose index ab1fcc87330..2b6189d3c2d 120000 --- a/packages/camera/camera_android_camerax/.agents/skills/write-prose +++ b/packages/camera/camera_android_camerax/.agents/skills/write-prose @@ -1 +1 @@ -./write-prose \ No newline at end of file +../../../../third_party/skill-repos/gspencergoog/.agents/skills \ No newline at end of file From 13e992508f2bcc9f1346814d0d51f8a94378bbc7 Mon Sep 17 00:00:00 2001 From: Camille Simon Date: Wed, 29 Jul 2026 09:50:06 -0700 Subject: [PATCH 3/3] correct symlink --- .../camera/camera_android_camerax/.agents/skills/write-prose | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_android_camerax/.agents/skills/write-prose b/packages/camera/camera_android_camerax/.agents/skills/write-prose index 2b6189d3c2d..d40b5fb2dcf 120000 --- a/packages/camera/camera_android_camerax/.agents/skills/write-prose +++ b/packages/camera/camera_android_camerax/.agents/skills/write-prose @@ -1 +1 @@ -../../../../third_party/skill-repos/gspencergoog/.agents/skills \ No newline at end of file +../../../../../third_party/skill-repos/gspencergoog/.agents/skills/write-prose \ No newline at end of file