mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
B4: design --version prints the version, and the probe uses it
The design CLI treated --version as an unknown command (exit 1), so the probe launched the binary with no arguments instead. Add --version (prints the gstack version, exit 0, before auth or network) and probe with it, so messages read '<path> --version exited <code>' as planned.
This commit is contained in:
1 parent
b94288db0b
commit
d3640f28f8
4 files changed
+37
-10
No files matched your search
@@ -26,6 +26,7 @@ import { generateDesignToCodePrompt } from "./design-to-code";
|
||||
import { serve } from "./serve";
|
||||
import { gallery } from "./gallery";
|
||||
import { normalizeIntFlag } from "./flag-utils";
|
||||
import { readVersionString } from "./daemon-state";
|
||||
import {
|
||||
daemonStatus as daemonStatusClient,
|
||||
ensureDaemon,
|
||||
@@ -44,6 +45,11 @@ function parseArgs(argv: string[]): {
|
||||
printUsage();
|
||||
process.exit(0);
|
||||
}
|
||||
// DESIGN SETUP's launch probe (B4): proves the binary starts, without auth or network.
|
||||
if (args[0] === "--version") {
|
||||
console.log(readVersionString());
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const command = args[0];
|
||||
const flags: Record<string, string | boolean> = {};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* B4: DESIGN SETUP probes `"$D" --version` to prove the binary starts. The CLI
|
||||
* treated `--version` as an unknown command (exit 1), so the probe could never
|
||||
* pass. It prints the gstack version and exits 0, before auth or network.
|
||||
*/
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { spawnSync } from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, '..', '..');
|
||||
|
||||
describe('design --version', () => {
|
||||
test('prints the gstack version and exits 0 without credentials', () => {
|
||||
const r = spawnSync(process.execPath, [path.join(ROOT, 'design/src/cli.ts'), '--version'], {
|
||||
encoding: 'utf8', timeout: 30_000, env: { PATH: process.env.PATH ?? '', HOME: '/nonexistent' },
|
||||
});
|
||||
expect(r.status, r.stderr).toBe(0);
|
||||
expect(r.stdout.trim()).toBe(fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf8').trim());
|
||||
});
|
||||
});
|
||||
@@ -1118,8 +1118,8 @@ Source: [OpenAI "Designing Delightful Frontends with GPT-5.4"](https://developer
|
||||
/**
|
||||
* B4 (#1076, #1254): DESIGN_READY only when the binary actually starts. A
|
||||
* binary that is merely executable can still be SIGKILLed at launch (an
|
||||
* invalid macOS code signature), so launch it (no arguments prints usage and
|
||||
* exits 0) under the portable deadline aside.ts uses. A success is cached
|
||||
* invalid macOS code signature), so run `--version` under the portable
|
||||
* deadline aside.ts uses. A success is cached
|
||||
* (inode + path, valid while newer than the binary) so Gatekeeper's
|
||||
* first-launch scan is paid once.
|
||||
*/
|
||||
@@ -1129,15 +1129,15 @@ _dt() { if command -v gtimeout >/dev/null; then gtimeout 10 "$@"; elif command -
|
||||
elif command -v perl >/dev/null; then perl -e 'alarm(shift);exec(@ARGV)' 10 "$@"; else return 125; fi; }
|
||||
_RC=0; _F="Fix: cd \${D%/design/dist/design} && ./setup"
|
||||
if [ ! -x "$D" ]; then _RC=missing
|
||||
elif [ ! "$_DC" -nt "$D" ] || [ "$(cat "$_DC")" != "$_DK" ]; then _dt "$D" >/dev/null 2>&1 </dev/null || _RC=$?
|
||||
elif [ ! "$_DC" -nt "$D" ] || [ "$(cat "$_DC")" != "$_DK" ]; then _dt "$D" --version >/dev/null 2>&1 </dev/null || _RC=$?
|
||||
fi
|
||||
case "$_RC" in
|
||||
0) echo "DESIGN_READY: $D"; [ -n "$_DC" ] && echo "$_DK" > "$_DC" 2>/dev/null ;;
|
||||
missing) echo "DESIGN_NOT_AVAILABLE: $D is not installed. $_F" ;;
|
||||
124|142) echo "DESIGN_NOT_AVAILABLE: $D timed out after 10s" ;;
|
||||
124|142) echo "DESIGN_NOT_AVAILABLE: $D --version timed out after 10s" ;;
|
||||
125) echo "DESIGN_NOT_AVAILABLE: no timeout/gtimeout/perl to bound $D" ;;
|
||||
137) echo "DESIGN_NOT_AVAILABLE: $D exited 137 (killed at launch; on macOS usually an invalid code signature). $_F" ;;
|
||||
*) echo "DESIGN_NOT_AVAILABLE: $D exited $_RC" ;;
|
||||
137) echo "DESIGN_NOT_AVAILABLE: $D --version exited 137 (killed at launch; on macOS usually an invalid code signature). $_F" ;;
|
||||
*) echo "DESIGN_NOT_AVAILABLE: $D --version exited $_RC" ;;
|
||||
esac`;
|
||||
}
|
||||
|
||||
@@ -1421,7 +1421,7 @@ else
|
||||
fi
|
||||
\`\`\`
|
||||
|
||||
**If TASTE_PROFILE_UNAVAILABLE:** say that line once, then continue without a taste profile (do not treat it as "no history").
|
||||
**If TASTE_PROFILE_UNAVAILABLE:** say so once; continue without a taste profile.
|
||||
|
||||
**If TASTE_PROFILE_FOUND:** Parse the full JSON; malformed/unreadable uses the legacy fallback. After decay, rank each dimension by confidence * approved_count (or rejected_count); take three per kind. Count retained sessions (at most 50, not lifetime). Include in ${ctx.skillName === 'design-consultation' ? 'the Phase 1 product brief (later shared unchanged with both independent voices)' : 'the brief'}:
|
||||
|
||||
|
||||
@@ -61,13 +61,13 @@ describe('B4: DESIGN_READY requires a binary that starts', () => {
|
||||
expect(w.launches()).toBe(1);
|
||||
fs.writeFileSync(path.join(w.install, 'design/dist/design'), `#!/bin/sh\necho launched >> "${w.home}/launches"\nexit 3\n`);
|
||||
fs.utimesSync(path.join(w.install, 'design/dist/design'), new Date(), new Date(Date.now() + 5_000));
|
||||
expect(run(setup(), w).stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design exited 3`);
|
||||
expect(run(setup(), w).stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design --version exited 3`);
|
||||
});
|
||||
|
||||
test(`${host.name}: a binary killed at launch is not ready and names the fix`, () => {
|
||||
const w = world(host.root, 'kill -9 $$');
|
||||
const r = run(setup(), w);
|
||||
expect(r.stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design exited 137 (killed at launch; on macOS usually an invalid code signature). Fix: cd ${w.install} && ./setup`);
|
||||
expect(r.stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design --version exited 137 (killed at launch; on macOS usually an invalid code signature). Fix: cd ${w.install} && ./setup`);
|
||||
expect(fs.existsSync(path.join(w.state, 'design-ready'))).toBe(false);
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ describe('B4: DESIGN_READY requires a binary that starts', () => {
|
||||
child.on('error', reject);
|
||||
child.on('close', () => resolve(text));
|
||||
});
|
||||
expect(stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design timed out after 10s`);
|
||||
expect(stdout.trim()).toBe(`DESIGN_NOT_AVAILABLE: ${w.install}/design/dist/design --version timed out after 10s`);
|
||||
}, 30_000);
|
||||
|
||||
test('office-hours visual exploration uses the same probe', () => {
|
||||
|
||||
Reference in new issue
Block a user