mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 13:15:24 +02:00
Merge remote-tracking branch 'origin/main' into garrytan/zsh-glob-fix
Resolved CHANGELOG.md conflict (bumped to v0.11.8.0 since main took v0.11.7.0). Resolved SKILL.md conflict via regeneration.
This commit is contained in:
@@ -410,6 +410,20 @@ describe('REVIEW_DASHBOARD resolver', () => {
|
||||
expect(content).toContain('REVIEW READINESS DASHBOARD');
|
||||
});
|
||||
|
||||
test('dashboard treats review as a valid Eng Review source', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('plan-eng-review, review, plan-design-review');
|
||||
expect(content).toContain('`review` (diff-scoped pre-landing review)');
|
||||
expect(content).toContain('`plan-eng-review` (plan-stage architecture review)');
|
||||
expect(content).toContain('from either \\`review\\` or \\`plan-eng-review\\`');
|
||||
});
|
||||
|
||||
test('shared dashboard propagates review source to plan-eng-review', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'plan-eng-review', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('plan-eng-review, review, plan-design-review');
|
||||
expect(content).toContain('`review` (diff-scoped pre-landing review)');
|
||||
});
|
||||
|
||||
test('resolver output contains key dashboard elements', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'plan-ceo-review', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('VERDICT');
|
||||
@@ -939,6 +953,14 @@ describe('Codex generation (--host codex)', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('root gstack bundle has OpenAI metadata for Codex skill browsing', () => {
|
||||
const rootMetadata = path.join(ROOT, 'agents', 'openai.yaml');
|
||||
expect(fs.existsSync(rootMetadata)).toBe(true);
|
||||
const content = fs.readFileSync(rootMetadata, 'utf-8');
|
||||
expect(content).toContain('display_name: "gstack"');
|
||||
expect(content).toContain('Use $gstack to locate the bundled gstack skills.');
|
||||
});
|
||||
|
||||
test('codexSkillName mapping: root is gstack, others are gstack-{dir}', () => {
|
||||
// Root → gstack
|
||||
expect(fs.existsSync(path.join(AGENTS_DIR, 'gstack', 'SKILL.md'))).toBe(true);
|
||||
@@ -968,6 +990,17 @@ describe('Codex generation (--host codex)', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('all Codex skills have agents/openai.yaml metadata', () => {
|
||||
for (const skill of CODEX_SKILLS) {
|
||||
const metadata = path.join(AGENTS_DIR, skill.codexName, 'agents', 'openai.yaml');
|
||||
expect(fs.existsSync(metadata)).toBe(true);
|
||||
const content = fs.readFileSync(metadata, 'utf-8');
|
||||
expect(content).toContain(`display_name: "${skill.codexName}"`);
|
||||
expect(content).toContain('short_description:');
|
||||
expect(content).toContain('allow_implicit_invocation: true');
|
||||
}
|
||||
});
|
||||
|
||||
test('no .claude/skills/ in Codex output', () => {
|
||||
for (const skill of CODEX_SKILLS) {
|
||||
const content = fs.readFileSync(path.join(AGENTS_DIR, skill.codexName, 'SKILL.md'), 'utf-8');
|
||||
|
||||
@@ -98,7 +98,8 @@ export function parseCodexJSONL(lines: string[]): ParsedCodexJSONL {
|
||||
|
||||
/**
|
||||
* Install a SKILL.md into a temp HOME directory for Codex to discover.
|
||||
* Creates ~/.codex/skills/{skillName}/SKILL.md in the temp HOME.
|
||||
* Creates ~/.codex/skills/{skillName}/SKILL.md in the temp HOME and copies
|
||||
* agents/openai.yaml when present so Codex sees the same metadata as a real install.
|
||||
*
|
||||
* Returns the temp HOME path. Caller is responsible for cleanup.
|
||||
*/
|
||||
@@ -116,6 +117,13 @@ export function installSkillToTempHome(
|
||||
fs.copyFileSync(srcSkill, path.join(destDir, 'SKILL.md'));
|
||||
}
|
||||
|
||||
const srcOpenAIYaml = path.join(skillDir, 'agents', 'openai.yaml');
|
||||
if (fs.existsSync(srcOpenAIYaml)) {
|
||||
const destAgentsDir = path.join(destDir, 'agents');
|
||||
fs.mkdirSync(destAgentsDir, { recursive: true });
|
||||
fs.copyFileSync(srcOpenAIYaml, path.join(destAgentsDir, 'openai.yaml'));
|
||||
}
|
||||
|
||||
return home;
|
||||
}
|
||||
|
||||
|
||||
@@ -1369,6 +1369,18 @@ describe('Codex skill', () => {
|
||||
expect(content).toContain('codex exec');
|
||||
});
|
||||
|
||||
test('/review persists a review-log entry for ship readiness', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('"skill":"review"');
|
||||
expect(content).toContain('"issues_found":N');
|
||||
expect(content).toContain('Persist Eng Review result');
|
||||
});
|
||||
|
||||
test('/ship gate suggests /review or /plan-eng-review when Eng Review is missing', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Abort — run /review or /plan-eng-review first');
|
||||
});
|
||||
|
||||
test('Review Readiness Dashboard includes Adversarial Review row', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'ship', 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Adversarial');
|
||||
|
||||
Reference in New Issue
Block a user