feat: add getTaskComment functionality and enhance pre-commit script
- Introduced a new function `getTaskComment` to retrieve a specific comment from a task, including relevant task details. - Updated the task store to support direct file reads for tasks that match canonical UUIDs. - Added a new server tool for fetching task comments, enhancing the API capabilities. - Modified the pre-commit script to improve environment setup and ensure lint-staged runs correctly.
This commit is contained in:
parent
ec547e0662
commit
b41cf9fad2
6 changed files with 69 additions and 1 deletions
15
.husky/pre-commit
Normal file → Executable file
15
.husky/pre-commit
Normal file → Executable file
|
|
@ -1 +1,14 @@
|
|||
pnpm exec lint-staged
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.." || exit 1
|
||||
|
||||
# Git/IDE hooks often get a minimal PATH — Node lives outside it.
|
||||
export PATH="$HOME/.local/share/mise/shims:$HOME/.volta/bin:/opt/homebrew/bin:/usr/local/bin:$HOME/.linuxbrew/bin:$PATH"
|
||||
|
||||
if [ -z "${NODE_SKIP_NVM:-}" ] && [ -f "$HOME/.nvm/nvm.sh" ]; then
|
||||
NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
||||
export NVM_DIR
|
||||
# shellcheck source=/dev/null
|
||||
. "$HOME/.nvm/nvm.sh"
|
||||
fi
|
||||
|
||||
exec ./node_modules/.bin/lint-staged
|
||||
|
|
|
|||
|
|
@ -117,6 +117,17 @@ function resolveTaskRef(paths, taskRef, options = {}) {
|
|||
}
|
||||
|
||||
const includeDeleted = options.includeDeleted === true;
|
||||
|
||||
// Fast path: if taskRef looks like a canonical UUID, try direct file read first
|
||||
if (looksLikeCanonicalTaskId(normalizedRef)) {
|
||||
const taskPath = getTaskPath(paths, normalizedRef);
|
||||
const rawTask = readJson(taskPath, null);
|
||||
if (rawTask && (includeDeleted || rawTask.status !== 'deleted')) {
|
||||
return normalizedRef;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: scan all tasks for displayId match or non-UUID refs
|
||||
const tasks = listRawTasks(paths);
|
||||
const exact = tasks.find((task) => task.id === normalizedRef);
|
||||
if (exact && (includeDeleted || exact.status !== 'deleted')) {
|
||||
|
|
|
|||
|
|
@ -165,6 +165,30 @@ function getTask(context, taskId) {
|
|||
return taskStore.readTask(context.paths, taskId, { includeDeleted: true });
|
||||
}
|
||||
|
||||
function getTaskComment(context, taskId, commentId) {
|
||||
const normalizedCommentId = String(commentId || '').trim();
|
||||
if (!normalizedCommentId) {
|
||||
throw new Error('Missing commentId');
|
||||
}
|
||||
const task = taskStore.readTask(context.paths, taskId, { includeDeleted: true });
|
||||
const comments = Array.isArray(task.comments) ? task.comments : [];
|
||||
const comment = comments.find((c) => c && c.id === normalizedCommentId);
|
||||
if (!comment) {
|
||||
throw new Error(`Comment ${normalizedCommentId} not found on task #${task.displayId || task.id}`);
|
||||
}
|
||||
return {
|
||||
comment,
|
||||
task: {
|
||||
id: task.id,
|
||||
displayId: task.displayId,
|
||||
subject: task.subject,
|
||||
status: task.status,
|
||||
owner: task.owner,
|
||||
commentCount: comments.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function listTasks(context) {
|
||||
return taskStore.listTasks(context.paths);
|
||||
}
|
||||
|
|
@ -609,6 +633,7 @@ module.exports = {
|
|||
completeTask,
|
||||
createTask,
|
||||
getTask,
|
||||
getTaskComment,
|
||||
linkTask,
|
||||
listDeletedTasks,
|
||||
listTasks,
|
||||
|
|
|
|||
1
mcp-server/src/agent-teams-controller.d.ts
vendored
1
mcp-server/src/agent-teams-controller.d.ts
vendored
|
|
@ -7,6 +7,7 @@ declare module 'agent-teams-controller' {
|
|||
export interface ControllerTaskApi {
|
||||
createTask(flags: Record<string, unknown>): unknown;
|
||||
getTask(taskId: string): unknown;
|
||||
getTaskComment(taskId: string, commentId: string): { comment: Record<string, unknown>; task: { id: string; displayId: string; subject: string; status: string; owner: string | null; commentCount: number } };
|
||||
listTasks(): unknown[];
|
||||
listDeletedTasks(): unknown[];
|
||||
resolveTaskId(taskRef: string): string;
|
||||
|
|
|
|||
|
|
@ -226,6 +226,23 @@ export function registerTaskTools(server: Pick<FastMCP, 'addTool'>) {
|
|||
await Promise.resolve(jsonTextContent(getController(teamName, claudeDir).tasks.getTask(taskId))),
|
||||
});
|
||||
|
||||
server.addTool({
|
||||
name: 'task_get_comment',
|
||||
description:
|
||||
'Get a single task comment by id. Returns the comment object and minimal task context (id, displayId, subject, status, owner).',
|
||||
parameters: z.object({
|
||||
...toolContextSchema,
|
||||
taskId: z.string().min(1),
|
||||
commentId: z.string().min(1),
|
||||
}),
|
||||
execute: async ({ teamName, claudeDir, taskId, commentId }) =>
|
||||
await Promise.resolve(
|
||||
jsonTextContent(
|
||||
getController(teamName, claudeDir).tasks.getTaskComment(taskId, commentId)
|
||||
)
|
||||
),
|
||||
});
|
||||
|
||||
server.addTool({
|
||||
name: 'task_list',
|
||||
description: 'List tasks for a team',
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ describe('agent-teams-mcp tools', () => {
|
|||
'task_create',
|
||||
'task_create_from_message',
|
||||
'task_get',
|
||||
'task_get_comment',
|
||||
'task_link',
|
||||
'task_list',
|
||||
'task_set_clarification',
|
||||
|
|
|
|||
Loading…
Reference in a new issue