93 lines
2.8 KiB
JavaScript
93 lines
2.8 KiB
JavaScript
/**
|
||
* Human-facing `/role` command for DeepSeek Harness.
|
||
*
|
||
* The command reads the same role files as the Claude skill, then injects the
|
||
* role instructions as a user message and starts a turn so the model can answer
|
||
* the five-line role summary. The command's own result is UI-only.
|
||
*/
|
||
|
||
import { createUserMessage } from '@deepseek-ai/dsh-llm'
|
||
import { buildRoleText, listRoles, parseRole } from './lib/role.js'
|
||
|
||
function currentDirectory(workingDirectory, agent) {
|
||
try {
|
||
const cwd = workingDirectory.get(agent.session)
|
||
if (typeof cwd === 'string' && cwd !== '') return cwd
|
||
} catch {
|
||
// Fall through to the process directory.
|
||
}
|
||
return process.cwd()
|
||
}
|
||
|
||
export function registerRoleCommand({
|
||
commands,
|
||
workingDirectory,
|
||
rolesDir,
|
||
projectRolesDir,
|
||
roleNames,
|
||
logger,
|
||
}) {
|
||
commands.register({
|
||
name: 'role',
|
||
description: 'Переключить сессию в роль dev | admin | analyst | qa',
|
||
input: { hint: 'dev|admin|analyst|qa' },
|
||
handler: async ({ agent, rawInput }) => {
|
||
const cwd = currentDirectory(workingDirectory, agent)
|
||
const parsed = parseRole(rawInput, roleNames)
|
||
|
||
if (parsed.kind === 'list') {
|
||
return {
|
||
kind: 'success',
|
||
text: listRoles({ cwd, rolesDir, projectRolesDir, roleNames }),
|
||
}
|
||
}
|
||
|
||
if (parsed.kind === 'invalid') {
|
||
return {
|
||
kind: 'error',
|
||
text: `Неизвестная роль «${parsed.role}». Доступны: ${roleNames.join(', ')}.`,
|
||
}
|
||
}
|
||
|
||
try {
|
||
const built = buildRoleText({
|
||
role: parsed.role,
|
||
cwd,
|
||
rolesDir,
|
||
projectRolesDir,
|
||
roleNames,
|
||
})
|
||
const message = createUserMessage({
|
||
content: [{ type: 'text', text: built.text }],
|
||
source: { kind: 'user' },
|
||
})
|
||
|
||
if (typeof agent.followup === 'function') {
|
||
agent.followup(message)
|
||
} else if (typeof agent.inject === 'function') {
|
||
agent.inject(message)
|
||
} else {
|
||
return {
|
||
kind: 'error',
|
||
text: 'Роль прочитана, но у агента нет followup/inject — передать правила в контекст не удалось.',
|
||
}
|
||
}
|
||
|
||
const projectNote = built.projectMissing
|
||
? ` Проектного файла роли ${parsed.role} нет, работаю по общему слою.`
|
||
: ''
|
||
return {
|
||
kind: 'success',
|
||
text: `Роль ${parsed.role} загружена (${built.globalPath}${built.projectMissing ? '' : ` + ${built.projectPath}`}).${projectNote}`,
|
||
}
|
||
} catch (error) {
|
||
logger?.warn?.('[dsh-harness] /role failed: %s', error?.message ?? error)
|
||
return {
|
||
kind: 'error',
|
||
text: String(error?.message ?? error),
|
||
}
|
||
}
|
||
},
|
||
})
|
||
}
|