mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-11 19:20:26 +01:00
fix: design briefs and approval feedback travel as agent-written files
Design briefs went into $D variants/generate/check as a double-quoted argument, and approval feedback was spliced into a single-quoted echo of JSON, so a quote, backtick or $(...) in either broke the command or ran. The agent now writes each brief into a private .gstack/tmp file and the block passes --brief "$(cat "$BRIEF_FILE")" (the CLI's --brief-file expects a JSON brief, so plain text uses --brief). variants and the later check reuse the same brief file. approved.json is built with jq -n from --arg values and --rawfile feedback, so the feedback is data. The office-hours mockup flow creates its brief and feedback files in one block. design-approval-flow now writes the feedback file (with quotes, backticks and $(...) in it) instead of substituting <FEEDBACK>, and checks the file is removed after the save. Co-authored-by: dgrant <dgrant@users.noreply.github.com>
This commit is contained in:
1 parent
e399cf69e2
commit
7637f604a4
13 files changed
+228
-77
No files matched your search
@@ -22,7 +22,8 @@ function bashBlockAfter(marker: string): string {
|
||||
}
|
||||
|
||||
const BOARD = bashBlockAfter('<!-- design:board -->');
|
||||
const APPROVAL = SKILL.slice(SKILL.indexOf('**Save the approved choice.**')).match(/```bash\n([\s\S]*?)```/)![1];
|
||||
// The save block follows the feedback-file block.
|
||||
const APPROVAL = SKILL.slice(SKILL.indexOf('**Save the approved choice.**')).match(/```bash\n(_IMG=[\s\S]*?)```/)![1];
|
||||
|
||||
let dir: string;
|
||||
let designDir: string;
|
||||
@@ -50,7 +51,12 @@ afterEach(() => { fs.rmSync(dir, { recursive: true, force: true }); });
|
||||
|
||||
const sh = (script: string) => spawnSync('bash', ['-c', script], { cwd: dir, env, encoding: 'utf8', timeout: 60_000 });
|
||||
const variants = () => JSON.parse(sh('"$D" variants --brief "home page" --count 2 --output-dir "$_DESIGN_DIR/"').stdout);
|
||||
const approve = (letter: string) => sh(APPROVAL.replaceAll('<VARIANT>', letter).replaceAll('<FEEDBACK>', 'calmer').replaceAll('<SCREEN>', 'home'));
|
||||
// CEO-12: the feedback travels in an agent-written file under the project's .gstack/tmp, never in the command.
|
||||
const approve = (letter: string) => {
|
||||
fs.mkdirSync(path.join(dir, '.gstack', 'tmp'), { recursive: true });
|
||||
fs.writeFileSync(path.join(dir, '.gstack', 'tmp', 'feedback.fixture'), 'calmer "quoted" `not run` $(not run)\n');
|
||||
return sh(APPROVAL.replaceAll('<VARIANT>', letter).replaceAll('<feedback-file-name>', 'feedback.fixture').replaceAll('<SCREEN>', 'home'));
|
||||
};
|
||||
|
||||
// Value: protects=round two's approval comes from round two's board, never round one's stale feedback.json or the newest-file listing;
|
||||
// fails_when=the board block stops archiving feedback.json or approval maps letters through the directory; why_new=eng feedback-binding; seam=none
|
||||
@@ -73,7 +79,8 @@ test('round two board archives round one Submit and approval maps to the bumped
|
||||
expect(approved.status, approved.stderr).toBe(0);
|
||||
expect(approved.stdout).toContain(`APPROVED_IMAGE: ${path.join(designDir, 'variant-A-2.png')}`);
|
||||
const record = JSON.parse(fs.readFileSync(path.join(designDir, 'approved.json'), 'utf8'));
|
||||
expect(record).toMatchObject({ approved_variant: 'A', approved_path: 'variant-A-2.png', screen: 'home', feedback: 'calmer' });
|
||||
expect(record).toMatchObject({ approved_variant: 'A', approved_path: 'variant-A-2.png', screen: 'home', feedback: 'calmer "quoted" `not run` $(not run)' });
|
||||
expect(fs.existsSync(path.join(dir, '.gstack', 'tmp', 'feedback.fixture'))).toBe(false);
|
||||
|
||||
const missing = approve('C');
|
||||
expect(missing.stdout).toContain('NO_BOARD_IMAGE');
|
||||
|
||||
@@ -161,4 +161,6 @@ export const IDENTIFIER_PLACEHOLDERS: Record<string, IdentifierGrammar> = {
|
||||
|
||||
// A3 group 1 (Aside prompts, design briefs, design approval feedback): mktemp basenames.
|
||||
'<prompt-file-name>': { grammar: ID, what: 'basename of the mktemp Aside prompt file printed by the previous block' },
|
||||
'<brief-file-name>': { grammar: ID, what: 'basename of the mktemp design brief file printed by the free-text block' },
|
||||
'<feedback-file-name>': { grammar: ID, what: 'basename of the mktemp design feedback file printed by the previous block' },
|
||||
};
|
||||
Reference in new issue
Block a user