mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-12 15:42:20 +02:00
Merge remote-tracking branch 'origin/main' into garrytan/learn-from-reviews
Resolved conflicts: - VERSION: bumped to 0.14.6.0 (our branch on top of main's 0.14.5.0) - CHANGELOG.md: kept our entry on top, main's 7 new entries below, updated version - package.json: version synced to 0.14.6.0 - Regenerated all SKILL.md files from merged templates Main brought: Review Army (parallel specialist reviewers), always-on adversarial, CSS inspector, per-tab agents, design-to-code, comparison board, ship idempotency, skill prefix fix, session intelligence roadmap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1268,38 +1268,49 @@ describe('Codex skill', () => {
|
||||
expect(content).toContain('mktemp');
|
||||
});
|
||||
|
||||
test('adversarial review in /review auto-scales by diff size', () => {
|
||||
test('adversarial review in /review always runs both passes', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Adversarial review (auto-scaled)');
|
||||
// Diff size thresholds
|
||||
expect(content).toContain('< 50');
|
||||
expect(content).toContain('50–199');
|
||||
expect(content).toContain('200+');
|
||||
// All three tiers present
|
||||
expect(content).toContain('Small');
|
||||
expect(content).toContain('Medium tier');
|
||||
expect(content).toContain('Large tier');
|
||||
expect(content).toContain('Adversarial review (always-on)');
|
||||
// Always-on: both Claude and Codex adversarial
|
||||
expect(content).toContain('Claude adversarial subagent (always runs)');
|
||||
expect(content).toContain('Codex adversarial challenge (always runs when available)');
|
||||
// Claude adversarial subagent dispatch
|
||||
expect(content).toContain('Agent tool');
|
||||
expect(content).toContain('FIXABLE');
|
||||
expect(content).toContain('INVESTIGATE');
|
||||
// Codex fallback logic
|
||||
// Codex availability check
|
||||
expect(content).toContain('CODEX_NOT_AVAILABLE');
|
||||
expect(content).toContain('fall back to the Claude adversarial subagent');
|
||||
// Review log uses new skill name
|
||||
// OLD_CFG only gates Codex, not Claude
|
||||
expect(content).toContain('skip Codex passes only');
|
||||
// Review log
|
||||
expect(content).toContain('adversarial-review');
|
||||
expect(content).toContain('reasoning_effort="high"');
|
||||
expect(content).toContain('ADVERSARIAL REVIEW SYNTHESIS');
|
||||
// Large diff structured review still gated
|
||||
expect(content).toContain('Codex structured review (large diffs only');
|
||||
expect(content).toContain('200');
|
||||
});
|
||||
|
||||
test('adversarial review in /ship auto-scales by diff size', () => {
|
||||
test('adversarial review in /ship always runs both passes', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Adversarial review (auto-scaled)');
|
||||
expect(content).toContain('< 50');
|
||||
expect(content).toContain('200+');
|
||||
expect(content).toContain('Adversarial review (always-on)');
|
||||
expect(content).toContain('adversarial-review');
|
||||
expect(content).toContain('reasoning_effort="high"');
|
||||
expect(content).toContain('Investigate and fix');
|
||||
expect(content).toContain('Claude adversarial subagent (always runs)');
|
||||
});
|
||||
|
||||
test('scope drift detection in /review and /ship', () => {
|
||||
const reviewContent = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const shipContent = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8');
|
||||
// Both should contain scope drift from the shared resolver
|
||||
for (const content of [reviewContent, shipContent]) {
|
||||
expect(content).toContain('Scope Check:');
|
||||
expect(content).toContain('DRIFT DETECTED');
|
||||
expect(content).toContain('SCOPE CREEP');
|
||||
expect(content).toContain('MISSING REQUIREMENTS');
|
||||
expect(content).toContain('stated intent');
|
||||
}
|
||||
});
|
||||
|
||||
test('codex-host ship/review do NOT contain adversarial review step', () => {
|
||||
@@ -1522,12 +1533,13 @@ describe('sidebar agent (#584)', () => {
|
||||
});
|
||||
|
||||
// #584 — Server Write: server.ts allowedTools includes Write (DRY parity)
|
||||
test('server.ts allowedTools includes Write', () => {
|
||||
test('server.ts allowedTools excludes Write (agent is read-only + Bash)', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'browse', 'src', 'server.ts'), 'utf-8');
|
||||
// Find the sidebar allowedTools in the headed-mode path
|
||||
const match = content.match(/--allowedTools['"]\s*,\s*['"]([^'"]+)['"]/);
|
||||
expect(match).not.toBeNull();
|
||||
expect(match![1]).toContain('Write');
|
||||
expect(match![1]).toContain('Bash');
|
||||
expect(match![1]).not.toContain('Write');
|
||||
});
|
||||
|
||||
// #584 — Sidebar stderr: stderr handler is not empty
|
||||
|
||||
Reference in New Issue
Block a user