ios-docc-writer
Skill0 starsChanged 23 days agoMITView on GitHub
Researches any flow, module, or kit in an iOS codebase and generates a DocC catalog article for it. Works with any iOS project architecture (SPM, CocoaPods, MVVM, VIPER, Clean, etc.). Invoke with /ios-docc-writer or when the user asks to "create a docc for X", "write DocC documentation for X", or "document the X flow/module/kit".
In this repository10 other files it gives its agents.
- agentic-auditSkill
- analyze-buildSkill
- claude-code-assessorSkill
- maestro-flow-writerSkill
- mindful-acceptanceSkill
- pr-diff-mermaidSkill
- pr-html-reportSkill
- pr-to-automation-planSkill
- session-retroSkill
- wwdc-adoption-advisorSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 23
Ask it to report:
- Very specific: line 104
Check (via Bash ls or Read) whether LANDING_PAGE already exists.
- Distinctive: line 133
After approval, write both files using the templates below.
- Distinctive: line 137
Only create if it does not already exist.
- Distinctive: line 257
No placeholder text: Every table cell, every code snippet, every section must come from actual research.
- Distinctive: line 262
Compilable Swift snippets: Every code block must use real types.
- Distinctive: line 264
Adapted structure: If the flow has no factory layer, omit that section.
- Distinctive: line 266
ASCII diagrams must match package boundaries: If two types live in different SPM targets, the diagram boundary must reflect that.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You generate DocC documentation for iOS codebases. Given a flow, module, or kit name in args,
you research the codebase and produce a complete DocC catalog article viewable in Xcode's
Documentation viewer.
You make no assumptions about architecture, DI framework, or module system — you discover them.
Phase 1 — Parallel Research (launch both subagents simultaneously)
Spawn two subagents in a single message so they run in parallel:
Subagent A: Project Analyzer
Prompt it to discover the project's structure. It must NOT modify any files.
Ask it to report:
- Module system — SPM (
Package.swiftfiles), CocoaPods (Podfile), or plain Xcode targets. For SPM: list every target name and itspath(from allPackage.swiftfiles found under the working directory, excluding.build/directories). - Existing
.docccatalogs — find every.doccdirectory in the project (excluding.build/). For each: the path, whether it has a root landing page (.mdmatching the target name), and what articles already exist. - Architecture pattern — infer from file/type naming:
- Orchestration: broker, coordinator, manager, interactor, use-case, service, view-model
- Dependency injection: Swinject assembly, Factory macro, manual init, environment values, service locator
- Reactive: Combine publishers, async/await, delegation, NotificationCenter, RxSwift
- Navigation: Coordinator, Router, NavigationStack, UINavigationController
- Naming conventions — how are public protocols named vs implementations? (e.g.
FooManagingprotocol +FooManagerconcrete, orFooInterface+Foo, orFooProtocol+FooImpl) - Testing setup — XCTest, Swift Testing, or both? Where do test targets live?
Subagent B: Flow Researcher
Prompt it with the user's request from args. It must NOT modify any files.
Ask it to report:
- Entry-point type — find the type named in
args. Report: file path, line number, type kind (class / struct / enum / protocol / actor), access level, and every method/property signature. - Full call chain — trace every type the entry point delegates to, down to the consumer-facing
public API. For each hop:
- Type name, file path, line number
- How it is obtained (DI resolve,
sharedsingleton,init, factory call,@LazyInject, etc.) - Key method(s) called across the hop
- Selection/factory layer — if any factory, builder, or
make(for:)function selects between implementations, list every condition → implementation mapping with exact match values. - All concrete implementations — for each implementation of the key protocol in the chain:
- What it does differently from siblings
- Any input → output mapping (e.g. config value → enabled features, role → permission set)
- Any reactive subscriptions it sets up (publisher name, filter conditions, loop-prevention)
- The consumer-facing public API — the type that callers outside the owning/orchestrating
layer use. Report every public method, property, and publisher with:
- Access modifier + signature
- Thread-safety contract (lock type, actor isolation, or DispatchQueue)
- Behaviour when called before the system is configured (default state, guard pattern)
- Consumer call sites — find at least 3 concrete usages across different files. For each:
- File path + line number
- The exact pattern used (synchronous check, publisher subscription, both combined with another system such as feature flags)
- Lifecycle hooks — if the entry-point participates in an app/module lifecycle (init, configure, purge, deinit, logout), list every hook and its effect.
- Reactive change propagation — how does a mid-session state change (e.g. settings change, logs out, switches account) flow from origin to the UI? Trace the full publisher / delegation chain including any loop-prevention.
Phase 2 — Synthesise and determine catalog path
Once both subagents return, combine their outputs:
- Identify the SPM target (or Xcode framework target) that owns the consumer-facing public API found by Subagent B.
- Using the target list from Subagent A, find that target's source path.
- Set:
CATALOG_DIR=<target-source-path>/<TargetName>.doccLANDING_PAGE=<CATALOG_DIR>/<TargetName>.mdARTICLE_PATH=<CATALOG_DIR>/Articles/<ArticleName>.mdwhere<ArticleName>is PascalCase derived fromargs(e.g. "auth token refresh flow" →AuthTokenRefreshFlow).
- Check (via Bash
lsor Read) whetherLANDING_PAGEalready exists. If it does, skip creating it and only write the article.
Phase 3 — Approval gate
Present to the user — wait for explicit approval before writing any file:
Files to create:
1. <CATALOG_DIR>/<TargetName>.md (landing page — or "skipped, already exists")
2. <CATALOG_DIR>/Articles/<ArticleName>.md
Article sections:
• Overview — what the system does and its key module/layer boundary
• <Entry-point type> — role, lifecycle table, key invocation patterns
• <Factory/Selection layer> — condition → implementation table
• <Each implementation> — input→output table, reactive setup, loop-prevention
• <Consumer-facing API> — method/property table with thread-safety + not-yet-ready behaviour
• Consumer Patterns — 4 code examples (sync check, publisher subscription, combined check, UI wiring)
• Full Event Sequence — ASCII trace from trigger to UI effect
• Adding a New <Feature/Key/Entry> — numbered checklistPhase 4 — Write files
After approval, write both files using the templates below.
Landing page (<TargetName>.md)
Only create if it does not already exist.
# ``<TargetName>``
<One sentence from the target's README, top-level comment, or inferred from Subagent A.>
## Overview
<2-3 sentences: what the module/kit provides, where it sits in the architecture.>
## Topics
### Articles
- <doc:<ArticleName>>
### <Logical group — e.g. "Essentials", "Core Types", "Observing State Changes">
- ``<PublicType>``
- ``<PublicType>``
### <Another logical group>
- ``<PublicType>``Article (<ArticleName>.md)
Fill every section from the research. Do not leave any placeholder text.
# <Human-readable title>
<One sentence: what this article explains.>
## Overview
<3-4 paragraphs:>
- What the system does and why it exists
- The key architectural boundary (which layer writes state vs which layer reads it)
- ASCII layer diagram showing the full chain from entry point to consumer
## <Entry-Point Type Name>
<Role in the system.>
<Lifecycle table if applicable:>
| Lifecycle call | Effect |
|---|---|
| ... | ... |
<Explanation of any parameter/flag that significantly changes behaviour.>
<Code example: the two most important invocation patterns.>
## <Factory / Selection Layer> (omit section if there is no factory)
<How implementations are selected.>
| <Condition> | <Implementation> |
|---|---|
| ... | ... |
## <Implementation Name> (one H3 per concrete implementation)
<What this implementation does and how it differs from siblings.>
<Input → output table if applicable (e.g. role → permissions).>
<Reactive subscription setup and any loop-prevention.>
## <Consumer-Facing API>
<Role: who writes/configures it and who reads from it.>
| API | Caller | Purpose |
|---|---|---|
| ... | ... | ... |
<Thread-safety contract.>
<Note on behaviour before the system is configured, if the API has a "not yet ready" state.>
## Consumer Patterns
### <Pattern 1: Synchronous check>
```swift
// concrete example from call sites found by Subagent B<Pattern 2: Reactive subscription>
// concrete example<Pattern 3: Combined with a second system>
// e.g. feature flag + entitlement check, or role check + permission gate<Pattern 4: UI-layer wiring>
// SwiftUI modifier, UIKit container view, or equivalentFull Event Sequence
<ASCII trace from the user-facing trigger to the final UI effect.
Cover both the launch path and the mid-session change path if they differ.>
Adding a New <Feature / Key / Permission / Entry>
- <Where to add the new case/type>
- <Where to update the mapping/logic>
<Where to add the check at call sites>- <What tests to write and why the static/pure function makes this testable>
---
## Quality Rules
- **No placeholder text.** Every table cell, every code snippet, every section must come from
actual research. If Subagent B could not find 3 consumer call sites, use what was found and
note the gap explicitly.
- **Accurate types and strings.** Plan descriptions, key raw values, publisher names — copy the
exact literals from source files. Do not paraphrase.
- **Compilable Swift snippets.** Every code block must use real types. Adapt from the actual call
sites, not from memory or imagination.
- **Adapted structure.** If the flow has no factory layer, omit that section. If there are 5
implementations instead of 3, include all 5. Follow the evidence, not the template rigidly.
- **ASCII diagrams must match package boundaries.** If two types live in different SPM targets,
the diagram boundary must reflect that.
- **No emoji.** DocC renders in Xcode — keep it professional.
- **No trailing summary.** End the article after the last section.
---
## After writing
Tell the user:
> Build documentation in Xcode: **Product → Build Documentation** (⌃⇧⌘D), then navigate to
> `<TargetName>` in the Documentation viewer to see the rendered article.Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

