awesome-slash 2.4.3 → 2.5.0

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.
Files changed (146) hide show
  1. package/.claude-plugin/marketplace.json +6 -6
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +99 -1
  4. package/README.md +173 -161
  5. package/SECURITY.md +25 -81
  6. package/adapters/codex/install.sh +58 -16
  7. package/adapters/opencode/install.sh +92 -23
  8. package/lib/index.js +47 -4
  9. package/lib/patterns/review-patterns.js +58 -11
  10. package/lib/patterns/slop-patterns.js +154 -147
  11. package/lib/platform/detect-platform.js +99 -350
  12. package/lib/platform/detection-configs.js +93 -0
  13. package/lib/platform/verify-tools.js +10 -78
  14. package/lib/schemas/README.md +195 -0
  15. package/lib/schemas/validator.js +247 -0
  16. package/lib/sources/custom-handler.js +199 -0
  17. package/lib/sources/policy-questions.js +239 -0
  18. package/lib/sources/source-cache.js +149 -0
  19. package/lib/state/workflow-state.js +363 -665
  20. package/lib/types/README.md +292 -0
  21. package/lib/types/agent-frontmatter.d.ts +134 -0
  22. package/lib/types/command-frontmatter.d.ts +107 -0
  23. package/lib/types/hook-frontmatter.d.ts +115 -0
  24. package/lib/types/index.d.ts +84 -0
  25. package/lib/types/plugin-manifest.d.ts +102 -0
  26. package/lib/types/skill-frontmatter.d.ts +89 -0
  27. package/lib/utils/cache-manager.js +154 -0
  28. package/lib/utils/context-optimizer.js +5 -36
  29. package/lib/utils/deprecation.js +37 -0
  30. package/lib/utils/shell-escape.js +88 -0
  31. package/mcp-server/index.js +513 -18
  32. package/package.json +6 -2
  33. package/plugins/deslop-around/.claude-plugin/plugin.json +1 -1
  34. package/plugins/deslop-around/lib/index.js +170 -0
  35. package/plugins/deslop-around/lib/patterns/review-patterns.js +58 -11
  36. package/plugins/deslop-around/lib/patterns/slop-patterns.js +170 -129
  37. package/plugins/deslop-around/lib/platform/detect-platform.js +212 -123
  38. package/plugins/deslop-around/lib/platform/detection-configs.js +93 -0
  39. package/plugins/deslop-around/lib/platform/verify-tools.js +10 -1
  40. package/plugins/deslop-around/lib/schemas/README.md +195 -0
  41. package/plugins/deslop-around/lib/schemas/validator.js +205 -0
  42. package/plugins/deslop-around/lib/sources/custom-handler.js +199 -0
  43. package/plugins/deslop-around/lib/sources/policy-questions.js +239 -0
  44. package/plugins/deslop-around/lib/sources/source-cache.js +149 -0
  45. package/plugins/deslop-around/lib/state/workflow-state.js +382 -484
  46. package/plugins/deslop-around/lib/types/README.md +292 -0
  47. package/plugins/deslop-around/lib/types/agent-frontmatter.d.ts +134 -0
  48. package/plugins/deslop-around/lib/types/command-frontmatter.d.ts +107 -0
  49. package/plugins/deslop-around/lib/types/hook-frontmatter.d.ts +115 -0
  50. package/plugins/deslop-around/lib/types/index.d.ts +84 -0
  51. package/plugins/deslop-around/lib/types/plugin-manifest.d.ts +102 -0
  52. package/plugins/deslop-around/lib/types/skill-frontmatter.d.ts +89 -0
  53. package/plugins/deslop-around/lib/utils/cache-manager.js +154 -0
  54. package/plugins/deslop-around/lib/utils/context-optimizer.js +115 -37
  55. package/plugins/deslop-around/lib/utils/deprecation.js +37 -0
  56. package/plugins/deslop-around/lib/utils/shell-escape.js +88 -0
  57. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  58. package/plugins/next-task/agents/ci-monitor.md +19 -0
  59. package/plugins/next-task/agents/delivery-validator.md +2 -2
  60. package/plugins/next-task/agents/implementation-agent.md +3 -4
  61. package/plugins/next-task/agents/planning-agent.md +77 -19
  62. package/plugins/next-task/agents/review-orchestrator.md +21 -122
  63. package/plugins/next-task/agents/task-discoverer.md +164 -23
  64. package/plugins/next-task/commands/next-task.md +180 -14
  65. package/plugins/next-task/lib/index.js +170 -0
  66. package/plugins/next-task/lib/patterns/review-patterns.js +58 -11
  67. package/plugins/next-task/lib/patterns/slop-patterns.js +170 -129
  68. package/plugins/next-task/lib/platform/detect-platform.js +212 -123
  69. package/plugins/next-task/lib/platform/detection-configs.js +93 -0
  70. package/plugins/next-task/lib/platform/verify-tools.js +10 -1
  71. package/plugins/next-task/lib/schemas/README.md +195 -0
  72. package/plugins/next-task/lib/schemas/validator.js +205 -0
  73. package/plugins/next-task/lib/sources/custom-handler.js +199 -0
  74. package/plugins/next-task/lib/sources/policy-questions.js +239 -0
  75. package/plugins/next-task/lib/sources/source-cache.js +149 -0
  76. package/plugins/next-task/lib/state/workflow-state.js +382 -484
  77. package/plugins/next-task/lib/types/README.md +292 -0
  78. package/plugins/next-task/lib/types/agent-frontmatter.d.ts +134 -0
  79. package/plugins/next-task/lib/types/command-frontmatter.d.ts +107 -0
  80. package/plugins/next-task/lib/types/hook-frontmatter.d.ts +115 -0
  81. package/plugins/next-task/lib/types/index.d.ts +84 -0
  82. package/plugins/next-task/lib/types/plugin-manifest.d.ts +102 -0
  83. package/plugins/next-task/lib/types/skill-frontmatter.d.ts +89 -0
  84. package/plugins/next-task/lib/utils/cache-manager.js +154 -0
  85. package/plugins/next-task/lib/utils/context-optimizer.js +115 -37
  86. package/plugins/next-task/lib/utils/deprecation.js +37 -0
  87. package/plugins/next-task/lib/utils/shell-escape.js +88 -0
  88. package/plugins/project-review/.claude-plugin/plugin.json +1 -1
  89. package/plugins/project-review/lib/index.js +170 -0
  90. package/plugins/project-review/lib/patterns/review-patterns.js +58 -11
  91. package/plugins/project-review/lib/patterns/slop-patterns.js +170 -129
  92. package/plugins/project-review/lib/platform/detect-platform.js +212 -123
  93. package/plugins/project-review/lib/platform/detection-configs.js +93 -0
  94. package/plugins/project-review/lib/platform/verify-tools.js +10 -1
  95. package/plugins/project-review/lib/schemas/README.md +195 -0
  96. package/plugins/project-review/lib/schemas/validator.js +205 -0
  97. package/plugins/project-review/lib/sources/custom-handler.js +199 -0
  98. package/plugins/project-review/lib/sources/policy-questions.js +239 -0
  99. package/plugins/project-review/lib/sources/source-cache.js +149 -0
  100. package/plugins/project-review/lib/state/workflow-state.js +382 -484
  101. package/plugins/project-review/lib/types/README.md +292 -0
  102. package/plugins/project-review/lib/types/agent-frontmatter.d.ts +134 -0
  103. package/plugins/project-review/lib/types/command-frontmatter.d.ts +107 -0
  104. package/plugins/project-review/lib/types/hook-frontmatter.d.ts +115 -0
  105. package/plugins/project-review/lib/types/index.d.ts +84 -0
  106. package/plugins/project-review/lib/types/plugin-manifest.d.ts +102 -0
  107. package/plugins/project-review/lib/types/skill-frontmatter.d.ts +89 -0
  108. package/plugins/project-review/lib/utils/cache-manager.js +154 -0
  109. package/plugins/project-review/lib/utils/context-optimizer.js +115 -37
  110. package/plugins/project-review/lib/utils/deprecation.js +37 -0
  111. package/plugins/project-review/lib/utils/shell-escape.js +88 -0
  112. package/plugins/reality-check/.claude-plugin/plugin.json +1 -1
  113. package/plugins/reality-check/agents/code-explorer.md +1 -1
  114. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  115. package/plugins/ship/commands/ship-ci-review-loop.md +19 -0
  116. package/plugins/ship/lib/index.js +170 -0
  117. package/plugins/ship/lib/patterns/review-patterns.js +58 -11
  118. package/plugins/ship/lib/patterns/slop-patterns.js +170 -129
  119. package/plugins/ship/lib/platform/detect-platform.js +212 -123
  120. package/plugins/ship/lib/platform/detection-configs.js +93 -0
  121. package/plugins/ship/lib/platform/verify-tools.js +10 -1
  122. package/plugins/ship/lib/schemas/README.md +195 -0
  123. package/plugins/ship/lib/schemas/validator.js +205 -0
  124. package/plugins/ship/lib/sources/custom-handler.js +199 -0
  125. package/plugins/ship/lib/sources/policy-questions.js +239 -0
  126. package/plugins/ship/lib/sources/source-cache.js +149 -0
  127. package/plugins/ship/lib/state/workflow-state.js +382 -484
  128. package/plugins/ship/lib/types/README.md +292 -0
  129. package/plugins/ship/lib/types/agent-frontmatter.d.ts +134 -0
  130. package/plugins/ship/lib/types/command-frontmatter.d.ts +107 -0
  131. package/plugins/ship/lib/types/hook-frontmatter.d.ts +115 -0
  132. package/plugins/ship/lib/types/index.d.ts +84 -0
  133. package/plugins/ship/lib/types/plugin-manifest.d.ts +102 -0
  134. package/plugins/ship/lib/types/skill-frontmatter.d.ts +89 -0
  135. package/plugins/ship/lib/utils/cache-manager.js +154 -0
  136. package/plugins/ship/lib/utils/context-optimizer.js +115 -37
  137. package/plugins/ship/lib/utils/deprecation.js +37 -0
  138. package/plugins/ship/lib/utils/shell-escape.js +88 -0
  139. package/lib/state/workflow-state.schema.json +0 -282
  140. package/plugins/deslop-around/lib/state/workflow-state.schema.json +0 -282
  141. package/plugins/next-task/agents/policy-selector.md +0 -248
  142. package/plugins/next-task/lib/state/tasks-registry.schema.json +0 -85
  143. package/plugins/next-task/lib/state/workflow-state.schema.json +0 -282
  144. package/plugins/next-task/lib/state/worktree-status.schema.json +0 -219
  145. package/plugins/project-review/lib/state/workflow-state.schema.json +0 -282
  146. 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
+ }