awesome-slash 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.claude-plugin/marketplace.json +6 -6
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +35 -0
  4. package/README.md +23 -8
  5. package/lib/platform/state-dir.js +122 -0
  6. package/lib/sources/source-cache.js +26 -11
  7. package/lib/state/workflow-state.js +18 -13
  8. package/mcp-server/index.js +7 -11
  9. package/package.json +1 -1
  10. package/plugins/deslop-around/.claude-plugin/plugin.json +1 -1
  11. package/plugins/deslop-around/lib/patterns/slop-patterns.js +2 -3
  12. package/plugins/deslop-around/lib/platform/detect-platform.js +44 -287
  13. package/plugins/deslop-around/lib/platform/state-dir.js +122 -0
  14. package/plugins/deslop-around/lib/platform/verify-tools.js +11 -88
  15. package/plugins/deslop-around/lib/schemas/validator.js +44 -2
  16. package/plugins/deslop-around/lib/sources/source-cache.js +26 -11
  17. package/plugins/deslop-around/lib/state/workflow-state.js +18 -13
  18. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  19. package/plugins/next-task/lib/patterns/slop-patterns.js +2 -3
  20. package/plugins/next-task/lib/platform/detect-platform.js +44 -287
  21. package/plugins/next-task/lib/platform/state-dir.js +122 -0
  22. package/plugins/next-task/lib/platform/verify-tools.js +11 -88
  23. package/plugins/next-task/lib/schemas/validator.js +44 -2
  24. package/plugins/next-task/lib/sources/source-cache.js +26 -11
  25. package/plugins/next-task/lib/state/workflow-state.js +18 -13
  26. package/plugins/project-review/.claude-plugin/plugin.json +1 -1
  27. package/plugins/project-review/lib/patterns/slop-patterns.js +2 -3
  28. package/plugins/project-review/lib/platform/detect-platform.js +44 -287
  29. package/plugins/project-review/lib/platform/state-dir.js +122 -0
  30. package/plugins/project-review/lib/platform/verify-tools.js +11 -88
  31. package/plugins/project-review/lib/schemas/validator.js +44 -2
  32. package/plugins/project-review/lib/sources/source-cache.js +26 -11
  33. package/plugins/project-review/lib/state/workflow-state.js +18 -13
  34. package/plugins/reality-check/.claude-plugin/plugin.json +1 -1
  35. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  36. package/plugins/ship/lib/patterns/slop-patterns.js +2 -3
  37. package/plugins/ship/lib/platform/detect-platform.js +44 -287
  38. package/plugins/ship/lib/platform/state-dir.js +122 -0
  39. package/plugins/ship/lib/platform/verify-tools.js +11 -88
  40. package/plugins/ship/lib/schemas/validator.js +44 -2
  41. package/plugins/ship/lib/sources/source-cache.js +26 -11
  42. package/plugins/ship/lib/state/workflow-state.js +18 -13
  43. package/scripts/install/codex.sh +216 -72
  44. package/scripts/install/opencode.sh +197 -21
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
3
  "description": "Professional-grade slash commands for Claude Code with cross-platform support (OpenCode, Codex CLI)",
4
- "version": "2.5.0",
4
+ "version": "2.5.1",
5
5
  "owner": {
6
6
  "name": "Avi Fenesh",
7
7
  "url": "https://github.com/avifenesh"
@@ -13,35 +13,35 @@
13
13
  "name": "next-task",
14
14
  "source": "./plugins/next-task",
15
15
  "description": "Master workflow orchestrator: autonomous workflow with model optimization (opus/sonnet/haiku), two-file state management, workflow enforcement gates, 14 specialist agents",
16
- "version": "2.5.0",
16
+ "version": "2.5.1",
17
17
  "category": "productivity"
18
18
  },
19
19
  {
20
20
  "name": "ship",
21
21
  "source": "./plugins/ship",
22
22
  "description": "Complete PR workflow: commit to production, skips review when called from next-task, removes task from registry on cleanup, automatic rollback",
23
- "version": "2.5.0",
23
+ "version": "2.5.1",
24
24
  "category": "deployment"
25
25
  },
26
26
  {
27
27
  "name": "deslop-around",
28
28
  "source": "./plugins/deslop-around",
29
29
  "description": "AI slop cleanup with minimal diffs and behavior preservation",
30
- "version": "2.5.0",
30
+ "version": "2.5.1",
31
31
  "category": "development"
32
32
  },
33
33
  {
34
34
  "name": "project-review",
35
35
  "source": "./plugins/project-review",
36
36
  "description": "Multi-agent iterative code review until zero issues remain",
37
- "version": "2.5.0",
37
+ "version": "2.5.1",
38
38
  "category": "development"
39
39
  },
40
40
  {
41
41
  "name": "reality-check",
42
42
  "source": "./plugins/reality-check",
43
43
  "description": "Deep repository analysis to realign project plans with code reality - detects drift, gaps, and creates prioritized reconstruction plans",
44
- "version": "2.5.0",
44
+ "version": "2.5.1",
45
45
  "category": "productivity"
46
46
  }
47
47
  ],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Professional-grade slash commands for Claude Code with cross-platform support",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
package/CHANGELOG.md CHANGED
@@ -9,6 +9,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  No unreleased changes documented.
11
11
 
12
+ ## [2.5.1] - 2026-01-19
13
+
14
+ ### Added
15
+ - **Platform-Aware State Directories** - State files now stored in platform-specific directories
16
+ - Claude Code: `.claude/`
17
+ - OpenCode: `.opencode/`
18
+ - Codex CLI: `.codex/`
19
+ - Override with `AI_STATE_DIR` environment variable
20
+ - **New lib/platform/state-dir.js** - Centralized platform detection module
21
+
22
+ ### Fixed
23
+ - **OpenCode Installer** - Fixed config format (uses `mcp` key, `type: local`)
24
+ - **Codex Installer** - Fixed to use `config.toml` with Windows-style paths
25
+ - **MCP Server Bugs** - Fixed `state.workflow.id` → `state.task.id` references
26
+ - **MCP Resume Logic** - Fixed `checkpoints.canResume` to use correct state fields
27
+
28
+ ### Changed
29
+ - **Codex Skills** - Added explicit instructions to get files from git diff or ask user
30
+ - **OpenCode Commands** - Added "CRITICAL: Always Ask User First" sections
31
+ - **Documentation** - Added note that Codex uses `$` prefix instead of `/` for commands
32
+
33
+ ## [2.5.0] - 2026-01-19
34
+
35
+ ### Added
36
+ - **Multi-Source Task Discovery** - Support for GitHub, GitLab, local files, custom CLI tools
37
+ - **Source Preference Caching** - Last-used source cached in `sources/preference.json`
38
+ - **Large Backlog Handling** - Pagination and priority filtering for repos with many issues
39
+
40
+ ### Changed
41
+ - **Streamlined Policy Selection** - Direct questions from orchestrator, removed separate agent
42
+
43
+ ### Security
44
+ - **Command Injection** - Fixed shell command injection vulnerabilities
45
+ - **Path Traversal** - Fixed path traversal in source-cache.js
46
+
12
47
  ## [2.4.7] - 2026-01-18
13
48
 
14
49
  ### Changed
package/README.md CHANGED
@@ -6,7 +6,7 @@ A cross-platform plugin providing powerful, zero-configuration slash commands fo
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/awesome-slash?color=red)](https://www.npmjs.com/package/awesome-slash)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Version](https://img.shields.io/badge/version-2.5.0-blue)](https://github.com/avifenesh/awesome-slash/releases)
9
+ [![Version](https://img.shields.io/badge/version-2.5.1-blue)](https://github.com/avifenesh/awesome-slash/releases)
10
10
  [![GitHub stars](https://img.shields.io/github/stars/avifenesh/awesome-slash?style=flat&color=yellow)](https://github.com/avifenesh/awesome-slash/stargazers)
11
11
  [![Claude Code](https://img.shields.io/badge/Claude-Code%20Plugin-blue)](https://docs.anthropic.com/en/docs/claude-code)
12
12
  [![Codex CLI](https://img.shields.io/badge/Codex-CLI%20Compatible-green)](https://developers.openai.com/codex/cli)
@@ -16,13 +16,18 @@ A cross-platform plugin providing powerful, zero-configuration slash commands fo
16
16
 
17
17
  > **💡 Model Recommendation**: Using **Opus** as the main agent model produces significantly better results and follows workflow phases more tightly. While Sonnet works for simpler tasks, Opus is recommended for complex multi-step workflows.
18
18
 
19
+ ## What's New in v2.5.1
20
+
21
+ - **Platform-Aware State Directories** - State now stored in `.opencode/` for OpenCode, `.codex/` for Codex
22
+ - **Fixed OpenCode/Codex Installers** - Correct config formats and Windows path handling
23
+ - **MCP Server Bug Fixes** - Fixed workflow state references and resume logic
24
+ - **Documentation Updates** - Added note that Codex uses `$` prefix instead of `/`
25
+
19
26
  ## What's New in v2.5.0
20
27
 
21
- - **Multi-Source Task Discovery** - Support for GitHub, GitLab, local files, custom CLI tools, and ad-hoc sources
28
+ - **Multi-Source Task Discovery** - Support for GitHub, GitLab, local files, custom CLI tools
22
29
  - **Source Preference Caching** - Your last-used source appears first on subsequent runs
23
30
  - **Security Hardening** - Fixed command injection and path traversal vulnerabilities
24
- - **Large Backlog Handling** - Intelligent pagination and priority filtering for repos with many issues
25
- - **Streamlined Policy Selection** - Direct questions from orchestrator, removed separate agent
26
31
 
27
32
  ## What's New in v2.4.7
28
33
 
@@ -54,6 +59,8 @@ git clone https://github.com/avifenesh/awesome-slash.git
54
59
 
55
60
  ## Available Commands
56
61
 
62
+ > **Platform Note:** Commands use `/` prefix in Claude Code and OpenCode, but `$` prefix in Codex CLI (e.g., `$next-task` instead of `/next-task`).
63
+
57
64
  ### `/next-task` - Master Workflow Orchestrator
58
65
 
59
66
  Complete task-to-production automation with state management and resume capability.
@@ -243,9 +250,17 @@ See [docs/CROSS_PLATFORM.md](./docs/CROSS_PLATFORM.md) for details.
243
250
 
244
251
  ### State Management
245
252
 
246
- Simple state tracking with three locations:
253
+ Simple state tracking with platform-aware directories:
254
+
255
+ | Platform | State Directory |
256
+ |----------|-----------------|
257
+ | Claude Code | `.claude/` |
258
+ | OpenCode | `.opencode/` |
259
+ | Codex CLI | `.codex/` |
260
+
261
+ Override with `AI_STATE_DIR` environment variable.
247
262
 
248
- **Main project: `.claude/tasks.json`** - Tracks active worktree/task:
263
+ **Main project: `{state-dir}/tasks.json`** - Tracks active worktree/task:
249
264
  ```json
250
265
  {
251
266
  "active": {
@@ -257,7 +272,7 @@ Simple state tracking with three locations:
257
272
  }
258
273
  ```
259
274
 
260
- **Worktree: `.claude/flow.json`** - Tracks workflow progress:
275
+ **Worktree: `{state-dir}/flow.json`** - Tracks workflow progress:
261
276
  ```json
262
277
  {
263
278
  "task": { "id": "123", "title": "Fix auth timeout" },
@@ -270,7 +285,7 @@ Simple state tracking with three locations:
270
285
  }
271
286
  ```
272
287
 
273
- **Source Preferences: `.claude/sources/preference.json`** - Caches task source selection:
288
+ **Source Preferences: `{state-dir}/sources/preference.json`** - Caches task source selection:
274
289
  ```json
275
290
  {
276
291
  "source": "custom",
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Platform-aware state directory detection
3
+ *
4
+ * Determines the appropriate state directory based on the AI coding assistant
5
+ * being used (Claude Code, OpenCode, or Codex CLI).
6
+ *
7
+ * @module lib/platform/state-dir
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ /**
14
+ * Cached state directory name (relative, without leading dot handling)
15
+ * @type {string|null}
16
+ */
17
+ let _cachedStateDir = null;
18
+
19
+ /**
20
+ * Detect which AI coding assistant is running and return appropriate state directory
21
+ *
22
+ * Detection order:
23
+ * 1. AI_STATE_DIR env var (user override)
24
+ * 2. OpenCode detection (OPENCODE_CONFIG env or .opencode/ exists)
25
+ * 3. Codex detection (CODEX_HOME env or .codex/ exists)
26
+ * 4. Default to .claude (Claude Code or unknown)
27
+ *
28
+ * @param {string} [basePath=process.cwd()] - Base path to check for project directories
29
+ * @returns {string} State directory name (e.g., '.claude', '.opencode', '.codex')
30
+ */
31
+ function getStateDir(basePath = process.cwd()) {
32
+ // Check user override first
33
+ if (process.env.AI_STATE_DIR) {
34
+ return process.env.AI_STATE_DIR;
35
+ }
36
+
37
+ // Return cached value if available
38
+ if (_cachedStateDir) {
39
+ return _cachedStateDir;
40
+ }
41
+
42
+ // OpenCode detection
43
+ if (process.env.OPENCODE_CONFIG || process.env.OPENCODE_CONFIG_DIR) {
44
+ _cachedStateDir = '.opencode';
45
+ return _cachedStateDir;
46
+ }
47
+
48
+ // Check for .opencode directory in project
49
+ try {
50
+ const opencodePath = path.join(basePath, '.opencode');
51
+ if (fs.existsSync(opencodePath) && fs.statSync(opencodePath).isDirectory()) {
52
+ _cachedStateDir = '.opencode';
53
+ return _cachedStateDir;
54
+ }
55
+ } catch {
56
+ // Ignore errors, continue detection
57
+ }
58
+
59
+ // Codex detection
60
+ if (process.env.CODEX_HOME) {
61
+ _cachedStateDir = '.codex';
62
+ return _cachedStateDir;
63
+ }
64
+
65
+ // Check for .codex directory in project
66
+ try {
67
+ const codexPath = path.join(basePath, '.codex');
68
+ if (fs.existsSync(codexPath) && fs.statSync(codexPath).isDirectory()) {
69
+ _cachedStateDir = '.codex';
70
+ return _cachedStateDir;
71
+ }
72
+ } catch {
73
+ // Ignore errors, continue detection
74
+ }
75
+
76
+ // Default to Claude Code
77
+ _cachedStateDir = '.claude';
78
+ return _cachedStateDir;
79
+ }
80
+
81
+ /**
82
+ * Get the full path to the state directory
83
+ * @param {string} [basePath=process.cwd()] - Base path
84
+ * @returns {string} Full path to state directory
85
+ */
86
+ function getStateDirPath(basePath = process.cwd()) {
87
+ return path.join(basePath, getStateDir(basePath));
88
+ }
89
+
90
+ /**
91
+ * Get the detected platform name
92
+ * @param {string} [basePath=process.cwd()] - Base path
93
+ * @returns {string} Platform name ('claude', 'opencode', 'codex', or 'custom')
94
+ */
95
+ function getPlatformName(basePath = process.cwd()) {
96
+ const stateDir = getStateDir(basePath);
97
+
98
+ if (process.env.AI_STATE_DIR) {
99
+ return 'custom';
100
+ }
101
+
102
+ switch (stateDir) {
103
+ case '.opencode': return 'opencode';
104
+ case '.codex': return 'codex';
105
+ case '.claude': return 'claude';
106
+ default: return 'unknown';
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Clear the cached state directory (useful for testing)
112
+ */
113
+ function clearCache() {
114
+ _cachedStateDir = null;
115
+ }
116
+
117
+ module.exports = {
118
+ getStateDir,
119
+ getStateDirPath,
120
+ getPlatformName,
121
+ clearCache
122
+ };
@@ -2,15 +2,28 @@
2
2
  * Source Cache
3
3
  * File-based persistence for task source preferences
4
4
  *
5
+ * State directory is platform-aware:
6
+ * - Claude Code: .claude/sources/
7
+ * - OpenCode: .opencode/sources/
8
+ * - Codex CLI: .codex/sources/
9
+ *
5
10
  * @module lib/sources/source-cache
6
11
  */
7
12
 
8
13
  const fs = require('fs');
9
14
  const path = require('path');
15
+ const { getStateDir } = require('../platform/state-dir');
10
16
 
11
- const SOURCES_DIR = '.claude/sources';
12
17
  const PREFERENCE_FILE = 'preference.json';
13
18
 
19
+ /**
20
+ * Get the sources directory path (platform-aware)
21
+ * @returns {string} Path to sources directory
22
+ */
23
+ function getSourcesDir() {
24
+ return path.join(getStateDir(), 'sources');
25
+ }
26
+
14
27
  /**
15
28
  * Validate tool name to prevent path traversal
16
29
  * @param {string} toolName - Tool name to validate
@@ -26,10 +39,11 @@ function isValidToolName(toolName) {
26
39
  * @returns {string} Path to sources directory
27
40
  */
28
41
  function ensureDir() {
29
- if (!fs.existsSync(SOURCES_DIR)) {
30
- fs.mkdirSync(SOURCES_DIR, { recursive: true });
42
+ const sourcesDir = getSourcesDir();
43
+ if (!fs.existsSync(sourcesDir)) {
44
+ fs.mkdirSync(sourcesDir, { recursive: true });
31
45
  }
32
- return SOURCES_DIR;
46
+ return sourcesDir;
33
47
  }
34
48
 
35
49
  /**
@@ -40,7 +54,7 @@ function ensureDir() {
40
54
  * // Or: { source: 'custom', type: 'cli', tool: 'tea' }
41
55
  */
42
56
  function getPreference() {
43
- const filePath = path.join(SOURCES_DIR, PREFERENCE_FILE);
57
+ const filePath = path.join(getSourcesDir(), PREFERENCE_FILE);
44
58
  if (!fs.existsSync(filePath)) {
45
59
  return null;
46
60
  }
@@ -62,7 +76,7 @@ function getPreference() {
62
76
  */
63
77
  function savePreference(preference) {
64
78
  ensureDir();
65
- const filePath = path.join(SOURCES_DIR, PREFERENCE_FILE);
79
+ const filePath = path.join(getSourcesDir(), PREFERENCE_FILE);
66
80
  fs.writeFileSync(filePath, JSON.stringify({
67
81
  ...preference,
68
82
  savedAt: new Date().toISOString()
@@ -80,7 +94,7 @@ function getToolCapabilities(toolName) {
80
94
  console.error(`Invalid tool name: ${toolName}`);
81
95
  return null;
82
96
  }
83
- const filePath = path.join(SOURCES_DIR, `${toolName}.json`);
97
+ const filePath = path.join(getSourcesDir(), `${toolName}.json`);
84
98
  if (!fs.existsSync(filePath)) {
85
99
  return null;
86
100
  }
@@ -106,7 +120,7 @@ function saveToolCapabilities(toolName, capabilities) {
106
120
  return;
107
121
  }
108
122
  ensureDir();
109
- const filePath = path.join(SOURCES_DIR, `${toolName}.json`);
123
+ const filePath = path.join(getSourcesDir(), `${toolName}.json`);
110
124
  fs.writeFileSync(filePath, JSON.stringify({
111
125
  ...capabilities,
112
126
  discoveredAt: new Date().toISOString()
@@ -117,10 +131,11 @@ function saveToolCapabilities(toolName, capabilities) {
117
131
  * Clear all cached preferences
118
132
  */
119
133
  function clearCache() {
120
- if (fs.existsSync(SOURCES_DIR)) {
121
- const files = fs.readdirSync(SOURCES_DIR);
134
+ const sourcesDir = getSourcesDir();
135
+ if (fs.existsSync(sourcesDir)) {
136
+ const files = fs.readdirSync(sourcesDir);
122
137
  for (const file of files) {
123
- const filePath = path.join(SOURCES_DIR, file);
138
+ const filePath = path.join(sourcesDir, file);
124
139
  const stats = fs.statSync(filePath);
125
140
  if (stats.isFile()) {
126
141
  fs.unlinkSync(filePath);
@@ -2,16 +2,21 @@
2
2
  * Simplified workflow state management
3
3
  *
4
4
  * Two files:
5
- * - Main project: .claude/tasks.json (tracks active worktree/task)
6
- * - Worktree: .claude/flow.json (tracks workflow progress)
5
+ * - Main project: {stateDir}/tasks.json (tracks active worktree/task)
6
+ * - Worktree: {stateDir}/flow.json (tracks workflow progress)
7
+ *
8
+ * State directory is platform-aware:
9
+ * - Claude Code: .claude/
10
+ * - OpenCode: .opencode/
11
+ * - Codex CLI: .codex/
7
12
  */
8
13
 
9
14
  const fs = require('fs');
10
15
  const path = require('path');
11
16
  const crypto = require('crypto');
17
+ const { getStateDir } = require('../platform/state-dir');
12
18
 
13
19
  // File paths
14
- const CLAUDE_DIR = '.claude';
15
20
  const TASKS_FILE = 'tasks.json';
16
21
  const FLOW_FILE = 'flow.json';
17
22
 
@@ -74,14 +79,14 @@ const PHASES = [
74
79
  ];
75
80
 
76
81
  /**
77
- * Ensure .claude directory exists
82
+ * Ensure state directory exists (platform-aware)
78
83
  */
79
- function ensureClaudeDir(basePath) {
80
- const claudeDir = path.join(basePath, CLAUDE_DIR);
81
- if (!fs.existsSync(claudeDir)) {
82
- fs.mkdirSync(claudeDir, { recursive: true });
84
+ function ensureStateDir(basePath) {
85
+ const stateDir = path.join(basePath, getStateDir(basePath));
86
+ if (!fs.existsSync(stateDir)) {
87
+ fs.mkdirSync(stateDir, { recursive: true });
83
88
  }
84
- return claudeDir;
89
+ return stateDir;
85
90
  }
86
91
 
87
92
  // =============================================================================
@@ -93,7 +98,7 @@ function ensureClaudeDir(basePath) {
93
98
  */
94
99
  function getTasksPath(projectPath = process.cwd()) {
95
100
  const validatedBase = validatePath(projectPath);
96
- const tasksPath = path.join(validatedBase, CLAUDE_DIR, TASKS_FILE);
101
+ const tasksPath = path.join(validatedBase, getStateDir(projectPath), TASKS_FILE);
97
102
  validatePathWithinBase(tasksPath, validatedBase);
98
103
  return tasksPath;
99
104
  }
@@ -125,7 +130,7 @@ function readTasks(projectPath = process.cwd()) {
125
130
  * Write tasks.json to main project
126
131
  */
127
132
  function writeTasks(tasks, projectPath = process.cwd()) {
128
- ensureClaudeDir(projectPath);
133
+ ensureStateDir(projectPath);
129
134
  const tasksPath = getTasksPath(projectPath);
130
135
  fs.writeFileSync(tasksPath, JSON.stringify(tasks, null, 2), 'utf8');
131
136
  return true;
@@ -170,7 +175,7 @@ function hasActiveTask(projectPath = process.cwd()) {
170
175
  */
171
176
  function getFlowPath(worktreePath = process.cwd()) {
172
177
  const validatedBase = validatePath(worktreePath);
173
- const flowPath = path.join(validatedBase, CLAUDE_DIR, FLOW_FILE);
178
+ const flowPath = path.join(validatedBase, getStateDir(worktreePath), FLOW_FILE);
174
179
  validatePathWithinBase(flowPath, validatedBase);
175
180
  return flowPath;
176
181
  }
@@ -198,7 +203,7 @@ function readFlow(worktreePath = process.cwd()) {
198
203
  * Creates a copy to avoid mutating the original object
199
204
  */
200
205
  function writeFlow(flow, worktreePath = process.cwd()) {
201
- ensureClaudeDir(worktreePath);
206
+ ensureStateDir(worktreePath);
202
207
  // Clone to avoid mutating the original object
203
208
  const flowCopy = JSON.parse(JSON.stringify(flow));
204
209
  flowCopy.lastUpdate = new Date().toISOString();
@@ -178,7 +178,7 @@ const toolHandlers = {
178
178
  return {
179
179
  content: [{
180
180
  type: 'text',
181
- text: `Workflow started: ${state.workflow.id}\nPolicy: ${JSON.stringify(policy, null, 2)}`
181
+ text: `Workflow started: ${state.task.id}\nPolicy: ${JSON.stringify(policy, null, 2)}`
182
182
  }]
183
183
  };
184
184
  },
@@ -199,7 +199,7 @@ const toolHandlers = {
199
199
  };
200
200
  }
201
201
 
202
- if (!state.checkpoints?.canResume) {
202
+ if (state.status !== 'in_progress' || state.phase === 'complete') {
203
203
  return {
204
204
  content: [{ type: 'text', text: 'Workflow cannot be resumed from current state.' }],
205
205
  isError: true
@@ -209,7 +209,7 @@ const toolHandlers = {
209
209
  return {
210
210
  content: [{
211
211
  type: 'text',
212
- text: `Resuming workflow ${state.workflow.id} from phase: ${state.checkpoints.resumeFrom}`
212
+ text: `Resuming workflow ${state.task.id} from phase: ${state.phase}`
213
213
  }]
214
214
  };
215
215
  },
@@ -234,7 +234,7 @@ const toolHandlers = {
234
234
  return {
235
235
  content: [{
236
236
  type: 'text',
237
- text: `Workflow ${state.workflow.id} aborted. Cleanup: worktree and branches should be removed manually.`
237
+ text: `Workflow ${state.task.id} aborted. Cleanup: worktree and branches should be removed manually.`
238
238
  }]
239
239
  };
240
240
  },
@@ -383,8 +383,7 @@ const toolHandlers = {
383
383
  foundFile = file;
384
384
  break;
385
385
  } catch (e) {
386
- // Log error for debugging but continue checking other files
387
- console.error(`Could not read ${file}: ${e.message}`);
386
+ // File doesn't exist, try next one
388
387
  }
389
388
  }
390
389
 
@@ -430,10 +429,7 @@ const toolHandlers = {
430
429
 
431
430
  // Validate file path - prevent path traversal
432
431
  const normalizedPath = path.normalize(customFile);
433
- if (normalizedPath.includes('..') || path.isAbsolute(normalizedPath)) {
434
- // Allow absolute paths but log for awareness
435
- console.error(`Custom task file: ${normalizedPath}`);
436
- }
432
+ // Note: absolute paths and '..' are allowed but monitored via file access
437
433
 
438
434
  try {
439
435
  const content = await fs.readFile(customFile, 'utf-8');
@@ -669,7 +665,7 @@ async function main() {
669
665
  const server = new Server(
670
666
  {
671
667
  name: 'awesome-slash',
672
- version: '2.4.7',
668
+ version: '2.5.1',
673
669
  },
674
670
  {
675
671
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "awesome-slash",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Professional-grade slash commands for Claude Code that work across any project",
5
5
  "main": "lib/platform/detect-platform.js",
6
6
  "type": "commonjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deslop-around",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "AI slop cleanup with minimal diffs and behavior preservation",
5
5
  "author": {
6
6
  "name": "Avi Fenesh",
@@ -644,9 +644,8 @@ function isFileExcluded(filePath, excludePatterns) {
644
644
  const cacheKey = JSON.stringify([filePath, excludePatterns]);
645
645
 
646
646
  // Check cache first (O(1) lookup)
647
- if (_excludeResultCache.has(cacheKey)) {
648
- return _excludeResultCache.get(cacheKey);
649
- }
647
+ const cached = _excludeResultCache.get(cacheKey);
648
+ if (cached !== undefined) return cached;
650
649
 
651
650
  // Compute result
652
651
  const result = excludePatterns.some(pattern => {