Proto Documentation Skill
Generate and maintain Obsidian-compatible markdown documentation for protobuf schemas.
Quick Reference
Generate Docs
# Via Docker (recommended) make docs-docker-generate # Local (requires Clojure) make docs-generate
Run Tests
make docs-docker-test
Search Schema
# Via babashka script bb docs/.protodoc/scripts/proto-search.clj "query" docs/.protodoc/proto-db.edn
Directory Structure
docs/ # Obsidian vault (output) ├── .protodoc/ # Implementation (hidden in Obsidian) │ ├── proto-db.edn # EDN database (git committed) │ ├── scripts/ # Babashka scripts │ │ ├── proto-search.clj # Search command │ │ ├── proto-coverage.clj # Coverage report │ │ ├── doc-next.clj # Next undocumented message │ │ ├── proto-lint.clj # Documentation linting │ │ └── patch-lint.clj # Batch lint fixes │ └── tools/ # Clojure tooling │ ├── src/protodoc/ # Core modules │ ├── test/protodoc/ # Tests │ ├── resources/ # Selmer templates │ └── deps.edn # Dependencies ├── proto/ # Message documentation │ ├── cmd.*.md # Command messages │ └── ser.*.md # State/data messages ├── enums/ # Enum documentation └── index.md # Schema index
Workflow: After Proto Changes
- •
Regenerate bindings (if proto files changed):
bashmake generate
- •
Regenerate docs:
bashmake docs-docker-generate
- •
Check diff for new fields/messages:
bashgit diff docs/proto/
- •
Add descriptions to new fields in the markdown files
- •
Commit changes:
bashgit add -A && git commit -m "docs: Update proto documentation"
Adding Field Descriptions
User content survives regeneration. Edit markdown directly:
Message Description
## Description Your description here. This survives regeneration.
Field Notes
## Field Notes ### field_name (#1) Your field description here. #### Metadata - **Semantic Type:** :normalized - **Unit:** % - **Precision:** 2
Interaction Metadata
## Interaction - **Category:** :actuator - **UI Pattern:** :slider - **Feedback:** :fire-and-forget ### Purpose What this message is used for. ### Related Commands - [[proto/cmd.Other.Command]]
Database Schema (proto-db.edn)
{:messages {"cmd.DayCamera.SetIris"
{:id "cmd.DayCamera.SetIris"
:name "SetIris"
:package "cmd.DayCamera"
:source "jon_shared_cmd_day_camera.proto"
:description "User docs (preserved)"
:fields [{:number 1
:name "value"
:type :double
:constraints {:gte 0 :lte 1}}]}}
:enums {"ser.JonGuiDataClientType" {...}}
:search-index {"iris" ["cmd.DayCamera.SetIris"] ...}}
Constraint Types
The parser supports these buf.validate constraints:
| Type | Constraints |
|---|---|
| Numeric | gt, gte, lt, lte, example |
| String | minLen, maxLen, pattern, in, email |
| Bytes | minLen, maxLen |
| Enum | definedOnly, notIn |
| Repeated | minItems |
| General | required |
Adding New Constraints
If you see an error like:
No method in multimethod 'parse-constraint' for dispatch value: :type/constraint
- •Add to
constraint-registryinparse.clj - •Add handler:
(defmethod parse-constraint :type/constraint [_ _ v] {...}) - •Update schema in
schema.clj - •Update
format-constraintsinrender.clj
Interaction Metadata
Categories
:sensor :actuator :settings :status :lifecycle :diagnostic
UI Patterns
- •Atomic:
:toggle:action-button:slider:stepper:indicator:enum-picker - •Molecular:
:slider-with-steppers:press-accelerating - •Composite:
:slider-with-presets:directional-mover:tabbed-config
Semantic Types
:normalized :angle :percentage :coordinate-geo :temperature :voltage :current :power :distance :duration :count :timestamp :enum-label :raw
Troubleshooting
Docker Image Missing
make docs-docker-build
Parse Error
Check the error message for the constraint type, then add support in parse.clj.
User Content Lost
User content is extracted from ## Description, ## Field Notes, and ## Interaction sections. Ensure these headers exist and are properly formatted.
Regeneration Shows No Changes
The descriptor-set.json may not have been updated. Run:
make generate # Regenerate all bindings including JSON descriptors make docs-docker-generate
Data Flow
proto/*.proto
→ make generate
→ output/json-descriptors/descriptor-set.json
→ make docs-docker-generate
→ docs/.protodoc/proto-db.edn + docs/proto/*.md
Roundtrip preservation:
descriptor-set.json → parse.clj → extract.clj → proto-db.edn → render.clj → docs/*.md
↑ │
└──────── user edits ──────────┘