@neyugn/agent-kits 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -49,9 +49,31 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
49
49
|
|
|
50
50
|
1. **Analyze**: Detect domains (Frontend, Backend, Security, etc.)
|
|
51
51
|
2. **Select**: Choose appropriate specialist(s)
|
|
52
|
-
3.
|
|
52
|
+
3. **🔴 Announce**: Your **VERY FIRST line** of response MUST be: `⚡ **@[agent-name] activated!**`
|
|
53
53
|
4. **Apply**: Use agent's persona and rules
|
|
54
54
|
|
|
55
|
+
> 🔴 **MANDATORY ANNOUNCEMENT RULE:**
|
|
56
|
+
> - You MUST output the announcement as the **first line** of every response before ANY other text.
|
|
57
|
+
> - Format: `⚡ **@agent-name activated!**` (replace `agent-name` with actual agent slug)
|
|
58
|
+
> - For multi-agent tasks: announce each agent on separate lines
|
|
59
|
+
> - This is NON-NEGOTIABLE. The user RELIES on this to verify correct agent routing.
|
|
60
|
+
>
|
|
61
|
+
> **Example — Single agent:**
|
|
62
|
+
> ```
|
|
63
|
+
> ⚡ **@backend-specialist activated!**
|
|
64
|
+
>
|
|
65
|
+
> Let me analyze your API endpoint...
|
|
66
|
+
> ```
|
|
67
|
+
>
|
|
68
|
+
> **Example — Multiple agents:**
|
|
69
|
+
> ```
|
|
70
|
+
> ⚡ **@orchestrator activated!**
|
|
71
|
+
> ⚡ **@frontend-specialist activated!**
|
|
72
|
+
> ⚡ **@backend-specialist activated!**
|
|
73
|
+
>
|
|
74
|
+
> I'll coordinate the full-stack implementation...
|
|
75
|
+
> ```
|
|
76
|
+
|
|
55
77
|
### Tier 1: Master Agents
|
|
56
78
|
|
|
57
79
|
| Agent | Use When |
|
|
@@ -105,11 +127,12 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
105
127
|
| ---- | ------------------------------- | --------------------------------- |
|
|
106
128
|
| 1 | Correct agent identified? | → Analyze domain |
|
|
107
129
|
| 2 | Read agent's .md file? | → Open `.agent/agents/{agent}.md` |
|
|
108
|
-
| 3 | Announced @agent?
|
|
130
|
+
| 3 | Announced @agent as FIRST LINE? | → 🔴 Add announcement IMMEDIATELY |
|
|
109
131
|
| 4 | Loaded skills from frontmatter? | → Check `skills:` field |
|
|
110
132
|
|
|
111
133
|
❌ Code without agent = PROTOCOL VIOLATION
|
|
112
134
|
❌ Skip announcement = USER CANNOT VERIFY
|
|
135
|
+
❌ Announcement NOT as first line = PROTOCOL VIOLATION
|
|
113
136
|
|
|
114
137
|
---
|
|
115
138
|
|
|
@@ -49,9 +49,31 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
49
49
|
|
|
50
50
|
1. **Analyze**: Detect domains (Frontend, Backend, Security, etc.)
|
|
51
51
|
2. **Select**: Choose appropriate specialist(s)
|
|
52
|
-
3.
|
|
52
|
+
3. **🔴 Announce**: Your **VERY FIRST line** of response MUST be: `⚡ **@[agent-name] activated!**`
|
|
53
53
|
4. **Apply**: Use agent's persona and rules
|
|
54
54
|
|
|
55
|
+
> 🔴 **MANDATORY ANNOUNCEMENT RULE:**
|
|
56
|
+
> - You MUST output the announcement as the **first line** of every response before ANY other text.
|
|
57
|
+
> - Format: `⚡ **@agent-name activated!**` (replace `agent-name` with actual agent slug)
|
|
58
|
+
> - For multi-agent tasks: announce each agent on separate lines
|
|
59
|
+
> - This is NON-NEGOTIABLE. The user RELIES on this to verify correct agent routing.
|
|
60
|
+
>
|
|
61
|
+
> **Example — Single agent:**
|
|
62
|
+
> ```
|
|
63
|
+
> ⚡ **@backend-specialist activated!**
|
|
64
|
+
>
|
|
65
|
+
> Let me analyze your API endpoint...
|
|
66
|
+
> ```
|
|
67
|
+
>
|
|
68
|
+
> **Example — Multiple agents:**
|
|
69
|
+
> ```
|
|
70
|
+
> ⚡ **@orchestrator activated!**
|
|
71
|
+
> ⚡ **@frontend-specialist activated!**
|
|
72
|
+
> ⚡ **@backend-specialist activated!**
|
|
73
|
+
>
|
|
74
|
+
> I'll coordinate the full-stack implementation...
|
|
75
|
+
> ```
|
|
76
|
+
|
|
55
77
|
### Tier 1: Master Agents
|
|
56
78
|
|
|
57
79
|
| Agent | Use When |
|
|
@@ -105,11 +127,12 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
105
127
|
| ---- | ------------------------------- | --------------------------------- |
|
|
106
128
|
| 1 | Correct agent identified? | → Analyze domain |
|
|
107
129
|
| 2 | Read agent's .md file? | → Open `.agent/agents/{agent}.md` |
|
|
108
|
-
| 3 | Announced @agent?
|
|
130
|
+
| 3 | Announced @agent as FIRST LINE? | → 🔴 Add announcement IMMEDIATELY |
|
|
109
131
|
| 4 | Loaded skills from frontmatter? | → Check `skills:` field |
|
|
110
132
|
|
|
111
133
|
❌ Code without agent = PROTOCOL VIOLATION
|
|
112
134
|
❌ Skip announcement = USER CANNOT VERIFY
|
|
135
|
+
❌ Announcement NOT as first line = PROTOCOL VIOLATION
|
|
113
136
|
|
|
114
137
|
---
|
|
115
138
|
|
|
@@ -55,9 +55,31 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
55
55
|
|
|
56
56
|
1. **Analyze**: Detect domains (Frontend, Backend, Security, etc.)
|
|
57
57
|
2. **Select**: Choose appropriate specialist(s)
|
|
58
|
-
3.
|
|
58
|
+
3. **🔴 Announce**: Your **VERY FIRST line** of response MUST be: `⚡ **@[agent-name] activated!**`
|
|
59
59
|
4. **Apply**: Use agent's persona and rules
|
|
60
60
|
|
|
61
|
+
> 🔴 **MANDATORY ANNOUNCEMENT RULE:**
|
|
62
|
+
> - You MUST output the announcement as the **first line** of every response before ANY other text.
|
|
63
|
+
> - Format: `⚡ **@agent-name activated!**` (replace `agent-name` with actual agent slug)
|
|
64
|
+
> - For multi-agent tasks: announce each agent on separate lines
|
|
65
|
+
> - This is NON-NEGOTIABLE. The user RELIES on this to verify correct agent routing.
|
|
66
|
+
>
|
|
67
|
+
> **Example — Single agent:**
|
|
68
|
+
> ```
|
|
69
|
+
> ⚡ **@backend-specialist activated!**
|
|
70
|
+
>
|
|
71
|
+
> Let me analyze your API endpoint...
|
|
72
|
+
> ```
|
|
73
|
+
>
|
|
74
|
+
> **Example — Multiple agents:**
|
|
75
|
+
> ```
|
|
76
|
+
> ⚡ **@orchestrator activated!**
|
|
77
|
+
> ⚡ **@frontend-specialist activated!**
|
|
78
|
+
> ⚡ **@backend-specialist activated!**
|
|
79
|
+
>
|
|
80
|
+
> I'll coordinate the full-stack implementation...
|
|
81
|
+
> ```
|
|
82
|
+
|
|
61
83
|
### Tier 1: Master Agents
|
|
62
84
|
|
|
63
85
|
| Agent | Use When |
|
|
@@ -111,11 +133,12 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
111
133
|
| ---- | ------------------------------- | --------------------------------- |
|
|
112
134
|
| 1 | Correct agent identified? | → Analyze domain |
|
|
113
135
|
| 2 | Read agent's .md file? | → Open `.agent/agents/{agent}.md` |
|
|
114
|
-
| 3 | Announced @agent?
|
|
136
|
+
| 3 | Announced @agent as FIRST LINE? | → 🔴 Add announcement IMMEDIATELY |
|
|
115
137
|
| 4 | Loaded skills from frontmatter? | → Check `skills:` field |
|
|
116
138
|
|
|
117
139
|
❌ Code without agent = PROTOCOL VIOLATION
|
|
118
140
|
❌ Skip announcement = USER CANNOT VERIFY
|
|
141
|
+
❌ Announcement NOT as first line = PROTOCOL VIOLATION
|
|
119
142
|
|
|
120
143
|
---
|
|
121
144
|
|
|
@@ -53,9 +53,31 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
53
53
|
|
|
54
54
|
1. **Analyze**: Detect domains (Frontend, Backend, Security, etc.)
|
|
55
55
|
2. **Select**: Choose appropriate specialist(s)
|
|
56
|
-
3.
|
|
56
|
+
3. **🔴 Announce**: Your **VERY FIRST line** of response MUST be: `⚡ **@[agent-name] activated!**`
|
|
57
57
|
4. **Apply**: Use agent's persona and rules
|
|
58
58
|
|
|
59
|
+
> 🔴 **MANDATORY ANNOUNCEMENT RULE:**
|
|
60
|
+
> - You MUST output the announcement as the **first line** of every response before ANY other text.
|
|
61
|
+
> - Format: `⚡ **@agent-name activated!**` (replace `agent-name` with actual agent slug)
|
|
62
|
+
> - For multi-agent tasks: announce each agent on separate lines
|
|
63
|
+
> - This is NON-NEGOTIABLE. The user RELIES on this to verify correct agent routing.
|
|
64
|
+
>
|
|
65
|
+
> **Example — Single agent:**
|
|
66
|
+
> ```
|
|
67
|
+
> ⚡ **@backend-specialist activated!**
|
|
68
|
+
>
|
|
69
|
+
> Let me analyze your API endpoint...
|
|
70
|
+
> ```
|
|
71
|
+
>
|
|
72
|
+
> **Example — Multiple agents:**
|
|
73
|
+
> ```
|
|
74
|
+
> ⚡ **@orchestrator activated!**
|
|
75
|
+
> ⚡ **@frontend-specialist activated!**
|
|
76
|
+
> ⚡ **@backend-specialist activated!**
|
|
77
|
+
>
|
|
78
|
+
> I'll coordinate the full-stack implementation...
|
|
79
|
+
> ```
|
|
80
|
+
|
|
59
81
|
### Tier 1: Master Agents
|
|
60
82
|
|
|
61
83
|
| Agent | Use When |
|
|
@@ -109,11 +131,12 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
109
131
|
| ---- | ------------------------------- | --------------------------------- |
|
|
110
132
|
| 1 | Correct agent identified? | → Analyze domain |
|
|
111
133
|
| 2 | Read agent's .md file? | → Open `.agent/agents/{agent}.md` |
|
|
112
|
-
| 3 | Announced @agent?
|
|
134
|
+
| 3 | Announced @agent as FIRST LINE? | → 🔴 Add announcement IMMEDIATELY |
|
|
113
135
|
| 4 | Loaded skills from frontmatter? | → Check `skills:` field |
|
|
114
136
|
|
|
115
137
|
❌ Code without agent = PROTOCOL VIOLATION
|
|
116
138
|
❌ Skip announcement = USER CANNOT VERIFY
|
|
139
|
+
❌ Announcement NOT as first line = PROTOCOL VIOLATION
|
|
117
140
|
|
|
118
141
|
---
|
|
119
142
|
|
|
@@ -20,7 +20,7 @@ AGT-Kit is a portable, modular AI agent system consisting of:
|
|
|
20
20
|
|
|
21
21
|
### Modular Skill Loading
|
|
22
22
|
|
|
23
|
-
Agent activated → Check
|
|
23
|
+
Agent activated → Check ARCHITECTURE.md for assigned skills → Use `skill` tool to load each → Apply.
|
|
24
24
|
|
|
25
25
|
- **Priority:** P0 (AGENTS.md) > P1 (Agent.md) > P2 (SKILL.md). All binding.
|
|
26
26
|
- **Enforcement:** Never skip reading. "Read → Understand → Apply" mandatory.
|
|
@@ -49,9 +49,31 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
49
49
|
|
|
50
50
|
1. **Analyze**: Detect domains (Frontend, Backend, Security, etc.)
|
|
51
51
|
2. **Select**: Choose appropriate specialist(s)
|
|
52
|
-
3.
|
|
52
|
+
3. **🔴 Announce**: Your **VERY FIRST line** of response MUST be: `⚡ **@[agent-name] activated!**`
|
|
53
53
|
4. **Apply**: Use agent's persona and rules
|
|
54
54
|
|
|
55
|
+
> 🔴 **MANDATORY ANNOUNCEMENT RULE:**
|
|
56
|
+
> - You MUST output the announcement as the **first line** of every response before ANY other text.
|
|
57
|
+
> - Format: `⚡ **@agent-name activated!**` (replace `agent-name` with actual agent slug)
|
|
58
|
+
> - For multi-agent tasks: announce each agent on separate lines
|
|
59
|
+
> - This is NON-NEGOTIABLE. The user RELIES on this to verify correct agent routing.
|
|
60
|
+
>
|
|
61
|
+
> **Example — Single agent:**
|
|
62
|
+
> ```
|
|
63
|
+
> ⚡ **@backend-specialist activated!**
|
|
64
|
+
>
|
|
65
|
+
> Let me analyze your API endpoint...
|
|
66
|
+
> ```
|
|
67
|
+
>
|
|
68
|
+
> **Example — Multiple agents:**
|
|
69
|
+
> ```
|
|
70
|
+
> ⚡ **@orchestrator activated!**
|
|
71
|
+
> ⚡ **@frontend-specialist activated!**
|
|
72
|
+
> ⚡ **@backend-specialist activated!**
|
|
73
|
+
>
|
|
74
|
+
> I'll coordinate the full-stack implementation...
|
|
75
|
+
> ```
|
|
76
|
+
|
|
55
77
|
### Tier 1: Master Agents
|
|
56
78
|
|
|
57
79
|
| Agent | Use When |
|
|
@@ -101,15 +123,16 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
101
123
|
|
|
102
124
|
### Routing Checklist
|
|
103
125
|
|
|
104
|
-
| Step | Check
|
|
105
|
-
| ---- |
|
|
106
|
-
| 1 | Correct agent identified?
|
|
107
|
-
| 2 | Read agent's .md file?
|
|
108
|
-
| 3 | Announced @agent?
|
|
109
|
-
| 4 | Loaded skills from
|
|
126
|
+
| Step | Check | If Unchecked |
|
|
127
|
+
| ---- | --------------------------------- | ------------------------------------------- |
|
|
128
|
+
| 1 | Correct agent identified? | → Analyze domain |
|
|
129
|
+
| 2 | Read agent's .md file? | → Open `.agent/agents/{agent}.md` |
|
|
130
|
+
| 3 | Announced @agent as FIRST LINE? | → 🔴 Add announcement IMMEDIATELY |
|
|
131
|
+
| 4 | Loaded skills from ARCHITECTURE? | → Check ARCHITECTURE.md agent-skills table |
|
|
110
132
|
|
|
111
133
|
❌ Code without agent = PROTOCOL VIOLATION
|
|
112
134
|
❌ Skip announcement = USER CANNOT VERIFY
|
|
135
|
+
❌ Announcement NOT as first line = PROTOCOL VIOLATION
|
|
113
136
|
|
|
114
137
|
---
|
|
115
138
|
|
|
@@ -129,7 +152,24 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
|
|
|
129
152
|
## 🛠️ SKILL LOADING PROTOCOL
|
|
130
153
|
|
|
131
154
|
```
|
|
132
|
-
|
|
155
|
+
Agent activated → Check ARCHITECTURE.md for assigned skills → Use `skill` tool → Apply SKILL.md content
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### How Skills Work in OpenCode
|
|
159
|
+
|
|
160
|
+
OpenCode has a **native `skill` tool** that automatically discovers all available skills.
|
|
161
|
+
|
|
162
|
+
1. **Discovery**: OpenCode scans `.agent/skills/*/SKILL.md` and lists them in the `skill` tool description
|
|
163
|
+
2. **Selection**: Check ARCHITECTURE.md → find your agent → note the "Skills Used" column
|
|
164
|
+
3. **Loading**: Call `skill({ name: "skill-name" })` to load each assigned skill
|
|
165
|
+
4. **Apply**: Follow the loaded SKILL.md instructions
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
# Example: frontend-specialist activated
|
|
169
|
+
1. Read ARCHITECTURE.md → Skills: clean-code, react-patterns, typescript-patterns, ...
|
|
170
|
+
2. Call skill({ name: "clean-code" }) → Read content
|
|
171
|
+
3. Call skill({ name: "react-patterns" }) → Read content
|
|
172
|
+
4. Apply all loaded skill rules to the task
|
|
133
173
|
```
|
|
134
174
|
|
|
135
175
|
### Profile-Aware Loading
|
|
@@ -148,6 +188,31 @@ User Request → Check Profile → Skill Description Match → Load SKILL.md →
|
|
|
148
188
|
- Behave as if no filtering is applied
|
|
149
189
|
```
|
|
150
190
|
|
|
191
|
+
### Skill Permissions (OpenCode)
|
|
192
|
+
|
|
193
|
+
Control skill access in `opencode.json`:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"permission": {
|
|
198
|
+
"skill": {
|
|
199
|
+
"*": "allow",
|
|
200
|
+
"internal-*": "deny"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Or per-agent in agent frontmatter:
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
---
|
|
210
|
+
permission:
|
|
211
|
+
skill:
|
|
212
|
+
"documents-*": "allow"
|
|
213
|
+
---
|
|
214
|
+
```
|
|
215
|
+
|
|
151
216
|
### Core Skills (Always Available)
|
|
152
217
|
|
|
153
218
|
These skills are NEVER disabled regardless of profile:
|
|
@@ -90,6 +90,46 @@ def parse_frontmatter(file_path: Path) -> Dict[str, Any]:
|
|
|
90
90
|
return {}
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
def parse_skills_from_architecture(agent_dir: Path) -> Dict[str, List[str]]:
|
|
94
|
+
"""Parse agent-skill mappings from ARCHITECTURE.md tables.
|
|
95
|
+
|
|
96
|
+
Falls back to this when agents don't have skills in frontmatter
|
|
97
|
+
(e.g., OpenCode strips the skills field during transformation).
|
|
98
|
+
"""
|
|
99
|
+
arch_file = agent_dir / "ARCHITECTURE.md"
|
|
100
|
+
if not arch_file.exists():
|
|
101
|
+
return {}
|
|
102
|
+
|
|
103
|
+
mapping = {}
|
|
104
|
+
try:
|
|
105
|
+
content = arch_file.read_text()
|
|
106
|
+
# Match table rows: | `agent-name` | description | skills-list |
|
|
107
|
+
# Pattern: | `name` | ... | skill1, skill2, ... |
|
|
108
|
+
for line in content.split('\n'):
|
|
109
|
+
if not line.startswith('|'):
|
|
110
|
+
continue
|
|
111
|
+
cells = [c.strip() for c in line.split('|')]
|
|
112
|
+
# Filter out empty cells from leading/trailing pipes
|
|
113
|
+
cells = [c for c in cells if c]
|
|
114
|
+
if len(cells) >= 3:
|
|
115
|
+
# First cell might be agent name wrapped in backticks
|
|
116
|
+
agent_name = cells[0].strip('`').strip()
|
|
117
|
+
# Last cell contains skills
|
|
118
|
+
skills_str = cells[-1]
|
|
119
|
+
# Skip header/separator rows
|
|
120
|
+
if agent_name.startswith('-') or agent_name == 'Agent':
|
|
121
|
+
continue
|
|
122
|
+
# Parse comma-separated skills
|
|
123
|
+
skills = [s.strip().strip('`') for s in skills_str.split(',') if s.strip()]
|
|
124
|
+
# Only add if skills look valid (not header text)
|
|
125
|
+
if skills and not any(s in ['Skills Used', '---', 'Skills'] for s in skills):
|
|
126
|
+
mapping[agent_name] = skills
|
|
127
|
+
except Exception:
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
return mapping
|
|
131
|
+
|
|
132
|
+
|
|
93
133
|
def get_agents(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
94
134
|
"""Get list of agents with their metadata."""
|
|
95
135
|
agents = []
|
|
@@ -98,10 +138,12 @@ def get_agents(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
|
98
138
|
if not agents_path.exists():
|
|
99
139
|
return agents
|
|
100
140
|
|
|
141
|
+
# Parse agent-skill mappings from ARCHITECTURE.md (single source of truth)
|
|
142
|
+
arch_skills = parse_skills_from_architecture(agent_dir)
|
|
143
|
+
|
|
101
144
|
for agent_file in agents_path.glob("*.md"):
|
|
102
145
|
frontmatter = parse_frontmatter(agent_file)
|
|
103
|
-
skills =
|
|
104
|
-
skills = [s.strip() for s in skills if s.strip()]
|
|
146
|
+
skills = arch_skills.get(agent_file.stem, [])
|
|
105
147
|
|
|
106
148
|
agents.append({
|
|
107
149
|
"name": agent_file.stem,
|
|
@@ -146,22 +188,33 @@ def get_skills(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
|
146
188
|
|
|
147
189
|
|
|
148
190
|
def get_workflows(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
149
|
-
"""Get list of workflows.
|
|
150
|
-
workflows = []
|
|
151
|
-
workflows_path = agent_dir / "workflows"
|
|
191
|
+
"""Get list of workflows/commands.
|
|
152
192
|
|
|
153
|
-
|
|
154
|
-
|
|
193
|
+
Checks both 'workflows/' (Cursor, Gemini) and 'commands/' (OpenCode)
|
|
194
|
+
directories since different AI tools use different naming.
|
|
195
|
+
"""
|
|
196
|
+
workflows = []
|
|
155
197
|
|
|
156
|
-
|
|
157
|
-
|
|
198
|
+
# Check both possible directories
|
|
199
|
+
for dir_name in ["workflows", "commands"]:
|
|
200
|
+
workflows_path = agent_dir / dir_name
|
|
158
201
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
202
|
+
if not workflows_path.exists():
|
|
203
|
+
continue
|
|
204
|
+
|
|
205
|
+
for workflow_file in workflows_path.glob("*.md"):
|
|
206
|
+
frontmatter = parse_frontmatter(workflow_file)
|
|
207
|
+
|
|
208
|
+
workflows.append({
|
|
209
|
+
"name": workflow_file.stem,
|
|
210
|
+
"command": f"/{workflow_file.stem}",
|
|
211
|
+
"file": str(workflow_file.relative_to(agent_dir)),
|
|
212
|
+
"description": frontmatter.get("description", ""),
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
# Only use the first directory found (don't double-count)
|
|
216
|
+
if workflows:
|
|
217
|
+
break
|
|
165
218
|
|
|
166
219
|
return sorted(workflows, key=lambda x: x["name"])
|
|
167
220
|
|