dify/cli/src/help/skill.test.ts
L1nSn0w f0fd7ddb60
feat(cli): unified help system (#36896)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 07:27:28 +00:00

54 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { commandTree } from '@/commands/tree.generated'
import { collectCommands } from '@/framework/registry'
import { versionInfo } from '@/version/info'
import { renderSkill } from './skill'
import { SKILL_TEMPLATE } from './skill-template'
// Self-references the skill is allowed to name — operational pointers, not a
// command listing. Everything else must be discovered via `help -o json`.
const SELF_REFERENCES = new Set(['resume app', 'skills install', 'version'])
describe('renderSkill', () => {
it('substitutes the version stamp and changes nothing else', () => {
expect(renderSkill({ version: '9.9.9-test' }))
.toBe(SKILL_TEMPLATE.replaceAll('{{VERSION}}', '9.9.9-test'))
})
it('stamps the running binary version (deterministic under test setup)', () => {
expect(versionInfo.version).toBe('0.0.0-test')
expect(renderSkill({ version: versionInfo.version })).toContain('difyctl skill v0.0.0-test')
})
it('leaves no unfilled template tokens', () => {
expect(renderSkill({ version: versionInfo.version })).not.toContain('{{')
})
it('points at the machine-readable surface instead of inlining it', () => {
expect(renderSkill({ version: versionInfo.version })).toContain('difyctl help -o json')
})
it('enumerates no command from the tree (zero drift surface)', () => {
const skill = renderSkill({ version: versionInfo.version })
for (const { path } of collectCommands(commandTree)) {
const command = path.join(' ')
if (SELF_REFERENCES.has(command))
continue
expect(skill, `skill must not enumerate command "${command}"`).not.toContain(command)
}
})
it('carries none of the old enumerated sections', () => {
const skill = renderSkill({ version: versionInfo.version })
for (const marker of ['## Safety', '## Core workflow', '## Reference', 'OUTPUT FORMATS', 'EXIT CODES', 'reference/'])
expect(skill).not.toContain(marker)
})
it('inlines no command-specific flags (only the --help pointer)', () => {
const skill = renderSkill({ version: versionInfo.version })
const longFlags = skill.match(/--[a-z][\w-]+/g) ?? []
for (const flag of longFlags)
expect(flag, `unexpected flag in skill: ${flag}`).toBe('--help')
})
})