awesome-slash 2.4.4 → 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.
- package/.claude-plugin/marketplace.json +6 -6
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +88 -1
- package/README.md +173 -161
- 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/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 +149 -0
- package/lib/state/workflow-state.js +363 -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 -18
- 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 +170 -129
- package/plugins/deslop-around/lib/platform/detect-platform.js +212 -123
- package/plugins/deslop-around/lib/platform/detection-configs.js +93 -0
- package/plugins/deslop-around/lib/platform/verify-tools.js +10 -1
- package/plugins/deslop-around/lib/schemas/README.md +195 -0
- package/plugins/deslop-around/lib/schemas/validator.js +205 -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 +149 -0
- package/plugins/deslop-around/lib/state/workflow-state.js +382 -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 +170 -129
- package/plugins/next-task/lib/platform/detect-platform.js +212 -123
- package/plugins/next-task/lib/platform/detection-configs.js +93 -0
- package/plugins/next-task/lib/platform/verify-tools.js +10 -1
- package/plugins/next-task/lib/schemas/README.md +195 -0
- package/plugins/next-task/lib/schemas/validator.js +205 -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 +149 -0
- package/plugins/next-task/lib/state/workflow-state.js +382 -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 +170 -129
- package/plugins/project-review/lib/platform/detect-platform.js +212 -123
- package/plugins/project-review/lib/platform/detection-configs.js +93 -0
- package/plugins/project-review/lib/platform/verify-tools.js +10 -1
- package/plugins/project-review/lib/schemas/README.md +195 -0
- package/plugins/project-review/lib/schemas/validator.js +205 -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 +149 -0
- package/plugins/project-review/lib/state/workflow-state.js +382 -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 +170 -129
- package/plugins/ship/lib/platform/detect-platform.js +212 -123
- package/plugins/ship/lib/platform/detection-configs.js +93 -0
- package/plugins/ship/lib/platform/verify-tools.js +10 -1
- package/plugins/ship/lib/schemas/README.md +195 -0
- package/plugins/ship/lib/schemas/validator.js +205 -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 +149 -0
- package/plugins/ship/lib/state/workflow-state.js +382 -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/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
package/SECURITY.md
CHANGED
|
@@ -1,101 +1,45 @@
|
|
|
1
1
|
# Security Policy
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
We release patches for security vulnerabilities. Currently supported versions:
|
|
6
|
-
|
|
7
|
-
| Version | Supported |
|
|
8
|
-
| ------- | ------------------ |
|
|
9
|
-
| 1.x.x | :white_check_mark: |
|
|
10
|
-
| < 1.0 | :x: |
|
|
3
|
+
> **Disclaimer:** This plugin is provided as-is. Usage is entirely at your own responsibility. The maintainers make no guarantees about security or fitness for any particular purpose.
|
|
11
4
|
|
|
12
5
|
## Reporting a Vulnerability
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### 1. Do Not Publicly Disclose
|
|
17
|
-
|
|
18
|
-
Please **do not** open a public issue. Security vulnerabilities should be reported privately.
|
|
19
|
-
|
|
20
|
-
### 2. Report Via GitHub Security Advisories
|
|
21
|
-
|
|
22
|
-
Use GitHub's Security Advisory feature:
|
|
23
|
-
1. Go to the [Security tab](https://github.com/avifenesh/awesome-slash/security/advisories)
|
|
24
|
-
2. Click "Report a vulnerability"
|
|
25
|
-
3. Provide detailed information about the vulnerability
|
|
26
|
-
|
|
27
|
-
### 3. Or Email Directly
|
|
28
|
-
|
|
29
|
-
If you prefer, you can email security reports to:
|
|
30
|
-
- **Email:** Create a private security advisory on GitHub instead (preferred method)
|
|
31
|
-
|
|
32
|
-
### 4. Include in Your Report
|
|
7
|
+
If you discover a security vulnerability:
|
|
33
8
|
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
- Potential impact
|
|
38
|
-
- Suggested fix (if you have one)
|
|
39
|
-
- Your contact information
|
|
9
|
+
1. **Do not** open a public issue
|
|
10
|
+
2. Use [GitHub Security Advisories](https://github.com/avifenesh/awesome-slash/security/advisories) to report privately
|
|
11
|
+
3. Include steps to reproduce and potential impact
|
|
40
12
|
|
|
41
|
-
##
|
|
13
|
+
## User Responsibility
|
|
42
14
|
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
15
|
+
**You are responsible for:**
|
|
16
|
+
- Reviewing all code changes made by agents before committing
|
|
17
|
+
- Never committing secrets, API keys, or credentials
|
|
18
|
+
- Validating deployments before shipping to production
|
|
19
|
+
- Understanding what commands do before running them
|
|
47
20
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
### When Using Commands
|
|
51
|
-
|
|
52
|
-
1. **Review Generated Code:** Always review code changes made by agents before committing
|
|
53
|
-
2. **Check Credentials:** Never commit secrets, API keys, or credentials
|
|
54
|
-
3. **Deployment Caution:** Validate deployments before shipping to production
|
|
55
|
-
4. **PR Reviews:** Use `/project-review` quality gates to catch security issues
|
|
56
|
-
|
|
57
|
-
### Platform Detection Scripts
|
|
58
|
-
|
|
59
|
-
The platform detection scripts in `lib/` execute shell commands. They:
|
|
60
|
-
- Do not execute arbitrary user input
|
|
61
|
-
- Only read configuration files
|
|
62
|
-
- Do not modify system files
|
|
63
|
-
- Run in the project directory only
|
|
64
|
-
|
|
65
|
-
### Command Safety
|
|
66
|
-
|
|
67
|
-
Commands that modify your repository:
|
|
68
|
-
- `/ship` - Commits, pushes code, creates and merges PRs
|
|
21
|
+
**Commands that modify your repository:**
|
|
22
|
+
- `/ship` - Commits, pushes, creates and merges PRs
|
|
69
23
|
- `/next-task` - Full workflow automation including code changes
|
|
70
24
|
- `/deslop-around --apply` - Modifies source files
|
|
71
25
|
|
|
72
26
|
Always review changes with `git status` and `git diff` before running commands that commit or push.
|
|
73
27
|
|
|
74
|
-
##
|
|
75
|
-
|
|
76
|
-
This security policy covers:
|
|
77
|
-
- Awesome Slash Commands plugin code
|
|
78
|
-
- Platform detection scripts
|
|
79
|
-
- Command implementations
|
|
80
|
-
- Dependencies
|
|
28
|
+
## Security Measures (v2.5.0+)
|
|
81
29
|
|
|
82
|
-
|
|
83
|
-
- Vulnerabilities in Claude Code itself (report to Anthropic)
|
|
84
|
-
- Vulnerabilities in external tools (gh, git, npm, etc.)
|
|
85
|
-
- Issues with deployment platforms (Railway, Vercel, etc.)
|
|
30
|
+
The plugin includes basic protections:
|
|
86
31
|
|
|
87
|
-
|
|
32
|
+
- **Command Injection Prevention:** Uses `execFileSync` with input validation
|
|
33
|
+
- **Path Traversal Prevention:** Tool names validated with allowlist patterns
|
|
34
|
+
- **Input Validation:** User-provided values sanitized before use
|
|
88
35
|
|
|
89
|
-
|
|
90
|
-
1. Check if we're using the latest version
|
|
91
|
-
2. If not, please report it
|
|
92
|
-
3. If we are, please report to the dependency maintainer
|
|
36
|
+
These measures reduce risk but do not guarantee security.
|
|
93
37
|
|
|
94
|
-
##
|
|
38
|
+
## Scope
|
|
95
39
|
|
|
96
|
-
|
|
97
|
-
- Our CHANGELOG.md
|
|
98
|
-
- The security advisory
|
|
99
|
-
- This SECURITY.md file
|
|
40
|
+
This policy covers the awesome-slash plugin code only.
|
|
100
41
|
|
|
101
|
-
|
|
42
|
+
**Not covered:**
|
|
43
|
+
- Claude Code itself (report to Anthropic)
|
|
44
|
+
- External tools (gh, git, npm, etc.)
|
|
45
|
+
- Deployment platforms (Railway, Vercel, etc.)
|
|
@@ -84,32 +84,74 @@ echo
|
|
|
84
84
|
# Install commands with path adjustments
|
|
85
85
|
echo "⚙️ Installing commands..."
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
87
|
+
# Command mappings: target_name:plugin:source_file
|
|
88
|
+
# Format allows commands from different plugins
|
|
89
|
+
COMMAND_MAPPINGS=(
|
|
90
|
+
"deslop-around:deslop-around:deslop-around"
|
|
91
|
+
"next-task:next-task:next-task"
|
|
92
|
+
"delivery-approval:next-task:delivery-approval"
|
|
93
|
+
"update-docs-around:next-task:update-docs-around"
|
|
94
|
+
"project-review:project-review:project-review"
|
|
95
|
+
"ship:ship:ship"
|
|
96
|
+
"reality-check-scan:reality-check:scan"
|
|
97
|
+
"reality-check-set:reality-check:set"
|
|
93
98
|
)
|
|
94
99
|
|
|
95
|
-
for
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
TARGET_FILE="$CODEX_PROMPTS_DIR/$
|
|
100
|
+
for mapping in "${COMMAND_MAPPINGS[@]}"; do
|
|
101
|
+
IFS=':' read -r TARGET_NAME PLUGIN SOURCE_NAME <<< "$mapping"
|
|
102
|
+
SOURCE_FILE="$REPO_ROOT/plugins/$PLUGIN/commands/$SOURCE_NAME.md"
|
|
103
|
+
TARGET_FILE="$CODEX_PROMPTS_DIR/$TARGET_NAME.md"
|
|
99
104
|
|
|
100
105
|
if [ -f "$SOURCE_FILE" ]; then
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
sed "s|\${CLAUDE_PLUGIN_ROOT}|${SAFE_LIB_DIR}|g" "$SOURCE_FILE" > "$TARGET_FILE"
|
|
105
|
-
echo " ✓ Installed /prompts:$cmd"
|
|
106
|
+
# Copy command file to prompts directory
|
|
107
|
+
cp "$SOURCE_FILE" "$TARGET_FILE"
|
|
108
|
+
echo " ✓ Installed /prompts:$TARGET_NAME"
|
|
106
109
|
else
|
|
107
|
-
echo " ⚠️ Skipped /$
|
|
110
|
+
echo " ⚠️ Skipped /$TARGET_NAME (source not found: $SOURCE_FILE)"
|
|
111
|
+
fi
|
|
112
|
+
done
|
|
113
|
+
|
|
114
|
+
# Remove old/legacy commands that no longer exist
|
|
115
|
+
OLD_COMMANDS=("pr-merge")
|
|
116
|
+
for old_cmd in "${OLD_COMMANDS[@]}"; do
|
|
117
|
+
if [ -f "$CODEX_PROMPTS_DIR/$old_cmd.md" ]; then
|
|
118
|
+
rm "$CODEX_PROMPTS_DIR/$old_cmd.md"
|
|
119
|
+
echo " 🗑️ Removed legacy /prompts:$old_cmd"
|
|
108
120
|
fi
|
|
109
121
|
done
|
|
110
122
|
|
|
111
123
|
echo
|
|
112
124
|
|
|
125
|
+
# Configure MCP server
|
|
126
|
+
echo "🔌 Configuring MCP server..."
|
|
127
|
+
CONFIG_TOML="$CODEX_CONFIG_DIR/config.toml"
|
|
128
|
+
|
|
129
|
+
# Convert repo path to forward slashes for config
|
|
130
|
+
MCP_PATH="${REPO_ROOT//\\//}"
|
|
131
|
+
|
|
132
|
+
# Check if config.toml exists and has MCP section
|
|
133
|
+
if [ -f "$CONFIG_TOML" ]; then
|
|
134
|
+
# Remove old awesome-slash MCP config if exists
|
|
135
|
+
if grep -q "\[mcp_servers.awesome-slash\]" "$CONFIG_TOML" 2>/dev/null; then
|
|
136
|
+
# Use sed to remove the old section (everything between [mcp_servers.awesome-slash] and next section or EOF)
|
|
137
|
+
sed -i '/\[mcp_servers.awesome-slash\]/,/^\[/{ /^\[mcp_servers.awesome-slash\]/d; /^\[/!d; }' "$CONFIG_TOML" 2>/dev/null || true
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Append MCP server config
|
|
142
|
+
cat >> "$CONFIG_TOML" << EOF
|
|
143
|
+
|
|
144
|
+
[mcp_servers.awesome-slash]
|
|
145
|
+
command = "node"
|
|
146
|
+
args = ["${MCP_PATH}/mcp-server/index.js"]
|
|
147
|
+
|
|
148
|
+
[mcp_servers.awesome-slash.env]
|
|
149
|
+
PLUGIN_ROOT = "${MCP_PATH}"
|
|
150
|
+
EOF
|
|
151
|
+
|
|
152
|
+
echo " ✓ Added MCP server to config.toml"
|
|
153
|
+
echo
|
|
154
|
+
|
|
113
155
|
# Create README
|
|
114
156
|
cat > "$CODEX_CONFIG_DIR/AWESOME_SLASH_README.md" << 'EOF'
|
|
115
157
|
# awesome-slash for Codex CLI
|
|
@@ -9,19 +9,16 @@ echo
|
|
|
9
9
|
|
|
10
10
|
# Configuration
|
|
11
11
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
12
|
+
|
|
13
|
+
# Use $HOME which works correctly on all platforms including Git Bash on Windows
|
|
14
|
+
# (Git Bash sets HOME to Unix-style path like /c/Users/username)
|
|
12
15
|
OPENCODE_CONFIG_DIR="${HOME}/.opencode"
|
|
13
16
|
OPENCODE_COMMANDS_DIR="${OPENCODE_CONFIG_DIR}/commands/awesome-slash"
|
|
14
17
|
LIB_DIR="${OPENCODE_COMMANDS_DIR}/lib"
|
|
15
18
|
|
|
16
|
-
# Detect OS
|
|
17
|
-
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
|
19
|
+
# Detect OS for platform-specific notes
|
|
20
|
+
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" || "$OSTYPE" == "cygwin" ]]; then
|
|
18
21
|
IS_WINDOWS=true
|
|
19
|
-
# Convert Windows path to Unix-style for bash compatibility
|
|
20
|
-
OPENCODE_CONFIG_DIR="${USERPROFILE}/.opencode"
|
|
21
|
-
# Replace backslashes with forward slashes
|
|
22
|
-
OPENCODE_CONFIG_DIR="${OPENCODE_CONFIG_DIR//\\//}"
|
|
23
|
-
OPENCODE_COMMANDS_DIR="${OPENCODE_CONFIG_DIR}/commands/awesome-slash"
|
|
24
|
-
LIB_DIR="${OPENCODE_COMMANDS_DIR}/lib"
|
|
25
22
|
else
|
|
26
23
|
IS_WINDOWS=false
|
|
27
24
|
fi
|
|
@@ -83,26 +80,39 @@ echo
|
|
|
83
80
|
# Install commands with path adjustments
|
|
84
81
|
echo "⚙️ Installing commands..."
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
83
|
+
# Command mappings: target_name:plugin:source_file
|
|
84
|
+
# Format allows commands from different plugins
|
|
85
|
+
COMMAND_MAPPINGS=(
|
|
86
|
+
"deslop-around:deslop-around:deslop-around"
|
|
87
|
+
"next-task:next-task:next-task"
|
|
88
|
+
"delivery-approval:next-task:delivery-approval"
|
|
89
|
+
"update-docs-around:next-task:update-docs-around"
|
|
90
|
+
"project-review:project-review:project-review"
|
|
91
|
+
"ship:ship:ship"
|
|
92
|
+
"reality-check-scan:reality-check:scan"
|
|
93
|
+
"reality-check-set:reality-check:set"
|
|
92
94
|
)
|
|
93
95
|
|
|
94
|
-
for
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
for mapping in "${COMMAND_MAPPINGS[@]}"; do
|
|
97
|
+
IFS=':' read -r TARGET_NAME PLUGIN SOURCE_NAME <<< "$mapping"
|
|
98
|
+
SOURCE_FILE="$REPO_ROOT/plugins/$PLUGIN/commands/$SOURCE_NAME.md"
|
|
99
|
+
TARGET_FILE="$OPENCODE_COMMANDS_DIR/$TARGET_NAME.md"
|
|
97
100
|
|
|
98
101
|
if [ -f "$SOURCE_FILE" ]; then
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
sed "s|\${CLAUDE_PLUGIN_ROOT}|${SAFE_COMMANDS_DIR}|g" "$SOURCE_FILE" > "$TARGET_FILE"
|
|
103
|
-
echo " ✓ Installed /$cmd"
|
|
102
|
+
# Copy command file to commands directory
|
|
103
|
+
cp "$SOURCE_FILE" "$TARGET_FILE"
|
|
104
|
+
echo " ✓ Installed /$TARGET_NAME"
|
|
104
105
|
else
|
|
105
|
-
echo " ⚠️ Skipped /$
|
|
106
|
+
echo " ⚠️ Skipped /$TARGET_NAME (source not found: $SOURCE_FILE)"
|
|
107
|
+
fi
|
|
108
|
+
done
|
|
109
|
+
|
|
110
|
+
# Remove old/legacy commands that no longer exist
|
|
111
|
+
OLD_COMMANDS=("pr-merge")
|
|
112
|
+
for old_cmd in "${OLD_COMMANDS[@]}"; do
|
|
113
|
+
if [ -f "$OPENCODE_COMMANDS_DIR/$old_cmd.md" ]; then
|
|
114
|
+
rm "$OPENCODE_COMMANDS_DIR/$old_cmd.md"
|
|
115
|
+
echo " 🗑️ Removed legacy /$old_cmd"
|
|
106
116
|
fi
|
|
107
117
|
done
|
|
108
118
|
|
|
@@ -129,6 +139,65 @@ chmod +x "$OPENCODE_COMMANDS_DIR/env.sh"
|
|
|
129
139
|
echo " ✓ Created environment setup script"
|
|
130
140
|
echo
|
|
131
141
|
|
|
142
|
+
# Configure MCP server
|
|
143
|
+
echo "🔌 Configuring MCP server..."
|
|
144
|
+
OPENCODE_GLOBAL_CONFIG_DIR="${HOME}/.config/opencode"
|
|
145
|
+
CONFIG_JSON="$OPENCODE_GLOBAL_CONFIG_DIR/opencode.json"
|
|
146
|
+
|
|
147
|
+
# Convert repo path to forward slashes for config
|
|
148
|
+
MCP_PATH="${REPO_ROOT//\\//}"
|
|
149
|
+
|
|
150
|
+
# Ensure config directory exists
|
|
151
|
+
mkdir -p "$OPENCODE_GLOBAL_CONFIG_DIR"
|
|
152
|
+
|
|
153
|
+
# Create or update opencode.json with MCP config
|
|
154
|
+
if [ -f "$CONFIG_JSON" ]; then
|
|
155
|
+
# Check if we have jq for proper JSON manipulation
|
|
156
|
+
if command -v jq &> /dev/null; then
|
|
157
|
+
# Update existing config with jq
|
|
158
|
+
jq --arg path "$MCP_PATH" '.mcp["awesome-slash"] = {
|
|
159
|
+
"type": "local",
|
|
160
|
+
"command": ["node", ($path + "/mcp-server/index.js")],
|
|
161
|
+
"environment": {"PLUGIN_ROOT": $path},
|
|
162
|
+
"enabled": true
|
|
163
|
+
}' "$CONFIG_JSON" > "$CONFIG_JSON.tmp" && mv "$CONFIG_JSON.tmp" "$CONFIG_JSON"
|
|
164
|
+
else
|
|
165
|
+
# Fallback: Use node to update JSON
|
|
166
|
+
node -e "
|
|
167
|
+
const fs = require('fs');
|
|
168
|
+
const config = JSON.parse(fs.readFileSync('$CONFIG_JSON', 'utf8'));
|
|
169
|
+
config.mcp = config.mcp || {};
|
|
170
|
+
config.mcp['awesome-slash'] = {
|
|
171
|
+
type: 'local',
|
|
172
|
+
command: ['node', '$MCP_PATH/mcp-server/index.js'],
|
|
173
|
+
environment: { PLUGIN_ROOT: '$MCP_PATH' },
|
|
174
|
+
enabled: true
|
|
175
|
+
};
|
|
176
|
+
fs.writeFileSync('$CONFIG_JSON', JSON.stringify(config, null, 2));
|
|
177
|
+
"
|
|
178
|
+
fi
|
|
179
|
+
else
|
|
180
|
+
# Create new config
|
|
181
|
+
cat > "$CONFIG_JSON" << EOF
|
|
182
|
+
{
|
|
183
|
+
"mcp": {
|
|
184
|
+
"awesome-slash": {
|
|
185
|
+
"type": "local",
|
|
186
|
+
"command": ["node", "${MCP_PATH}/mcp-server/index.js"],
|
|
187
|
+
"environment": {
|
|
188
|
+
"PLUGIN_ROOT": "${MCP_PATH}"
|
|
189
|
+
},
|
|
190
|
+
"enabled": true
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"\$schema": "https://opencode.ai/config.json"
|
|
194
|
+
}
|
|
195
|
+
EOF
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
echo " ✓ Added MCP server to opencode.json"
|
|
199
|
+
echo
|
|
200
|
+
|
|
132
201
|
# Create README
|
|
133
202
|
cat > "$OPENCODE_COMMANDS_DIR/README.md" << 'EOF'
|
|
134
203
|
# awesome-slash for OpenCode
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Unified entry point for all core library modules.
|
|
5
5
|
* Provides platform detection, pattern matching, workflow state management,
|
|
6
|
-
* and context optimization utilities.
|
|
6
|
+
* configuration management, and context optimization utilities.
|
|
7
7
|
*
|
|
8
8
|
* @module awesome-slash/lib
|
|
9
9
|
* @author Avi Fenesh
|
|
@@ -16,6 +16,11 @@ const reviewPatterns = require('./patterns/review-patterns');
|
|
|
16
16
|
const slopPatterns = require('./patterns/slop-patterns');
|
|
17
17
|
const workflowState = require('./state/workflow-state');
|
|
18
18
|
const contextOptimizer = require('./utils/context-optimizer');
|
|
19
|
+
const shellEscape = require('./utils/shell-escape');
|
|
20
|
+
const config = require('./config');
|
|
21
|
+
const sourceCache = require('./sources/source-cache');
|
|
22
|
+
const customHandler = require('./sources/custom-handler');
|
|
23
|
+
const policyQuestions = require('./sources/policy-questions');
|
|
19
24
|
|
|
20
25
|
/**
|
|
21
26
|
* Platform detection and verification utilities
|
|
@@ -77,6 +82,7 @@ const state = {
|
|
|
77
82
|
generateWorkflowId: workflowState.generateWorkflowId,
|
|
78
83
|
getStatePath: workflowState.getStatePath,
|
|
79
84
|
ensureStateDir: workflowState.ensureStateDir,
|
|
85
|
+
validateStateSchema: workflowState.validateStateSchema,
|
|
80
86
|
|
|
81
87
|
// CRUD operations
|
|
82
88
|
createState: workflowState.createState,
|
|
@@ -103,11 +109,42 @@ const state = {
|
|
|
103
109
|
};
|
|
104
110
|
|
|
105
111
|
/**
|
|
106
|
-
* Git command optimization utilities
|
|
112
|
+
* Git command optimization and string escaping utilities
|
|
107
113
|
* @see module:utils/context-optimizer
|
|
114
|
+
* @see module:utils/shell-escape
|
|
108
115
|
*/
|
|
109
116
|
const utils = {
|
|
110
|
-
contextOptimizer
|
|
117
|
+
contextOptimizer,
|
|
118
|
+
shellEscape
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Task source management
|
|
123
|
+
* @see module:sources/source-cache
|
|
124
|
+
* @see module:sources/custom-handler
|
|
125
|
+
* @see module:sources/policy-questions
|
|
126
|
+
*/
|
|
127
|
+
const sources = {
|
|
128
|
+
// Main entry point - returns ready-to-use question structure
|
|
129
|
+
getPolicyQuestions: policyQuestions.getPolicyQuestions,
|
|
130
|
+
getCustomTypeQuestions: policyQuestions.getCustomTypeQuestions,
|
|
131
|
+
getCustomNameQuestion: policyQuestions.getCustomNameQuestion,
|
|
132
|
+
parseAndCachePolicy: policyQuestions.parseAndCachePolicy,
|
|
133
|
+
isUsingCached: policyQuestions.isUsingCached,
|
|
134
|
+
needsCustomFollowUp: policyQuestions.needsCustomFollowUp,
|
|
135
|
+
needsOtherDescription: policyQuestions.needsOtherDescription,
|
|
136
|
+
|
|
137
|
+
// Cache operations (direct access if needed)
|
|
138
|
+
getPreference: sourceCache.getPreference,
|
|
139
|
+
savePreference: sourceCache.savePreference,
|
|
140
|
+
getToolCapabilities: sourceCache.getToolCapabilities,
|
|
141
|
+
saveToolCapabilities: sourceCache.saveToolCapabilities,
|
|
142
|
+
clearCache: sourceCache.clearCache,
|
|
143
|
+
|
|
144
|
+
// Custom source handling (direct access if needed)
|
|
145
|
+
SOURCE_TYPES: customHandler.SOURCE_TYPES,
|
|
146
|
+
probeCLI: customHandler.probeCLI,
|
|
147
|
+
buildCustomConfig: customHandler.buildCustomConfig
|
|
111
148
|
};
|
|
112
149
|
|
|
113
150
|
// Main exports
|
|
@@ -116,6 +153,8 @@ module.exports = {
|
|
|
116
153
|
patterns,
|
|
117
154
|
state,
|
|
118
155
|
utils,
|
|
156
|
+
config,
|
|
157
|
+
sources,
|
|
119
158
|
|
|
120
159
|
// Direct module access for backward compatibility
|
|
121
160
|
detectPlatform,
|
|
@@ -123,5 +162,9 @@ module.exports = {
|
|
|
123
162
|
reviewPatterns,
|
|
124
163
|
slopPatterns,
|
|
125
164
|
workflowState,
|
|
126
|
-
contextOptimizer
|
|
165
|
+
contextOptimizer,
|
|
166
|
+
shellEscape,
|
|
167
|
+
sourceCache,
|
|
168
|
+
customHandler,
|
|
169
|
+
policyQuestions
|
|
127
170
|
};
|
|
@@ -328,8 +328,24 @@ const _patternCountByFramework = new Map();
|
|
|
328
328
|
*/
|
|
329
329
|
const _flattenedPatterns = new Map();
|
|
330
330
|
|
|
331
|
-
|
|
332
|
-
(
|
|
331
|
+
/**
|
|
332
|
+
* Track if indexes have been built (lazy initialization)
|
|
333
|
+
*/
|
|
334
|
+
let _indexesBuilt = false;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Cached arrays for getAvailableFrameworks/Categories (computed once)
|
|
338
|
+
*/
|
|
339
|
+
let _cachedFrameworks = null;
|
|
340
|
+
let _cachedCategories = null;
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Build indexes on first access (lazy initialization)
|
|
344
|
+
* This improves module load time by deferring work until needed
|
|
345
|
+
*/
|
|
346
|
+
function ensureIndexesBuilt() {
|
|
347
|
+
if (_indexesBuilt) return;
|
|
348
|
+
|
|
333
349
|
for (const [framework, categories] of Object.entries(reviewPatterns)) {
|
|
334
350
|
let totalPatterns = 0;
|
|
335
351
|
const flattened = [];
|
|
@@ -355,11 +371,13 @@ const _flattenedPatterns = new Map();
|
|
|
355
371
|
_patternCountByFramework.set(framework, totalPatterns);
|
|
356
372
|
_flattenedPatterns.set(framework, flattened);
|
|
357
373
|
}
|
|
358
|
-
})();
|
|
359
374
|
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
375
|
+
// Cache the arrays (avoid repeated Array.from calls)
|
|
376
|
+
_cachedFrameworks = Array.from(_frameworksSet);
|
|
377
|
+
_cachedCategories = Array.from(_categoriesSet);
|
|
378
|
+
|
|
379
|
+
_indexesBuilt = true;
|
|
380
|
+
}
|
|
363
381
|
|
|
364
382
|
/**
|
|
365
383
|
* Get review patterns for a detected framework (O(1) lookup)
|
|
@@ -377,6 +395,7 @@ function getPatternsForFramework(framework) {
|
|
|
377
395
|
* @returns {Map<string, Array>} Map of framework -> patterns for that category
|
|
378
396
|
*/
|
|
379
397
|
function getPatternsByCategory(category) {
|
|
398
|
+
ensureIndexesBuilt();
|
|
380
399
|
return _patternsByCategory.get(category) || new Map();
|
|
381
400
|
}
|
|
382
401
|
|
|
@@ -393,19 +412,23 @@ function getPatternsForFrameworkCategory(framework, category) {
|
|
|
393
412
|
}
|
|
394
413
|
|
|
395
414
|
/**
|
|
396
|
-
* Get all available frameworks (O(1) via
|
|
415
|
+
* Get all available frameworks (O(1) via cached array)
|
|
416
|
+
* Optimized: returns cached array instead of Array.from() on every call
|
|
397
417
|
* @returns {Array<string>} List of framework names
|
|
398
418
|
*/
|
|
399
419
|
function getAvailableFrameworks() {
|
|
400
|
-
|
|
420
|
+
ensureIndexesBuilt();
|
|
421
|
+
return _cachedFrameworks;
|
|
401
422
|
}
|
|
402
423
|
|
|
403
424
|
/**
|
|
404
|
-
* Get all available categories across all frameworks
|
|
425
|
+
* Get all available categories across all frameworks (O(1) via cached array)
|
|
426
|
+
* Optimized: returns cached array instead of Array.from() on every call
|
|
405
427
|
* @returns {Array<string>} List of category names
|
|
406
428
|
*/
|
|
407
429
|
function getAvailableCategories() {
|
|
408
|
-
|
|
430
|
+
ensureIndexesBuilt();
|
|
431
|
+
return _cachedCategories;
|
|
409
432
|
}
|
|
410
433
|
|
|
411
434
|
/**
|
|
@@ -435,6 +458,7 @@ function hasPatternsFor(framework) {
|
|
|
435
458
|
* @returns {boolean} True if category exists
|
|
436
459
|
*/
|
|
437
460
|
function hasCategory(category) {
|
|
461
|
+
ensureIndexesBuilt();
|
|
438
462
|
return _categoriesSet.has(category);
|
|
439
463
|
}
|
|
440
464
|
|
|
@@ -444,6 +468,7 @@ function hasCategory(category) {
|
|
|
444
468
|
* @returns {number} Number of patterns
|
|
445
469
|
*/
|
|
446
470
|
function getPatternCount(framework) {
|
|
471
|
+
ensureIndexesBuilt();
|
|
447
472
|
return _patternCountByFramework.get(framework.toLowerCase()) || 0;
|
|
448
473
|
}
|
|
449
474
|
|
|
@@ -452,6 +477,7 @@ function getPatternCount(framework) {
|
|
|
452
477
|
* @returns {number} Total pattern count
|
|
453
478
|
*/
|
|
454
479
|
function getTotalPatternCount() {
|
|
480
|
+
ensureIndexesBuilt();
|
|
455
481
|
let total = 0;
|
|
456
482
|
for (const count of _patternCountByFramework.values()) {
|
|
457
483
|
total += count;
|
|
@@ -461,17 +487,37 @@ function getTotalPatternCount() {
|
|
|
461
487
|
|
|
462
488
|
/**
|
|
463
489
|
* Search patterns by keyword across all frameworks
|
|
490
|
+
* Optimized: supports pagination to avoid returning thousands of results
|
|
464
491
|
* @param {string} keyword - Search term (case-insensitive)
|
|
492
|
+
* @param {Object} [options] - Search options
|
|
493
|
+
* @param {number} [options.limit] - Maximum number of results (default: unlimited)
|
|
494
|
+
* @param {number} [options.offset=0] - Number of results to skip
|
|
465
495
|
* @returns {Array<{framework: string, category: string, pattern: string}>} Matching patterns
|
|
466
496
|
*/
|
|
467
|
-
function searchPatterns(keyword) {
|
|
497
|
+
function searchPatterns(keyword, options = {}) {
|
|
498
|
+
ensureIndexesBuilt();
|
|
468
499
|
const lowerKeyword = keyword.toLowerCase();
|
|
500
|
+
const { limit, offset = 0 } = options;
|
|
469
501
|
const results = [];
|
|
502
|
+
let skipped = 0;
|
|
503
|
+
let collected = 0;
|
|
470
504
|
|
|
471
505
|
for (const [framework, patterns] of _flattenedPatterns) {
|
|
472
506
|
for (const { category, pattern } of patterns) {
|
|
473
507
|
if (pattern.toLowerCase().includes(lowerKeyword)) {
|
|
508
|
+
// Skip results until we reach offset
|
|
509
|
+
if (skipped < offset) {
|
|
510
|
+
skipped++;
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
|
|
474
514
|
results.push({ framework, category, pattern });
|
|
515
|
+
collected++;
|
|
516
|
+
|
|
517
|
+
// Stop if we've collected enough results
|
|
518
|
+
if (limit && collected >= limit) {
|
|
519
|
+
return results;
|
|
520
|
+
}
|
|
475
521
|
}
|
|
476
522
|
}
|
|
477
523
|
}
|
|
@@ -485,6 +531,7 @@ function searchPatterns(keyword) {
|
|
|
485
531
|
* @returns {Array<string>} List of frameworks with this category
|
|
486
532
|
*/
|
|
487
533
|
function getFrameworksWithCategory(category) {
|
|
534
|
+
ensureIndexesBuilt();
|
|
488
535
|
const categoryMap = _patternsByCategory.get(category);
|
|
489
536
|
if (!categoryMap) return [];
|
|
490
537
|
return Array.from(categoryMap.keys());
|