Skip to content

Commit 1374256

Browse files
committed
feat ✨ (core): SRE-1879 add glab task template
Signed-off-by: Luis Mayta <luis@hadenlabs.com>
1 parent 8b394e2 commit 1374256

9 files changed

Lines changed: 707 additions & 85 deletions

File tree

.claude/skills/opencode-tasks-scaffold/SKILL.md

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
description: Generate documentation for a task from its Taskfile
3+
---
4+
5+
1. Read input from `{{args}}`
6+
2. Extract:
7+
- task_slug = first word (e.g., "glab", "terraform")
8+
3. Validate:
9+
- If empty → ask user for task_slug
10+
- Check if src/{{task_slug}}/Taskfile.yml exists
11+
4. Execute:
12+
- Create docs/tasks/{{task_slug}}.md with:
13+
- Header with task name
14+
- Table of tasks (task | description)
15+
- Detailed sections for each task with commands, deps, preconditions
16+
- Add to provision/generators/README.yaml if not exists:
17+
- Line: ` - docs/tasks/{{task_slug}}.md`
18+
- Run `task readme` to regenerate README.md
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "task-docs-generator",
3+
"description": "Generate documentation for a task from its Taskfile"
4+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
name: task-docs-generator
3+
description: Generate documentation for a task from its Taskfile and update README.yaml
4+
---
5+
6+
# Task Docs Generator Skill
7+
8+
## Trigger phrases
9+
10+
- "genera documentacion de task"
11+
- "genera docs para task"
12+
- "genera documentacion de glab"
13+
- "docs-generate"
14+
- "task-docs"
15+
16+
## What I do
17+
18+
1. Extract `task_slug` from user input (first word)
19+
2. Validate that `src/<task_slug>/Taskfile.yml` exists
20+
3. Generate `docs/tasks/<task_slug>.md` with:
21+
- Header with task name
22+
- Table of tasks (task | description)
23+
- Detailed sections for each task with commands, deps, preconditions
24+
4. Add to `provision/generators/README.yaml` if not exists:
25+
- Line: ` - docs/tasks/<task_slug>.md`
26+
5. Run `task readme` to regenerate README.md
27+
28+
## Input
29+
30+
- `task_slug`: Name of the task (e.g., "glab", "terraform", "go")
31+
32+
## Output
33+
34+
- `docs/tasks/<task_slug>.md`: Generated documentation
35+
- Updated `provision/generators/README.yaml`
36+
- Regenerated `README.md`
37+
38+
## Implementation
39+
40+
Run the Python script from the skill:
41+
42+
```bash
43+
python3 .claude/skills/task-docs-generator/scripts/generate_task_docs.py <task_slug>
44+
task readme
45+
```
46+
47+
## Example
48+
49+
- Input: `/docs-generate glab`
50+
- Output:
51+
- Creates `docs/tasks/glab.md`
52+
- Adds ` - docs/tasks/glab.md` to `provision/generators/README.yaml`
53+
- Runs `task readme`
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python3
2+
"""Generate documentation from a Taskfile."""
3+
4+
import sys
5+
import yaml
6+
from pathlib import Path
7+
8+
9+
def generate_task_docs(task_slug: str) -> None:
10+
"""Generate documentation for a task."""
11+
taskfile_path = Path(f"src/{task_slug}/Taskfile.yml")
12+
output_path = Path(f"docs/tasks/{task_slug}.md")
13+
readme_yaml_path = Path("provision/generators/README.yaml")
14+
15+
if not taskfile_path.exists():
16+
print(f"Error: Taskfile not found: {taskfile_path}")
17+
sys.exit(1)
18+
19+
# Load Taskfile
20+
with open(taskfile_path) as f:
21+
taskfile = yaml.safe_load(f)
22+
23+
tasks = taskfile.get("tasks", {})
24+
25+
# Generate markdown
26+
lines = [
27+
f"# {task_slug}",
28+
"",
29+
f"Generated from: `src/{task_slug}/Taskfile.yml`",
30+
"---",
31+
"",
32+
"## Tasks",
33+
"",
34+
"| Task | Description |",
35+
"| ---- | ----------- |",
36+
]
37+
38+
# Add task table
39+
for task_name, task_data in tasks.items():
40+
desc = task_data.get("desc", "")
41+
if desc:
42+
lines.append(f"| `{task_name}` | {desc} |")
43+
44+
lines.append("")
45+
lines.append("## Task Details")
46+
lines.append("")
47+
48+
# Add detailed sections
49+
for task_name, task_data in tasks.items():
50+
desc = task_data.get("desc", "")
51+
if not desc:
52+
continue
53+
54+
lines.append(f"### {task_name}")
55+
lines.append("")
56+
lines.append(desc)
57+
lines.append("")
58+
59+
# Add commands
60+
cmds = task_data.get("cmds", [])
61+
if cmds:
62+
lines.append("**Commands:**")
63+
lines.append("```bash")
64+
for cmd in cmds:
65+
if isinstance(cmd, str):
66+
lines.append(cmd)
67+
elif isinstance(cmd, dict) and "task" in cmd:
68+
lines.append(f"- task: {cmd['task']}")
69+
lines.append("```")
70+
lines.append("")
71+
72+
# Add dependencies
73+
deps = task_data.get("deps", [])
74+
if deps:
75+
lines.append("**Dependencies:**")
76+
for dep in deps:
77+
if isinstance(dep, str):
78+
lines.append(f"- {dep}")
79+
elif isinstance(dep, dict) and "task" in dep:
80+
lines.append(f"- task: {dep['task']}")
81+
lines.append("")
82+
83+
# Add preconditions
84+
preconditions = task_data.get("preconditions", [])
85+
if preconditions:
86+
lines.append("**Preconditions:**")
87+
for precond in preconditions:
88+
if isinstance(precond, dict) and "msg" in precond:
89+
lines.append(f"- {precond['msg']}")
90+
lines.append("")
91+
92+
# Write output
93+
output_path.parent.mkdir(parents=True, exist_ok=True)
94+
with open(output_path, "w") as f:
95+
f.write("\n".join(lines))
96+
97+
print(f"Documentation generated: {output_path}")
98+
99+
# Update README.yaml
100+
module_line = f" - docs/tasks/{task_slug}.md"
101+
with open(readme_yaml_path) as f:
102+
content = f.read()
103+
104+
if module_line not in content:
105+
# Add module line before examples
106+
if "examples:" in content:
107+
content = content.replace("examples:", f"{module_line}\nexamples:")
108+
else:
109+
content += f"\n{module_line}\n"
110+
111+
with open(readme_yaml_path, "w") as f:
112+
f.write(content)
113+
114+
print(f"Added {module_line} to provision/generators/README.yaml")
115+
else:
116+
print(f"Module already exists in README.yaml")
117+
118+
119+
if __name__ == "__main__":
120+
if len(sys.argv) < 2:
121+
print("Usage: python generate_task_docs.py <task_slug>")
122+
sys.exit(1)
123+
124+
generate_task_docs(sys.argv[1])

.slim/cartography.json

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"metadata": {
33
"version": "1.0.0",
4-
"last_run": "2026-03-24T14:07:29.404339Z",
4+
"last_run": "2026-03-24T14:46:01.182486Z",
55
"root": "/Users/luchomayta/Projects/src/github.com/InfosisARG/tasks",
66
"include_patterns": ["Taskfile.yml", "src/**/Taskfile.yml", "provision/**/*.yml", "provision/**/*.yaml"],
77
"exclude_patterns": ["docs/**", "**/*.md", ".venv/**", "node_modules/**"],
88
"exceptions": []
99
},
1010
"file_hashes": {
11-
"Taskfile.yml": "51b6ccdba5da15b88849f90919fd9eaf",
11+
"Taskfile.yml": "a4f001abac2721da8d4973ddbb75d3dd",
1212
"provision/diagrams/Taskfile.yml": "0e3595b25ff213adf0f0f10401982cb8",
13-
"provision/generators/README.yaml": "fbdb26098366c461b7d1a861de2a7585",
13+
"provision/generators/README.yaml": "28ee7aaeb57fcd0f41556788d6dbe51e",
1414
"src/android/Taskfile.yml": "a93ea6a2b65159902257277f26ff37f5",
1515
"src/ansible/Taskfile.yml": "dd864db0aace29eae2b5ca8b3aa377bf",
1616
"src/aws/Taskfile.yml": "a8d19f7fe5100da8955f45dc7cb8773f",
@@ -23,6 +23,7 @@
2323
"src/flutter/Taskfile.yml": "f202ab81d9f515d6a623861b23d2c59a",
2424
"src/git/Taskfile.yml": "8e3b500a688eee0ad97e301320566232",
2525
"src/github/Taskfile.yml": "124adba54be3a5ce50011750d0cfc517",
26+
"src/glab/Taskfile.yml": "5d0bb3273a031ae715557b202eacf30a",
2627
"src/go/Taskfile.yml": "127ef9b033f0d8208a0a5f312c3ffad9",
2728
"src/gradle/Taskfile.yml": "ddd901a88afb92137ba754a46cce90b5",
2829
"src/k8s/Taskfile.yml": "cc10ac616e12d5064ebab6cb477186e8",
@@ -55,52 +56,53 @@
5556
"src/yarn/Taskfile.yml": "307d1907f10ba819c2b3fb3ad8239364"
5657
},
5758
"folder_hashes": {
58-
"src/gradle": "69bc903436deaae2b5229dbd2451e8fe",
59-
"provision/diagrams": "d5bb1d6dea35da5174551c1b6ba3ebef",
60-
"src/maven": "5969378269a4bfc38ce17441f1cf331a",
61-
"src/pnpm": "16d84321c6384487d6451e957c87a093",
62-
"src/lua": "73c483c5260897fc19804a42f7a49e41",
63-
"src/git": "8c97eaa3fa58ca56f949406f6139d69a",
59+
"src/poetry": "35408d52e22ed2ffd1ddf160a414c154",
60+
"src/sonar": "311799709357ae3962f1adfe10382a4b",
61+
"src/flutter": "bfa287f8211a302d71f1fa05e4eea79f",
62+
"provision/generators": "b6443a538e8b42ff867ac36e7ff68bd1",
63+
"src/plantuml": "3d92c9b0693024629fa05b5e6ea0e956",
64+
"src/python": "19c7c68e6d44aca85edf412396638b26",
65+
"src/keybase": "1318fdbb42b9da25b22dee2451585ad0",
66+
"src/version": "4a887ac1880335fb6411fe64ee30fa28",
67+
"src/docker": "6a7890561019f34b80d775fbdac9c485",
68+
"src/terraform": "a25646010dc307119f5e29ee45dc7420",
6469
"src/uv": "037888cc765769967a162f91cb6d29e8",
65-
"provision": "cfeca3b4802d2ecf335bd9f724a857ad",
66-
"src/go": "5261dfb4d7d2a6ebbfcd8a4e923bf758",
67-
"src/release": "b592473e9e5f94dd2ff08c9897bb18ce",
70+
"src": "833ea412a5ff768895ccb9c4690d5f73",
71+
"src/changelog": "9a90190c7ea2234ddf16ef374b92578f",
72+
"src/github": "99bbafdcd38c4d536414f8df30ff317a",
73+
"src/renovate": "6b5076c93fb56fefe1541d1ccf1b314c",
74+
"src/skills": "fd0b85a56fea16aa67e5c6d487a43639",
6875
"src/sops": "e582aa84a2f82b4db8c2c557cac58390",
76+
"src/glab": "d5c72e50794decf9a8f1696163b18817",
77+
"provision/diagrams": "d5bb1d6dea35da5174551c1b6ba3ebef",
78+
"src/node": "03080b12b3ebcf1d57e01bbf4bd50505",
79+
"src/ssh": "334a01aa78d764d550a80332565061ff",
80+
".": "e565edbc43704cc22ada3157cc47e503",
81+
"src/aws": "4f4af4df8f9697cf0f35b1fae81d5521",
82+
"src/android": "545cfbab883380e61bf9930fff8245f2",
83+
"src/mark": "722442486e6d601954048f4463fcbaa5",
6984
"src/openssl": "d4f734423fee50bf98277ab7edec5828",
70-
"src/python": "19c7c68e6d44aca85edf412396638b26",
85+
"src/lua": "73c483c5260897fc19804a42f7a49e41",
86+
"src/k8s": "40cc19eab72ce4c5d1638dae0066620c",
87+
"src/molecule": "94c1f08f5981d90bc0ade9fc75c936c8",
88+
"src/release": "b592473e9e5f94dd2ff08c9897bb18ce",
89+
"src/prettier": "33b65e8d508034be80fa0f06a29bd128",
90+
"src/gradle": "69bc903436deaae2b5229dbd2451e8fe",
91+
"src/maven": "5969378269a4bfc38ce17441f1cf331a",
7192
"src/multipass": "b3153375c8f6e83cd881ff29a341e3e0",
72-
"src/packer": "fba5d6327af905d63d9d9ebe5181ea93",
73-
"src/poetry": "35408d52e22ed2ffd1ddf160a414c154",
74-
"src/renovate": "6b5076c93fb56fefe1541d1ccf1b314c",
75-
"src/ssh": "334a01aa78d764d550a80332565061ff",
76-
"src/version": "4a887ac1880335fb6411fe64ee30fa28",
7793
"src/bun": "fee1ee571cbf8a6c5d87ca3bde176ce8",
78-
"src/aws": "4f4af4df8f9697cf0f35b1fae81d5521",
79-
"src/node": "03080b12b3ebcf1d57e01bbf4bd50505",
80-
"src/terragrunt": "f4784d4762bf07eaaae724434502dc6c",
81-
"provision/generators": "32b038787dda92fc55c07cd507b2696c",
94+
"src/yarn": "e5c61143d0ee22a99aa4bc0bc81a3fdd",
95+
"src/packer": "fba5d6327af905d63d9d9ebe5181ea93",
96+
"src/pnpm": "16d84321c6384487d6451e957c87a093",
8297
"src/ansible": "38f695855d924902856321a0dcbe3b1d",
83-
"src/confluence": "e9b3121e9efb1ffe11f060ec993c59af",
84-
"src/keybase": "1318fdbb42b9da25b22dee2451585ad0",
85-
"src/plantuml": "3d92c9b0693024629fa05b5e6ea0e956",
86-
"src/docker": "6a7890561019f34b80d775fbdac9c485",
87-
"src/android": "545cfbab883380e61bf9930fff8245f2",
88-
"src/skills": "fd0b85a56fea16aa67e5c6d487a43639",
89-
"src/changelog": "9a90190c7ea2234ddf16ef374b92578f",
90-
"src/opencode": "f75d00da4ee63c9f13a045d82f512dc6",
91-
"src/github": "99bbafdcd38c4d536414f8df30ff317a",
92-
".": "a5c97d70d49b7c73c04446abb84bf08f",
93-
"src/sonar": "311799709357ae3962f1adfe10382a4b",
94-
"src/pre-commit": "f7009595df55847f524eb4d3bcc7efcc",
9598
"src/coursier": "52b5ceb2ecfd4c2c2a4a26048277f2d5",
99+
"src/pre-commit": "f7009595df55847f524eb4d3bcc7efcc",
100+
"src/terragrunt": "f4784d4762bf07eaaae724434502dc6c",
101+
"src/confluence": "e9b3121e9efb1ffe11f060ec993c59af",
96102
"src/biomejs": "8a7cf26b091e5ff60b6f8779a3f22478",
97-
"src": "9f8f4f17226da54bf24e608ec2ada884",
98-
"src/terraform": "a25646010dc307119f5e29ee45dc7420",
99-
"src/flutter": "bfa287f8211a302d71f1fa05e4eea79f",
100-
"src/yarn": "e5c61143d0ee22a99aa4bc0bc81a3fdd",
101-
"src/molecule": "94c1f08f5981d90bc0ade9fc75c936c8",
102-
"src/prettier": "33b65e8d508034be80fa0f06a29bd128",
103-
"src/k8s": "40cc19eab72ce4c5d1638dae0066620c",
104-
"src/mark": "722442486e6d601954048f4463fcbaa5"
103+
"src/go": "5261dfb4d7d2a6ebbfcd8a4e923bf758",
104+
"provision": "0bb09c46d099c701e689dc1fe578409f",
105+
"src/opencode": "f75d00da4ee63c9f13a045d82f512dc6",
106+
"src/git": "8c97eaa3fa58ca56f949406f6139d69a"
105107
}
106108
}

0 commit comments

Comments
 (0)