kimi-code/packages/agent-core/test/plugin/commands.test.ts
qer 5cb80ce879
feat: support plugin slash commands (#1204)
* feat(agent-core): support plugin slash commands

* feat(node-sdk): expose listPluginCommands

* feat(kimi-code): register and dispatch plugin slash commands

* chore: add changeset for plugin commands

* feat(agent-core): activate plugin commands server-side

* feat(node-sdk): add activatePluginCommand

* feat(kimi-code): render plugin command activations compactly

* feat(agent-core): recurse plugin command directories and preserve namespace

* fix(kimi-code): parse nested plugin command names

* fix(agent-core): update prompt metadata for plugin command turns

* fix(kimi-code): replay plugin command turns as command cards

* fix: treat plugin-command origins as real user prompts in undo

* fix(kimi-code): guard model-empty and clear plugin command render ids

* fix: propagate plugin_command to web and vis turn projectors

* fix(kimi-code): refresh plugin commands through auth flow

* fix(kimi-web): render plugin command cards in chat pane

* fix(kimi-web): render plugin command card in desktop chat view

* fix(kimi-code): treat slash-activation cards as transcript turn boundaries

* fix(kimi-code): count slash-activation entries when trimming transcript turns

* fix(kimi-code): preserve plugin command args in undo selector
2026-06-30 19:38:01 +08:00

65 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { expandCommandArguments, parseCommandText } from '../../src/plugin/commands';
describe('parseCommandText', () => {
it('parses frontmatter description and body', () => {
const def = parseCommandText({
text: '---\ndescription: Deploy to Vercel\n---\nDeploy this. Args: $ARGUMENTS',
commandPath: '/p/commands/deploy.md',
pluginId: 'my-plugin',
});
expect(def).toEqual({
pluginId: 'my-plugin',
name: 'deploy',
description: 'Deploy to Vercel',
body: 'Deploy this. Args: $ARGUMENTS',
path: '/p/commands/deploy.md',
});
});
it('uses frontmatter name over the filename', () => {
const def = parseCommandText({
text: '---\nname: ship\ndescription: Ship it\n---\nbody',
commandPath: '/p/commands/deploy.md',
pluginId: 'p',
});
expect(def.name).toBe('ship');
});
it('falls back to filename for name and first body line for description', () => {
const def = parseCommandText({
text: 'Deploy this project to Vercel.\n\nMore details.',
commandPath: '/p/commands/deploy.md',
pluginId: 'p',
});
expect(def.name).toBe('deploy');
expect(def.description).toBe('Deploy this project to Vercel.');
expect(def.body).toBe('Deploy this project to Vercel.\n\nMore details.');
});
it('handles an empty body with a default description', () => {
const def = parseCommandText({
text: '',
commandPath: '/p/commands/x.md',
pluginId: 'p',
});
expect(def.name).toBe('x');
expect(def.description).toBe('No description provided.');
expect(def.body).toBe('');
});
});
describe('expandCommandArguments', () => {
it('replaces $ARGUMENTS with the typed args', () => {
expect(expandCommandArguments('Deploy $ARGUMENTS now', 'prod')).toBe('Deploy prod now');
});
it('appends args when there is no placeholder', () => {
expect(expandCommandArguments('Deploy now', 'prod')).toBe('Deploy now\n\nARGUMENTS: prod');
});
it('leaves the body unchanged when there is no placeholder and no args', () => {
expect(expandCommandArguments('Deploy now', '')).toBe('Deploy now');
});
});