claude-code-workflow 6.3.50 → 6.3.51
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/commands/view.md +367 -0
- package/.claude/commands/workflow/unified-execute-with-file.md +807 -0
- package/.claude/skills/ccw-help/SKILL.md +72 -12
- package/.claude/skills/ccw-help/command.json +922 -520
- package/.claude/skills/ccw-help/index/all-agents.json +97 -0
- package/.claude/skills/ccw-help/index/all-commands.json +805 -0
- package/.claude/skills/ccw-help/index/by-category.json +833 -0
- package/.claude/skills/ccw-help/index/by-use-case.json +819 -0
- package/.claude/skills/ccw-help/index/command-relationships.json +160 -0
- package/.claude/skills/ccw-help/index/essential-commands.json +90 -0
- package/.claude/skills/ccw-help/scripts/auto-update.py +34 -0
- package/.claude/skills/skill-generator/SKILL.md +255 -208
- package/.claude/skills/skill-generator/phases/01-requirements-discovery.md +238 -228
- package/.claude/skills/skill-generator/phases/02-structure-generation.md +261 -262
- package/.claude/skills/skill-generator/phases/03-phase-generation.md +976 -969
- package/.claude/skills/skill-generator/phases/04-specs-templates.md +398 -398
- package/.claude/skills/skill-generator/phases/05-validation.md +417 -417
- package/.claude/skills/skill-generator/specs/cli-integration.md +131 -131
- package/.claude/skills/skill-generator/specs/execution-modes.md +399 -396
- package/.claude/skills/skill-generator/specs/reference-docs-spec.md +271 -0
- package/.claude/skills/skill-generator/specs/scripting-integration.md +265 -265
- package/.claude/skills/skill-generator/specs/skill-requirements.md +466 -466
- package/.claude/skills/skill-generator/templates/autonomous-action.md +91 -88
- package/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +89 -89
- package/.claude/skills/skill-generator/templates/code-analysis-action.md +148 -149
- package/.claude/skills/skill-generator/templates/llm-action.md +367 -367
- package/.claude/skills/skill-generator/templates/script-template.md +79 -79
- package/.claude/skills/skill-generator/templates/sequential-phase.md +129 -129
- package/.claude/skills/skill-generator/templates/skill-md.md +134 -75
- package/.codex/prompts/UNIFIED_EXECUTE_COMPARISON.md +205 -0
- package/.codex/prompts/unified-execute-with-file.md +722 -0
- package/.codex/skills/codex-issue-plan-execute/SKILL.md +239 -0
- package/.codex/skills/codex-issue-plan-execute/phases/actions/action-complete.md +173 -0
- package/.codex/skills/codex-issue-plan-execute/phases/actions/action-execute.md +220 -0
- package/.codex/skills/codex-issue-plan-execute/phases/actions/action-init.md +86 -0
- package/.codex/skills/codex-issue-plan-execute/phases/actions/action-list.md +165 -0
- package/.codex/skills/codex-issue-plan-execute/phases/actions/action-plan.md +170 -0
- package/.codex/skills/codex-issue-plan-execute/phases/orchestrator.md +210 -0
- package/.codex/skills/codex-issue-plan-execute/phases/state-schema.md +136 -0
- package/.codex/skills/codex-issue-plan-execute/prompts/execution-agent-system.md +136 -0
- package/.codex/skills/codex-issue-plan-execute/prompts/execution-agent.md +135 -0
- package/.codex/skills/codex-issue-plan-execute/prompts/planning-agent-system.md +107 -0
- package/.codex/skills/codex-issue-plan-execute/prompts/planning-agent.md +122 -0
- package/.codex/skills/codex-issue-plan-execute/specs/issue-handling.md +187 -0
- package/.codex/skills/codex-issue-plan-execute/specs/quality-standards.md +231 -0
- package/.codex/skills/codex-issue-plan-execute/specs/solution-schema.md +270 -0
- package/.codex/skills/codex-issue-plan-execute/specs/subagent-roles.md +268 -0
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +23 -2
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/core/routes/help-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/help-routes.js +51 -1
- package/ccw/dist/core/routes/help-routes.js.map +1 -1
- package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor-core.js +5 -3
- package/ccw/dist/tools/cli-executor-core.js.map +1 -1
- package/ccw/dist/tools/cli-executor-utils.d.ts +1 -0
- package/ccw/dist/tools/cli-executor-utils.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor-utils.js +3 -1
- package/ccw/dist/tools/cli-executor-utils.js.map +1 -1
- package/ccw/src/commands/cli.ts +26 -2
- package/ccw/src/core/routes/help-routes.ts +60 -1
- package/ccw/src/templates/dashboard-js/views/help.js +423 -1
- package/ccw/src/tools/cli-executor-core.ts +6 -3
- package/ccw/src/tools/cli-executor-utils.ts +5 -2
- package/package.json +1 -1
|
@@ -1,265 +1,265 @@
|
|
|
1
|
-
# Scripting Integration
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
.claude/skills/<skill-name>/
|
|
15
|
-
├── scripts/ #
|
|
16
|
-
│ ├── process-data.py # id: process-data
|
|
17
|
-
│ ├── validate-output.sh # id: validate-output
|
|
18
|
-
│ └── transform-json.js # id: transform-json
|
|
19
|
-
├── phases/
|
|
20
|
-
└── specs/
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
|
|
|
26
|
-
|
|
27
|
-
| `.py` | python | `python scripts/{id}.py` |
|
|
28
|
-
| `.sh` | bash | `bash scripts/{id}.sh` |
|
|
29
|
-
| `.js` | node | `node scripts/{id}.js` |
|
|
30
|
-
|
|
31
|
-
##
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```yaml
|
|
36
|
-
## Scripts
|
|
37
|
-
|
|
38
|
-
- process-data
|
|
39
|
-
- validate-output
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
##
|
|
43
|
-
|
|
44
|
-
###
|
|
45
|
-
|
|
46
|
-
```javascript
|
|
47
|
-
const result = await ExecuteScript('script-id', { key: value });
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
###
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
| JS
|
|
55
|
-
|
|
56
|
-
| `input_path` | `--input-path` |
|
|
57
|
-
| `output_dir` | `--output-dir` |
|
|
58
|
-
| `max_count` | `--max-count` |
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
###
|
|
63
|
-
|
|
64
|
-
```javascript
|
|
65
|
-
const result = await ExecuteScript('process-data', {
|
|
66
|
-
input_path: `${workDir}/data.json`,
|
|
67
|
-
threshold: 0.9
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
if (!result.success) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const { output_file, count } = result.outputs;
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
interface ScriptResult {
|
|
81
|
-
success: boolean; // exit code === 0
|
|
82
|
-
stdout: string; //
|
|
83
|
-
stderr: string; //
|
|
84
|
-
outputs: { //
|
|
85
|
-
[key: string]: any;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
##
|
|
91
|
-
|
|
92
|
-
###
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# Python: argparse
|
|
96
|
-
--input-path /path/to/file --threshold 0.9
|
|
97
|
-
|
|
98
|
-
# Bash:
|
|
99
|
-
--input-path /path/to/file
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
###
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```json
|
|
107
|
-
{"output_file": "/tmp/result.json", "count": 42}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Python
|
|
111
|
-
|
|
112
|
-
```python
|
|
113
|
-
import argparse
|
|
114
|
-
import json
|
|
115
|
-
|
|
116
|
-
def main():
|
|
117
|
-
parser = argparse.ArgumentParser()
|
|
118
|
-
parser.add_argument('--input-path', required=True)
|
|
119
|
-
parser.add_argument('--threshold', type=float, default=0.9)
|
|
120
|
-
args = parser.parse_args()
|
|
121
|
-
|
|
122
|
-
#
|
|
123
|
-
result_path = "/tmp/result.json"
|
|
124
|
-
|
|
125
|
-
#
|
|
126
|
-
print(json.dumps({
|
|
127
|
-
"output_file": result_path,
|
|
128
|
-
"items_processed": 100
|
|
129
|
-
}))
|
|
130
|
-
|
|
131
|
-
if __name__ == '__main__':
|
|
132
|
-
main()
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Bash
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
#!/bin/bash
|
|
139
|
-
|
|
140
|
-
#
|
|
141
|
-
while [[ "$#" -gt 0 ]]; do
|
|
142
|
-
case $1 in
|
|
143
|
-
--input-path) INPUT_PATH="$2"; shift ;;
|
|
144
|
-
*) echo "Unknown: $1" >&2; exit 1 ;;
|
|
145
|
-
esac
|
|
146
|
-
shift
|
|
147
|
-
done
|
|
148
|
-
|
|
149
|
-
#
|
|
150
|
-
LOG_FILE="/tmp/process.log"
|
|
151
|
-
echo "Processing $INPUT_PATH" > "$LOG_FILE"
|
|
152
|
-
|
|
153
|
-
#
|
|
154
|
-
echo "{\"log_file\": \"$LOG_FILE\", \"status\": \"done\"}"
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## ExecuteScript
|
|
158
|
-
|
|
159
|
-
```javascript
|
|
160
|
-
async function ExecuteScript(scriptId, inputs = {}) {
|
|
161
|
-
const skillDir = GetSkillDir();
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
const extensions = ['.py', '.sh', '.js'];
|
|
165
|
-
let scriptPath, runtime;
|
|
166
|
-
|
|
167
|
-
for (const ext of extensions) {
|
|
168
|
-
const path = `${skillDir}/scripts/${scriptId}${ext}`;
|
|
169
|
-
if (FileExists(path)) {
|
|
170
|
-
scriptPath = path;
|
|
171
|
-
runtime = ext === '.py' ? 'python' : ext === '.sh' ? 'bash' : 'node';
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (!scriptPath) {
|
|
177
|
-
throw new Error(`Script not found: ${scriptId}`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
//
|
|
181
|
-
const args = Object.entries(inputs)
|
|
182
|
-
.map(([k, v]) => `--${k.replace(/_/g, '-')} "${v}"`)
|
|
183
|
-
.join(' ');
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
const cmd = `${runtime} "${scriptPath}" ${args}`;
|
|
187
|
-
const { stdout, stderr, exitCode } = await Bash(cmd);
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
let outputs = {};
|
|
191
|
-
try {
|
|
192
|
-
const lastLine = stdout.trim().split('\n').pop();
|
|
193
|
-
outputs = JSON.parse(lastLine);
|
|
194
|
-
} catch (e) {
|
|
195
|
-
//
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
success: exitCode === 0,
|
|
200
|
-
stdout,
|
|
201
|
-
stderr,
|
|
202
|
-
outputs
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
##
|
|
208
|
-
|
|
209
|
-
###
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
|
|
217
|
-
###
|
|
218
|
-
|
|
219
|
-
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
-
|
|
224
|
-
##
|
|
225
|
-
|
|
226
|
-
###
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
.claude/skills/<skill-name>/ #
|
|
232
|
-
├── SKILL.md
|
|
233
|
-
├── scripts/ #
|
|
234
|
-
│ └── process-data.py #
|
|
235
|
-
└── phases/
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
`ExecuteScript`
|
|
239
|
-
```javascript
|
|
240
|
-
//
|
|
241
|
-
await ExecuteScript('process-data', { ... });
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
###
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
//
|
|
250
|
-
const result = await ExecuteScript('process-data', {
|
|
251
|
-
input_path: `${workDir}/data.json`,
|
|
252
|
-
output_dir: `${workDir}/output` //
|
|
253
|
-
});
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
##
|
|
259
|
-
|
|
260
|
-
1.
|
|
261
|
-
2.
|
|
262
|
-
3.
|
|
263
|
-
4.
|
|
264
|
-
5.
|
|
265
|
-
6.
|
|
1
|
+
# Scripting Integration Specification
|
|
2
|
+
|
|
3
|
+
Skill scripting integration specification that defines how to use external scripts for deterministic task execution.
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
1. **Convention over configuration**: Naming is ID, file extension is runtime
|
|
8
|
+
2. **Minimal invocation**: Complete script call in one line
|
|
9
|
+
3. **Standard input/output**: Command-line parameters as input, JSON as standard output
|
|
10
|
+
|
|
11
|
+
## Directory Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
.claude/skills/<skill-name>/
|
|
15
|
+
├── scripts/ # Scripts directory
|
|
16
|
+
│ ├── process-data.py # id: process-data
|
|
17
|
+
│ ├── validate-output.sh # id: validate-output
|
|
18
|
+
│ └── transform-json.js # id: transform-json
|
|
19
|
+
├── phases/
|
|
20
|
+
└── specs/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Naming Conventions
|
|
24
|
+
|
|
25
|
+
| Extension | Runtime | Execution Command |
|
|
26
|
+
|-----------|---------|-------------------|
|
|
27
|
+
| `.py` | python | `python scripts/{id}.py` |
|
|
28
|
+
| `.sh` | bash | `bash scripts/{id}.sh` |
|
|
29
|
+
| `.js` | node | `node scripts/{id}.js` |
|
|
30
|
+
|
|
31
|
+
## Declaration Format
|
|
32
|
+
|
|
33
|
+
Declare in the `## Scripts` section of Phase or Action files:
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
## Scripts
|
|
37
|
+
|
|
38
|
+
- process-data
|
|
39
|
+
- validate-output
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Invocation Syntax
|
|
43
|
+
|
|
44
|
+
### Basic Call
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
const result = await ExecuteScript('script-id', { key: value });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Parameter Name Conversion
|
|
51
|
+
|
|
52
|
+
Keys in the JS object are **automatically converted** to `kebab-case` command-line parameters:
|
|
53
|
+
|
|
54
|
+
| JS Key Name | Converted Parameter |
|
|
55
|
+
|-------------|-------------------|
|
|
56
|
+
| `input_path` | `--input-path` |
|
|
57
|
+
| `output_dir` | `--output-dir` |
|
|
58
|
+
| `max_count` | `--max-count` |
|
|
59
|
+
|
|
60
|
+
Use `--input-path` in scripts, pass `input_path` when calling.
|
|
61
|
+
|
|
62
|
+
### Complete Call (with Error Handling)
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const result = await ExecuteScript('process-data', {
|
|
66
|
+
input_path: `${workDir}/data.json`,
|
|
67
|
+
threshold: 0.9
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!result.success) {
|
|
71
|
+
throw new Error(`Script execution failed: ${result.stderr}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { output_file, count } = result.outputs;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Return Format
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
interface ScriptResult {
|
|
81
|
+
success: boolean; // exit code === 0
|
|
82
|
+
stdout: string; // Complete standard output
|
|
83
|
+
stderr: string; // Complete standard error
|
|
84
|
+
outputs: { // JSON parsed from last line of stdout
|
|
85
|
+
[key: string]: any;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Script Writing Specification
|
|
91
|
+
|
|
92
|
+
### Input: Command-line Parameters
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Python: argparse
|
|
96
|
+
--input-path /path/to/file --threshold 0.9
|
|
97
|
+
|
|
98
|
+
# Bash: manual parsing
|
|
99
|
+
--input-path /path/to/file
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Output: Standard Output JSON
|
|
103
|
+
|
|
104
|
+
Script must print single-line JSON on last line:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{"output_file": "/tmp/result.json", "count": 42}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Python Template
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
import argparse
|
|
114
|
+
import json
|
|
115
|
+
|
|
116
|
+
def main():
|
|
117
|
+
parser = argparse.ArgumentParser()
|
|
118
|
+
parser.add_argument('--input-path', required=True)
|
|
119
|
+
parser.add_argument('--threshold', type=float, default=0.9)
|
|
120
|
+
args = parser.parse_args()
|
|
121
|
+
|
|
122
|
+
# Execution logic...
|
|
123
|
+
result_path = "/tmp/result.json"
|
|
124
|
+
|
|
125
|
+
# Output JSON
|
|
126
|
+
print(json.dumps({
|
|
127
|
+
"output_file": result_path,
|
|
128
|
+
"items_processed": 100
|
|
129
|
+
}))
|
|
130
|
+
|
|
131
|
+
if __name__ == '__main__':
|
|
132
|
+
main()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Bash Template
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
#!/bin/bash
|
|
139
|
+
|
|
140
|
+
# Parse parameters
|
|
141
|
+
while [[ "$#" -gt 0 ]]; do
|
|
142
|
+
case $1 in
|
|
143
|
+
--input-path) INPUT_PATH="$2"; shift ;;
|
|
144
|
+
*) echo "Unknown: $1" >&2; exit 1 ;;
|
|
145
|
+
esac
|
|
146
|
+
shift
|
|
147
|
+
done
|
|
148
|
+
|
|
149
|
+
# Execution logic...
|
|
150
|
+
LOG_FILE="/tmp/process.log"
|
|
151
|
+
echo "Processing $INPUT_PATH" > "$LOG_FILE"
|
|
152
|
+
|
|
153
|
+
# Output JSON
|
|
154
|
+
echo "{\"log_file\": \"$LOG_FILE\", \"status\": \"done\"}"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## ExecuteScript Implementation
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
async function ExecuteScript(scriptId, inputs = {}) {
|
|
161
|
+
const skillDir = GetSkillDir();
|
|
162
|
+
|
|
163
|
+
// Find script file
|
|
164
|
+
const extensions = ['.py', '.sh', '.js'];
|
|
165
|
+
let scriptPath, runtime;
|
|
166
|
+
|
|
167
|
+
for (const ext of extensions) {
|
|
168
|
+
const path = `${skillDir}/scripts/${scriptId}${ext}`;
|
|
169
|
+
if (FileExists(path)) {
|
|
170
|
+
scriptPath = path;
|
|
171
|
+
runtime = ext === '.py' ? 'python' : ext === '.sh' ? 'bash' : 'node';
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!scriptPath) {
|
|
177
|
+
throw new Error(`Script not found: ${scriptId}`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Build command-line parameters
|
|
181
|
+
const args = Object.entries(inputs)
|
|
182
|
+
.map(([k, v]) => `--${k.replace(/_/g, '-')} "${v}"`)
|
|
183
|
+
.join(' ');
|
|
184
|
+
|
|
185
|
+
// Execute script
|
|
186
|
+
const cmd = `${runtime} "${scriptPath}" ${args}`;
|
|
187
|
+
const { stdout, stderr, exitCode } = await Bash(cmd);
|
|
188
|
+
|
|
189
|
+
// Parse output
|
|
190
|
+
let outputs = {};
|
|
191
|
+
try {
|
|
192
|
+
const lastLine = stdout.trim().split('\n').pop();
|
|
193
|
+
outputs = JSON.parse(lastLine);
|
|
194
|
+
} catch (e) {
|
|
195
|
+
// Unable to parse JSON, keep empty object
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
success: exitCode === 0,
|
|
200
|
+
stdout,
|
|
201
|
+
stderr,
|
|
202
|
+
outputs
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Use Cases
|
|
208
|
+
|
|
209
|
+
### Suitable for Scripting
|
|
210
|
+
|
|
211
|
+
- Data processing and transformation
|
|
212
|
+
- File format conversion
|
|
213
|
+
- Batch file operations
|
|
214
|
+
- Complex calculation logic
|
|
215
|
+
- Call external tools/libraries
|
|
216
|
+
|
|
217
|
+
### Not Suitable for Scripting
|
|
218
|
+
|
|
219
|
+
- Tasks requiring user interaction
|
|
220
|
+
- Tasks needing access to Claude tools
|
|
221
|
+
- Simple file read/write
|
|
222
|
+
- Tasks requiring dynamic decision-making
|
|
223
|
+
|
|
224
|
+
## Path Conventions
|
|
225
|
+
|
|
226
|
+
### Script Path
|
|
227
|
+
|
|
228
|
+
Script paths are relative to the directory containing `SKILL.md` (skill root directory):
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
.claude/skills/<skill-name>/ # Skill root directory (SKILL.md location)
|
|
232
|
+
├── SKILL.md
|
|
233
|
+
├── scripts/ # Scripts directory
|
|
234
|
+
│ └── process-data.py # Relative path: scripts/process-data.py
|
|
235
|
+
└── phases/
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
`ExecuteScript` automatically finds scripts from skill root directory:
|
|
239
|
+
```javascript
|
|
240
|
+
// Actually executes: python .claude/skills/<skill-name>/scripts/process-data.py
|
|
241
|
+
await ExecuteScript('process-data', { ... });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Output Directory
|
|
245
|
+
|
|
246
|
+
**Recommended**: Pass output directory from caller, not hardcode in script to `/tmp`:
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
// Specify output directory when calling (in workflow working directory)
|
|
250
|
+
const result = await ExecuteScript('process-data', {
|
|
251
|
+
input_path: `${workDir}/data.json`,
|
|
252
|
+
output_dir: `${workDir}/output` // Explicitly specify output location
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Scripts should accept `--output-dir` parameter instead of hardcoding output paths.
|
|
257
|
+
|
|
258
|
+
## Best Practices
|
|
259
|
+
|
|
260
|
+
1. **Single Responsibility**: Each script does one thing
|
|
261
|
+
2. **No Side Effects**: Scripts should not modify global state
|
|
262
|
+
3. **Idempotence**: Same input produces same output
|
|
263
|
+
4. **Clear Errors**: Error messages to stderr, normal output to stdout
|
|
264
|
+
5. **Fail Fast**: Exit immediately on parameter validation failure
|
|
265
|
+
6. **Parameterized Paths**: Output paths specified by caller, not hardcoded
|