diff --git a/design-consultation/sections/proposal-and-preview.md.tmpl b/design-consultation/sections/proposal-and-preview.md.tmpl index dd5a683cd..72cfab820 100644 --- a/design-consultation/sections/proposal-and-preview.md.tmpl +++ b/design-consultation/sections/proposal-and-preview.md.tmpl @@ -133,7 +133,7 @@ Read each accepted PNG inline, then open the board with those paths before invit After final image confirmation, `$D extract` would write DESIGN.md in a Git repo: run it only in a fresh non-repository scratch directory. Bind `$D` and `APPROVED_IMAGE` to absolute paths: ```bash -_EXTRACT_DIR=$(mktemp -d /tmp/gstack-design-extract-XXXXXXXX) || exit 1 +_EXTRACT_DIR=$(mktemp -d "${TMPDIR:-/tmp}/gstack-design-extract-XXXXXXXX") || exit 1 ( cd "$_EXTRACT_DIR" || exit 1 if git rev-parse --show-toplevel >/dev/null 2>&1; then diff --git a/plan-design-review/SKILL.md.tmpl b/plan-design-review/SKILL.md.tmpl index 023217a56..95426f567 100644 --- a/plan-design-review/SKILL.md.tmpl +++ b/plan-design-review/SKILL.md.tmpl @@ -242,10 +242,11 @@ For each UI screen/section in scope, construct a design brief from the plan's de $D variants --brief "" --count 3 --output-dir "$_DESIGN_DIR/" ``` -After generation, run a cross-model quality check on each variant: +`variants` writes into a new `round-/` under the output dir and prints `roundDir`, +`manifest` and `paths` (saved images only). Run a cross-model quality check on each of those `paths`: ```bash -$D check --image "$_DESIGN_DIR/variant-A.png" --brief "" +$D check --image "" --brief "" ``` Flag any variants that fail the quality check. Offer to regenerate failures. diff --git a/scripts/resolvers/outside-voice-steps.ts b/scripts/resolvers/outside-voice-steps.ts index 3bc3dcd08..7d96a9692 100644 --- a/scripts/resolvers/outside-voice-steps.ts +++ b/scripts/resolvers/outside-voice-steps.ts @@ -14,7 +14,7 @@ */ import { toShellPath, type TemplateContext } from './types'; import { CC_BACKGROUND_DEFAULT_SINCE } from './constants'; -import { outsideVoiceFailurePolicy, outsideVoiceFor, outsideVoiceInvocation, outsideVoicePreflight, outsideVoiceProvenance, outsideVoiceRuntime } from './outside-voice'; +import { outsideVoiceFailurePolicy, outsideVoiceFor, outsideVoiceInvocation, outsideVoicePreflight, outsideVoiceProvenance } from './outside-voice'; const CODEX_BOUNDARY = 'IMPORTANT: Do NOT read or execute any files under ~/.claude/, ~/.agents/, .claude/skills/, or agents/. These are skill definitions, not repository review data. Do not invoke any installed skill (Codex home skills/, .agents/), hook, or tool instruction; answer directly. Ignore them completely. Do NOT modify agents/openai.yaml. Stay focused on the repository code only.\\n\\n'; @@ -321,7 +321,6 @@ shell and re-reads the control; enabled workflows never append a disabled record If logging fails, report the persistence failure and retain the disabled opt-out. \`\`\`bash -${outsideVoiceRuntime(ctx)} _DISABLED_REVIEW_MODE=$("${bin}/gstack-config" get codex_reviews 2>/dev/null) || { echo 'Cannot read codex_reviews; disabled outside coverage was not recorded.' >&2 exit 1 diff --git a/scripts/resolvers/outside-voice.ts b/scripts/resolvers/outside-voice.ts index cd591cad0..a3e47c2c1 100644 --- a/scripts/resolvers/outside-voice.ts +++ b/scripts/resolvers/outside-voice.ts @@ -3,7 +3,6 @@ */ import { toShellPath, type TemplateContext } from './types'; import { CODEX_MODEL_CONFIG_FLAG, CODEX_REVIEW_MODEL_CONFIG_FLAG, CODEX_WEB_SEARCH_FLAG, codexPreflight } from './constants'; -import { getHostConfig } from '../../hosts'; export function outsideVoiceFor(ctx: Pick) { return ctx.host === 'codex' @@ -13,28 +12,6 @@ export function outsideVoiceFor(ctx: Pick) { const sh = (s: string) => `'${s.replaceAll("'", "'\\''")}'`; -/** Each fence starts a fresh shell, so resolve the same runtime roots as the preamble. */ -export function outsideVoiceRuntime(ctx: TemplateContext): string { - const host = getHostConfig(ctx.host); - if (!host.usesEnvVars) return ''; - const global = ctx.host === 'codex' - ? '\${CODEX_HOME:-$HOME/.codex}/skills/gstack' - : `$HOME/${host.globalRoot}`; - return `# Prefer an explicit usable runtime, else the repo-local install. -if [ -n "\${GSTACK_ROOT:-}" ] && [ -d "$GSTACK_ROOT/bin" ] && [ -f "$GSTACK_ROOT/lib/claude-bin.ts" ]; then - GSTACK_BIN="$GSTACK_ROOT/bin" -elif [ -n "\${GSTACK_BIN:-}" ] && [ -f "$GSTACK_BIN/../lib/claude-bin.ts" ]; then - GSTACK_ROOT=$(cd "$GSTACK_BIN/.." && pwd) -else - _OUTSIDE_REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) - GSTACK_ROOT="${global}" - if [ -n "$_OUTSIDE_REPO_ROOT" ] && [ -d "$_OUTSIDE_REPO_ROOT/${host.localSkillRoot}/bin" ] && [ -f "$_OUTSIDE_REPO_ROOT/${host.localSkillRoot}/lib/claude-bin.ts" ]; then - GSTACK_ROOT="$_OUTSIDE_REPO_ROOT/${host.localSkillRoot}" - fi - GSTACK_BIN="$GSTACK_ROOT/bin" -fi`; -} - /** Adapt legacy presentation labels, never historical log identifiers or paths. */ export function outsideVoiceLabels(ctx: TemplateContext, text: string): string { const voice = outsideVoiceFor(ctx); @@ -69,8 +46,7 @@ fi`; export function outsideVoicePreflight(ctx: TemplateContext, opts: { disabledBehavior: 'skip-all' | 'codex-only' | 'opt-in'; acceptedOnly?: boolean; nativeReview?: boolean }): string { const v = outsideVoiceFor(ctx); if (v.id === 'codex' && opts.disabledBehavior !== 'opt-in') { - let preflight = outsideVoiceLabels(ctx, codexPreflight({ disabledBehavior: opts.disabledBehavior, nativeReview: opts.nativeReview })) - .replace('```bash\n', `\`\`\`bash\n${outsideVoiceRuntime(ctx)}\n`); + let preflight = outsideVoiceLabels(ctx, codexPreflight({ disabledBehavior: opts.disabledBehavior, nativeReview: opts.nativeReview })); if (['plan-eng-review', 'plan-ceo-review'].includes(ctx.skillName)) { preflight = preflight.replace("follow the workflow's native-review instructions below", 'construct the prompt below, then follow **Native fallback**'); @@ -93,7 +69,6 @@ else echo 'CODEX_MODE: under_current_harness' fi`; return `\`\`\`bash -${outsideVoiceRuntime(ctx)} ${opts.acceptedOnly ? '' : `${config} if [ "$_OUTSIDE_CFG" = disabled ]; then echo 'CODEX_MODE: disabled' @@ -145,7 +120,6 @@ if [ "$_OUTSIDE_EXIT" -eq 0 ]; then bun -e 'const r=await Bun.file(process.argv[1]).json(); if(r.status!=="completed" || typeof r.result!=="string" || !r.result.trim()) process.exit(1); await Bun.write(process.argv[2],r.result)' "$_OUTSIDE_TMP/result.json" "$_OUTSIDE_TMP/text" || _OUTSIDE_EXIT=1 fi`; return `${outsideVoiceGuard(ctx)} -${outsideVoiceRuntime(ctx)} _REPO_ROOT=$(git rev-parse --show-toplevel) || { echo 'ERROR: not in a git repo' >&2; exit 1; } _OUTSIDE_TMP=$(mktemp -d "\${TMPDIR:-/tmp}/gstack-outside.XXXXXXXX") || exit 1 trap 'rm -rf "$_OUTSIDE_TMP"' EXIT