Agent-almanac annotate-source-files
git clone https://github.com/pjt222/agent-almanac
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/caveman-ultra/skills/annotate-source-files" ~/.claude/skills/pjt222-agent-almanac-annotate-source-files-46bd30 && rm -rf "$T"
i18n/caveman-ultra/skills/annotate-source-files/SKILL.mdAnnotate Source Files
Add PUT workflow annotations → putior extracts structured workflow data + generates Mermaid diagrams.
Use When
- After
+ annotation plananalyze-codebase-workflow - Add workflow docs new/existing src
- Enrich auto-detected w/ manual labels + connections
- Doc data pipelines, ETL, multi-step computations
In
- Required: Src files to annotate
- Required: Annotation plan or workflow steps knowledge
- Optional: Style — single-line or multiline (default: single-line)
- Optional: Use
skeletons? (default: yes)put_generate()
Do
Step 1: Determine Comment Prefix
Each lang has specific prefix.
get_comment_prefix() → correct one.
library(putior) # Common prefixes get_comment_prefix("R") # "#" get_comment_prefix("py") # "#" get_comment_prefix("sql") # "--" get_comment_prefix("js") # "//" get_comment_prefix("ts") # "//" get_comment_prefix("go") # "//" get_comment_prefix("rs") # "//" get_comment_prefix("m") # "%" get_comment_prefix("lua") # "--"
→ String like
"#", "--", "//", or "%".
Line + block comments: putior detects annotations in both line comments (
,//,#) + C-style block comments (--,/* */). JS/TS both/** */+//scanned. Python triple-quote strings (/* */) not detected — use''' '''for Python.#
If err: Ext not recognized → lang may not be supported. Check
get_supported_extensions(). Unsupported langs → use # conventional default.
Step 2: Generate Skeletons
put_generate() → annotation templates based on auto-detected I/O.
# Print suggestions to console put_generate("./src/etl/") # Single-line style (default) put_generate("./src/etl/", style = "single") # Multiline style for complex annotations put_generate("./src/etl/", style = "multiline") # Copy to clipboard for pasting put_generate("./src/etl/", output = "clipboard")
Example out for R file:
# put id:'extract_data', label:'Extract Customer Data', input:'customers.csv', output:'raw_data.internal'
Example out for SQL:
-- put id:'load_data', label:'Load Customer Table', output:'customers'
→ 1+ annotation comment lines per file, pre-filled w/ detected fn names + I/O.
If err: No suggestions → file may not have recognizable I/O patterns. Write annotations manually.
Step 3: Refine Annotations
Edit generated skeletons → accurate labels, connections, metadata.
Annotation syntax:
<prefix> put id:'unique_id', label:'Human Readable Label', input:'file1.csv, file2.rds', output:'result.parquet, summary.internal'
Fields:
(required): Unique ID, for node connectionsid
(required): Human-readable desc shown diagramlabel
: Comma-separated insinput
: Comma-separated outsoutput
ext: Marks in-memory vars (not persisted between scripts).internal
: Mermaid shape + class styling. Values:node_type
— stadium shape"input"
data srcs + config([...])
— subroutine shape"output"
generated artifacts[[...]]
— rectangle"process"
processing steps (default)[...]
— diamond"decision"
conditional logic{...}
/"start"
— stadium shape"end"
entry/terminal([...])
Example w/
node_type:
# put id:'config', label:'Load Config', node_type:'input', output:'config.internal' # put id:'transform', label:'Apply Rules', node_type:'process', input:'config.internal', output:'result.rds' # put id:'report', label:'Generate Report', node_type:'output', input:'result.rds'
Multiline syntax (complex):
# put id:'complex_step', \ # label:'Multi-line Label', \ # input:'data.csv, config.yaml', \ # output:'result.parquet'
Block comment syntax (
//-prefix langs only: JS, TS, Go, Rust, C, C++, Java, etc.):
Langs w/
// line comments also support PUT in /* */ + /** */ blocks. Use * put as line prefix inside block body:
/* put id:'init', label:'Initialize Config', output:'config.internal' */ /** * put id:'process', \ * label:'Process Records', \ * input:'config.internal, records.json', \ * output:'results.json' */ function processRecords(config, records) { // ... }
JSDoc annotations useful documenting workflow + API docs:
/** * Transform raw sensor data into normalized readings. * put id:'normalize', label:'Normalize Sensor Data', input:'raw_readings.json', output:'normalized.parquet' */ export function normalizeSensorData(readings: SensorReading[]): NormalizedData { // ... }
Note: Block comment annotations not supported for
-prefix (R, Python, Shell) or#-prefix (SQL, Lua). Line comments only those. Block-originated no backslash continuation across lines.--
Cross-file data flow (connect scripts via file-based I/O):
# Script 1: extract.R # put id:'extract', label:'Extract Data', output:'raw_data.internal, raw_data.rds' data <- read.csv("source.csv") saveRDS(data, "raw_data.rds") # Script 2: transform.R # put id:'transform', label:'Transform Data', input:'raw_data.rds', output:'clean_data.parquet' data <- readRDS("raw_data.rds") arrow::write_parquet(clean, "clean_data.parquet")
→ Annotations refined w/ accurate IDs, labels, I/O reflecting actual data flow.
If err: Unsure I/O →
.internal ext for in-memory intermediates + explicit file names for persisted.
Step 4: Insert Annotations
Place at top of file or immediately above relevant code block.
Placement conventions:
- File-level: Top after shebang or header comment
- Block-level: Immediately above code block it describes
- Multi per file: Distinct workflow phases
Example in R:
#!/usr/bin/env Rscript # ETL Extract Script # # put id:'read_source', label:'Read Source Data', input:'raw_data.csv', output:'df.internal' df <- read.csv("raw_data.csv") # put id:'clean_data', label:'Clean and Validate', input:'df.internal', output:'clean.rds' df_clean <- df[complete.cases(df), ] saveRDS(df_clean, "clean.rds")
Edit tool → insert into existing files no disturb surrounding.
→ Annotations inserted at appropriate locations per file.
If err: Break syntax highlighting → verify prefix correct for lang. PUT = std comments + should not affect exec.
Step 5: Validate
Run putior validation → syntax + connectivity.
# Scan annotated files workflow <- put("./src/", validate = TRUE) # Check for validation issues print(workflow) cat(sprintf("Total nodes: %d\n", nrow(workflow))) # Verify connections by checking input/output overlap inputs <- unlist(strsplit(workflow$input, ",\\s*")) outputs <- unlist(strsplit(workflow$output, ",\\s*")) connected <- intersect(inputs, outputs) cat(sprintf("Connected data flows: %d\n", length(connected))) # Generate diagram to visually inspect cat(put_diagram(workflow, theme = "github", show_source_info = TRUE)) # Merge with auto-detected for maximum coverage merged <- put_merge("./src/", merge_strategy = "supplement") cat(put_diagram(merged, theme = "github"))
→ All annotations parse no err. Diagram shows connected workflow.
put_merge() fills gaps from auto-detection.
If err: Common issues:
- Missing close quote:
→id:'nameid:'name' - Double quotes inside:
→id:"name"id:'name' - Duplicate IDs across files: each
must be unique across entire scanned dirid - Backslash continuation wrong line:
must be last char before newline\
Check
- Every annotated file has syntactically valid PUT annotations
-
returns df w/ expected node countput("./src/") - No duplicate
values across scanned dirid -
produces connected flowchart (not all isolated)put_diagram() - Multiline annotations (if used) parse correct w/ backslash continuation
-
vars appear only outputs, never cross-file ins.internal - Files excluded via
no appear in workflow (e.g.,exclude
skips test helpers)put("./src/", exclude = "test_")
Traps
- Quote nesting: PUT uses single quotes:
. Double quotes → parsing issues when annotation in string ctx.id:'name' - Duplicate IDs: Every
must be globally unique within scanned scope. Naming:id
(e.g.,<script>_<step>
,extract_read
).transform_clean - .internal as cross-file in:
exists only during script exec. Pass data between scripts → persisted file format (.internal
,.rds
,.csv
) as out of one + in of next..parquet - Missing connections: Disconnected nodes → check out filenames in 1 annotation exactly match in filenames in another (including exts).
- Wrong prefix:
in SQL or#
in Python → annotation treated as code not comment. Always verify//
.get_comment_prefix() - Forget multiline continuation: Every continued line must end
+ next line must start w/ comment prefix.\ - Python triple-quote strings: putior no scan (
,''' '''
). Always""" """
for Python PUT.# - Meta-pipeline annotations: Annotate build script that also scans for annotations (e.g., script calling
+put()
) → script's own annotations appear in generated diagram. Exclude file from scanning (seeput_diagram()
Traps) or no PUT in build script itself.generate-workflow-diagram
→
— prereq: produces annotation plan this followsanalyze-codebase-workflow
— next: generate final from annotationsgenerate-workflow-diagram
— putior installed before annotatinginstall-putior
— MCP tools interactive annotation assistanceconfigure-putior-mcp