This commit is contained in:
Abdul Wahab
2026-09-01 10:08:03 +05:00
parent 89c842e5f4
commit 0aec856f45
4 changed files with 67 additions and 6 deletions
+57
View File
@@ -1171,6 +1171,7 @@ async function cli() {
parts.push(buildResolvedContextDirective(ctx, cliOptions, { targetExists }));
appendDetectorFallback(parts, ctx);
appendImageGenDirective(parts);
appendDesignContextDirective(parts, ctx);
appendBuildPathDirective(parts, ctx);
await appendCompRoundOpenDirective(parts, ctx);
appendAutonomyCounterDirective(parts);
@@ -1191,6 +1192,7 @@ async function cli() {
parts.push(buildResolvedContextDirective(ctx, cliOptions, { targetExists }));
appendDetectorFallback(parts, ctx);
appendImageGenDirective(parts);
appendDesignContextDirective(parts, ctx);
appendBuildPathDirective(parts, ctx);
await appendCompRoundOpenDirective(parts, ctx);
appendAutonomyCounterDirective(parts);
@@ -1367,6 +1369,61 @@ function appendBuildPathDirective(parts, ctx) {
}
}
// The design interview's durable record: when the user chose the visual world
// in the browser questionnaire, the choice survives as files (the cue image
// the palette was picked from, staged brand assets, every per-surface answer),
// not only as DESIGN.md prose. A later session must learn those files exist
// to open them; an older seed DESIGN.md may not name them at all. Bounded
// stats on fixed store paths only (Tier 1: no walks, no git).
//
// The names are spelled here rather than imported from
// design-context/store.mjs, which owns them: this script boots every session
// and imports only node builtins and ./lib, so a sibling directory missing
// from a harness's copy cannot take the whole session down with a resolve
// error. Same reason `.impeccable/config.json` is spelled out below. If the
// store ever moves, this list moves with it.
const DESIGN_CONTEXT_DIR = '.impeccable/design-context';
function appendDesignContextDirective(parts, ctx) {
const roots = [...new Set(
[process.cwd(), ctx.projectRoot, ctx.contextDir]
.filter(Boolean)
.map((dir) => path.resolve(dir)),
)];
for (const root of roots) {
const store = {
cuePng: path.join(root, DESIGN_CONTEXT_DIR, 'cue.png'),
answersJson: path.join(root, DESIGN_CONTEXT_DIR, 'answers.json'),
contextJson: path.join(root, DESIGN_CONTEXT_DIR, 'context.json'),
assetsDir: path.join(root, DESIGN_CONTEXT_DIR, 'assets'),
};
let cueExists = false;
let answersExist = false;
let contextExists = false;
let assetNames = [];
try { cueExists = fs.existsSync(store.cuePng); } catch {}
try { answersExist = fs.existsSync(store.answersJson); } catch {}
try { contextExists = fs.existsSync(store.contextJson); } catch {}
try {
assetNames = fs.readdirSync(store.assetsDir).filter((name) => !name.startsWith('.'));
} catch {}
if (!cueExists && !answersExist && assetNames.length === 0) continue;
const rel = (target) => path.relative(process.cwd(), target) || target;
const pieces = [];
if (cueExists) pieces.push(`${rel(store.cuePng)} (the image the user picked the palette from)`);
if (assetNames.length > 0) pieces.push(`${rel(store.assetsDir)}/ (staged brand material: ${assetNames.join(', ')})`);
if (answersExist) pieces.push(`${rel(store.answersJson)} (every questionnaire decision, per surface)`);
if (contextExists) pieces.push(`${rel(store.contextJson)} (the interview's chat half, with each staged file's kind and note under context.assets)`);
parts.push([
'DESIGN_CONTEXT: the visual world on record was chosen by the user in the design interview, and the interview record is files, not only prose: ' + pieces.join('; ') + '.',
"Before building or comping any surface on this world, open the cue image and every staged asset; they are the world's pixel truth, and a staged logo is the project's real mark.",
'reference/new-work.md names where each rides (comp reference, build material, reviewer calibration).',
].join(' '));
return;
}
}
// Image generation availability: harness-native tools always win, but when the
// environment carries an OpenAI key the API fallback works everywhere. The
// flag only reports capability, positively: absence stays silent, because a