mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
72 lines
3.3 KiB
TypeScript
72 lines
3.3 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
// OPS108: pins the `--auto` autonomous-mode contract of the plan-issue and
|
|
// work-issue skills (and their thin command wrappers). The flag lives inside
|
|
// the prompt ($ARGUMENTS), not in the opencode CLI argv — the specs below pin
|
|
// the fail-safe wording (no flag = current supervised flow) and the hard-stop
|
|
// list that the flag can never cross.
|
|
|
|
const repoRoot = process.cwd()
|
|
|
|
const skills = ['plan-issue', 'work-issue'] as const
|
|
|
|
function readSkill(name: (typeof skills)[number]): string {
|
|
return readFileSync(resolve(repoRoot, `.agents/skills/${name}/SKILL.md`), 'utf8')
|
|
}
|
|
|
|
describe.each(skills)('skill /%s documents the --auto autonomous mode', (name) => {
|
|
it('declares the flag, the fail-safe and the CLI disambiguation', () => {
|
|
const content = readSkill(name)
|
|
|
|
expect(content, 'skill must declare the --auto flag').toContain('--auto')
|
|
expect(content, 'skill must name the autonomous-mode section').toContain('Modo autônomo')
|
|
expect(content, 'skill must state the no-flag fail-safe').toContain('Sem a flag')
|
|
expect(content, 'skill must disambiguate from the opencode CLI flag').toContain('Não confundir')
|
|
expect(content, 'disambiguation must name the opencode CLI').toContain('CLI opencode')
|
|
})
|
|
|
|
it('pins the hard-stop list the flag can never cross', () => {
|
|
const content = readSkill(name)
|
|
|
|
expect(content, 'hard-stop must cite Consent/LGPD').toContain('Consent/LGPD')
|
|
expect(content, 'hard-stop must cite schema migration').toContain('migração de schema')
|
|
expect(content, 'hard-stop must cite the public URL contract').toContain('URL público')
|
|
expect(content, 'hard-stop must cite production').toContain('produção')
|
|
})
|
|
})
|
|
|
|
describe('work-issue --auto keeps the environment contract', () => {
|
|
it('self-approves the impl plan but never claims and flips divergence to blocked', () => {
|
|
const content = readSkill('work-issue')
|
|
|
|
expect(content, 'autonomous impl plan must be self-approved').toContain('aprovado')
|
|
expect(content, 'autonomous mode must never claim an issue').toContain('nunca claima')
|
|
expect(content, 'material divergence must flip to blocked').toContain('blocked')
|
|
})
|
|
})
|
|
|
|
describe('plan-issue --auto keeps the tracker gate', () => {
|
|
it('skips only the pause and leaves diverged items unregistered', () => {
|
|
const content = readSkill('plan-issue')
|
|
|
|
expect(content, 'diverged items must stay unregistered').toContain('não é registrado')
|
|
expect(content, 'nothing hits the tracker before the gate').toContain(
|
|
'Nada no tracker antes do gate',
|
|
)
|
|
})
|
|
})
|
|
|
|
describe.each(skills)('command /%s advertises --auto without gaining logic', (name) => {
|
|
it('mentions --auto while keeping the thin-wrapper contract', () => {
|
|
const content = readFileSync(resolve(repoRoot, `.opencode/commands/${name}.md`), 'utf8')
|
|
|
|
expect(content, 'command must advertise the --auto flag').toContain('--auto')
|
|
expect(content, 'command must pass arguments through').toContain('$ARGUMENTS')
|
|
expect(content, 'command must reference the skill by exact name').toContain(`\`${name}\``)
|
|
expect(content, 'command must point at the canonical skill file').toContain(
|
|
`.agents/skills/${name}/SKILL.md`,
|
|
)
|
|
})
|
|
})
|