awesome-slash 3.8.1 → 3.8.2

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 (29) hide show
  1. package/.claude-plugin/marketplace.json +10 -10
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +11 -0
  4. package/adapters/opencode/install.sh +63 -4
  5. package/bin/cli.js +1 -1
  6. package/lib/patterns/slop-patterns.js +18 -0
  7. package/package.json +1 -1
  8. package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
  9. package/plugins/audit-project/lib/patterns/slop-patterns.js +18 -0
  10. package/plugins/deslop/.claude-plugin/plugin.json +1 -1
  11. package/plugins/deslop/lib/patterns/slop-patterns.js +18 -0
  12. package/plugins/deslop/references/slop-categories.md +15 -0
  13. package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
  14. package/plugins/drift-detect/lib/patterns/slop-patterns.js +18 -0
  15. package/plugins/enhance/.claude-plugin/plugin.json +1 -1
  16. package/plugins/enhance/lib/patterns/slop-patterns.js +18 -0
  17. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  18. package/plugins/next-task/commands/next-task.md +45 -18
  19. package/plugins/next-task/lib/patterns/slop-patterns.js +18 -0
  20. package/plugins/perf/.claude-plugin/plugin.json +1 -1
  21. package/plugins/perf/lib/patterns/slop-patterns.js +18 -0
  22. package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
  23. package/plugins/repo-map/lib/patterns/slop-patterns.js +18 -0
  24. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  25. package/plugins/ship/lib/patterns/slop-patterns.js +18 -0
  26. package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
  27. package/plugins/sync-docs/lib/patterns/slop-patterns.js +18 -0
  28. package/scripts/dev-install.js +116 -34
  29. package/scripts/validate-opencode-install.js +16 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
3
  "description": "9 specialized plugins for AI workflow automation - task orchestration, PR workflow, slop detection, code review, drift detection, enhancement analysis, documentation sync, repo mapping, and perf investigations",
4
- "version": "3.8.1",
4
+ "version": "3.8.2",
5
5
  "owner": {
6
6
  "name": "Avi Fenesh",
7
7
  "url": "https://github.com/avifenesh"
@@ -26,63 +26,63 @@
26
26
  "name": "next-task",
27
27
  "source": "./plugins/next-task",
28
28
  "description": "Master workflow orchestrator: autonomous workflow with model optimization (opus/sonnet/haiku), two-file state management, workflow enforcement gates, 14 specialist agents",
29
- "version": "3.8.1",
29
+ "version": "3.8.2",
30
30
  "category": "productivity"
31
31
  },
32
32
  {
33
33
  "name": "ship",
34
34
  "source": "./plugins/ship",
35
35
  "description": "Complete PR workflow: commit to production, skips review when called from next-task, removes task from registry on cleanup, automatic rollback",
36
- "version": "3.8.1",
36
+ "version": "3.8.2",
37
37
  "category": "deployment"
38
38
  },
39
39
  {
40
40
  "name": "deslop",
41
41
  "source": "./plugins/deslop",
42
42
  "description": "3-phase AI slop detection: regex patterns (HIGH), multi-pass analyzers (MEDIUM), CLI tools (LOW)",
43
- "version": "3.8.1",
43
+ "version": "3.8.2",
44
44
  "category": "development"
45
45
  },
46
46
  {
47
47
  "name": "audit-project",
48
48
  "source": "./plugins/audit-project",
49
49
  "description": "Multi-agent iterative code review until zero issues remain",
50
- "version": "3.8.1",
50
+ "version": "3.8.2",
51
51
  "category": "development"
52
52
  },
53
53
  {
54
54
  "name": "drift-detect",
55
55
  "source": "./plugins/drift-detect",
56
56
  "description": "Deep repository analysis to realign project plans with code reality - detects drift, gaps, and creates prioritized reconstruction plans",
57
- "version": "3.8.1",
57
+ "version": "3.8.2",
58
58
  "category": "productivity"
59
59
  },
60
60
  {
61
61
  "name": "enhance",
62
62
  "source": "./plugins/enhance",
63
63
  "description": "Master enhancement orchestrator: parallel analyzer execution for plugins, agents, docs, CLAUDE.md, and prompts with unified reporting",
64
- "version": "3.8.1",
64
+ "version": "3.8.2",
65
65
  "category": "development"
66
66
  },
67
67
  {
68
68
  "name": "sync-docs",
69
69
  "source": "./plugins/sync-docs",
70
70
  "description": "Standalone documentation sync: find outdated refs, update CHANGELOG, flag stale examples based on code changes",
71
- "version": "3.8.1",
71
+ "version": "3.8.2",
72
72
  "category": "development"
73
73
  },
74
74
  {
75
75
  "name": "repo-map",
76
76
  "source": "./plugins/repo-map",
77
77
  "description": "AST-based repository map generation using ast-grep with incremental updates for faster drift analysis",
78
- "version": "3.8.1",
78
+ "version": "3.8.2",
79
79
  "category": "development"
80
80
  },
81
81
  {
82
82
  "name": "perf",
83
83
  "source": "./plugins/perf",
84
84
  "description": "Rigorous performance investigation workflow with baselines, profiling, hypotheses, and evidence-backed decisions",
85
- "version": "3.8.1",
85
+ "version": "3.8.2",
86
86
  "category": "development"
87
87
  }
88
88
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Professional-grade slash commands for Claude Code with cross-platform support",
5
5
  "keywords": [
6
6
  "workflow",
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.8.2] - 2026-02-04
11
+
12
+ ### Fixed
13
+ - **Policy Questions Enforcement** - /next-task Phase 1 now explicitly requires all 3 policy questions (Source, Priority, Stop Point) with table and forbidden actions
14
+ - **Codex CLI Installer** - Fixed undefined `configPath` variable (should be `configDir`)
15
+
16
+ ### Changed
17
+ - **XML Tag Consistency** - All 12 workflow phases now wrapped in consistent `<phase-N>` tags
18
+ - **Constructive Language** - Replaced "you are wrong" with guidance pointing to consequences table
19
+ - **Redundancy Reduction** - Consolidated duplicate forbidden actions lists
20
+
10
21
  ## [3.8.1] - 2026-02-04
11
22
 
12
23
  ### Fixed
@@ -12,10 +12,22 @@ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
12
12
 
13
13
  # Use $HOME which works correctly on all platforms including Git Bash on Windows
14
14
  # (Git Bash sets HOME to Unix-style path like /c/Users/username)
15
- OPENCODE_CONFIG_DIR="${HOME}/.opencode"
16
- OPENCODE_COMMANDS_DIR="${OPENCODE_CONFIG_DIR}/commands/awesome-slash"
15
+ # OpenCode global config follows XDG Base Directory Specification:
16
+ # - Default: ~/.config/opencode/
17
+ # - Override: $XDG_CONFIG_HOME/opencode/ (if XDG_CONFIG_HOME is set and not empty/whitespace)
18
+ # Note: Must match logic in scripts/dev-install.js getOpenCodeConfigDir()
19
+ if [[ -n "${XDG_CONFIG_HOME}" && "${XDG_CONFIG_HOME}" =~ [^[:space:]] ]]; then
20
+ OPENCODE_CONFIG_DIR="${XDG_CONFIG_HOME}/opencode"
21
+ else
22
+ OPENCODE_CONFIG_DIR="${HOME}/.config/opencode"
23
+ fi
24
+ # OpenCode expects commands directly in commands/, not a subdirectory
25
+ OPENCODE_COMMANDS_DIR="${OPENCODE_CONFIG_DIR}/commands"
17
26
  LIB_DIR="${OPENCODE_COMMANDS_DIR}/lib"
18
27
 
28
+ # Legacy path for cleanup (incorrect, pre-XDG location)
29
+ LEGACY_OPENCODE_DIR="${HOME}/.opencode"
30
+
19
31
  # Detect OS for platform-specific notes
20
32
  if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" || "$OSTYPE" == "cygwin" ]]; then
21
33
  IS_WINDOWS=true
@@ -235,17 +247,64 @@ else
235
247
  fi
236
248
  echo
237
249
 
250
+ # Clean up legacy paths (~/.opencode/ - incorrect, pre-XDG location)
251
+ echo "[CLEANUP] Checking for legacy installations..."
252
+ LEGACY_COMMANDS_DIR="${LEGACY_OPENCODE_DIR}/commands/awesome-slash"
253
+ LEGACY_PLUGINS_DIR="${LEGACY_OPENCODE_DIR}/plugins/awesome-slash"
254
+ LEGACY_AGENTS_DIR="${LEGACY_OPENCODE_DIR}/agents"
255
+
256
+ cleaned_legacy=false
257
+ if [ -d "$LEGACY_COMMANDS_DIR" ]; then
258
+ rm -rf "$LEGACY_COMMANDS_DIR"
259
+ echo " [DEL] Removed legacy ~/.opencode/commands/awesome-slash"
260
+ cleaned_legacy=true
261
+ fi
262
+ if [ -d "$LEGACY_PLUGINS_DIR" ]; then
263
+ rm -rf "$LEGACY_PLUGINS_DIR"
264
+ echo " [DEL] Removed legacy ~/.opencode/plugins/awesome-slash"
265
+ cleaned_legacy=true
266
+ fi
267
+ if [ -d "$LEGACY_AGENTS_DIR" ]; then
268
+ # Only remove known agent files, not the whole directory
269
+ # Must match list in scripts/dev-install.js knownAgents array
270
+ # Generated from: ls plugins/*/agents/*.md | xargs basename | sort -u
271
+ known_agents=(
272
+ 'agent-enhancer.md' 'ci-fixer.md' 'ci-monitor.md' 'claudemd-enhancer.md'
273
+ 'delivery-validator.md' 'deslop-agent.md' 'docs-enhancer.md' 'enhancement-orchestrator.md'
274
+ 'enhancement-reporter.md' 'exploration-agent.md' 'hooks-enhancer.md' 'implementation-agent.md'
275
+ 'map-validator.md' 'perf-analyzer.md' 'perf-code-paths.md' 'perf-investigation-logger.md'
276
+ 'perf-orchestrator.md' 'perf-theory-gatherer.md' 'perf-theory-tester.md' 'plan-synthesizer.md'
277
+ 'planning-agent.md' 'plugin-enhancer.md' 'prompt-enhancer.md' 'simple-fixer.md'
278
+ 'skills-enhancer.md' 'sync-docs-agent.md' 'task-discoverer.md' 'test-coverage-checker.md'
279
+ 'worktree-manager.md'
280
+ )
281
+ for agent in "${known_agents[@]}"; do
282
+ if [ -f "$LEGACY_AGENTS_DIR/$agent" ]; then
283
+ rm "$LEGACY_AGENTS_DIR/$agent"
284
+ cleaned_legacy=true
285
+ fi
286
+ done
287
+ if [ "$cleaned_legacy" = true ]; then
288
+ echo " [DEL] Removed legacy agent files from ~/.opencode/agents"
289
+ fi
290
+ fi
291
+ if [ "$cleaned_legacy" = false ]; then
292
+ echo " [OK] No legacy installations found"
293
+ fi
294
+ echo
295
+
238
296
  # Success message
239
297
  echo "[OK] Installation complete!"
240
298
  echo
241
299
  echo "[LIST] Installed Commands:"
242
- for cmd in "${COMMANDS[@]}"; do
300
+ for mapping in "${COMMAND_MAPPINGS[@]}"; do
301
+ IFS=':' read -r cmd _ _ <<< "$mapping"
243
302
  echo " • /$cmd"
244
303
  done
245
304
  echo
246
305
  echo "[NEXT] Next Steps:"
247
306
  echo " 1. Start OpenCode TUI: opencode"
248
- echo " 2. Use commands: /$cmd"
307
+ echo " 2. Use commands: /next-task, /ship, etc."
249
308
  echo " 3. See help: cat $OPENCODE_COMMANDS_DIR/README.md"
250
309
  echo
251
310
  echo "[TIP] OpenCode Pro Tips:"
package/bin/cli.js CHANGED
@@ -797,7 +797,7 @@ function installForCodex(installDir) {
797
797
  }
798
798
 
799
799
  console.log('\n[OK] Codex CLI installation complete!');
800
- console.log(` Config: ${configPath}`);
800
+ console.log(` Config: ${configDir}`);
801
801
  console.log(` Skills: ${skillsDir}`);
802
802
  console.log(' Access via: $next-task, $ship, $deslop, etc.\n');
803
803
  return true;
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "9 specialized plugins for AI workflow automation (drift detection + AST repo maps) - works with Claude Code, OpenCode, and Codex CLI",
5
5
  "main": "lib/platform/detect-platform.js",
6
6
  "type": "commonjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "audit-project",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Multi-agent iterative code review until zero issues remain",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deslop",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "AI slop cleanup with minimal diffs and behavior preservation",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -14,6 +14,21 @@ Detailed reference for all slop patterns detected by the pipeline.
14
14
 
15
15
  **Excludes**: Test files, CLI entry points, config files
16
16
 
17
+ ### Unsafe Error Handling (Rust)
18
+
19
+ | Pattern | Severity | Better Alternatives |
20
+ |---------|----------|---------------------|
21
+ | `.unwrap()` | medium | `.expect("msg")`, `.unwrap_or(default)`, `?` operator |
22
+
23
+ Bare `.unwrap()` calls can cause panics in production. Prefer:
24
+ - `.expect("descriptive message")` - panic with context
25
+ - `.unwrap_or(default)` / `.unwrap_or_default()` - provide fallback
26
+ - `.unwrap_or_else(\|\| ...)` - lazy fallback computation
27
+ - `?` operator - propagate errors to caller
28
+ - `.ok()` / `.map()` / `.and_then()` - transform Result/Option
29
+
30
+ **Excludes**: Test files, examples, benchmarks
31
+
17
32
  ### Placeholder Code
18
33
 
19
34
  | Pattern | Language | Severity |
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drift-detect",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Deep repository analysis to realign project plans with actual code reality - discovers drift, gaps, and produces prioritized reconstruction plans",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enhance",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Plugin structure and tool use analyzer - validates plugin.json, MCP tools, and security patterns",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-task",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Master workflow orchestrator with autonomous task-to-production automation, quality gates, and multi-agent review",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -27,16 +27,13 @@ This workflow exists because each step serves a purpose. Taking shortcuts defeat
27
27
  1. Every step is mandatory - not suggestions, not guidelines, requirements
28
28
  2. Use the specified agents - do not substitute with manual commands
29
29
  3. Output verification blocks - prove each step completed
30
- 4. If you think a step is unnecessary, you are wrong
30
+ 4. If you think a step is unnecessary, review the "What Happens If Skipped" column above
31
31
 
32
- ### Forbidden Actions
32
+ ### Forbidden Shortcuts
33
33
 
34
- - Using `git checkout -b` instead of `worktree-manager` agent
35
- - Skipping review loop iterations
36
- - Checking CI once and moving to merge
37
- - Skipping the 3-minute wait for auto-reviewers
38
- - Leaving PR comments unaddressed
39
- - Rationalizing shortcuts ("it's faster", "not needed this time")
34
+ - `git checkout -b` or `git branch` instead of `worktree-manager` agent
35
+ - Single CI check instead of monitoring loop
36
+ - Rationalizing skips ("it's faster", "not needed this time")
40
37
  </no-shortcuts-policy>
41
38
 
42
39
  ---
@@ -79,11 +76,8 @@ Each phase must complete before the next starts:
79
76
  | Ship | Explicit /ship invocation (not hook-only) |
80
77
 
81
78
  **Forbidden actions for agents:**
82
- - No agent may create PRs (only /ship)
83
- - No agent may push to remote (only /ship)
84
- - No agent may skip Phase 9 review loop
85
- - No agent may skip delivery-validator
86
- - No agent may skip docs update (sync-docs-agent)
79
+ - No agent may create PRs or push to remote (only /ship)
80
+ - No agent may skip Phase 9, delivery-validator, or docs update
87
81
  </workflow-gates>
88
82
 
89
83
  ## Arguments
@@ -170,18 +164,36 @@ if (args.includes('--resume')) {
170
164
  }
171
165
  ```
172
166
 
167
+ <phase-1>
173
168
  ## Phase 1: Policy Selection
174
169
 
175
- No agent needed. Use `lib/sources/policy-questions.js`:
170
+ No agent needed. Use AskUserQuestion tool with ALL 3 questions from `lib/sources/policy-questions.js`.
171
+
172
+ **MANDATORY - Ask ALL 3 Questions:**
173
+
174
+ | # | Header | Question | Options |
175
+ |---|--------|----------|---------|
176
+ | 1 | Source | Where should I look for tasks? | GitHub Issues, GitLab Issues, Local tasks.md, Custom, Other (+ cached if exists) |
177
+ | 2 | Priority | What type of tasks to prioritize? | All, Bugs, Security, Features |
178
+ | 3 | Stop Point | How far should I take this task? | Merged, PR Created, Implemented, Deployed, Production |
179
+
180
+ **Forbidden Actions:**
181
+ - Skipping any of the 3 questions
182
+ - Inventing your own questions instead of using the exact ones above
183
+ - Proceeding to Phase 2 without all 3 answers
176
184
 
177
185
  ```javascript
186
+ // Reference implementation - use ALL questions
178
187
  const { sources } = require(path.join(pluginRoot, 'lib'));
179
188
  const { questions, cachedPreference } = sources.getPolicyQuestions();
180
- AskUserQuestion({ questions });
189
+ // questions array contains all 3 questions above
190
+ AskUserQuestion({ questions }); // Pass all 3 questions
181
191
  const policy = sources.parseAndCachePolicy(responses);
182
192
  workflowState.updateFlow({ policy, phase: 'task-discovery' });
183
193
  ```
194
+ </phase-1>
184
195
 
196
+ <phase-2>
185
197
  ## Phase 2: Task Discovery
186
198
 
187
199
  **Agent**: `next-task:task-discoverer` (sonnet)
@@ -193,6 +205,7 @@ await Task({
193
205
  prompt: `Discover tasks from source: ${JSON.stringify(policy.taskSource)}. Filter: ${policy.priorityFilter}. Present top 5 for selection.`
194
206
  });
195
207
  ```
208
+ </phase-2>
196
209
 
197
210
  <phase-3>
198
211
  ## Phase 3: Worktree Setup
@@ -224,6 +237,7 @@ console.log(`[VERIFIED] Worktree: ${worktreeResult.worktreePath}`);
224
237
  - Skipping worktree "because branching is faster"
225
238
  </phase-3>
226
239
 
240
+ <phase-4>
227
241
  ## Phase 4: Exploration
228
242
 
229
243
  **Agent**: `next-task:exploration-agent` (opus)
@@ -236,7 +250,9 @@ await Task({
236
250
  prompt: `Deep codebase analysis for task #${state.task.id}. Find key files, patterns, dependencies.`
237
251
  });
238
252
  ```
253
+ </phase-4>
239
254
 
255
+ <phase-5>
240
256
  ## Phase 5: Planning
241
257
 
242
258
  **Agent**: `next-task:planning-agent` (opus)
@@ -249,7 +265,9 @@ const planOutput = await Task({
249
265
  prompt: `Design implementation plan for task #${state.task.id}. Output structured JSON between === PLAN_START === and === PLAN_END === markers.`
250
266
  });
251
267
  ```
268
+ </phase-5>
252
269
 
270
+ <phase-6>
253
271
  ## Phase 6: User Approval (Plan Mode)
254
272
 
255
273
  **Last human interaction point.** Present plan via EnterPlanMode/ExitPlanMode.
@@ -259,7 +277,9 @@ EnterPlanMode();
259
277
  // User reviews and approves via ExitPlanMode
260
278
  workflowState.completePhase({ planApproved: true, plan });
261
279
  ```
280
+ </phase-6>
262
281
 
282
+ <phase-7>
263
283
  ## Phase 7: Implementation
264
284
 
265
285
  **Agent**: `next-task:implementation-agent` (opus)
@@ -273,7 +293,9 @@ await Task({
273
293
  });
274
294
  // → SubagentStop hook triggers pre-review gates
275
295
  ```
296
+ </phase-7>
276
297
 
298
+ <phase-8>
277
299
  ## Phase 8: Pre-Review Gates
278
300
 
279
301
  **Agents** (parallel): `deslop:deslop-agent` + `next-task:test-coverage-checker` (sonnet)
@@ -318,6 +340,7 @@ Use Edit tool to apply. Commit message: "fix: clean up AI slop"`
318
340
  });
319
341
  }
320
342
  ```
343
+ </phase-8>
321
344
 
322
345
  <phase-9>
323
346
  ## Phase 9: Review Loop
@@ -416,6 +439,7 @@ After review loop completes, output:
416
439
  ```
417
440
  </phase-9>
418
441
 
442
+ <phase-10>
419
443
  ## Phase 10: Delivery Validation
420
444
 
421
445
  **Agent**: `next-task:delivery-validator` (sonnet)
@@ -431,7 +455,9 @@ if (!result.approved) {
431
455
  return; // Retries from implementation
432
456
  }
433
457
  ```
458
+ </phase-10>
434
459
 
460
+ <phase-11>
435
461
  ## Phase 11: Docs Update
436
462
 
437
463
  **Agent**: `sync-docs:sync-docs-agent` (sonnet)
@@ -474,9 +500,10 @@ Use the Edit tool to apply each fix. Commit message: "docs: sync documentation w
474
500
 
475
501
  workflowState.completePhase({ docsUpdated: true, fixesApplied: result.fixes?.length || 0 });
476
502
  ```
503
+ </phase-11>
477
504
 
478
- <ship-handoff>
479
- ## Handoff to /ship
505
+ <phase-12>
506
+ ## Phase 12: Handoff to /ship
480
507
 
481
508
  After docs update (sync-docs-agent) completes, invoke /ship explicitly:
482
509
 
@@ -491,7 +518,7 @@ await Task({ subagent_type: "ship:ship", prompt: `Ship the task. State file: ${s
491
518
  - Monitor CI and review comments
492
519
  - Merge when approved
493
520
  - Cleanup worktree and tasks.json
494
- </ship-handoff>
521
+ </phase-12>
495
522
 
496
523
  ## Error Handling
497
524
 
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perf",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Rigorous performance investigation workflow with baselines, profiling, and evidence-backed decisions",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-map",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "AST-based repository map generator using ast-grep for symbol and import extraction with incremental updates",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ship",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Complete PR workflow from commit to production with validation",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sync-docs",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Sync documentation with code changes. Find outdated refs, update CHANGELOG, flag stale examples.",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -275,6 +275,24 @@ const slopPatterns = {
275
275
  description: 'Rust panic!("TODO: ...") placeholder'
276
276
  },
277
277
 
278
+ /**
279
+ * Rust: Bare .unwrap() calls without error context
280
+ * Can cause panics in production - prefer:
281
+ * - .unwrap_or(default) / .unwrap_or_else(|| ...)
282
+ * - .unwrap_or_default()
283
+ * - .expect("descriptive message")
284
+ * - ? operator for propagation
285
+ * - .ok() / .map() / .and_then() for transformation
286
+ */
287
+ rust_bare_unwrap: {
288
+ pattern: /\.unwrap\(\s*\)(?!\s*\.)/,
289
+ exclude: ['*_test.rs', '*_tests.rs', '**/tests/**', '**/examples/**', '**/benches/**'],
290
+ severity: 'medium',
291
+ autoFix: 'flag',
292
+ language: 'rust',
293
+ description: 'Bare .unwrap() can panic - use .expect(), .unwrap_or(), or ? operator'
294
+ },
295
+
278
296
  /**
279
297
  * Python: raise NotImplementedError
280
298
  */
@@ -30,8 +30,22 @@ const VERSION = require(path.join(SOURCE_DIR, 'package.json')).version;
30
30
  // Target directories
31
31
  const HOME = process.env.HOME || process.env.USERPROFILE;
32
32
  const CLAUDE_PLUGINS_DIR = path.join(HOME, '.claude', 'plugins');
33
- const OPENCODE_DIR = path.join(HOME, '.opencode');
34
- const OPENCODE_CONFIG_DIR = path.join(HOME, '.config', 'opencode');
33
+
34
+ /**
35
+ * Get OpenCode config directory following XDG Base Directory Specification.
36
+ * OpenCode uses ~/.config/opencode/ by default, or $XDG_CONFIG_HOME/opencode if set.
37
+ */
38
+ function getOpenCodeConfigDir() {
39
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME;
40
+ if (xdgConfigHome && xdgConfigHome.trim()) {
41
+ return path.join(xdgConfigHome, 'opencode');
42
+ }
43
+ return path.join(HOME, '.config', 'opencode');
44
+ }
45
+
46
+ const OPENCODE_CONFIG_DIR = getOpenCodeConfigDir();
47
+ // Legacy path - kept for cleanup of old installations
48
+ const LEGACY_OPENCODE_DIR = path.join(HOME, '.opencode');
35
49
  const CODEX_DIR = path.join(HOME, '.codex');
36
50
  const AWESOME_SLASH_DIR = path.join(HOME, '.awesome-slash');
37
51
 
@@ -66,33 +80,63 @@ function cleanAll() {
66
80
  }
67
81
  }
68
82
 
69
- // Clean OpenCode
70
- const opencodeCommandsDir = path.join(OPENCODE_DIR, 'commands', 'awesome-slash');
71
- const opencodePluginDir = path.join(OPENCODE_DIR, 'plugins', 'awesome-slash');
72
- const opencodeAgentsDir = path.join(OPENCODE_DIR, 'agents');
83
+ // Clean OpenCode (correct XDG path: ~/.config/opencode/)
84
+ // OpenCode expects commands directly in commands/, not a subdirectory
85
+ const opencodeCommandsDir = path.join(OPENCODE_CONFIG_DIR, 'commands');
86
+ const opencodePluginDir = path.join(OPENCODE_CONFIG_DIR, 'plugins');
87
+ const opencodeAgentsDir = path.join(OPENCODE_CONFIG_DIR, 'agents');
88
+ // Note: Skills cleanup not implemented yet - would need skill list similar to agents
89
+
90
+ // List of agent filenames we install (from plugins/*/agents/*.md)
91
+ // Generated from: ls plugins/*/agents/*.md | xargs basename | sort -u
92
+ const knownAgents = [
93
+ 'agent-enhancer.md', 'ci-fixer.md', 'ci-monitor.md', 'claudemd-enhancer.md',
94
+ 'delivery-validator.md', 'deslop-agent.md', 'docs-enhancer.md', 'enhancement-orchestrator.md',
95
+ 'enhancement-reporter.md', 'exploration-agent.md', 'hooks-enhancer.md', 'implementation-agent.md',
96
+ 'map-validator.md', 'perf-analyzer.md', 'perf-code-paths.md', 'perf-investigation-logger.md',
97
+ 'perf-orchestrator.md', 'perf-theory-gatherer.md', 'perf-theory-tester.md', 'plan-synthesizer.md',
98
+ 'planning-agent.md', 'plugin-enhancer.md', 'prompt-enhancer.md', 'simple-fixer.md',
99
+ 'skills-enhancer.md', 'sync-docs-agent.md', 'task-discoverer.md', 'test-coverage-checker.md',
100
+ 'worktree-manager.md'
101
+ ];
73
102
 
103
+ // Known commands we install
104
+ const knownCommands = [
105
+ 'deslop.md', 'enhance.md', 'next-task.md', 'delivery-approval.md',
106
+ 'sync-docs.md', 'audit-project.md', 'ship.md', 'drift-detect.md',
107
+ 'repo-map.md', 'perf.md'
108
+ ];
109
+
110
+ // Clean commands (remove our files, not the whole directory)
74
111
  if (fs.existsSync(opencodeCommandsDir)) {
75
- fs.rmSync(opencodeCommandsDir, { recursive: true, force: true });
76
- log(' Removed OpenCode commands');
112
+ let removedCount = 0;
113
+ for (const file of knownCommands) {
114
+ const filePath = path.join(opencodeCommandsDir, file);
115
+ if (fs.existsSync(filePath)) {
116
+ fs.unlinkSync(filePath);
117
+ removedCount++;
118
+ }
119
+ }
120
+ // Also clean lib directory we install
121
+ const libDir = path.join(opencodeCommandsDir, 'lib');
122
+ if (fs.existsSync(libDir)) {
123
+ fs.rmSync(libDir, { recursive: true, force: true });
124
+ removedCount++;
125
+ }
126
+ if (removedCount > 0) {
127
+ log(` Removed ${removedCount} OpenCode commands/lib`);
128
+ }
77
129
  }
78
- if (fs.existsSync(opencodePluginDir)) {
79
- fs.rmSync(opencodePluginDir, { recursive: true, force: true });
130
+
131
+ // Clean plugin file
132
+ const pluginFile = path.join(opencodePluginDir, 'awesome-slash.ts');
133
+ if (fs.existsSync(pluginFile)) {
134
+ fs.unlinkSync(pluginFile);
80
135
  log(' Removed OpenCode plugin');
81
136
  }
137
+
82
138
  // Clean agent files installed by us - only known awesome-slash agents
83
139
  if (fs.existsSync(opencodeAgentsDir)) {
84
- // List of agent filenames we install (from plugins/*/agents/*.md)
85
- const knownAgents = [
86
- 'plan-synthesizer.md', 'enhancement-reporter.md', 'ci-fixer.md',
87
- 'deslop-work.md', 'simple-fixer.md', 'perf-analyzer.md', 'perf-code-paths.md',
88
- 'perf-investigation-logger.md', 'perf-theory-gatherer.md', 'perf-theory-tester.md',
89
- 'map-validator.md', 'exploration-agent.md', 'perf-orchestrator.md', 'ci-monitor.md',
90
- 'implementation-agent.md', 'planning-agent.md', 'test-coverage-checker.md',
91
- 'plugin-enhancer.md', 'agent-enhancer.md', 'docs-enhancer.md', 'claudemd-enhancer.md',
92
- 'prompt-enhancer.md', 'hooks-enhancer.md', 'skills-enhancer.md', 'enhancement-orchestrator.md',
93
- 'task-discoverer.md', 'delivery-validator.md', 'docs-updater.md', 'worktree-manager.md',
94
- 'deslop-analyzer.md', 'docs-analyzer.md', 'docs-validator.md'
95
- ];
96
140
  let removedCount = 0;
97
141
  for (const file of knownAgents) {
98
142
  const filePath = path.join(opencodeAgentsDir, file);
@@ -106,6 +150,33 @@ function cleanAll() {
106
150
  }
107
151
  }
108
152
 
153
+ // Clean legacy OpenCode paths (~/.opencode/ - incorrect, pre-XDG)
154
+ const legacyCommandsDir = path.join(LEGACY_OPENCODE_DIR, 'commands', 'awesome-slash');
155
+ const legacyPluginDir = path.join(LEGACY_OPENCODE_DIR, 'plugins', 'awesome-slash');
156
+ const legacyAgentsDir = path.join(LEGACY_OPENCODE_DIR, 'agents');
157
+
158
+ if (fs.existsSync(legacyCommandsDir)) {
159
+ fs.rmSync(legacyCommandsDir, { recursive: true, force: true });
160
+ log(' Removed legacy ~/.opencode/commands/awesome-slash');
161
+ }
162
+ if (fs.existsSync(legacyPluginDir)) {
163
+ fs.rmSync(legacyPluginDir, { recursive: true, force: true });
164
+ log(' Removed legacy ~/.opencode/plugins/awesome-slash');
165
+ }
166
+ if (fs.existsSync(legacyAgentsDir)) {
167
+ let removedCount = 0;
168
+ for (const file of knownAgents) {
169
+ const filePath = path.join(legacyAgentsDir, file);
170
+ if (fs.existsSync(filePath)) {
171
+ fs.unlinkSync(filePath);
172
+ removedCount++;
173
+ }
174
+ }
175
+ if (removedCount > 0) {
176
+ log(` Removed ${removedCount} legacy OpenCode agents from ~/.opencode/`);
177
+ }
178
+ }
179
+
109
180
  // Clean Codex
110
181
  const codexSkillsDir = path.join(CODEX_DIR, 'skills');
111
182
  if (fs.existsSync(codexSkillsDir)) {
@@ -219,29 +290,40 @@ function installClaude() {
219
290
  function installOpenCode() {
220
291
  log('Installing for OpenCode...');
221
292
 
222
- // Create directories
223
- const commandsDir = path.join(OPENCODE_DIR, 'commands', 'awesome-slash');
224
- const pluginDir = path.join(OPENCODE_DIR, 'plugins', 'awesome-slash');
225
- const agentsDir = path.join(OPENCODE_DIR, 'agents');
293
+ // Create directories in correct XDG location (~/.config/opencode/)
294
+ // OpenCode expects commands directly in commands/, not a subdirectory
295
+ const commandsDir = path.join(OPENCODE_CONFIG_DIR, 'commands');
296
+ const pluginDir = path.join(OPENCODE_CONFIG_DIR, 'plugins');
297
+ const agentsDir = path.join(OPENCODE_CONFIG_DIR, 'agents');
226
298
 
227
299
  fs.mkdirSync(commandsDir, { recursive: true });
228
300
  fs.mkdirSync(pluginDir, { recursive: true });
229
301
  fs.mkdirSync(agentsDir, { recursive: true });
230
302
 
303
+ // Clean up legacy paths (~/.opencode/) if they exist
304
+ const legacyCommandsDir = path.join(LEGACY_OPENCODE_DIR, 'commands', 'awesome-slash');
305
+ const legacyPluginDir = path.join(LEGACY_OPENCODE_DIR, 'plugins', 'awesome-slash');
306
+ if (fs.existsSync(legacyCommandsDir)) {
307
+ fs.rmSync(legacyCommandsDir, { recursive: true, force: true });
308
+ log(' Cleaned up legacy ~/.opencode/commands/awesome-slash');
309
+ }
310
+ if (fs.existsSync(legacyPluginDir)) {
311
+ fs.rmSync(legacyPluginDir, { recursive: true, force: true });
312
+ log(' Cleaned up legacy ~/.opencode/plugins/awesome-slash');
313
+ }
314
+
231
315
  // Copy to ~/.awesome-slash first (OpenCode needs local files)
232
316
  copyToAwesomeSlash();
233
317
 
234
- // Copy native plugin
318
+ // Copy native plugin (OpenCode expects plugins as single .ts files in ~/.config/opencode/plugins/)
235
319
  const pluginSrcDir = path.join(SOURCE_DIR, 'adapters', 'opencode-plugin');
236
320
  if (fs.existsSync(pluginSrcDir)) {
237
- for (const file of ['index.ts', 'package.json']) {
238
- const srcPath = path.join(pluginSrcDir, file);
239
- const destPath = path.join(pluginDir, file);
240
- if (fs.existsSync(srcPath)) {
241
- fs.copyFileSync(srcPath, destPath);
242
- }
321
+ const srcPath = path.join(pluginSrcDir, 'index.ts');
322
+ const destPath = path.join(pluginDir, 'awesome-slash.ts');
323
+ if (fs.existsSync(srcPath)) {
324
+ fs.copyFileSync(srcPath, destPath);
325
+ log(' [OK] Native plugin');
243
326
  }
244
- log(' [OK] Native plugin');
245
327
  }
246
328
 
247
329
  // Transform helpers
@@ -14,7 +14,20 @@ const fs = require('fs');
14
14
  const path = require('path');
15
15
 
16
16
  const home = process.env.HOME || process.env.USERPROFILE;
17
- const OPENCODE_DIR = path.join(home, '.opencode');
17
+
18
+ /**
19
+ * Get OpenCode config directory following XDG Base Directory Specification.
20
+ * OpenCode uses ~/.config/opencode/ by default, or $XDG_CONFIG_HOME/opencode if set.
21
+ */
22
+ function getOpenCodeConfigDir() {
23
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME;
24
+ if (xdgConfigHome && xdgConfigHome.trim()) {
25
+ return path.join(xdgConfigHome, 'opencode');
26
+ }
27
+ return path.join(home, '.config', 'opencode');
28
+ }
29
+
30
+ const OPENCODE_DIR = getOpenCodeConfigDir();
18
31
 
19
32
  const issues = [];
20
33
 
@@ -119,7 +132,8 @@ console.log('Validating OpenCode Installation...\n');
119
132
  console.log(`OpenCode directory: ${OPENCODE_DIR}\n`);
120
133
 
121
134
  // Validate each type
122
- validateDirectory(path.join(OPENCODE_DIR, 'commands', 'awesome-slash'), 'commands');
135
+ // OpenCode expects commands directly in commands/, not a subdirectory
136
+ validateDirectory(path.join(OPENCODE_DIR, 'commands'), 'commands');
123
137
  validateDirectory(path.join(OPENCODE_DIR, 'agents'), 'agents');
124
138
  validateDirectory(path.join(OPENCODE_DIR, 'skills'), 'skills');
125
139