MCPcopy Index your code
hub / github.com/garrytan/gstack / runCodexSkill

Function runCodexSkill

test/helpers/codex-session-runner.ts:140–297  ·  view source on GitHub ↗
(opts: {
  skillDir: string;         // Path to skill directory containing SKILL.md
  prompt: string;           // What to ask Codex to do with the skill
  timeoutMs?: number;       // Default 300000 (5 min)
  cwd?: string;             // Working directory
  skillName?: string;       // Skill name for installation (default: dirname)
  sandbox?: string;         // Sandbox mode (default: 'read-only')
})

Source from the content-addressed store, hash-verified

138 * and returns a CodexResult. Skips gracefully if codex binary is not found.
139 */
140export async function runCodexSkill(opts: {
141 skillDir: string; // Path to skill directory containing SKILL.md
142 prompt: string; // What to ask Codex to do with the skill
143 timeoutMs?: number; // Default 300000 (5 min)
144 cwd?: string; // Working directory
145 skillName?: string; // Skill name for installation (default: dirname)
146 sandbox?: string; // Sandbox mode (default: 'read-only')
147}): Promise<CodexResult> {
148 const {
149 skillDir,
150 prompt,
151 timeoutMs = 300_000,
152 cwd,
153 skillName,
154 sandbox = 'read-only',
155 } = opts;
156
157 const startTime = Date.now();
158 const name = skillName || path.basename(skillDir) || 'gstack';
159
160 // Check if codex binary exists
161 const whichResult = Bun.spawnSync(['which', 'codex']);
162 if (whichResult.exitCode !== 0) {
163 return {
164 output: 'SKIP: codex binary not found',
165 reasoning: [],
166 toolCalls: [],
167 tokens: 0,
168 exitCode: -1,
169 durationMs: Date.now() - startTime,
170 sessionId: null,
171 rawLines: [],
172 stderr: '',
173 };
174 }
175
176 // Set up temp HOME with skill installed
177 const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'codex-e2e-'));
178 const realHome = os.homedir();
179
180 try {
181 installSkillToTempHome(skillDir, name, tempHome);
182
183 // Symlink real Codex auth config so codex can authenticate from temp HOME.
184 // Codex stores auth in ~/.codex/ — we need the config but not the skills
185 // (we install our own test skills above).
186 const realCodexConfig = path.join(realHome, '.codex');
187 const tempCodexDir = path.join(tempHome, '.codex');
188 if (fs.existsSync(realCodexConfig)) {
189 // Copy auth-related files from real ~/.codex/ into temp ~/.codex/
190 // (skills/ is already set up by installSkillToTempHome)
191 const entries = fs.readdirSync(realCodexConfig);
192 for (const entry of entries) {
193 if (entry === 'skills') continue; // don't clobber our test skills
194 const src = path.join(realCodexConfig, entry);
195 const dst = path.join(tempCodexDir, entry);
196 if (!fs.existsSync(dst)) {
197 fs.cpSync(src, dst, { recursive: true });

Calls 5

hermeticChildEnvFunction · 0.90
installSkillToTempHomeFunction · 0.85
parseCodexJSONLFunction · 0.85
textMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected