generated from nhcarrigan/template
fix: resolve all linting issues in command files
Refactored createIssue, createTask, and onboardMentee commands to extract helper functions, fix JSDoc descriptions, correct type handling, and satisfy all ESLint rules. Also fixed object-shorthand mixing in index.ts and the naming convention in anthropic.ts.
This commit is contained in:
+83
-51
@@ -4,19 +4,94 @@
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { MessageFlags } from "discord.js";
|
||||
import { MessageFlags, type ChatInputCommandInteraction } from "discord.js";
|
||||
import { ids } from "../config/ids.js";
|
||||
import { anthropic } from "../utils/anthropic.js";
|
||||
import { logger } from "../utils/logger.js";
|
||||
import type { ChatInputCommandInteraction } from "discord.js";
|
||||
|
||||
interface LeantimeResponse {
|
||||
error?: { message: string };
|
||||
result?: number;
|
||||
}
|
||||
|
||||
const taskSystemPrompt = "You are a helpful assistant that creates"
|
||||
+ " well-structured task descriptions. Be concise and actionable."
|
||||
+ " Return only the description text with no extra formatting or headers.";
|
||||
|
||||
/**
|
||||
* @param interaction
|
||||
* Generates an AI-augmented task description using Claude.
|
||||
* @param description - Optional additional context for the task.
|
||||
* @param title - The subject of the Leantime task.
|
||||
* @returns The generated task description text.
|
||||
*/
|
||||
const generateTaskDescription = async(
|
||||
description: string,
|
||||
title: string,
|
||||
): Promise<string> => {
|
||||
const aiResponse = await anthropic.messages.create({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- Anthropic API field.
|
||||
max_tokens: 500,
|
||||
messages: [
|
||||
{
|
||||
content: `Create a clear, concise task description for a personal productivity board.\n\nTask title: ${title}${description === ""
|
||||
? ""
|
||||
: `\nAdditional context: ${description}`}`,
|
||||
role: "user",
|
||||
},
|
||||
],
|
||||
model: "claude-haiku-4-5-20251001",
|
||||
system: taskSystemPrompt,
|
||||
});
|
||||
const [ firstContent ] = aiResponse.content;
|
||||
return firstContent.type === "text"
|
||||
? firstContent.text
|
||||
: description;
|
||||
};
|
||||
|
||||
/**
|
||||
* Posts a task to the Leantime board via JSON-RPC.
|
||||
* @param description - Body copy for the Leantime task.
|
||||
* @param priority - The task priority level.
|
||||
* @param title - The headline for the Leantime task.
|
||||
* @returns The Leantime API response.
|
||||
*/
|
||||
const postLeantimeTask = async(
|
||||
description: string,
|
||||
priority: number,
|
||||
title: string,
|
||||
): Promise<LeantimeResponse> => {
|
||||
const response = await fetch("https://board.nhcarrigan.com/api/jsonrpc", {
|
||||
body: JSON.stringify({
|
||||
id: `amari-task-${Date.now().toString()}`,
|
||||
jsonrpc: "2.0",
|
||||
method: "leantime.rpc.tickets.addTicket",
|
||||
params: {
|
||||
values: {
|
||||
description: description,
|
||||
editorId: "1",
|
||||
headline: title,
|
||||
priority: priority.toString(),
|
||||
projectId: "1",
|
||||
type: "task",
|
||||
},
|
||||
},
|
||||
}),
|
||||
headers: {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- HTTP header name.
|
||||
"Content-Type": "application/json",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- HTTP header name.
|
||||
"x-api-key": process.env.LEANTIME_KEY ?? "",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Required to type Response.json() output.
|
||||
const data = await response.json() as LeantimeResponse;
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Leantime task using AI-augmented description content.
|
||||
* @param interaction - The Discord slash command interaction.
|
||||
*/
|
||||
export const createTask = async(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
@@ -35,51 +110,8 @@ export const createTask = async(
|
||||
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
const aiResponse = await anthropic.messages.create({
|
||||
max_tokens: 500,
|
||||
messages: [
|
||||
{
|
||||
content: `Create a clear, concise task description for a personal productivity board.\n\nTask title: ${title}${description
|
||||
? `\nAdditional context: ${description}`
|
||||
: ""}`,
|
||||
role: "user",
|
||||
},
|
||||
],
|
||||
model: "claude-haiku-4-5-20251001",
|
||||
system: "You are a helpful assistant that creates well-structured task descriptions. Be concise and actionable. Return only the description text with no extra formatting or headers.",
|
||||
});
|
||||
|
||||
const firstContent = aiResponse.content[0];
|
||||
const augmentedDesc = firstContent.type === "text"
|
||||
? firstContent.text
|
||||
: description;
|
||||
|
||||
const response = await fetch("https://board.nhcarrigan.com/api/jsonrpc", {
|
||||
body: JSON.stringify({
|
||||
id: `amari-task-${Date.now().toString()}`,
|
||||
jsonrpc: "2.0",
|
||||
method: "leantime.rpc.tickets.addTicket",
|
||||
params: {
|
||||
values: {
|
||||
description: augmentedDesc,
|
||||
|
||||
editorId: "1",
|
||||
headline: title,
|
||||
priority: priority.toString(),
|
||||
|
||||
projectId: "1",
|
||||
type: "task",
|
||||
},
|
||||
},
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": process.env.LEANTIME_KEY ?? "",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
const data: LeantimeResponse = await response.json();
|
||||
const augmentedDesc = await generateTaskDescription(description, title);
|
||||
const data = await postLeantimeTask(augmentedDesc, priority, title);
|
||||
|
||||
if (data.error !== undefined) {
|
||||
await interaction.editReply({
|
||||
@@ -89,9 +121,9 @@ export const createTask = async(
|
||||
}
|
||||
|
||||
const taskId = data.result;
|
||||
const taskUrl = taskId !== undefined
|
||||
? `https://board.nhcarrigan.com/dashboard/home#/tickets/showTicket/${taskId.toString()}`
|
||||
: "https://board.nhcarrigan.com";
|
||||
const taskUrl = taskId === undefined
|
||||
? "https://board.nhcarrigan.com"
|
||||
: `https://board.nhcarrigan.com/dashboard/home#/tickets/showTicket/${taskId.toString()}`;
|
||||
|
||||
await logger.metric("created_task", 1, { title });
|
||||
await interaction.editReply({
|
||||
|
||||
Reference in New Issue
Block a user