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,239 @@
1
+ /**
2
+ * Policy Questions Builder
3
+ * Builds AskUserQuestion-ready structure with cache awareness
4
+ *
5
+ * @module lib/sources/policy-questions
6
+ */
7
+
8
+ const sourceCache = require('./source-cache');
9
+ const customHandler = require('./custom-handler');
10
+
11
+ /**
12
+ * Source label mapping for proper casing
13
+ */
14
+ const SOURCE_LABELS = {
15
+ github: 'GitHub',
16
+ gitlab: 'GitLab',
17
+ local: 'Local',
18
+ custom: 'Custom',
19
+ other: 'Other'
20
+ };
21
+
22
+ /**
23
+ * Get policy questions with cache-aware options
24
+ * Call this once - returns full question structure ready for AskUserQuestion
25
+ *
26
+ * @returns {Object} { questions: [...], cachedPreference: {...}|null }
27
+ */
28
+ function getPolicyQuestions() {
29
+ const cached = sourceCache.getPreference();
30
+
31
+ // Build source options
32
+ const sourceOptions = [];
33
+
34
+ // If cached, add as first option
35
+ if (cached) {
36
+ const cachedLabel = cached.source === 'custom'
37
+ ? `${cached.tool} (${cached.type})`
38
+ : SOURCE_LABELS[cached.source] || (cached.source.charAt(0).toUpperCase() + cached.source.slice(1));
39
+
40
+ sourceOptions.push({
41
+ label: `${cachedLabel} (last used)`,
42
+ description: 'Use your previous choice'
43
+ });
44
+ }
45
+
46
+ // Standard options
47
+ sourceOptions.push(
48
+ { label: 'GitHub Issues', description: 'Use gh CLI to list issues' },
49
+ { label: 'GitLab Issues', description: 'Use glab CLI to list issues' },
50
+ { label: 'Local tasks.md', description: 'Read from PLAN.md, tasks.md, or TODO.md' },
51
+ { label: 'Custom', description: 'Specify your tool: CLI, MCP, Skill, or file path' },
52
+ { label: 'Other', description: 'Describe your source - agent figures it out' }
53
+ );
54
+
55
+ return {
56
+ questions: [
57
+ {
58
+ header: 'Source',
59
+ question: 'Where should I look for tasks?',
60
+ options: sourceOptions,
61
+ multiSelect: false
62
+ },
63
+ {
64
+ header: 'Priority',
65
+ question: 'What type of tasks to prioritize?',
66
+ options: [
67
+ { label: 'All', description: 'Consider all tasks, pick by score' },
68
+ { label: 'Bugs', description: 'Focus on bug fixes' },
69
+ { label: 'Security', description: 'Security issues first' },
70
+ { label: 'Features', description: 'New feature development' }
71
+ ],
72
+ multiSelect: false
73
+ },
74
+ {
75
+ header: 'Stop Point',
76
+ question: 'How far should I take this task?',
77
+ options: [
78
+ { label: 'Merged', description: 'Until PR is merged to main' },
79
+ { label: 'PR Created', description: 'Stop after creating PR' },
80
+ { label: 'Implemented', description: 'Stop after local implementation' },
81
+ { label: 'Deployed', description: 'Deploy to staging' },
82
+ { label: 'Production', description: 'Full production deployment' }
83
+ ],
84
+ multiSelect: false
85
+ }
86
+ ],
87
+ cachedPreference: cached
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Get custom source follow-up questions
93
+ * Call after user selects "Custom"
94
+ *
95
+ * @returns {Object} Question structure for custom type selection
96
+ */
97
+ function getCustomTypeQuestions() {
98
+ return {
99
+ questions: [customHandler.getCustomTypeQuestion()]
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Get custom name question based on type
105
+ * @param {string} type - cli, mcp, skill, or file
106
+ * @returns {Object} Question structure for tool/path name
107
+ */
108
+ function getCustomNameQuestion(type) {
109
+ const q = customHandler.getCustomNameQuestion(type);
110
+ return {
111
+ questions: [{
112
+ header: q.header,
113
+ question: q.question,
114
+ options: [], // Free text input via "Other"
115
+ multiSelect: false
116
+ }]
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Parse policy responses and build policy object
122
+ * Also handles caching
123
+ *
124
+ * @param {Object} responses - User's answers
125
+ * @param {string} responses.source - Source selection
126
+ * @param {string} responses.priority - Priority selection
127
+ * @param {string} responses.stopPoint - Stop point selection
128
+ * @param {Object} [responses.custom] - Custom source details (if applicable)
129
+ * @returns {Object} Policy object ready for workflow state
130
+ */
131
+ function parseAndCachePolicy(responses) {
132
+ const policy = {
133
+ taskSource: mapSource(responses.source, responses.custom),
134
+ priorityFilter: mapPriority(responses.priority),
135
+ stoppingPoint: mapStopPoint(responses.stopPoint)
136
+ };
137
+
138
+ // Cache source preference (unless "other" which is ad-hoc)
139
+ if (policy.taskSource.source !== 'other') {
140
+ sourceCache.savePreference(policy.taskSource);
141
+ }
142
+
143
+ return policy;
144
+ }
145
+
146
+ /**
147
+ * Map source selection to policy value
148
+ */
149
+ function mapSource(selection, customDetails) {
150
+ // Check if user selected cached option
151
+ if (selection.includes('(last used)')) {
152
+ return sourceCache.getPreference();
153
+ }
154
+
155
+ const sourceMap = {
156
+ 'GitHub Issues': { source: 'github' },
157
+ 'GitLab Issues': { source: 'gitlab' },
158
+ 'Local tasks.md': { source: 'local' },
159
+ 'Custom': null, // Handled separately
160
+ 'Other': null // Handled separately
161
+ };
162
+
163
+ if (selection === 'Custom' && customDetails) {
164
+ // Normalize type label to internal value (e.g., "CLI Tool" -> "cli")
165
+ const normalizedType = customHandler.mapTypeSelection(customDetails.type);
166
+ const config = customHandler.buildCustomConfig(normalizedType, customDetails.name);
167
+ return config;
168
+ }
169
+
170
+ if (selection === 'Other') {
171
+ return { source: 'other', description: customDetails?.description || '' };
172
+ }
173
+
174
+ return sourceMap[selection] || { source: 'github' };
175
+ }
176
+
177
+ /**
178
+ * Map priority selection to policy value
179
+ */
180
+ function mapPriority(selection) {
181
+ const map = {
182
+ 'All': 'all',
183
+ 'Bugs': 'bugs',
184
+ 'Security': 'security',
185
+ 'Features': 'features'
186
+ };
187
+ return map[selection] || 'all';
188
+ }
189
+
190
+ /**
191
+ * Map stop point selection to policy value
192
+ */
193
+ function mapStopPoint(selection) {
194
+ const map = {
195
+ 'Merged': 'merged',
196
+ 'PR Created': 'pr-created',
197
+ 'Implemented': 'implemented',
198
+ 'Deployed': 'deployed',
199
+ 'Production': 'production'
200
+ };
201
+ return map[selection] || 'merged';
202
+ }
203
+
204
+ /**
205
+ * Check if user selected cached preference
206
+ * @param {string} selection - User's source selection
207
+ * @returns {boolean}
208
+ */
209
+ function isUsingCached(selection) {
210
+ return selection.includes('(last used)');
211
+ }
212
+
213
+ /**
214
+ * Check if custom follow-up is needed
215
+ * @param {string} selection - User's source selection
216
+ * @returns {boolean}
217
+ */
218
+ function needsCustomFollowUp(selection) {
219
+ return selection === 'Custom';
220
+ }
221
+
222
+ /**
223
+ * Check if "other" description is needed
224
+ * @param {string} selection - User's source selection
225
+ * @returns {boolean}
226
+ */
227
+ function needsOtherDescription(selection) {
228
+ return selection === 'Other';
229
+ }
230
+
231
+ module.exports = {
232
+ getPolicyQuestions,
233
+ getCustomTypeQuestions,
234
+ getCustomNameQuestion,
235
+ parseAndCachePolicy,
236
+ isUsingCached,
237
+ needsCustomFollowUp,
238
+ needsOtherDescription
239
+ };
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Source Cache
3
+ * File-based persistence for task source preferences
4
+ *
5
+ * @module lib/sources/source-cache
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const SOURCES_DIR = '.claude/sources';
12
+ const PREFERENCE_FILE = 'preference.json';
13
+
14
+ /**
15
+ * Validate tool name to prevent path traversal
16
+ * @param {string} toolName - Tool name to validate
17
+ * @returns {boolean} True if valid
18
+ */
19
+ function isValidToolName(toolName) {
20
+ // Prevent path traversal and shell metacharacters
21
+ return /^[a-zA-Z0-9_-]+$/.test(toolName);
22
+ }
23
+
24
+ /**
25
+ * Ensure sources directory exists
26
+ * @returns {string} Path to sources directory
27
+ */
28
+ function ensureDir() {
29
+ if (!fs.existsSync(SOURCES_DIR)) {
30
+ fs.mkdirSync(SOURCES_DIR, { recursive: true });
31
+ }
32
+ return SOURCES_DIR;
33
+ }
34
+
35
+ /**
36
+ * Get cached source preference
37
+ * @returns {Object|null} Preference object or null if not cached
38
+ * @example
39
+ * // Returns: { source: 'github' }
40
+ * // Or: { source: 'custom', type: 'cli', tool: 'tea' }
41
+ */
42
+ function getPreference() {
43
+ const filePath = path.join(SOURCES_DIR, PREFERENCE_FILE);
44
+ if (!fs.existsSync(filePath)) {
45
+ return null;
46
+ }
47
+ try {
48
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
49
+ } catch (err) {
50
+ console.error(`Failed to read preference file:`, err.message);
51
+ return null;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Save source preference
57
+ * @param {Object} preference - Preference object
58
+ * @param {string} preference.source - Source type (github, gitlab, local, custom, other)
59
+ * @param {string} [preference.type] - For custom: mcp, cli, skill, file
60
+ * @param {string} [preference.tool] - Tool name or path
61
+ * @param {string} [preference.description] - For other: user's free text
62
+ */
63
+ function savePreference(preference) {
64
+ ensureDir();
65
+ const filePath = path.join(SOURCES_DIR, PREFERENCE_FILE);
66
+ fs.writeFileSync(filePath, JSON.stringify({
67
+ ...preference,
68
+ savedAt: new Date().toISOString()
69
+ }, null, 2));
70
+ }
71
+
72
+ /**
73
+ * Get cached tool capabilities (for custom sources)
74
+ * @param {string} toolName - Tool identifier (e.g., 'tea', 'glab')
75
+ * @returns {Object|null} Capabilities object or null
76
+ */
77
+ function getToolCapabilities(toolName) {
78
+ // Prevent path traversal
79
+ if (!isValidToolName(toolName)) {
80
+ console.error(`Invalid tool name: ${toolName}`);
81
+ return null;
82
+ }
83
+ const filePath = path.join(SOURCES_DIR, `${toolName}.json`);
84
+ if (!fs.existsSync(filePath)) {
85
+ return null;
86
+ }
87
+ try {
88
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
89
+ } catch (err) {
90
+ console.error(`Failed to read tool capabilities for ${toolName}:`, err.message);
91
+ return null;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Save tool capabilities after discovery
97
+ * @param {string} toolName - Tool identifier
98
+ * @param {Object} capabilities - Discovered capabilities
99
+ * @param {string[]} capabilities.features - Available features (issues, prs, ci)
100
+ * @param {Object} capabilities.commands - Command mappings
101
+ */
102
+ function saveToolCapabilities(toolName, capabilities) {
103
+ // Prevent path traversal
104
+ if (!isValidToolName(toolName)) {
105
+ console.error(`Invalid tool name: ${toolName}`);
106
+ return;
107
+ }
108
+ ensureDir();
109
+ const filePath = path.join(SOURCES_DIR, `${toolName}.json`);
110
+ fs.writeFileSync(filePath, JSON.stringify({
111
+ ...capabilities,
112
+ discoveredAt: new Date().toISOString()
113
+ }, null, 2));
114
+ }
115
+
116
+ /**
117
+ * Clear all cached preferences
118
+ */
119
+ function clearCache() {
120
+ if (fs.existsSync(SOURCES_DIR)) {
121
+ const files = fs.readdirSync(SOURCES_DIR);
122
+ for (const file of files) {
123
+ const filePath = path.join(SOURCES_DIR, file);
124
+ const stats = fs.statSync(filePath);
125
+ if (stats.isFile()) {
126
+ fs.unlinkSync(filePath);
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Check if preference matches a specific source
134
+ * @param {string} source - Source to check
135
+ * @returns {boolean} True if preference matches
136
+ */
137
+ function isPreferred(source) {
138
+ const pref = getPreference();
139
+ return pref?.source === source;
140
+ }
141
+
142
+ module.exports = {
143
+ getPreference,
144
+ savePreference,
145
+ getToolCapabilities,
146
+ saveToolCapabilities,
147
+ clearCache,
148
+ isPreferred
149
+ };