awesome-slash 2.4.4 → 2.5.1
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.
- package/.claude-plugin/marketplace.json +6 -6
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +123 -1
- package/README.md +186 -159
- package/SECURITY.md +25 -81
- package/adapters/codex/install.sh +58 -16
- package/adapters/opencode/install.sh +92 -23
- package/lib/index.js +47 -4
- package/lib/patterns/review-patterns.js +58 -11
- package/lib/patterns/slop-patterns.js +154 -147
- package/lib/platform/detect-platform.js +99 -350
- package/lib/platform/detection-configs.js +93 -0
- package/lib/platform/state-dir.js +122 -0
- package/lib/platform/verify-tools.js +10 -78
- package/lib/schemas/README.md +195 -0
- package/lib/schemas/validator.js +247 -0
- package/lib/sources/custom-handler.js +199 -0
- package/lib/sources/policy-questions.js +239 -0
- package/lib/sources/source-cache.js +164 -0
- package/lib/state/workflow-state.js +368 -665
- package/lib/types/README.md +292 -0
- package/lib/types/agent-frontmatter.d.ts +134 -0
- package/lib/types/command-frontmatter.d.ts +107 -0
- package/lib/types/hook-frontmatter.d.ts +115 -0
- package/lib/types/index.d.ts +84 -0
- package/lib/types/plugin-manifest.d.ts +102 -0
- package/lib/types/skill-frontmatter.d.ts +89 -0
- package/lib/utils/cache-manager.js +154 -0
- package/lib/utils/context-optimizer.js +5 -36
- package/lib/utils/deprecation.js +37 -0
- package/lib/utils/shell-escape.js +88 -0
- package/mcp-server/index.js +513 -22
- package/package.json +6 -2
- package/plugins/deslop-around/.claude-plugin/plugin.json +1 -1
- package/plugins/deslop-around/lib/index.js +170 -0
- package/plugins/deslop-around/lib/patterns/review-patterns.js +58 -11
- package/plugins/deslop-around/lib/patterns/slop-patterns.js +169 -129
- package/plugins/deslop-around/lib/platform/detect-platform.js +162 -316
- package/plugins/deslop-around/lib/platform/detection-configs.js +93 -0
- package/plugins/deslop-around/lib/platform/state-dir.js +122 -0
- package/plugins/deslop-around/lib/platform/verify-tools.js +10 -78
- package/plugins/deslop-around/lib/schemas/README.md +195 -0
- package/plugins/deslop-around/lib/schemas/validator.js +247 -0
- package/plugins/deslop-around/lib/sources/custom-handler.js +199 -0
- package/plugins/deslop-around/lib/sources/policy-questions.js +239 -0
- package/plugins/deslop-around/lib/sources/source-cache.js +164 -0
- package/plugins/deslop-around/lib/state/workflow-state.js +387 -484
- package/plugins/deslop-around/lib/types/README.md +292 -0
- package/plugins/deslop-around/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/deslop-around/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/deslop-around/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/deslop-around/lib/types/index.d.ts +84 -0
- package/plugins/deslop-around/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/deslop-around/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/deslop-around/lib/utils/cache-manager.js +154 -0
- package/plugins/deslop-around/lib/utils/context-optimizer.js +115 -37
- package/plugins/deslop-around/lib/utils/deprecation.js +37 -0
- package/plugins/deslop-around/lib/utils/shell-escape.js +88 -0
- package/plugins/next-task/.claude-plugin/plugin.json +1 -1
- package/plugins/next-task/agents/delivery-validator.md +2 -2
- package/plugins/next-task/agents/implementation-agent.md +3 -4
- package/plugins/next-task/agents/planning-agent.md +77 -19
- package/plugins/next-task/agents/review-orchestrator.md +21 -122
- package/plugins/next-task/agents/task-discoverer.md +164 -23
- package/plugins/next-task/commands/next-task.md +180 -14
- package/plugins/next-task/lib/index.js +170 -0
- package/plugins/next-task/lib/patterns/review-patterns.js +58 -11
- package/plugins/next-task/lib/patterns/slop-patterns.js +169 -129
- package/plugins/next-task/lib/platform/detect-platform.js +162 -316
- package/plugins/next-task/lib/platform/detection-configs.js +93 -0
- package/plugins/next-task/lib/platform/state-dir.js +122 -0
- package/plugins/next-task/lib/platform/verify-tools.js +10 -78
- package/plugins/next-task/lib/schemas/README.md +195 -0
- package/plugins/next-task/lib/schemas/validator.js +247 -0
- package/plugins/next-task/lib/sources/custom-handler.js +199 -0
- package/plugins/next-task/lib/sources/policy-questions.js +239 -0
- package/plugins/next-task/lib/sources/source-cache.js +164 -0
- package/plugins/next-task/lib/state/workflow-state.js +387 -484
- package/plugins/next-task/lib/types/README.md +292 -0
- package/plugins/next-task/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/next-task/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/next-task/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/next-task/lib/types/index.d.ts +84 -0
- package/plugins/next-task/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/next-task/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/next-task/lib/utils/cache-manager.js +154 -0
- package/plugins/next-task/lib/utils/context-optimizer.js +115 -37
- package/plugins/next-task/lib/utils/deprecation.js +37 -0
- package/plugins/next-task/lib/utils/shell-escape.js +88 -0
- package/plugins/project-review/.claude-plugin/plugin.json +1 -1
- package/plugins/project-review/lib/index.js +170 -0
- package/plugins/project-review/lib/patterns/review-patterns.js +58 -11
- package/plugins/project-review/lib/patterns/slop-patterns.js +169 -129
- package/plugins/project-review/lib/platform/detect-platform.js +162 -316
- package/plugins/project-review/lib/platform/detection-configs.js +93 -0
- package/plugins/project-review/lib/platform/state-dir.js +122 -0
- package/plugins/project-review/lib/platform/verify-tools.js +10 -78
- package/plugins/project-review/lib/schemas/README.md +195 -0
- package/plugins/project-review/lib/schemas/validator.js +247 -0
- package/plugins/project-review/lib/sources/custom-handler.js +199 -0
- package/plugins/project-review/lib/sources/policy-questions.js +239 -0
- package/plugins/project-review/lib/sources/source-cache.js +164 -0
- package/plugins/project-review/lib/state/workflow-state.js +387 -484
- package/plugins/project-review/lib/types/README.md +292 -0
- package/plugins/project-review/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/project-review/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/project-review/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/project-review/lib/types/index.d.ts +84 -0
- package/plugins/project-review/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/project-review/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/project-review/lib/utils/cache-manager.js +154 -0
- package/plugins/project-review/lib/utils/context-optimizer.js +115 -37
- package/plugins/project-review/lib/utils/deprecation.js +37 -0
- package/plugins/project-review/lib/utils/shell-escape.js +88 -0
- package/plugins/reality-check/.claude-plugin/plugin.json +1 -1
- package/plugins/reality-check/agents/code-explorer.md +1 -1
- package/plugins/ship/.claude-plugin/plugin.json +1 -1
- package/plugins/ship/lib/index.js +170 -0
- package/plugins/ship/lib/patterns/review-patterns.js +58 -11
- package/plugins/ship/lib/patterns/slop-patterns.js +169 -129
- package/plugins/ship/lib/platform/detect-platform.js +162 -316
- package/plugins/ship/lib/platform/detection-configs.js +93 -0
- package/plugins/ship/lib/platform/state-dir.js +122 -0
- package/plugins/ship/lib/platform/verify-tools.js +10 -78
- package/plugins/ship/lib/schemas/README.md +195 -0
- package/plugins/ship/lib/schemas/validator.js +247 -0
- package/plugins/ship/lib/sources/custom-handler.js +199 -0
- package/plugins/ship/lib/sources/policy-questions.js +239 -0
- package/plugins/ship/lib/sources/source-cache.js +164 -0
- package/plugins/ship/lib/state/workflow-state.js +387 -484
- package/plugins/ship/lib/types/README.md +292 -0
- package/plugins/ship/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/ship/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/ship/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/ship/lib/types/index.d.ts +84 -0
- package/plugins/ship/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/ship/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/ship/lib/utils/cache-manager.js +154 -0
- package/plugins/ship/lib/utils/context-optimizer.js +115 -37
- package/plugins/ship/lib/utils/deprecation.js +37 -0
- package/plugins/ship/lib/utils/shell-escape.js +88 -0
- package/scripts/install/codex.sh +216 -72
- package/scripts/install/opencode.sh +197 -21
- package/lib/state/workflow-state.schema.json +0 -282
- package/plugins/deslop-around/lib/state/workflow-state.schema.json +0 -282
- package/plugins/next-task/agents/policy-selector.md +0 -248
- package/plugins/next-task/lib/state/tasks-registry.schema.json +0 -85
- package/plugins/next-task/lib/state/workflow-state.schema.json +0 -282
- package/plugins/next-task/lib/state/worktree-status.schema.json +0 -219
- package/plugins/project-review/lib/state/workflow-state.schema.json +0 -282
- package/plugins/ship/lib/state/workflow-state.schema.json +0 -282
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Plugin Interface Type Definitions
|
|
2
|
+
|
|
3
|
+
TypeScript type definitions for Claude Code plugin components.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This directory contains the canonical type definitions for all plugin components:
|
|
8
|
+
|
|
9
|
+
- **Plugin Manifest** (`plugin.json`) - Plugin metadata and configuration
|
|
10
|
+
- **Command Frontmatter** - YAML metadata for slash commands
|
|
11
|
+
- **Agent Frontmatter** - YAML metadata for specialized agents
|
|
12
|
+
- **Skill Frontmatter** - YAML metadata for user-invocable skills
|
|
13
|
+
- **Hook Frontmatter** - YAML metadata for lifecycle hooks
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### TypeScript Projects
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import {
|
|
21
|
+
PluginManifest,
|
|
22
|
+
CommandFrontmatter,
|
|
23
|
+
AgentFrontmatter,
|
|
24
|
+
SkillFrontmatter,
|
|
25
|
+
HookFrontmatter,
|
|
26
|
+
validatePluginManifest,
|
|
27
|
+
validateCommandFrontmatter
|
|
28
|
+
} from './lib/types';
|
|
29
|
+
|
|
30
|
+
// Validate a plugin manifest
|
|
31
|
+
const manifest: PluginManifest = {
|
|
32
|
+
name: "my-plugin",
|
|
33
|
+
version: "1.0.0",
|
|
34
|
+
description: "My awesome plugin",
|
|
35
|
+
author: {
|
|
36
|
+
name: "John Doe"
|
|
37
|
+
},
|
|
38
|
+
license: "MIT"
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
validatePluginManifest(manifest); // Throws if invalid
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### JavaScript Projects (JSDoc)
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {import('./lib/types').PluginManifest} PluginManifest
|
|
49
|
+
* @typedef {import('./lib/types').CommandFrontmatter} CommandFrontmatter
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Load and validate plugin manifest
|
|
54
|
+
* @param {string} path - Path to plugin.json
|
|
55
|
+
* @returns {PluginManifest} Validated manifest
|
|
56
|
+
*/
|
|
57
|
+
function loadPluginManifest(path) {
|
|
58
|
+
const manifest = JSON.parse(fs.readFileSync(path, 'utf8'));
|
|
59
|
+
const { validatePluginManifest } = require('./lib/types/plugin-manifest');
|
|
60
|
+
validatePluginManifest(manifest);
|
|
61
|
+
return manifest;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Type Definitions
|
|
66
|
+
|
|
67
|
+
### PluginManifest
|
|
68
|
+
|
|
69
|
+
Defines the structure of `plugin.json`:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
interface PluginManifest {
|
|
73
|
+
name: string; // Unique identifier (kebab-case)
|
|
74
|
+
version: string; // Semantic version (X.Y.Z)
|
|
75
|
+
description: string; // Short description
|
|
76
|
+
author: PluginAuthor; // Author info
|
|
77
|
+
homepage?: string; // Plugin homepage URL
|
|
78
|
+
repository?: string; // Repository URL
|
|
79
|
+
license: string; // SPDX license identifier
|
|
80
|
+
keywords?: string[]; // Search keywords
|
|
81
|
+
minClaudeVersion?: string; // Minimum Claude Code version
|
|
82
|
+
dependencies?: { // Plugin dependencies
|
|
83
|
+
[pluginName: string]: string;
|
|
84
|
+
};
|
|
85
|
+
config?: { // Plugin configuration
|
|
86
|
+
[key: string]: unknown;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CommandFrontmatter
|
|
92
|
+
|
|
93
|
+
Defines YAML frontmatter for commands:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
---
|
|
97
|
+
command: my-command
|
|
98
|
+
description: Do something awesome
|
|
99
|
+
argument-hint: "[options]"
|
|
100
|
+
model: sonnet
|
|
101
|
+
requiresGit: true
|
|
102
|
+
tags:
|
|
103
|
+
- utility
|
|
104
|
+
- automation
|
|
105
|
+
---
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface CommandFrontmatter {
|
|
110
|
+
command: string; // Command name
|
|
111
|
+
description: string; // Short description
|
|
112
|
+
'argument-hint'?: string; // Autocomplete hint
|
|
113
|
+
usage?: string[]; // Usage examples
|
|
114
|
+
arguments?: CommandArgument[]; // Argument definitions
|
|
115
|
+
aliases?: string[]; // Alternative names
|
|
116
|
+
category?: string; // Command category
|
|
117
|
+
requiresGit?: boolean; // Requires git repo
|
|
118
|
+
requiresNetwork?: boolean; // Requires network
|
|
119
|
+
model?: 'sonnet' | 'opus' | 'haiku';
|
|
120
|
+
maxTurns?: number; // Max conversation turns
|
|
121
|
+
tags?: string[]; // Tags for search
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### AgentFrontmatter
|
|
126
|
+
|
|
127
|
+
Defines YAML frontmatter for agents:
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
---
|
|
131
|
+
agent: my-agent
|
|
132
|
+
description: Specialized agent for X
|
|
133
|
+
tools:
|
|
134
|
+
- Read
|
|
135
|
+
- Grep
|
|
136
|
+
- Glob
|
|
137
|
+
model: opus
|
|
138
|
+
color: blue
|
|
139
|
+
maxTurns: 10
|
|
140
|
+
---
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
interface AgentFrontmatter {
|
|
145
|
+
agent: string; // Agent identifier
|
|
146
|
+
description: string; // Purpose description
|
|
147
|
+
tools?: AgentTool[]; // Available tools
|
|
148
|
+
model?: 'sonnet' | 'opus' | 'haiku';
|
|
149
|
+
maxTurns?: number; // Max turns
|
|
150
|
+
color?: AgentColor; // UI color
|
|
151
|
+
canRunInBackground?: boolean; // Background support
|
|
152
|
+
requiresApproval?: boolean; // User approval needed
|
|
153
|
+
category?: string; // Agent category
|
|
154
|
+
tags?: string[]; // Tags for search
|
|
155
|
+
'when-to-use'?: string[]; // Triggering conditions
|
|
156
|
+
examples?: string[]; // Usage examples
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### SkillFrontmatter
|
|
161
|
+
|
|
162
|
+
Defines YAML frontmatter for skills:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
---
|
|
166
|
+
skill: my-skill
|
|
167
|
+
description: User-invocable skill
|
|
168
|
+
model: sonnet
|
|
169
|
+
when-to-use:
|
|
170
|
+
- "User says /my-skill"
|
|
171
|
+
- "Task requires X functionality"
|
|
172
|
+
---
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
interface SkillFrontmatter {
|
|
177
|
+
skill: string; // Skill identifier
|
|
178
|
+
description: string; // Purpose description
|
|
179
|
+
category?: string; // Skill category
|
|
180
|
+
'when-to-use'?: string[]; // Triggering conditions
|
|
181
|
+
examples?: string[]; // Usage examples
|
|
182
|
+
model?: 'sonnet' | 'opus' | 'haiku';
|
|
183
|
+
requiresApproval?: boolean; // User approval needed
|
|
184
|
+
tags?: string[]; // Tags for search
|
|
185
|
+
related?: string[]; // Related components
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### HookFrontmatter
|
|
190
|
+
|
|
191
|
+
Defines YAML frontmatter for hooks:
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
---
|
|
195
|
+
hook: my-hook
|
|
196
|
+
event: SubagentStop
|
|
197
|
+
description: Triggered when agent stops
|
|
198
|
+
priority: 10
|
|
199
|
+
enabled: true
|
|
200
|
+
---
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
interface HookFrontmatter {
|
|
205
|
+
hook: string; // Hook identifier
|
|
206
|
+
event: HookEvent; // Trigger event
|
|
207
|
+
description: string; // Purpose description
|
|
208
|
+
tool?: string; // Tool name (for PreToolUse/PostToolUse)
|
|
209
|
+
priority?: number; // Execution priority
|
|
210
|
+
enabled?: boolean; // Enabled by default
|
|
211
|
+
category?: string; // Hook category
|
|
212
|
+
tags?: string[]; // Tags for search
|
|
213
|
+
related?: string[]; // Related hooks
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Validation
|
|
218
|
+
|
|
219
|
+
All frontmatter types include validation functions:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import {
|
|
223
|
+
validatePluginManifest,
|
|
224
|
+
validateCommandFrontmatter,
|
|
225
|
+
validateAgentFrontmatter,
|
|
226
|
+
validateSkillFrontmatter,
|
|
227
|
+
validateHookFrontmatter
|
|
228
|
+
} from './lib/types';
|
|
229
|
+
|
|
230
|
+
// Throws Error if invalid
|
|
231
|
+
validatePluginManifest(manifest);
|
|
232
|
+
validateCommandFrontmatter(frontmatter);
|
|
233
|
+
validateAgentFrontmatter(frontmatter);
|
|
234
|
+
validateSkillFrontmatter(frontmatter);
|
|
235
|
+
validateHookFrontmatter(frontmatter);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Type Guards
|
|
239
|
+
|
|
240
|
+
Use type guards for runtime checking:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { isPluginManifest, isCommandFrontmatter } from './lib/types';
|
|
244
|
+
|
|
245
|
+
if (isPluginManifest(obj)) {
|
|
246
|
+
// obj is PluginManifest
|
|
247
|
+
console.log(obj.name);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (isCommandFrontmatter(obj)) {
|
|
251
|
+
// obj is CommandFrontmatter
|
|
252
|
+
console.log(obj.command);
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Plugin Structure
|
|
257
|
+
|
|
258
|
+
Standard plugin directory structure:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
my-plugin/
|
|
262
|
+
├── .claude-plugin/
|
|
263
|
+
│ └── plugin.json # Plugin manifest
|
|
264
|
+
├── commands/ # Slash commands
|
|
265
|
+
│ └── my-command.md
|
|
266
|
+
├── agents/ # Specialized agents
|
|
267
|
+
│ └── my-agent.md
|
|
268
|
+
├── skills/ # User-invocable skills
|
|
269
|
+
│ └── my-skill.md
|
|
270
|
+
├── hooks/ # Lifecycle hooks
|
|
271
|
+
│ └── my-hook.md
|
|
272
|
+
├── lib/ # Shared libraries
|
|
273
|
+
│ ├── platform/
|
|
274
|
+
│ ├── patterns/
|
|
275
|
+
│ └── utils/
|
|
276
|
+
└── tests/ # Tests
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Contributing
|
|
280
|
+
|
|
281
|
+
When adding new plugin component types:
|
|
282
|
+
|
|
283
|
+
1. Create a new `.d.ts` file in this directory
|
|
284
|
+
2. Define the interface with JSDoc comments
|
|
285
|
+
3. Add type guard function (`is*`)
|
|
286
|
+
4. Add validation function (`validate*`)
|
|
287
|
+
5. Export from `index.d.ts`
|
|
288
|
+
6. Update this README
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
MIT © Avi Fenesh
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Frontmatter Type Definitions
|
|
3
|
+
* Defines the structure of YAML frontmatter in agent markdown files
|
|
4
|
+
*
|
|
5
|
+
* @module lib/types/agent-frontmatter
|
|
6
|
+
* @author Avi Fenesh
|
|
7
|
+
* @license MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Tool permission for agent
|
|
12
|
+
*/
|
|
13
|
+
export type AgentTool =
|
|
14
|
+
| 'Bash'
|
|
15
|
+
| 'Bash(git:*)'
|
|
16
|
+
| 'Bash(gh:*)'
|
|
17
|
+
| 'Bash(npm:*)'
|
|
18
|
+
| 'Bash(node:*)'
|
|
19
|
+
| 'Bash(deployment:*)'
|
|
20
|
+
| 'Read'
|
|
21
|
+
| 'Write'
|
|
22
|
+
| 'Edit'
|
|
23
|
+
| 'Glob'
|
|
24
|
+
| 'Grep'
|
|
25
|
+
| 'Task'
|
|
26
|
+
| 'LSP'
|
|
27
|
+
| 'EnterPlanMode'
|
|
28
|
+
| 'ExitPlanMode'
|
|
29
|
+
| 'AskUserQuestion'
|
|
30
|
+
| 'TodoWrite'
|
|
31
|
+
| 'WebFetch'
|
|
32
|
+
| 'WebSearch'
|
|
33
|
+
| string; // Allow custom tools
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Agent color for UI identification
|
|
37
|
+
*/
|
|
38
|
+
export type AgentColor =
|
|
39
|
+
| 'blue'
|
|
40
|
+
| 'green'
|
|
41
|
+
| 'purple'
|
|
42
|
+
| 'orange'
|
|
43
|
+
| 'red'
|
|
44
|
+
| 'yellow'
|
|
45
|
+
| 'pink'
|
|
46
|
+
| 'cyan';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Agent frontmatter structure
|
|
50
|
+
* YAML metadata at the top of agent markdown files
|
|
51
|
+
*/
|
|
52
|
+
export interface AgentFrontmatter {
|
|
53
|
+
/** Agent unique identifier (kebab-case) */
|
|
54
|
+
agent: string;
|
|
55
|
+
|
|
56
|
+
/** Short description of agent purpose */
|
|
57
|
+
description: string;
|
|
58
|
+
|
|
59
|
+
/** Tools the agent has access to */
|
|
60
|
+
tools?: AgentTool[];
|
|
61
|
+
|
|
62
|
+
/** Preferred model for this agent (sonnet, opus, haiku) */
|
|
63
|
+
model?: 'sonnet' | 'opus' | 'haiku';
|
|
64
|
+
|
|
65
|
+
/** Maximum number of turns before stopping */
|
|
66
|
+
maxTurns?: number;
|
|
67
|
+
|
|
68
|
+
/** UI color for agent identification */
|
|
69
|
+
color?: AgentColor;
|
|
70
|
+
|
|
71
|
+
/** Whether agent can run in background */
|
|
72
|
+
canRunInBackground?: boolean;
|
|
73
|
+
|
|
74
|
+
/** Whether agent requires user approval before running */
|
|
75
|
+
requiresApproval?: boolean;
|
|
76
|
+
|
|
77
|
+
/** Agent category for organization */
|
|
78
|
+
category?: string;
|
|
79
|
+
|
|
80
|
+
/** Tags for searchability */
|
|
81
|
+
tags?: string[];
|
|
82
|
+
|
|
83
|
+
/** When this agent should be used (triggering conditions) */
|
|
84
|
+
'when-to-use'?: string[];
|
|
85
|
+
|
|
86
|
+
/** Example usage scenarios */
|
|
87
|
+
examples?: string[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Type guard to check if an object is valid AgentFrontmatter
|
|
92
|
+
*/
|
|
93
|
+
export function isAgentFrontmatter(obj: unknown): obj is AgentFrontmatter {
|
|
94
|
+
if (typeof obj !== 'object' || obj === null) return false;
|
|
95
|
+
const fm = obj as Partial<AgentFrontmatter>;
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
typeof fm.agent === 'string' &&
|
|
99
|
+
fm.agent.length > 0 &&
|
|
100
|
+
typeof fm.description === 'string' &&
|
|
101
|
+
fm.description.length > 0
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Validates agent frontmatter
|
|
107
|
+
* @throws {Error} If frontmatter is invalid
|
|
108
|
+
*/
|
|
109
|
+
export function validateAgentFrontmatter(
|
|
110
|
+
frontmatter: unknown
|
|
111
|
+
): asserts frontmatter is AgentFrontmatter {
|
|
112
|
+
if (!isAgentFrontmatter(frontmatter)) {
|
|
113
|
+
throw new Error('Invalid agent frontmatter: missing required fields');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Additional validations
|
|
117
|
+
if (frontmatter.tools && !Array.isArray(frontmatter.tools)) {
|
|
118
|
+
throw new Error('Invalid agent frontmatter: tools must be an array');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (frontmatter.model && !['sonnet', 'opus', 'haiku'].includes(frontmatter.model)) {
|
|
122
|
+
throw new Error('Invalid agent frontmatter: model must be sonnet, opus, or haiku');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (frontmatter.maxTurns !== undefined &&
|
|
126
|
+
(typeof frontmatter.maxTurns !== 'number' || frontmatter.maxTurns < 1)) {
|
|
127
|
+
throw new Error('Invalid agent frontmatter: maxTurns must be a positive number');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const validColors: AgentColor[] = ['blue', 'green', 'purple', 'orange', 'red', 'yellow', 'pink', 'cyan'];
|
|
131
|
+
if (frontmatter.color && !validColors.includes(frontmatter.color)) {
|
|
132
|
+
throw new Error(`Invalid agent frontmatter: color must be one of ${validColors.join(', ')}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Frontmatter Type Definitions
|
|
3
|
+
* Defines the structure of YAML frontmatter in command markdown files
|
|
4
|
+
*
|
|
5
|
+
* @module lib/types/command-frontmatter
|
|
6
|
+
* @author Avi Fenesh
|
|
7
|
+
* @license MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Command argument definition
|
|
12
|
+
*/
|
|
13
|
+
export interface CommandArgument {
|
|
14
|
+
/** Argument name */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Argument description */
|
|
17
|
+
description: string;
|
|
18
|
+
/** Whether argument is required */
|
|
19
|
+
required?: boolean;
|
|
20
|
+
/** Default value if not provided */
|
|
21
|
+
default?: string | number | boolean;
|
|
22
|
+
/** Allowed values (enum) */
|
|
23
|
+
enum?: string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Command frontmatter structure
|
|
28
|
+
* YAML metadata at the top of command markdown files
|
|
29
|
+
*/
|
|
30
|
+
export interface CommandFrontmatter {
|
|
31
|
+
/** Command name (should match filename without extension) */
|
|
32
|
+
command: string;
|
|
33
|
+
|
|
34
|
+
/** Short description shown in help */
|
|
35
|
+
description: string;
|
|
36
|
+
|
|
37
|
+
/** Argument hint shown in autocomplete (e.g., "[options]", "<file>") */
|
|
38
|
+
'argument-hint'?: string;
|
|
39
|
+
|
|
40
|
+
/** Detailed usage examples */
|
|
41
|
+
usage?: string[];
|
|
42
|
+
|
|
43
|
+
/** Command arguments definition */
|
|
44
|
+
arguments?: CommandArgument[];
|
|
45
|
+
|
|
46
|
+
/** Command aliases (alternative names) */
|
|
47
|
+
aliases?: string[];
|
|
48
|
+
|
|
49
|
+
/** Command category for grouping */
|
|
50
|
+
category?: string;
|
|
51
|
+
|
|
52
|
+
/** Whether command requires git repository */
|
|
53
|
+
requiresGit?: boolean;
|
|
54
|
+
|
|
55
|
+
/** Whether command requires network access */
|
|
56
|
+
requiresNetwork?: boolean;
|
|
57
|
+
|
|
58
|
+
/** Preferred model for this command (sonnet, opus, haiku) */
|
|
59
|
+
model?: 'sonnet' | 'opus' | 'haiku';
|
|
60
|
+
|
|
61
|
+
/** Maximum number of turns for multi-turn commands */
|
|
62
|
+
maxTurns?: number;
|
|
63
|
+
|
|
64
|
+
/** Tags for searchability */
|
|
65
|
+
tags?: string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Type guard to check if an object is valid CommandFrontmatter
|
|
70
|
+
*/
|
|
71
|
+
export function isCommandFrontmatter(obj: unknown): obj is CommandFrontmatter {
|
|
72
|
+
if (typeof obj !== 'object' || obj === null) return false;
|
|
73
|
+
const fm = obj as Partial<CommandFrontmatter>;
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
typeof fm.command === 'string' &&
|
|
77
|
+
fm.command.length > 0 &&
|
|
78
|
+
typeof fm.description === 'string' &&
|
|
79
|
+
fm.description.length > 0
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Validates command frontmatter
|
|
85
|
+
* @throws {Error} If frontmatter is invalid
|
|
86
|
+
*/
|
|
87
|
+
export function validateCommandFrontmatter(
|
|
88
|
+
frontmatter: unknown
|
|
89
|
+
): asserts frontmatter is CommandFrontmatter {
|
|
90
|
+
if (!isCommandFrontmatter(frontmatter)) {
|
|
91
|
+
throw new Error('Invalid command frontmatter: missing required fields');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Additional validations
|
|
95
|
+
if (frontmatter.arguments && !Array.isArray(frontmatter.arguments)) {
|
|
96
|
+
throw new Error('Invalid command frontmatter: arguments must be an array');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (frontmatter.model && !['sonnet', 'opus', 'haiku'].includes(frontmatter.model)) {
|
|
100
|
+
throw new Error('Invalid command frontmatter: model must be sonnet, opus, or haiku');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (frontmatter.maxTurns !== undefined &&
|
|
104
|
+
(typeof frontmatter.maxTurns !== 'number' || frontmatter.maxTurns < 1)) {
|
|
105
|
+
throw new Error('Invalid command frontmatter: maxTurns must be a positive number');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook Frontmatter Type Definitions
|
|
3
|
+
* Defines the structure of YAML frontmatter in hook markdown files
|
|
4
|
+
*
|
|
5
|
+
* @module lib/types/hook-frontmatter
|
|
6
|
+
* @author Avi Fenesh
|
|
7
|
+
* @license MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Hook event types
|
|
12
|
+
*/
|
|
13
|
+
export type HookEvent =
|
|
14
|
+
| 'PreToolUse'
|
|
15
|
+
| 'PostToolUse'
|
|
16
|
+
| 'Stop'
|
|
17
|
+
| 'SubagentStop'
|
|
18
|
+
| 'SessionStart'
|
|
19
|
+
| 'SessionEnd'
|
|
20
|
+
| 'UserPromptSubmit'
|
|
21
|
+
| 'PreCompact'
|
|
22
|
+
| 'Notification';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Hook frontmatter structure
|
|
26
|
+
* YAML metadata at the top of hook markdown files
|
|
27
|
+
*/
|
|
28
|
+
export interface HookFrontmatter {
|
|
29
|
+
/** Hook unique identifier (kebab-case) */
|
|
30
|
+
hook: string;
|
|
31
|
+
|
|
32
|
+
/** Event that triggers this hook */
|
|
33
|
+
event: HookEvent;
|
|
34
|
+
|
|
35
|
+
/** Short description of hook purpose */
|
|
36
|
+
description: string;
|
|
37
|
+
|
|
38
|
+
/** Tool name this hook applies to (for PreToolUse/PostToolUse) */
|
|
39
|
+
tool?: string;
|
|
40
|
+
|
|
41
|
+
/** Hook priority (higher = runs first, default: 0) */
|
|
42
|
+
priority?: number;
|
|
43
|
+
|
|
44
|
+
/** Whether hook is enabled by default */
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
|
|
47
|
+
/** Hook category for organization */
|
|
48
|
+
category?: string;
|
|
49
|
+
|
|
50
|
+
/** Tags for searchability */
|
|
51
|
+
tags?: string[];
|
|
52
|
+
|
|
53
|
+
/** Related hooks */
|
|
54
|
+
related?: string[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Type guard to check if an object is valid HookFrontmatter
|
|
59
|
+
*/
|
|
60
|
+
export function isHookFrontmatter(obj: unknown): obj is HookFrontmatter {
|
|
61
|
+
if (typeof obj !== 'object' || obj === null) return false;
|
|
62
|
+
const fm = obj as Partial<HookFrontmatter>;
|
|
63
|
+
|
|
64
|
+
const validEvents: HookEvent[] = [
|
|
65
|
+
'PreToolUse',
|
|
66
|
+
'PostToolUse',
|
|
67
|
+
'Stop',
|
|
68
|
+
'SubagentStop',
|
|
69
|
+
'SessionStart',
|
|
70
|
+
'SessionEnd',
|
|
71
|
+
'UserPromptSubmit',
|
|
72
|
+
'PreCompact',
|
|
73
|
+
'Notification'
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
typeof fm.hook === 'string' &&
|
|
78
|
+
fm.hook.length > 0 &&
|
|
79
|
+
typeof fm.event === 'string' &&
|
|
80
|
+
validEvents.includes(fm.event as HookEvent) &&
|
|
81
|
+
typeof fm.description === 'string' &&
|
|
82
|
+
fm.description.length > 0
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validates hook frontmatter
|
|
88
|
+
* @throws {Error} If frontmatter is invalid
|
|
89
|
+
*/
|
|
90
|
+
export function validateHookFrontmatter(
|
|
91
|
+
frontmatter: unknown
|
|
92
|
+
): asserts frontmatter is HookFrontmatter {
|
|
93
|
+
if (!isHookFrontmatter(frontmatter)) {
|
|
94
|
+
throw new Error('Invalid hook frontmatter: missing required fields or invalid event type');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Tool-specific hooks must specify tool
|
|
98
|
+
if ((frontmatter.event === 'PreToolUse' || frontmatter.event === 'PostToolUse') &&
|
|
99
|
+
!frontmatter.tool) {
|
|
100
|
+
throw new Error('Invalid hook frontmatter: PreToolUse and PostToolUse hooks must specify tool');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (frontmatter.priority !== undefined &&
|
|
104
|
+
(typeof frontmatter.priority !== 'number' || !Number.isInteger(frontmatter.priority))) {
|
|
105
|
+
throw new Error('Invalid hook frontmatter: priority must be an integer');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (frontmatter.tags && !Array.isArray(frontmatter.tags)) {
|
|
109
|
+
throw new Error('Invalid hook frontmatter: tags must be an array');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (frontmatter.related && !Array.isArray(frontmatter.related)) {
|
|
113
|
+
throw new Error('Invalid hook frontmatter: related must be an array');
|
|
114
|
+
}
|
|
115
|
+
}
|