oh-my-customcode 0.12.1 → 0.12.3
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/README.md +8 -11
- package/dist/cli/index.js +137 -336
- package/dist/index.js +99 -260
- package/package.json +2 -4
- package/templates/.claude/skills/codex-exec/SKILL.md +123 -0
- package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +413 -0
- package/templates/CLAUDE.md.en +1 -0
- package/templates/CLAUDE.md.ko +1 -0
- package/templates/.codex/agents/arch-documenter.md +0 -33
- package/templates/.codex/agents/arch-speckit-agent.md +0 -47
- package/templates/.codex/agents/be-express-expert.md +0 -30
- package/templates/.codex/agents/be-fastapi-expert.md +0 -43
- package/templates/.codex/agents/be-go-backend-expert.md +0 -43
- package/templates/.codex/agents/be-nestjs-expert.md +0 -28
- package/templates/.codex/agents/be-springboot-expert.md +0 -40
- package/templates/.codex/agents/db-postgres-expert.md +0 -36
- package/templates/.codex/agents/db-redis-expert.md +0 -36
- package/templates/.codex/agents/db-supabase-expert.md +0 -35
- package/templates/.codex/agents/de-airflow-expert.md +0 -34
- package/templates/.codex/agents/de-dbt-expert.md +0 -34
- package/templates/.codex/agents/de-kafka-expert.md +0 -81
- package/templates/.codex/agents/de-pipeline-expert.md +0 -32
- package/templates/.codex/agents/de-snowflake-expert.md +0 -36
- package/templates/.codex/agents/de-spark-expert.md +0 -36
- package/templates/.codex/agents/fe-svelte-agent.md +0 -29
- package/templates/.codex/agents/fe-vercel-agent.md +0 -37
- package/templates/.codex/agents/fe-vuejs-agent.md +0 -30
- package/templates/.codex/agents/infra-aws-expert.md +0 -47
- package/templates/.codex/agents/infra-docker-expert.md +0 -47
- package/templates/.codex/agents/lang-golang-expert.md +0 -43
- package/templates/.codex/agents/lang-java21-expert.md +0 -39
- package/templates/.codex/agents/lang-kotlin-expert.md +0 -43
- package/templates/.codex/agents/lang-python-expert.md +0 -43
- package/templates/.codex/agents/lang-rust-expert.md +0 -43
- package/templates/.codex/agents/lang-typescript-expert.md +0 -43
- package/templates/.codex/agents/mgr-claude-code-bible.md +0 -58
- package/templates/.codex/agents/mgr-creator.md +0 -39
- package/templates/.codex/agents/mgr-gitnerd.md +0 -45
- package/templates/.codex/agents/mgr-sauron.md +0 -161
- package/templates/.codex/agents/mgr-supplier.md +0 -35
- package/templates/.codex/agents/mgr-sync-checker.md +0 -38
- package/templates/.codex/agents/mgr-updater.md +0 -33
- package/templates/.codex/agents/qa-engineer.md +0 -32
- package/templates/.codex/agents/qa-planner.md +0 -73
- package/templates/.codex/agents/qa-writer.md +0 -27
- package/templates/.codex/agents/sys-memory-keeper.md +0 -43
- package/templates/.codex/agents/sys-naggy.md +0 -37
- package/templates/.codex/agents/tool-bun-expert.md +0 -26
- package/templates/.codex/agents/tool-npm-expert.md +0 -30
- package/templates/.codex/agents/tool-optimizer.md +0 -34
- package/templates/.codex/codex-native-hash.txt +0 -1
- package/templates/.codex/contexts/dev.md +0 -20
- package/templates/.codex/contexts/ecomode.md +0 -63
- package/templates/.codex/contexts/index.yaml +0 -41
- package/templates/.codex/contexts/research.md +0 -28
- package/templates/.codex/contexts/review.md +0 -23
- package/templates/.codex/hooks/hooks.json +0 -150
- package/templates/.codex/install-hooks.sh +0 -100
- package/templates/.codex/rules/MAY-optimization.md +0 -29
- package/templates/.codex/rules/MUST-agent-design.md +0 -57
- package/templates/.codex/rules/MUST-agent-identification.md +0 -29
- package/templates/.codex/rules/MUST-continuous-improvement.md +0 -25
- package/templates/.codex/rules/MUST-intent-transparency.md +0 -42
- package/templates/.codex/rules/MUST-language-policy.md +0 -27
- package/templates/.codex/rules/MUST-orchestrator-coordination.md +0 -128
- package/templates/.codex/rules/MUST-parallel-execution.md +0 -97
- package/templates/.codex/rules/MUST-permissions.md +0 -30
- package/templates/.codex/rules/MUST-safety.md +0 -23
- package/templates/.codex/rules/MUST-sync-verification.md +0 -125
- package/templates/.codex/rules/MUST-tool-identification.md +0 -82
- package/templates/.codex/rules/SHOULD-agent-teams.md +0 -39
- package/templates/.codex/rules/SHOULD-ecomode.md +0 -37
- package/templates/.codex/rules/SHOULD-error-handling.md +0 -33
- package/templates/.codex/rules/SHOULD-hud-statusline.md +0 -32
- package/templates/.codex/rules/SHOULD-interaction.md +0 -34
- package/templates/.codex/rules/SHOULD-memory-integration.md +0 -39
- package/templates/.codex/rules/index.yaml +0 -141
- package/templates/.codex/skills/airflow-best-practices/SKILL.md +0 -56
- package/templates/.codex/skills/audit-agents/SKILL.md +0 -116
- package/templates/.codex/skills/aws-best-practices/SKILL.md +0 -280
- package/templates/.codex/skills/claude-code-bible/SKILL.md +0 -100
- package/templates/.codex/skills/claude-code-bible/scripts/fetch-docs.js +0 -272
- package/templates/.codex/skills/create-agent/SKILL.md +0 -91
- package/templates/.codex/skills/dbt-best-practices/SKILL.md +0 -54
- package/templates/.codex/skills/de-lead-routing/SKILL.md +0 -243
- package/templates/.codex/skills/dev-lead-routing/SKILL.md +0 -94
- package/templates/.codex/skills/dev-refactor/SKILL.md +0 -123
- package/templates/.codex/skills/dev-review/SKILL.md +0 -81
- package/templates/.codex/skills/docker-best-practices/SKILL.md +0 -275
- package/templates/.codex/skills/fastapi-best-practices/SKILL.md +0 -270
- package/templates/.codex/skills/fix-refs/SKILL.md +0 -107
- package/templates/.codex/skills/go-backend-best-practices/SKILL.md +0 -338
- package/templates/.codex/skills/go-best-practices/SKILL.md +0 -203
- package/templates/.codex/skills/help/SKILL.md +0 -125
- package/templates/.codex/skills/intent-detection/SKILL.md +0 -215
- package/templates/.codex/skills/intent-detection/patterns/agent-triggers.yaml +0 -349
- package/templates/.codex/skills/kafka-best-practices/SKILL.md +0 -52
- package/templates/.codex/skills/kotlin-best-practices/SKILL.md +0 -256
- package/templates/.codex/skills/lists/SKILL.md +0 -78
- package/templates/.codex/skills/memory-management/SKILL.md +0 -195
- package/templates/.codex/skills/memory-recall/SKILL.md +0 -152
- package/templates/.codex/skills/memory-save/SKILL.md +0 -126
- package/templates/.codex/skills/monitoring-setup/SKILL.md +0 -115
- package/templates/.codex/skills/npm-audit/SKILL.md +0 -72
- package/templates/.codex/skills/npm-publish/SKILL.md +0 -63
- package/templates/.codex/skills/npm-version/SKILL.md +0 -75
- package/templates/.codex/skills/optimize-analyze/SKILL.md +0 -55
- package/templates/.codex/skills/optimize-bundle/SKILL.md +0 -67
- package/templates/.codex/skills/optimize-report/SKILL.md +0 -74
- package/templates/.codex/skills/pipeline-architecture-patterns/SKILL.md +0 -83
- package/templates/.codex/skills/postgres-best-practices/SKILL.md +0 -66
- package/templates/.codex/skills/python-best-practices/SKILL.md +0 -222
- package/templates/.codex/skills/qa-lead-routing/SKILL.md +0 -290
- package/templates/.codex/skills/react-best-practices/SKILL.md +0 -101
- package/templates/.codex/skills/redis-best-practices/SKILL.md +0 -83
- package/templates/.codex/skills/result-aggregation/SKILL.md +0 -164
- package/templates/.codex/skills/rust-best-practices/SKILL.md +0 -267
- package/templates/.codex/skills/sauron-watch/SKILL.md +0 -144
- package/templates/.codex/skills/secretary-routing/SKILL.md +0 -203
- package/templates/.codex/skills/snowflake-best-practices/SKILL.md +0 -65
- package/templates/.codex/skills/spark-best-practices/SKILL.md +0 -52
- package/templates/.codex/skills/springboot-best-practices/SKILL.md +0 -218
- package/templates/.codex/skills/status/SKILL.md +0 -153
- package/templates/.codex/skills/supabase-postgres-best-practices/SKILL.md +0 -99
- package/templates/.codex/skills/typescript-best-practices/SKILL.md +0 -321
- package/templates/.codex/skills/update-docs/SKILL.md +0 -140
- package/templates/.codex/skills/update-external/SKILL.md +0 -149
- package/templates/.codex/skills/vercel-deploy/SKILL.md +0 -73
- package/templates/.codex/skills/web-design-guidelines/SKILL.md +0 -118
- package/templates/.codex/skills/writing-clearly-and-concisely/SKILL.md +0 -64
- package/templates/.codex/uninstall-hooks.sh +0 -52
- package/templates/AGENTS.md.en +0 -39
- package/templates/AGENTS.md.ko +0 -39
- package/templates/manifest.codex.json +0 -43
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codex-exec
|
|
3
|
+
description: Execute OpenAI Codex CLI prompts and return results
|
|
4
|
+
argument-hint: "<prompt> [--json] [--output <path>] [--model <name>] [--timeout <ms>]"
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Codex Exec Skill
|
|
9
|
+
|
|
10
|
+
Execute OpenAI Codex CLI prompts in non-interactive mode and return structured results. Enables Claude + Codex hybrid workflows.
|
|
11
|
+
|
|
12
|
+
## Options
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
<prompt> Required. The prompt to send to Codex CLI
|
|
16
|
+
--json Return structured JSON Lines output
|
|
17
|
+
--output <path> Save final message to file
|
|
18
|
+
--model <name> Model override (o3, o4-mini, etc.)
|
|
19
|
+
--timeout <ms> Execution timeout (default: 120000, max: 600000)
|
|
20
|
+
--full-auto Enable auto-approval mode (codex -a full-auto)
|
|
21
|
+
--working-dir Working directory for Codex execution
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
1. Pre-checks
|
|
28
|
+
- Verify `codex` binary is installed (which codex || npx codex --version)
|
|
29
|
+
- Verify authentication (OPENAI_API_KEY or logged in)
|
|
30
|
+
2. Build command
|
|
31
|
+
- Base: codex exec --ephemeral "<prompt>"
|
|
32
|
+
- Apply options: --json, --model, --full-auto, -C <dir>
|
|
33
|
+
- Set --working-dir if specified
|
|
34
|
+
3. Execute
|
|
35
|
+
- Run via Bash tool with timeout (default 2min, max 10min)
|
|
36
|
+
- Or use helper script: node .claude/skills/codex-exec/scripts/codex-wrapper.cjs
|
|
37
|
+
4. Parse output
|
|
38
|
+
- Text mode: return raw stdout
|
|
39
|
+
- JSON mode: parse JSON Lines, extract final assistant message
|
|
40
|
+
5. Report results
|
|
41
|
+
- Format output with execution metadata
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Safety Defaults
|
|
45
|
+
|
|
46
|
+
- `--ephemeral`: No session persistence (conversations not saved)
|
|
47
|
+
- Default mode: Normal approval (Codex prompts for confirmation)
|
|
48
|
+
- Override with `--full-auto` only when explicitly requested
|
|
49
|
+
|
|
50
|
+
## Output Format
|
|
51
|
+
|
|
52
|
+
### Success (Text Mode)
|
|
53
|
+
```
|
|
54
|
+
[Codex Exec] Completed
|
|
55
|
+
|
|
56
|
+
Model: o3
|
|
57
|
+
Duration: 23.4s
|
|
58
|
+
Working Dir: /path/to/project
|
|
59
|
+
|
|
60
|
+
--- Output ---
|
|
61
|
+
{codex response text}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Success (JSON Mode)
|
|
65
|
+
```
|
|
66
|
+
[Codex Exec] Completed (JSON)
|
|
67
|
+
|
|
68
|
+
Model: o3
|
|
69
|
+
Duration: 23.4s
|
|
70
|
+
Events: 12
|
|
71
|
+
|
|
72
|
+
--- Final Message ---
|
|
73
|
+
{extracted final assistant message}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Failure
|
|
77
|
+
```
|
|
78
|
+
[Codex Exec] Failed
|
|
79
|
+
|
|
80
|
+
Error: {error_message}
|
|
81
|
+
Exit Code: {code}
|
|
82
|
+
Suggested Fix: {suggestion}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Helper Script
|
|
86
|
+
|
|
87
|
+
For complex executions, use the wrapper script:
|
|
88
|
+
```bash
|
|
89
|
+
node .claude/skills/codex-exec/scripts/codex-wrapper.cjs --prompt "your prompt" [options]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The wrapper provides:
|
|
93
|
+
- Environment validation (binary + auth checks)
|
|
94
|
+
- Safe command construction
|
|
95
|
+
- JSON Lines parsing with event extraction
|
|
96
|
+
- Structured JSON output
|
|
97
|
+
- Timeout handling with graceful termination
|
|
98
|
+
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Simple text prompt
|
|
103
|
+
codex-exec "explain what this project does"
|
|
104
|
+
|
|
105
|
+
# JSON output with model override
|
|
106
|
+
codex-exec "list all TODO items" --json --model o4-mini
|
|
107
|
+
|
|
108
|
+
# Save output to file
|
|
109
|
+
codex-exec "generate a README" --output ./README.md
|
|
110
|
+
|
|
111
|
+
# Full auto mode with custom timeout
|
|
112
|
+
codex-exec "fix the failing tests" --full-auto --timeout 300000
|
|
113
|
+
|
|
114
|
+
# Specify working directory
|
|
115
|
+
codex-exec "analyze the codebase" --working-dir /path/to/project
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Integration
|
|
119
|
+
|
|
120
|
+
Works with the orchestrator pattern:
|
|
121
|
+
- Main conversation delegates Codex execution via this skill
|
|
122
|
+
- Results are returned to the main conversation for further processing
|
|
123
|
+
- Can be chained with other skills (e.g., dev-review after Codex generates code)
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* codex-wrapper.js
|
|
5
|
+
*
|
|
6
|
+
* Node.js wrapper for OpenAI Codex CLI (non-interactive execution).
|
|
7
|
+
* Executes codex in ephemeral mode with structured JSON output.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node codex-wrapper.js --prompt "your prompt" [options]
|
|
11
|
+
*
|
|
12
|
+
* Options:
|
|
13
|
+
* --prompt <text> Required: prompt to execute
|
|
14
|
+
* --json Enable JSON Lines output from codex
|
|
15
|
+
* --output <path> Save final message to file
|
|
16
|
+
* --model <name> Specify model (default: o3)
|
|
17
|
+
* --timeout <ms> Execution timeout in milliseconds (default: 120000, max: 600000)
|
|
18
|
+
* --full-auto Use full-auto approval mode (default: -a never)
|
|
19
|
+
* --working-dir <dir> Set working directory for execution
|
|
20
|
+
*
|
|
21
|
+
* Output (JSON to stdout):
|
|
22
|
+
* Success: { "success": true, "output": "...", "duration_ms": 1234, ... }
|
|
23
|
+
* Failure: { "success": false, "error": "...", "stderr": "...", ... }
|
|
24
|
+
*
|
|
25
|
+
* Exit codes:
|
|
26
|
+
* 0 = success
|
|
27
|
+
* 1 = execution error
|
|
28
|
+
* 2 = validation error (missing binary/auth)
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const { spawn, execFileSync } = require('child_process');
|
|
32
|
+
const fs = require('fs');
|
|
33
|
+
const path = require('path');
|
|
34
|
+
const os = require('os');
|
|
35
|
+
|
|
36
|
+
// Configuration
|
|
37
|
+
const DEFAULT_TIMEOUT_MS = 120000; // 2 minutes
|
|
38
|
+
const MAX_TIMEOUT_MS = 600000; // 10 minutes
|
|
39
|
+
const KILL_GRACE_PERIOD_MS = 5000; // 5 seconds for graceful shutdown
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Parse command line arguments
|
|
43
|
+
* @returns {Object} Parsed arguments
|
|
44
|
+
*/
|
|
45
|
+
function parseArgs() {
|
|
46
|
+
const args = {
|
|
47
|
+
prompt: null,
|
|
48
|
+
json: false,
|
|
49
|
+
output: null,
|
|
50
|
+
model: null,
|
|
51
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
52
|
+
fullAuto: false,
|
|
53
|
+
workingDir: null,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
57
|
+
const arg = process.argv[i];
|
|
58
|
+
|
|
59
|
+
switch (arg) {
|
|
60
|
+
case '--prompt':
|
|
61
|
+
if (i + 1 < process.argv.length) {
|
|
62
|
+
args.prompt = process.argv[++i];
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case '--json':
|
|
66
|
+
args.json = true;
|
|
67
|
+
break;
|
|
68
|
+
case '--output':
|
|
69
|
+
if (i + 1 < process.argv.length) {
|
|
70
|
+
args.output = process.argv[++i];
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
case '--model':
|
|
74
|
+
if (i + 1 < process.argv.length) {
|
|
75
|
+
args.model = process.argv[++i];
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
case '--timeout':
|
|
79
|
+
if (i + 1 < process.argv.length) {
|
|
80
|
+
const timeoutValue = parseInt(process.argv[++i], 10);
|
|
81
|
+
if (!isNaN(timeoutValue)) {
|
|
82
|
+
args.timeout = Math.min(timeoutValue, MAX_TIMEOUT_MS);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
case '--full-auto':
|
|
87
|
+
args.fullAuto = true;
|
|
88
|
+
break;
|
|
89
|
+
case '--working-dir':
|
|
90
|
+
if (i + 1 < process.argv.length) {
|
|
91
|
+
args.workingDir = process.argv[++i];
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return args;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Validate environment for codex execution
|
|
102
|
+
* @returns {Object} Validation result { valid: boolean, errors: string[] }
|
|
103
|
+
*/
|
|
104
|
+
function validateEnvironment() {
|
|
105
|
+
const errors = [];
|
|
106
|
+
|
|
107
|
+
// Check for codex binary
|
|
108
|
+
try {
|
|
109
|
+
execFileSync('which', ['codex'], { stdio: 'pipe' });
|
|
110
|
+
} catch (error) {
|
|
111
|
+
// Try common installation paths
|
|
112
|
+
const commonPaths = [
|
|
113
|
+
'/usr/local/bin/codex',
|
|
114
|
+
path.join(os.homedir(), '.local', 'bin', 'codex'),
|
|
115
|
+
path.join(os.homedir(), 'bin', 'codex'),
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
const codexExists = commonPaths.some(p => fs.existsSync(p));
|
|
119
|
+
if (!codexExists) {
|
|
120
|
+
errors.push('codex binary not found in PATH or common locations');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Note: OPENAI_API_KEY is optional if codex has its own stored auth (via `codex auth`)
|
|
125
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
126
|
+
console.error('[codex-wrapper] Note: OPENAI_API_KEY not set, relying on codex built-in auth');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
valid: errors.length === 0,
|
|
131
|
+
errors,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Build codex command array
|
|
137
|
+
* @param {Object} options - Command options
|
|
138
|
+
* @returns {Object} Command structure { binary: string, args: string[] }
|
|
139
|
+
*/
|
|
140
|
+
function buildCommand(options) {
|
|
141
|
+
const args = ['exec', '--ephemeral'];
|
|
142
|
+
|
|
143
|
+
// Approval mode (default: normal, --full-auto: automatic execution)
|
|
144
|
+
if (options.fullAuto) {
|
|
145
|
+
args.push('--full-auto');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// JSON output
|
|
149
|
+
if (options.json) {
|
|
150
|
+
args.push('--json');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Model selection
|
|
154
|
+
if (options.model) {
|
|
155
|
+
args.push('--model', options.model);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Working directory
|
|
159
|
+
if (options.workingDir) {
|
|
160
|
+
args.push('-C', options.workingDir);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Add prompt as last argument
|
|
164
|
+
args.push(options.prompt);
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
binary: 'codex',
|
|
168
|
+
args,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Execute codex command
|
|
174
|
+
* @param {string} binary - Binary to execute
|
|
175
|
+
* @param {string[]} args - Command arguments
|
|
176
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
177
|
+
* @param {string|null} workingDir - Working directory
|
|
178
|
+
* @returns {Promise<Object>} Execution result
|
|
179
|
+
*/
|
|
180
|
+
function executeCodex(binary, args, timeout, workingDir = null) {
|
|
181
|
+
return new Promise((resolve) => {
|
|
182
|
+
const startTime = Date.now();
|
|
183
|
+
let stdout = '';
|
|
184
|
+
let stderr = '';
|
|
185
|
+
let timedOut = false;
|
|
186
|
+
|
|
187
|
+
const spawnOptions = {
|
|
188
|
+
cwd: workingDir || process.cwd(),
|
|
189
|
+
env: process.env,
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const child = spawn(binary, args, spawnOptions);
|
|
193
|
+
|
|
194
|
+
// Collect output
|
|
195
|
+
child.stdout.on('data', (data) => {
|
|
196
|
+
stdout += data.toString();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
child.stderr.on('data', (data) => {
|
|
200
|
+
stderr += data.toString();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Set timeout
|
|
204
|
+
const timeoutHandle = setTimeout(() => {
|
|
205
|
+
timedOut = true;
|
|
206
|
+
console.error('[codex-wrapper] Timeout reached, terminating process...', { file: 'stderr' });
|
|
207
|
+
|
|
208
|
+
// Graceful termination attempt
|
|
209
|
+
child.kill('SIGTERM');
|
|
210
|
+
|
|
211
|
+
// Force kill after grace period
|
|
212
|
+
setTimeout(() => {
|
|
213
|
+
if (!child.killed) {
|
|
214
|
+
console.error('[codex-wrapper] Force killing process...', { file: 'stderr' });
|
|
215
|
+
child.kill('SIGKILL');
|
|
216
|
+
}
|
|
217
|
+
}, KILL_GRACE_PERIOD_MS);
|
|
218
|
+
}, timeout);
|
|
219
|
+
|
|
220
|
+
// Handle process exit
|
|
221
|
+
child.on('close', (exitCode) => {
|
|
222
|
+
clearTimeout(timeoutHandle);
|
|
223
|
+
const durationMs = Date.now() - startTime;
|
|
224
|
+
|
|
225
|
+
resolve({
|
|
226
|
+
exitCode: exitCode !== null ? exitCode : 1,
|
|
227
|
+
stdout,
|
|
228
|
+
stderr,
|
|
229
|
+
timedOut,
|
|
230
|
+
durationMs,
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Handle spawn errors
|
|
235
|
+
child.on('error', (error) => {
|
|
236
|
+
clearTimeout(timeoutHandle);
|
|
237
|
+
const durationMs = Date.now() - startTime;
|
|
238
|
+
|
|
239
|
+
resolve({
|
|
240
|
+
exitCode: 1,
|
|
241
|
+
stdout,
|
|
242
|
+
stderr: stderr + '\nSpawn error: ' + error.message,
|
|
243
|
+
timedOut: false,
|
|
244
|
+
durationMs,
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Parse JSON Lines output from codex
|
|
252
|
+
* @param {string} output - Raw output string
|
|
253
|
+
* @returns {Object} Parsed result { events: object[], finalMessage: string|null, parseErrors: string[] }
|
|
254
|
+
*/
|
|
255
|
+
function parseJsonLines(output) {
|
|
256
|
+
const lines = output.split('\n').filter(line => line.trim().length > 0);
|
|
257
|
+
const events = [];
|
|
258
|
+
const parseErrors = [];
|
|
259
|
+
let finalMessage = null;
|
|
260
|
+
|
|
261
|
+
for (const line of lines) {
|
|
262
|
+
try {
|
|
263
|
+
const event = JSON.parse(line);
|
|
264
|
+
events.push(event);
|
|
265
|
+
|
|
266
|
+
// Codex CLI v0.99.0 format: item.completed events with agent_message type
|
|
267
|
+
if (event.type === 'item.completed' && event.item) {
|
|
268
|
+
if (event.item.type === 'agent_message' && event.item.text) {
|
|
269
|
+
finalMessage = event.item.text;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Look for assistant message in various event structures (fallback for future API changes)
|
|
273
|
+
else if (event.type === 'assistant_message' && event.content) {
|
|
274
|
+
finalMessage = event.content;
|
|
275
|
+
} else if (event.message && event.message.role === 'assistant') {
|
|
276
|
+
finalMessage = event.message.content || event.message.text;
|
|
277
|
+
} else if (event.role === 'assistant' && event.content) {
|
|
278
|
+
finalMessage = event.content;
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
parseErrors.push(`Failed to parse line: ${error.message}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
events,
|
|
287
|
+
finalMessage,
|
|
288
|
+
parseErrors,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Main execution function
|
|
294
|
+
*/
|
|
295
|
+
async function main() {
|
|
296
|
+
const args = parseArgs();
|
|
297
|
+
|
|
298
|
+
// Validate required arguments
|
|
299
|
+
if (!args.prompt) {
|
|
300
|
+
const result = {
|
|
301
|
+
success: false,
|
|
302
|
+
error: 'Missing required argument: --prompt',
|
|
303
|
+
exit_code: 2,
|
|
304
|
+
};
|
|
305
|
+
console.log(JSON.stringify(result, null, 2));
|
|
306
|
+
process.exit(2);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Validate environment
|
|
310
|
+
const validation = validateEnvironment();
|
|
311
|
+
if (!validation.valid) {
|
|
312
|
+
const result = {
|
|
313
|
+
success: false,
|
|
314
|
+
error: 'Environment validation failed',
|
|
315
|
+
validation_errors: validation.errors,
|
|
316
|
+
exit_code: 2,
|
|
317
|
+
};
|
|
318
|
+
console.log(JSON.stringify(result, null, 2));
|
|
319
|
+
process.exit(2);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
console.error(`[codex-wrapper] Executing codex with timeout: ${args.timeout}ms`);
|
|
323
|
+
if (args.workingDir) {
|
|
324
|
+
console.error(`[codex-wrapper] Working directory: ${args.workingDir}`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Build command
|
|
328
|
+
const command = buildCommand(args);
|
|
329
|
+
console.error(`[codex-wrapper] Command: ${command.binary} ${command.args.join(' ')}`);
|
|
330
|
+
|
|
331
|
+
// Execute
|
|
332
|
+
const execResult = await executeCodex(
|
|
333
|
+
command.binary,
|
|
334
|
+
command.args,
|
|
335
|
+
args.timeout,
|
|
336
|
+
args.workingDir
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
// Process result
|
|
340
|
+
let output = null;
|
|
341
|
+
let eventsCount = 0;
|
|
342
|
+
|
|
343
|
+
if (args.json && execResult.stdout) {
|
|
344
|
+
const parsed = parseJsonLines(execResult.stdout);
|
|
345
|
+
eventsCount = parsed.events.length;
|
|
346
|
+
output = parsed.finalMessage;
|
|
347
|
+
|
|
348
|
+
if (parsed.parseErrors.length > 0) {
|
|
349
|
+
console.error('[codex-wrapper] JSON parse errors:', parsed.parseErrors.join('; '));
|
|
350
|
+
}
|
|
351
|
+
} else {
|
|
352
|
+
output = execResult.stdout.trim();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Determine success
|
|
356
|
+
const success = execResult.exitCode === 0 && !execResult.timedOut;
|
|
357
|
+
|
|
358
|
+
// Build result object
|
|
359
|
+
const result = {
|
|
360
|
+
success,
|
|
361
|
+
duration_ms: execResult.durationMs,
|
|
362
|
+
exit_code: execResult.exitCode,
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
if (success) {
|
|
366
|
+
result.output = output || execResult.stdout;
|
|
367
|
+
result.model = args.model || 'o3';
|
|
368
|
+
if (args.json) {
|
|
369
|
+
result.events_count = eventsCount;
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
if (execResult.timedOut) {
|
|
373
|
+
result.error = `Execution timed out after ${args.timeout}ms`;
|
|
374
|
+
} else {
|
|
375
|
+
result.error = 'Execution failed';
|
|
376
|
+
}
|
|
377
|
+
if (execResult.stderr) {
|
|
378
|
+
result.stderr = execResult.stderr.trim();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Write output file if requested
|
|
383
|
+
if (args.output && output) {
|
|
384
|
+
try {
|
|
385
|
+
const outputDir = path.dirname(args.output);
|
|
386
|
+
if (!fs.existsSync(outputDir)) {
|
|
387
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
388
|
+
}
|
|
389
|
+
fs.writeFileSync(args.output, output, 'utf-8');
|
|
390
|
+
console.error(`[codex-wrapper] Output written to: ${args.output}`);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
console.error(`[codex-wrapper] Failed to write output file: ${error.message}`);
|
|
393
|
+
result.output_file_error = error.message;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Output JSON result to stdout
|
|
398
|
+
console.log(JSON.stringify(result, null, 2));
|
|
399
|
+
|
|
400
|
+
process.exit(result.exit_code);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Run
|
|
404
|
+
main().catch(error => {
|
|
405
|
+
const result = {
|
|
406
|
+
success: false,
|
|
407
|
+
error: 'Unexpected error: ' + error.message,
|
|
408
|
+
stack: error.stack,
|
|
409
|
+
exit_code: 1,
|
|
410
|
+
};
|
|
411
|
+
console.log(JSON.stringify(result, null, 2));
|
|
412
|
+
process.exit(1);
|
|
413
|
+
});
|
package/templates/CLAUDE.md.en
CHANGED
|
@@ -155,6 +155,7 @@ Flow:
|
|
|
155
155
|
| `/npm-publish` | Publish package to npm registry |
|
|
156
156
|
| `/npm-version` | Manage semantic versions |
|
|
157
157
|
| `/npm-audit` | Audit dependencies |
|
|
158
|
+
| `/codex-exec` | Execute Codex CLI prompts |
|
|
158
159
|
| `/optimize-analyze` | Analyze bundle and performance |
|
|
159
160
|
| `/optimize-bundle` | Optimize bundle size |
|
|
160
161
|
| `/optimize-report` | Generate optimization report |
|
package/templates/CLAUDE.md.ko
CHANGED
|
@@ -155,6 +155,7 @@ oh-my-customcode로 구동됩니다.
|
|
|
155
155
|
| `/npm-publish` | npm 레지스트리에 패키지 배포 |
|
|
156
156
|
| `/npm-version` | 시맨틱 버전 관리 |
|
|
157
157
|
| `/npm-audit` | 의존성 감사 |
|
|
158
|
+
| `/codex-exec` | Codex CLI 프롬프트 실행 |
|
|
158
159
|
| `/optimize-analyze` | 번들 및 성능 분석 |
|
|
159
160
|
| `/optimize-bundle` | 번들 크기 최적화 |
|
|
160
161
|
| `/optimize-report` | 최적화 리포트 생성 |
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arch-documenter
|
|
3
|
-
description: Use for generating architecture documentation, API specifications (OpenAPI), Architecture Decision Records (ADRs), technical diagrams (Mermaid/PlantUML), and README maintenance
|
|
4
|
-
model: balanced
|
|
5
|
-
memory: project
|
|
6
|
-
effort: high
|
|
7
|
-
skills: []
|
|
8
|
-
tools:
|
|
9
|
-
- Read
|
|
10
|
-
- Write
|
|
11
|
-
- Edit
|
|
12
|
-
- Grep
|
|
13
|
-
- Glob
|
|
14
|
-
- Bash
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
You handle software architecture documentation: system design docs, API specs, ADRs, and technical doc maintenance.
|
|
18
|
-
|
|
19
|
-
## Capabilities
|
|
20
|
-
|
|
21
|
-
- Architecture documentation with diagrams (Mermaid, PlantUML)
|
|
22
|
-
- API specifications (OpenAPI/Swagger)
|
|
23
|
-
- Architecture Decision Records (ADRs)
|
|
24
|
-
- README and developer guide maintenance
|
|
25
|
-
|
|
26
|
-
## Document Types
|
|
27
|
-
|
|
28
|
-
| Type | Format | Purpose |
|
|
29
|
-
|------|--------|---------|
|
|
30
|
-
| Architecture | Markdown + Diagrams | System overview |
|
|
31
|
-
| API Spec | OpenAPI/Swagger | API documentation |
|
|
32
|
-
| ADR | Markdown | Decision records |
|
|
33
|
-
| README/Guides | Markdown | Project/developer docs |
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arch-speckit-agent
|
|
3
|
-
description: Use for spec-driven development, transforming requirements into executable specifications, defining project constitution, creating technical plans, and generating TDD task lists
|
|
4
|
-
model: balanced
|
|
5
|
-
memory: project
|
|
6
|
-
effort: high
|
|
7
|
-
skills: []
|
|
8
|
-
tools:
|
|
9
|
-
- Read
|
|
10
|
-
- Write
|
|
11
|
-
- Edit
|
|
12
|
-
- Grep
|
|
13
|
-
- Glob
|
|
14
|
-
- Bash
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
You are a Spec-Driven Development agent that transforms requirements into executable specifications.
|
|
18
|
-
|
|
19
|
-
## Source
|
|
20
|
-
|
|
21
|
-
External agent from https://github.com/github/spec-kit
|
|
22
|
-
- **Version**: latest
|
|
23
|
-
- **Update**: `uv tool upgrade specify-cli --from git+https://github.com/github/spec-kit.git`
|
|
24
|
-
- **Prerequisites**: Python 3.11+, uv, Git
|
|
25
|
-
|
|
26
|
-
## Commands
|
|
27
|
-
|
|
28
|
-
| Command | Purpose |
|
|
29
|
-
|---------|---------|
|
|
30
|
-
| `/speckit.constitution` | Define project principles |
|
|
31
|
-
| `/speckit.specify` | Define WHAT to build |
|
|
32
|
-
| `/speckit.clarify` | Clarify requirements (Q&A) |
|
|
33
|
-
| `/speckit.plan` | Define HOW to build |
|
|
34
|
-
| `/speckit.tasks` | Generate implementation tasks |
|
|
35
|
-
| `/speckit.implement` | Execute all tasks |
|
|
36
|
-
| `/speckit.analyze` | Check spec consistency |
|
|
37
|
-
| `/speckit.checklist` | Generate QA checklist |
|
|
38
|
-
|
|
39
|
-
## Workflow
|
|
40
|
-
|
|
41
|
-
1. `specify init <project> --ai codex`
|
|
42
|
-
2. `/speckit.constitution` -> principles
|
|
43
|
-
3. `/speckit.specify` -> feature spec
|
|
44
|
-
4. `/speckit.clarify` -> Q&A
|
|
45
|
-
5. `/speckit.plan` -> technical plan
|
|
46
|
-
6. `/speckit.tasks` -> TDD task list
|
|
47
|
-
7. `/speckit.implement` -> execute
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: be-express-expert
|
|
3
|
-
description: Expert Express.js developer for production-ready Node.js APIs following security best practices and 12-factor app principles. Use for Express.js APIs, REST API architectures, middleware chains, authentication/authorization, security hardening, and Node.js performance optimization.
|
|
4
|
-
model: balanced
|
|
5
|
-
memory: project
|
|
6
|
-
effort: high
|
|
7
|
-
skills: []
|
|
8
|
-
tools:
|
|
9
|
-
- Read
|
|
10
|
-
- Write
|
|
11
|
-
- Edit
|
|
12
|
-
- Grep
|
|
13
|
-
- Glob
|
|
14
|
-
- Bash
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
You are an expert Express.js developer for production-ready Node.js APIs following security best practices and 12-factor app principles.
|
|
18
|
-
|
|
19
|
-
## Capabilities
|
|
20
|
-
|
|
21
|
-
- Scalable Express.js architecture, modular routers
|
|
22
|
-
- Middleware chains (helmet, cors, json, custom, error handler)
|
|
23
|
-
- Centralized error handling, async/await error propagation
|
|
24
|
-
- 12-factor app configuration
|
|
25
|
-
- Security: helmet, rate limiting, input validation, parameterized queries, secure cookies, CORS, HTTPS
|
|
26
|
-
|
|
27
|
-
## Reference Documentation
|
|
28
|
-
|
|
29
|
-
- https://expressjs.com/
|
|
30
|
-
- https://expressjs.com/en/advanced/best-practice-security.html
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: be-fastapi-expert
|
|
3
|
-
description: Expert FastAPI developer for building high-performance async Python APIs. Use for FastAPI projects, Python async/await patterns, Pydantic models, API architecture design, and performance optimization.
|
|
4
|
-
model: balanced
|
|
5
|
-
memory: project
|
|
6
|
-
effort: high
|
|
7
|
-
skills:
|
|
8
|
-
- fastapi-best-practices
|
|
9
|
-
tools:
|
|
10
|
-
- Read
|
|
11
|
-
- Write
|
|
12
|
-
- Edit
|
|
13
|
-
- Grep
|
|
14
|
-
- Glob
|
|
15
|
-
- Bash
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
You are an expert FastAPI developer specialized in building high-performance async Python APIs following best practices and modern patterns.
|
|
19
|
-
|
|
20
|
-
## Capabilities
|
|
21
|
-
|
|
22
|
-
- Design scalable FastAPI application architecture
|
|
23
|
-
- Implement async/await patterns correctly
|
|
24
|
-
- Create Pydantic models for validation
|
|
25
|
-
- Design dependency injection systems
|
|
26
|
-
- Implement proper error handling
|
|
27
|
-
- Optimize API performance
|
|
28
|
-
|
|
29
|
-
## Skills
|
|
30
|
-
|
|
31
|
-
Apply the **fastapi-best-practices** skill for FastAPI development patterns.
|
|
32
|
-
|
|
33
|
-
## Reference Guides
|
|
34
|
-
|
|
35
|
-
Consult the **fastapi** guide at `guides/fastapi/` for FastAPI reference documentation.
|
|
36
|
-
|
|
37
|
-
## Workflow
|
|
38
|
-
|
|
39
|
-
1. Understand requirements
|
|
40
|
-
2. Apply fastapi-best-practices skill
|
|
41
|
-
3. Reference fastapi guide for specifics
|
|
42
|
-
4. Write/review code with async patterns
|
|
43
|
-
5. Ensure proper validation and error handling
|