diff --git a/scripts/codex-imagegen/main.ts b/scripts/codex-imagegen/main.ts index 76dfbc4..5de567f 100644 --- a/scripts/codex-imagegen/main.ts +++ b/scripts/codex-imagegen/main.ts @@ -71,13 +71,22 @@ function parseArgs(argv: string[]): CliOptions { } if (!opts.outputPath) throw new GenError("invalid_args", "--image is required", false); if (!opts.prompt && !promptFile) throw new GenError("invalid_args", "--prompt or --prompt-file required", false); + + // Resolve every filesystem path to absolute up front, so behavior is + // independent of the caller's cwd. This matters when the wrapper is + // invoked from a skill running in an arbitrary working directory. + const cwd = process.cwd(); + const toAbs = (p: string) => (path.isAbsolute(p) ? p : path.resolve(cwd, p)); + + opts.outputPath = toAbs(opts.outputPath); if (promptFile) { opts.prompt = ""; // will be loaded later - (opts as any).__promptFile = promptFile; - } - if (!path.isAbsolute(opts.outputPath)) { - opts.outputPath = path.resolve(process.cwd(), opts.outputPath); + (opts as any).__promptFile = toAbs(promptFile); } + opts.refImages = opts.refImages.map(toAbs); + if (opts.cacheDir) opts.cacheDir = toAbs(opts.cacheDir); + if (opts.logFile) opts.logFile = toAbs(opts.logFile); + return opts; } diff --git a/scripts/codex-imagegen/spawn.ts b/scripts/codex-imagegen/spawn.ts index 1e79caf..f422c54 100644 --- a/scripts/codex-imagegen/spawn.ts +++ b/scripts/codex-imagegen/spawn.ts @@ -16,7 +16,16 @@ export async function runCodexExec(input: SpawnInput): Promise { const logDir = await mkdtemp(path.join(tmpdir(), "codex-imggen-")); const rawLogPath = path.join(logDir, "stream.jsonl"); - const args = ["exec", "--json", "--sandbox", "danger-full-access"]; + // --skip-git-repo-check: lets the wrapper run from non-git cwds + // (e.g. /tmp, or a skill installed under ~/.claude/plugins/...). + // Without it, codex refuses with "Not inside a trusted directory". + const args = [ + "exec", + "--json", + "--sandbox", + "danger-full-access", + "--skip-git-repo-check", + ]; for (const img of input.refImages ?? []) { args.push("--image", img); } diff --git a/skills/baoyu-cover-image/SKILL.md b/skills/baoyu-cover-image/SKILL.md index b4effdb..d62b0a7 100644 --- a/skills/baoyu-cover-image/SKILL.md +++ b/skills/baoyu-cover-image/SKILL.md @@ -29,17 +29,17 @@ When this skill needs to render an image, resolve the backend in this order: 2. **Saved preference** — if `EXTEND.md` sets `preferred_image_backend` to a backend available right now, use it. 3. **Auto-select** (when the preference is `auto`, unset, or the pinned backend isn't available): - **Codex (`imagegen`)** — first, inspect your available-skills / tool inventory. If a skill named `imagegen` is listed, you are running inside Codex and MUST use it: invoke via the `Skill` tool with `skill: "imagegen"`, passing the saved prompt file's content (plus output path and aspect ratio per Codex `imagegen`'s own args). Codex `imagegen` is the official raster backend in that runtime and outranks any non-native skill (e.g., `baoyu-imagine`) unless the user has explicitly pinned a different `preferred_image_backend`. - - **Codex via `codex exec` (`codex-imagegen`)** — if the current runtime does NOT expose a native `imagegen` skill but the `codex` CLI is on `PATH` and `codex login` is active (e.g., Claude Code with Codex CLI installed), invoke the `codex-imagegen` wrapper. Command shape: + - **Codex via `codex exec` (`codex-imagegen`)** — if the current runtime does NOT expose a native `imagegen` skill but the `codex` CLI is on `PATH` and `codex login` is active (e.g., Claude Code with Codex CLI installed), invoke the `codex-imagegen` wrapper. **Path resolution**: `scripts/codex-imagegen.sh` lives at the plugin/repo root, NOT relative to your shell cwd. From this `SKILL.md`'s base directory, the wrapper is at `../../scripts/codex-imagegen.sh` — resolve to an absolute path before invoking. Command shape: ```bash - ./scripts/codex-imagegen.sh \ + /scripts/codex-imagegen.sh \ --image \ - --prompt-file \ + --prompt-file \ --aspect \ - [--ref ]... \ + [--ref ]... \ [--cache-dir ~/.cache/baoyu-codex-imagegen] \ - [--log-file ] + [--log-file ] ``` - Parse the single-line JSON on stdout. On `{"status":"ok",...}` proceed to Step 5. On `{"status":"error","error_kind":...}` report the `error_kind` to the user and (if retryable) ask whether to retry or fall back to another backend. The wrapper uses the user's Codex subscription — no `OPENAI_API_KEY` needed. + All input paths to the wrapper are auto-resolved against the wrapper's `process.cwd()` if you pass relative ones, but agents should pass absolute paths to be robust against cwd drift. Parse the single-line JSON on stdout. On `{"status":"ok",...}` proceed to Step 5. On `{"status":"error","error_kind":...}` report the `error_kind` to the user and (if retryable) ask whether to retry or fall back to another backend. The wrapper uses the user's Codex subscription — no `OPENAI_API_KEY` needed. - **Other runtime-native tools** — if the runtime exposes a different native image tool (e.g., Hermes `image_generate`), use it the same way. - Otherwise, if exactly one non-native backend is installed (e.g., `baoyu-imagine`), use it. - Otherwise (multiple non-native backends with no runtime-native tool), ask the user once — batch with any other initial questions. @@ -226,7 +226,7 @@ Save to `prompts/cover.md`. Template: [references/workflow/prompt-template.md](r - `direct` usage → pass via `--ref` (use ref-capable backend) - `style`/`palette` → extract traits, append to prompt 5. **Generate**: Call the chosen backend with the prompt file, output path, aspect ratio. - - **`codex-imagegen`**: run `./scripts/codex-imagegen.sh --image --prompt-file prompts/01-cover-[slug].md --aspect ` (add `--ref ` per reference, `--cache-dir ~/.cache/baoyu-codex-imagegen` to enable the idempotency cache). Read the stdout JSON; act on `status` and `error_kind`. + - **`codex-imagegen`**: invoke `/scripts/codex-imagegen.sh` (NOT a cwd-relative `./scripts/...` — resolve the absolute path from this skill's base directory: `../../scripts/codex-imagegen.sh`) with `--image ` `--prompt-file ` `--aspect ` (add `--ref ` per reference, `--cache-dir ~/.cache/baoyu-codex-imagegen` to enable the idempotency cache). All input paths to the wrapper are auto-resolved against its `process.cwd()` if relative, but passing absolutes is more robust. Read the stdout JSON; act on `status` and `error_kind`. - **Codex `imagegen` (native)** or other runtime-native tools / `baoyu-imagine` skill: per the rule in `## Image Generation Tools` above. 6. On failure: auto-retry once