mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-26 01:35:29 +02:00
* fix(cli): reject help/version flags instead of silently ignoring them (#1818) AI agents can hallucinate --help or --version on gsd-tools invocations. Without a guard, unknown flags were silently ignored and the command proceeded — including destructive ones like `phases clear`. Add a pre-dispatch check in main() that errors immediately if any never-valid flag (-h, --help, -?, --version, -v, --usage) is present in args after global flags are stripped. Regression test covers phases clear, generate- slug, state load, and current-timestamp with both --help and -h variants. Closes #1818 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(agents): convert gsd-verifier required_reading to inline wiring The thinking-model-guidance test requires inline @-reference wiring at decision points rather than a <required_reading> block. Convert verification-overrides.md reference from the <required_reading> block to an inline reference inside <verification_process> alongside the existing thinking-models-verification.md reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(tests): resolve conflict between thinking-model and verification-overrides tests thinking-model-guidance.test prohibited <required_reading> entirely, but verification-overrides.test requires gsd-verifier.md to have a <required_reading> block for verification-overrides.md between </role> and <project_context>. The tests were mutually exclusive. Fix: narrow the thinking-model assertion to check that the thinking-models reference is not *inside* a <required_reading> block (using regex extraction), rather than asserting no <required_reading> block exists at all. Restore the <required_reading> block in gsd-verifier.md. Both suites now pass (2345/2345). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
85 lines
3.3 KiB
JavaScript
85 lines
3.3 KiB
JavaScript
/**
|
|
* Regression test for bug #1818
|
|
*
|
|
* gsd-tools must reject unknown/invalid flags (--help, -h, etc.) with a
|
|
* non-zero exit and an error message instead of silently ignoring them and
|
|
* proceeding with the command — which can cause destructive operations to run
|
|
* when an AI agent hallucinates a flag like --help.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const { describe, test, beforeEach, afterEach } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
|
|
|
describe('unknown flag guard (bug #1818)', () => {
|
|
let tmpDir;
|
|
|
|
beforeEach(() => {
|
|
tmpDir = createTempProject();
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup(tmpDir);
|
|
});
|
|
|
|
// ── --help flag ────────────────────────────────────────────────────────────
|
|
|
|
test('phases clear --help is rejected with non-zero exit', () => {
|
|
const result = runGsdTools(['phases', 'clear', '--help'], tmpDir);
|
|
assert.strictEqual(result.success, false, 'should fail, not run destructive clear');
|
|
assert.match(result.error, /--help/);
|
|
});
|
|
|
|
test('generate-slug hello --help is rejected', () => {
|
|
// Non-destructive baseline: generate-slug hello succeeds without --help
|
|
const ok = runGsdTools(['generate-slug', 'hello'], tmpDir);
|
|
assert.strictEqual(ok.success, true, 'control: generate-slug without --help must succeed');
|
|
|
|
const result = runGsdTools(['generate-slug', 'hello', '--help'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /--help/);
|
|
});
|
|
|
|
test('phase complete --help is rejected', () => {
|
|
const result = runGsdTools(['phase', 'complete', '--help'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /--help/);
|
|
});
|
|
|
|
test('state load --help is rejected', () => {
|
|
const result = runGsdTools(['state', 'load', '--help'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /--help/);
|
|
});
|
|
|
|
// ── -h shorthand ──────────────────────────────────────────────────────────
|
|
|
|
test('phases clear -h is rejected', () => {
|
|
const result = runGsdTools(['phases', 'clear', '-h'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /-h/);
|
|
});
|
|
|
|
test('generate-slug hello -h is rejected', () => {
|
|
const result = runGsdTools(['generate-slug', 'hello', '-h'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /-h/);
|
|
});
|
|
|
|
// ── other common hallucinated flags ───────────────────────────────────────
|
|
|
|
test('generate-slug hello --version is rejected', () => {
|
|
const result = runGsdTools(['generate-slug', 'hello', '--version'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /--version/);
|
|
});
|
|
|
|
test('current-timestamp --help is rejected', () => {
|
|
const result = runGsdTools(['current-timestamp', '--help'], tmpDir);
|
|
assert.strictEqual(result.success, false);
|
|
assert.match(result.error, /--help/);
|
|
});
|
|
});
|