From 4049f34d5afaf813b6257678082fe3475ae14030 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:08:04 +0100 Subject: [PATCH] feat: implement local-only command checkers for cli and mcp (#1426) --- .../src/ui/components/cardBox.component.ts | 39 +- apps/cli/src/utils/command-guard.ts | 144 ++ apps/cli/src/utils/index.ts | 6 + apps/mcp/src/index.ts | 2 + apps/mcp/src/shared/types.ts | 25 + apps/mcp/src/shared/utils.ts | 172 +- apps/mcp/src/tools/autopilot/abort.tool.ts | 30 +- apps/mcp/src/tools/autopilot/commit.tool.ts | 60 +- apps/mcp/src/tools/autopilot/complete.tool.ts | 34 +- apps/mcp/src/tools/autopilot/finalize.tool.ts | 30 +- apps/mcp/src/tools/autopilot/next.tool.ts | 30 +- apps/mcp/src/tools/autopilot/resume.tool.ts | 28 +- apps/mcp/src/tools/autopilot/start.tool.ts | 44 +- apps/mcp/src/tools/autopilot/status.tool.ts | 28 +- apps/mcp/src/tools/tasks/get-task.tool.ts | 36 +- apps/mcp/src/tools/tasks/get-tasks.tool.ts | 32 +- mcp-server/src/tools/add-dependency.js | 111 +- mcp-server/src/tools/add-subtask.js | 2 +- mcp-server/src/tools/add-tag.js | 2 +- mcp-server/src/tools/add-task.js | 2 +- mcp-server/src/tools/analyze.js | 2 +- mcp-server/src/tools/clear-subtasks.js | 32 +- mcp-server/src/tools/complexity-report.js | 2 +- mcp-server/src/tools/copy-tag.js | 2 +- mcp-server/src/tools/delete-tag.js | 2 +- mcp-server/src/tools/expand-all.js | 2 +- mcp-server/src/tools/expand-task.js | 2 +- mcp-server/src/tools/fix-dependencies.js | 31 +- mcp-server/src/tools/get-operation-status.js | 2 +- mcp-server/src/tools/initialize-project.js | 2 +- mcp-server/src/tools/list-tags.js | 2 +- mcp-server/src/tools/models.js | 20 +- mcp-server/src/tools/move-task.js | 2 +- mcp-server/src/tools/next-task.js | 2 +- mcp-server/src/tools/parse-prd.js | 2 +- mcp-server/src/tools/remove-dependency.js | 32 +- mcp-server/src/tools/remove-subtask.js | 2 +- mcp-server/src/tools/remove-task.js | 2 +- mcp-server/src/tools/rename-tag.js | 2 +- mcp-server/src/tools/research.js | 2 +- mcp-server/src/tools/response-language.js | 9 +- mcp-server/src/tools/rules.js | 8 +- mcp-server/src/tools/scope-down.js | 2 +- mcp-server/src/tools/scope-up.js | 2 +- mcp-server/src/tools/set-task-status.js | 2 +- mcp-server/src/tools/update-subtask.js | 2 +- mcp-server/src/tools/update-task.js | 2 +- mcp-server/src/tools/update.js | 2 +- mcp-server/src/tools/use-tag.js | 2 +- mcp-server/src/tools/validate-dependencies.js | 101 +- package-lock.json | 1707 +++++++++++++++++ packages/tm-core/src/index.ts | 6 + .../tm-core/src/modules/auth/auth-domain.ts | 36 + .../tm-core/src/modules/auth/command.guard.ts | 77 + .../tm-core/src/modules/auth/constants.ts | 18 + packages/tm-core/src/modules/auth/index.ts | 6 + scripts/modules/commands.js | 172 +- 57 files changed, 2676 insertions(+), 482 deletions(-) create mode 100644 apps/cli/src/utils/command-guard.ts create mode 100644 packages/tm-core/src/modules/auth/command.guard.ts create mode 100644 packages/tm-core/src/modules/auth/constants.ts diff --git a/apps/cli/src/ui/components/cardBox.component.ts b/apps/cli/src/ui/components/cardBox.component.ts index 6521e999..31215ca9 100644 --- a/apps/cli/src/ui/components/cardBox.component.ts +++ b/apps/cli/src/ui/components/cardBox.component.ts @@ -1,21 +1,28 @@ import boxen from 'boxen'; import chalk from 'chalk'; +/** + * Level/variant for the card box styling + */ +export type CardBoxLevel = 'warn' | 'info'; + /** * Configuration for the card box component */ export interface CardBoxConfig { - /** Header text displayed in yellow bold */ + /** Header text displayed in bold */ header: string; /** Body paragraphs displayed in white */ body: string[]; - /** Call to action section with label and URL */ - callToAction: { + /** Call to action section with label and URL (optional) */ + callToAction?: { label: string; action: string; }; /** Footer text displayed in gray (usage instructions) */ footer?: string; + /** Level/variant for styling (default: 'warn' = yellow, 'info' = blue) */ + level?: CardBoxLevel; } /** @@ -26,22 +33,30 @@ export interface CardBoxConfig { * @returns Formatted string ready for console.log */ export function displayCardBox(config: CardBoxConfig): string { - const { header, body, callToAction, footer } = config; + const { header, body, callToAction, footer, level = 'warn' } = config; + + // Determine colors based on level + const headerColor = level === 'info' ? chalk.blue.bold : chalk.yellow.bold; + const borderColor = level === 'info' ? 'blue' : 'yellow'; // Build the content sections const sections: string[] = [ // Header - chalk.yellow.bold(header), + headerColor(header), // Body paragraphs - ...body.map((paragraph) => chalk.white(paragraph)), - - // Call to action - chalk.cyan(callToAction.label) + - '\n' + - chalk.blue.underline(callToAction.action) + ...body.map((paragraph) => chalk.white(paragraph)) ]; + // Add call to action if provided + if (callToAction && callToAction.label && callToAction.action) { + sections.push( + chalk.cyan(callToAction.label) + + '\n' + + chalk.blue.underline(callToAction.action) + ); + } + // Add footer if provided if (footer) { sections.push(chalk.gray(footer)); @@ -53,7 +68,7 @@ export function displayCardBox(config: CardBoxConfig): string { // Wrap in boxen return boxen(content, { padding: 1, - borderColor: 'yellow', + borderColor, borderStyle: 'round', margin: { top: 1, bottom: 1 } }); diff --git a/apps/cli/src/utils/command-guard.ts b/apps/cli/src/utils/command-guard.ts new file mode 100644 index 00000000..16e7f12b --- /dev/null +++ b/apps/cli/src/utils/command-guard.ts @@ -0,0 +1,144 @@ +/** + * @fileoverview Command guard for CLI commands + * CLI presentation layer - uses tm-core for logic, displays with cardBox + */ + +import chalk from 'chalk'; +import { createTmCore, type TmCore, type LocalOnlyCommand } from '@tm/core'; +import { displayCardBox } from '../ui/components/cardBox.component.js'; + +/** + * Command-specific messaging configuration + */ +interface CommandMessage { + header: string; + getBody: (briefName: string) => string[]; + footer: string; +} + +/** + * Get command-specific message configuration + * + * NOTE: Command groups below are intentionally hardcoded (not imported from LOCAL_ONLY_COMMANDS) + * to allow flexible categorization with custom messaging per category. All commands here are + * subsets of LOCAL_ONLY_COMMANDS from @tm/core, which is the source of truth for blocked commands. + * + * Categories exist for UX purposes (tailored messaging), while LOCAL_ONLY_COMMANDS exists for + * enforcement (what's actually blocked when using Hamster). + */ +function getCommandMessage(commandName: LocalOnlyCommand): CommandMessage { + // Dependency management commands + if ( + [ + 'add-dependency', + 'remove-dependency', + 'validate-dependencies', + 'fix-dependencies' + ].includes(commandName) + ) { + return { + header: 'Hamster Manages Dependencies', + getBody: (briefName) => [ + `Hamster handles dependencies for the ${chalk.blue(`"${briefName}"`)} Brief.`, + `To manage dependencies manually, log out with ${chalk.cyan('tm auth logout')} and work locally.` + ], + footer: + 'Switch between local and remote workflows anytime by logging in/out.' + }; + } + + // Subtask management commands + if (commandName === 'clear-subtasks') { + return { + header: 'Hamster Manages Subtasks', + getBody: (briefName) => [ + `Hamster handles subtask management for the ${chalk.blue(`"${briefName}"`)} Brief.`, + `To manage subtasks manually, log out with ${chalk.cyan('tm auth logout')} and work locally.` + ], + footer: + 'Switch between local and remote workflows anytime by logging in/out.' + }; + } + + // Model configuration commands + if (commandName === 'models') { + return { + header: 'Hamster Manages AI Models', + getBody: (briefName) => [ + `Hamster configures AI models automatically for the ${chalk.blue(`"${briefName}"`)} Brief.`, + `To configure models manually, log out with ${chalk.cyan('tm auth logout')} and work locally.` + ], + footer: + 'Switch between local and remote workflows anytime by logging in/out.' + }; + } + + // Default message for any other local-only commands + return { + header: 'Command Not Available in Hamster', + getBody: (briefName) => [ + `The ${chalk.cyan(commandName)} command is managed by Hamster for the ${chalk.blue(`"${briefName}"`)} Brief.`, + `To use this command, log out with ${chalk.cyan('tm auth logout')} and work locally.` + ], + footer: + 'Switch between local and remote workflows anytime by logging in/out.' + }; +} + +/** + * Check if a command should be blocked when authenticated and display CLI message + * + * Use this for CLI commands that are only available for local file storage (not Hamster). + * This uses tm-core's AuthDomain.guardCommand() and formats the result for CLI display. + * + * @param commandName - Name of the command being executed + * @param tmCoreOrProjectRoot - TmCore instance or project root path + * @returns true if command should be blocked, false otherwise + * + * @example + * ```ts + * const isBlocked = await checkAndBlockIfAuthenticated('add-dependency', projectRoot); + * if (isBlocked) { + * process.exit(1); + * } + * ``` + */ +export async function checkAndBlockIfAuthenticated( + commandName: string, + tmCoreOrProjectRoot: TmCore | string +): Promise { + // Get or create TmCore instance + const tmCore = + typeof tmCoreOrProjectRoot === 'string' + ? await createTmCore({ projectPath: tmCoreOrProjectRoot }) + : tmCoreOrProjectRoot; + + // Use tm-core's auth domain to check the command guard + const result = await tmCore.auth.guardCommand( + commandName, + tmCore.tasks.getStorageType() + ); + + if (result.isBlocked) { + // Get command-specific message configuration + // Safe to cast: guardCommand only blocks commands in LOCAL_ONLY_COMMANDS + const message = getCommandMessage(commandName as LocalOnlyCommand); + const briefName = result.briefName || 'remote brief'; + + // Format and display CLI message with cardBox + console.log( + displayCardBox({ + header: message.header, + body: message.getBody(briefName), + footer: message.footer, + level: 'info' + }) + ); + return true; + } + + return false; +} + +// Legacy export for backward compatibility +export const checkAndBlockDependencyCommand = checkAndBlockIfAuthenticated; diff --git a/apps/cli/src/utils/index.ts b/apps/cli/src/utils/index.ts index 890ba5c5..e47218eb 100644 --- a/apps/cli/src/utils/index.ts +++ b/apps/cli/src/utils/index.ts @@ -12,6 +12,12 @@ export { type CheckAuthOptions } from './auth-helpers.js'; +// Command guard for local-only commands +export { + checkAndBlockIfAuthenticated, + checkAndBlockDependencyCommand // Legacy export +} from './command-guard.js'; + // Error handling utilities export { displayError, isDebugMode } from './error-handler.js'; diff --git a/apps/mcp/src/index.ts b/apps/mcp/src/index.ts index 44cd7df5..6e451cf4 100644 --- a/apps/mcp/src/index.ts +++ b/apps/mcp/src/index.ts @@ -5,5 +5,7 @@ export * from './tools/autopilot/index.js'; export * from './tools/tasks/index.js'; +// TODO: Re-enable when TypeScript dependency tools are implemented +// export * from './tools/dependencies/index.js'; export * from './shared/utils.js'; export * from './shared/types.js'; diff --git a/apps/mcp/src/shared/types.ts b/apps/mcp/src/shared/types.ts index 0e15fef5..df7d8ac2 100644 --- a/apps/mcp/src/shared/types.ts +++ b/apps/mcp/src/shared/types.ts @@ -2,6 +2,8 @@ * Shared types for MCP tools */ +import type { TmCore } from '@tm/core'; + export interface MCPResponse { success: boolean; data?: T; @@ -31,6 +33,29 @@ export interface MCPContext { session: any; } +/** + * Enhanced MCP context with tmCore instance + */ +export interface ToolContext { + /** Logger instance (matches fastmcp's Context.log signature) */ + log: { + info: (message: string, data?: any) => void; + warn: (message: string, data?: any) => void; + error: (message: string, data?: any) => void; + debug: (message: string, data?: any) => void; + }; + /** MCP session */ + session?: { + roots?: Array<{ uri: string; name?: string }>; + env?: Record; + clientCapabilities?: { + sampling?: Record; + }; + }; + /** TmCore instance (already initialized) */ + tmCore: TmCore; +} + export interface WithProjectRoot { projectRoot: string; } diff --git a/apps/mcp/src/shared/utils.ts b/apps/mcp/src/shared/utils.ts index 165bc1fd..1aaaf9d0 100644 --- a/apps/mcp/src/shared/utils.ts +++ b/apps/mcp/src/shared/utils.ts @@ -2,10 +2,16 @@ * Shared utilities for MCP tools */ -import type { ContentResult } from 'fastmcp'; -import path from 'node:path'; import fs from 'node:fs'; +import path from 'node:path'; +import { + LOCAL_ONLY_COMMANDS, + createTmCore, + type LocalOnlyCommand +} from '@tm/core'; +import type { ContentResult, Context } from 'fastmcp'; import packageJson from '../../../../package.json' with { type: 'json' }; +import type { ToolContext } from './types.js'; /** * Get version information @@ -17,6 +23,82 @@ export function getVersionInfo() { }; } +/** + * Creates a content response for MCP tools + * FastMCP requires text type, so we format objects as JSON strings + */ +export function createContentResponse(content: any): ContentResult { + return { + content: [ + { + type: 'text', + text: + typeof content === 'object' + ? // Format JSON nicely with indentation + JSON.stringify(content, null, 2) + : // Keep other content types as-is + String(content) + } + ] + }; +} + +/** + * Creates an error response for MCP tools + */ +export function createErrorResponse( + errorMessage: string, + versionInfo?: { version: string; name: string }, + tagInfo?: { currentTag: string } +): ContentResult { + // Provide fallback version info if not provided + if (!versionInfo) { + versionInfo = getVersionInfo(); + } + + let responseText = `Error: ${errorMessage} +Version: ${versionInfo.version} +Name: ${versionInfo.name}`; + + // Add tag information if available + if (tagInfo) { + responseText += ` +Current Tag: ${tagInfo.currentTag}`; + } + + return { + content: [ + { + type: 'text', + text: responseText + } + ], + isError: true + }; +} + +/** + * Function signature for progress reporting + */ +export type ReportProgressFn = (progress: number, total?: number) => void; + +/** + * Validate that reportProgress is available for long-running operations + */ +export function checkProgressCapability( + reportProgress: any, + log: any +): ReportProgressFn | undefined { + if (typeof reportProgress !== 'function') { + log?.debug?.( + 'reportProgress not available - operation will run without progress updates' + ); + return undefined; + } + + return reportProgress; +} + /** * Get current tag for a project root */ @@ -183,7 +265,7 @@ function getProjectRootFromSession(session: any): string | null { export function withNormalizedProjectRoot( fn: ( args: T & { projectRoot: string }, - context: any + context: Context ) => Promise ): (args: T, context: any) => Promise { return async (args: T, context: any): Promise => { @@ -268,3 +350,87 @@ export function withNormalizedProjectRoot( } }; } + +/** + * Tool execution function signature with tmCore provided + */ +export type ToolExecuteFn = ( + args: TArgs, + context: ToolContext +) => Promise; + +/** + * Higher-order function that wraps MCP tool execution with: + * - Normalized project root (via withNormalizedProjectRoot) + * - TmCore instance creation + * - Command guard check (for local-only commands) + * + * Use this for ALL MCP tools to provide consistent context and auth checking. + * + * @param commandName - Name of the command (used for guard check) + * @param executeFn - Tool execution function that receives args and enhanced context + * @returns Wrapped execute function + * + * @example + * ```ts + * export function registerAddDependencyTool(server: FastMCP) { + * server.addTool({ + * name: 'add_dependency', + * parameters: AddDependencySchema, + * execute: withToolContext('add-dependency', async (args, context) => { + * // context.tmCore is already available + * // Auth guard already checked + * // Just implement the tool logic! + * }) + * }); + * } + * ``` + */ +export function withToolContext( + commandName: string, + executeFn: ToolExecuteFn +) { + return withNormalizedProjectRoot( + async ( + args: TArgs & { projectRoot: string }, + context: Context + ) => { + // Create tmCore instance + const tmCore = await createTmCore({ + projectPath: args.projectRoot, + loggerConfig: { mcpMode: true, logCallback: context.log } + }); + + // Check if this is a local-only command that needs auth guard + if (LOCAL_ONLY_COMMANDS.includes(commandName as LocalOnlyCommand)) { + const authResult = await tmCore.auth.guardCommand( + commandName, + tmCore.tasks.getStorageType() + ); + + if (authResult.isBlocked) { + const errorMsg = `You're working on the ${authResult.briefName} Brief in Hamster so this command is managed for you. This command is only available for local file storage. Log out with 'tm auth logout' to use local commands.`; + context.log.info(errorMsg); + return handleApiResult({ + result: { + success: false, + error: { message: errorMsg } + }, + log: context.log, + projectRoot: args.projectRoot + }); + } + } + + // Create enhanced context with tmCore + const enhancedContext: ToolContext = { + log: context.log, + session: context.session, + tmCore + }; + + // Execute the actual tool logic with enhanced context + return executeFn(args, enhancedContext); + } + ); +} diff --git a/apps/mcp/src/tools/autopilot/abort.tool.ts b/apps/mcp/src/tools/autopilot/abort.tool.ts index 1da290d8..22d9c66f 100644 --- a/apps/mcp/src/tools/autopilot/abort.tool.ts +++ b/apps/mcp/src/tools/autopilot/abort.tool.ts @@ -3,14 +3,11 @@ * Abort a running TDD workflow and clean up state */ -import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; +import { z } from 'zod'; +import type { ToolContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; const AbortSchema = z.object({ projectRoot: z @@ -29,12 +26,13 @@ export function registerAutopilotAbortTool(server: FastMCP) { description: 'Abort the current TDD workflow and clean up workflow state. This will remove the workflow state file but will NOT delete the git branch or any code changes.', parameters: AbortSchema, - execute: withNormalizedProjectRoot( - async (args: AbortArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-abort', + async (args: AbortArgs, { log }: ToolContext) => { const { projectRoot } = args; try { - context.log.info(`Aborting autopilot workflow in ${projectRoot}`); + log.info(`Aborting autopilot workflow in ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -42,7 +40,7 @@ export function registerAutopilotAbortTool(server: FastMCP) { const hasWorkflow = await workflowService.hasWorkflow(); if (!hasWorkflow) { - context.log.warn('No active workflow to abort'); + log.warn('No active workflow to abort'); return handleApiResult({ result: { success: true, @@ -51,7 +49,7 @@ export function registerAutopilotAbortTool(server: FastMCP) { hadWorkflow: false } }, - log: context.log, + log, projectRoot }); } @@ -63,7 +61,7 @@ export function registerAutopilotAbortTool(server: FastMCP) { // Abort workflow await workflowService.abortWorkflow(); - context.log.info('Workflow state deleted'); + log.info('Workflow state deleted'); return handleApiResult({ result: { @@ -76,20 +74,20 @@ export function registerAutopilotAbortTool(server: FastMCP) { note: 'Git branch and code changes were preserved. You can manually clean them up if needed.' } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-abort: ${error.message}`); + log.error(`Error in autopilot-abort: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { success: false, error: { message: `Failed to abort workflow: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/commit.tool.ts b/apps/mcp/src/tools/autopilot/commit.tool.ts index babd94a2..938159b0 100644 --- a/apps/mcp/src/tools/autopilot/commit.tool.ts +++ b/apps/mcp/src/tools/autopilot/commit.tool.ts @@ -3,14 +3,11 @@ * Create a git commit with automatic staging and message generation */ -import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; -import { WorkflowService, GitAdapter, CommitMessageGenerator } from '@tm/core'; +import { CommitMessageGenerator, GitAdapter, WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; +import { z } from 'zod'; +import type { ToolContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; const CommitSchema = z.object({ projectRoot: z @@ -39,12 +36,13 @@ export function registerAutopilotCommitTool(server: FastMCP) { description: 'Create a git commit with automatic staging, message generation, and metadata embedding. Generates appropriate commit messages based on subtask context and TDD phase.', parameters: CommitSchema, - execute: withNormalizedProjectRoot( - async (args: CommitArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-commit', + async (args: CommitArgs, { log }: ToolContext) => { const { projectRoot, files, customMessage } = args; try { - context.log.info(`Creating commit for workflow in ${projectRoot}`); + log.info(`Creating commit for workflow in ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -58,7 +56,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { 'No active workflow found. Start a workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -70,9 +68,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { // Verify we're in COMMIT phase if (status.tddPhase !== 'COMMIT') { - context.log.warn( - `Not in COMMIT phase (currently in ${status.tddPhase})` - ); + log.warn(`Not in COMMIT phase (currently in ${status.tddPhase})`); return handleApiResult({ result: { success: false, @@ -80,7 +76,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { message: `Cannot commit: currently in ${status.tddPhase} phase. Complete the ${status.tddPhase} phase first using autopilot_complete_phase` } }, - log: context.log, + log, projectRoot }); } @@ -92,7 +88,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { success: false, error: { message: 'No active subtask to commit' } }, - log: context.log, + log, projectRoot }); } @@ -104,19 +100,19 @@ export function registerAutopilotCommitTool(server: FastMCP) { try { if (files && files.length > 0) { await gitAdapter.stageFiles(files); - context.log.info(`Staged ${files.length} files`); + log.info(`Staged ${files.length} files`); } else { await gitAdapter.stageFiles(['.']); - context.log.info('Staged all changes'); + log.info('Staged all changes'); } } catch (error: any) { - context.log.error(`Failed to stage files: ${error.message}`); + log.error(`Failed to stage files: ${error.message}`); return handleApiResult({ result: { success: false, error: { message: `Failed to stage files: ${error.message}` } }, - log: context.log, + log, projectRoot }); } @@ -124,7 +120,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { // Check if there are staged changes const hasStagedChanges = await gitAdapter.hasStagedChanges(); if (!hasStagedChanges) { - context.log.warn('No staged changes to commit'); + log.warn('No staged changes to commit'); return handleApiResult({ result: { success: false, @@ -133,7 +129,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { 'No staged changes to commit. Make code changes before committing' } }, - log: context.log, + log, projectRoot }); } @@ -145,7 +141,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { let commitMessage: string; if (customMessage) { commitMessage = customMessage; - context.log.info('Using custom commit message'); + log.info('Using custom commit message'); } else { const messageGenerator = new CommitMessageGenerator(); @@ -168,21 +164,21 @@ export function registerAutopilotCommitTool(server: FastMCP) { }; commitMessage = messageGenerator.generateMessage(options); - context.log.info('Generated commit message automatically'); + log.info('Generated commit message automatically'); } // Create commit try { await gitAdapter.createCommit(commitMessage); - context.log.info('Commit created successfully'); + log.info('Commit created successfully'); } catch (error: any) { - context.log.error(`Failed to create commit: ${error.message}`); + log.error(`Failed to create commit: ${error.message}`); return handleApiResult({ result: { success: false, error: { message: `Failed to create commit: ${error.message}` } }, - log: context.log, + log, projectRoot }); } @@ -193,7 +189,7 @@ export function registerAutopilotCommitTool(server: FastMCP) { // Complete COMMIT phase and advance workflow const newStatus = await workflowService.commit(); - context.log.info( + log.info( `Commit completed. Current phase: ${newStatus.tddPhase || newStatus.phase}` ); @@ -217,20 +213,20 @@ export function registerAutopilotCommitTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-commit: ${error.message}`); + log.error(`Error in autopilot-commit: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { success: false, error: { message: `Failed to commit: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/complete.tool.ts b/apps/mcp/src/tools/autopilot/complete.tool.ts index 5b4d1023..0609f181 100644 --- a/apps/mcp/src/tools/autopilot/complete.tool.ts +++ b/apps/mcp/src/tools/autopilot/complete.tool.ts @@ -3,14 +3,11 @@ * Complete the current TDD phase with test result validation */ -import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; +import { z } from 'zod'; +import type { ToolContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; const CompletePhaseSchema = z.object({ projectRoot: z @@ -37,14 +34,13 @@ export function registerAutopilotCompleteTool(server: FastMCP) { description: 'Complete the current TDD phase (RED, GREEN, or COMMIT) with test result validation. RED phase: expects failures (if 0 failures, feature is already implemented and subtask auto-completes). GREEN phase: expects all tests passing.', parameters: CompletePhaseSchema, - execute: withNormalizedProjectRoot( - async (args: CompletePhaseArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-complete-phase', + async (args: CompletePhaseArgs, { log }: ToolContext) => { const { projectRoot, testResults } = args; try { - context.log.info( - `Completing current phase in workflow for ${projectRoot}` - ); + log.info(`Completing current phase in workflow for ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -58,7 +54,7 @@ export function registerAutopilotCompleteTool(server: FastMCP) { 'No active workflow found. Start a workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -76,7 +72,7 @@ export function registerAutopilotCompleteTool(server: FastMCP) { message: `Cannot complete phase: not in a TDD phase (current phase: ${currentStatus.phase})` } }, - log: context.log, + log, projectRoot }); } @@ -91,7 +87,7 @@ export function registerAutopilotCompleteTool(server: FastMCP) { 'Cannot complete COMMIT phase with this tool. Use autopilot_commit instead' } }, - log: context.log, + log, projectRoot }); } @@ -112,7 +108,7 @@ export function registerAutopilotCompleteTool(server: FastMCP) { const status = await workflowService.completePhase(fullTestResults); const nextAction = workflowService.getNextAction(); - context.log.info( + log.info( `Phase completed. New phase: ${status.tddPhase || status.phase}` ); @@ -127,13 +123,13 @@ export function registerAutopilotCompleteTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-complete: ${error.message}`); + log.error(`Error in autopilot-complete: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -142,7 +138,7 @@ export function registerAutopilotCompleteTool(server: FastMCP) { message: `Failed to complete phase: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/finalize.tool.ts b/apps/mcp/src/tools/autopilot/finalize.tool.ts index 4fb94f41..e0a5a969 100644 --- a/apps/mcp/src/tools/autopilot/finalize.tool.ts +++ b/apps/mcp/src/tools/autopilot/finalize.tool.ts @@ -3,14 +3,11 @@ * Finalize and complete the workflow with working tree validation */ -import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; +import { z } from 'zod'; +import type { ToolContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; const FinalizeSchema = z.object({ projectRoot: z @@ -29,12 +26,13 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { description: 'Finalize and complete the workflow. Validates that all changes are committed and working tree is clean before marking workflow as complete.', parameters: FinalizeSchema, - execute: withNormalizedProjectRoot( - async (args: FinalizeArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-finalize', + async (args: FinalizeArgs, { log }: ToolContext) => { const { projectRoot } = args; try { - context.log.info(`Finalizing workflow in ${projectRoot}`); + log.info(`Finalizing workflow in ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -48,7 +46,7 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { 'No active workflow found. Start a workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -66,7 +64,7 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { message: `Cannot finalize: workflow is in ${currentStatus.phase} phase. Complete all subtasks first.` } }, - log: context.log, + log, projectRoot }); } @@ -74,7 +72,7 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { // Finalize workflow (validates clean working tree) const newStatus = await workflowService.finalizeWorkflow(); - context.log.info('Workflow finalized successfully'); + log.info('Workflow finalized successfully'); // Get next action const nextAction = workflowService.getNextAction(); @@ -89,13 +87,13 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-finalize: ${error.message}`); + log.error(`Error in autopilot-finalize: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -104,7 +102,7 @@ export function registerAutopilotFinalizeTool(server: FastMCP) { message: `Failed to finalize workflow: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/next.tool.ts b/apps/mcp/src/tools/autopilot/next.tool.ts index 821c95e2..e48328fb 100644 --- a/apps/mcp/src/tools/autopilot/next.tool.ts +++ b/apps/mcp/src/tools/autopilot/next.tool.ts @@ -3,14 +3,11 @@ * Get the next action to perform in the TDD workflow */ -import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; +import { z } from 'zod'; +import type { ToolContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; const NextActionSchema = z.object({ projectRoot: z @@ -29,14 +26,13 @@ export function registerAutopilotNextTool(server: FastMCP) { description: 'Get the next action to perform in the TDD workflow. Returns detailed context about what needs to be done next, including the current phase, subtask, and expected actions.', parameters: NextActionSchema, - execute: withNormalizedProjectRoot( - async (args: NextActionArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-next', + async (args: NextActionArgs, { log }: ToolContext) => { const { projectRoot } = args; try { - context.log.info( - `Getting next action for workflow in ${projectRoot}` - ); + log.info(`Getting next action for workflow in ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -50,7 +46,7 @@ export function registerAutopilotNextTool(server: FastMCP) { 'No active workflow found. Start a workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -62,7 +58,7 @@ export function registerAutopilotNextTool(server: FastMCP) { const nextAction = workflowService.getNextAction(); const status = workflowService.getStatus(); - context.log.info(`Next action determined: ${nextAction.action}`); + log.info(`Next action determined: ${nextAction.action}`); return handleApiResult({ result: { @@ -74,13 +70,13 @@ export function registerAutopilotNextTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-next: ${error.message}`); + log.error(`Error in autopilot-next: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -89,7 +85,7 @@ export function registerAutopilotNextTool(server: FastMCP) { message: `Failed to get next action: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/resume.tool.ts b/apps/mcp/src/tools/autopilot/resume.tool.ts index 1a65ad3a..d9e1b466 100644 --- a/apps/mcp/src/tools/autopilot/resume.tool.ts +++ b/apps/mcp/src/tools/autopilot/resume.tool.ts @@ -4,11 +4,8 @@ */ import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; +import type { ToolContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; @@ -29,12 +26,13 @@ export function registerAutopilotResumeTool(server: FastMCP) { description: 'Resume a previously started TDD workflow from saved state. Restores the workflow state machine and continues from where it left off.', parameters: ResumeWorkflowSchema, - execute: withNormalizedProjectRoot( - async (args: ResumeWorkflowArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-resume', + async (args: ResumeWorkflowArgs, { log }: ToolContext) => { const { projectRoot } = args; try { - context.log.info(`Resuming autopilot workflow in ${projectRoot}`); + log.info(`Resuming autopilot workflow in ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -48,7 +46,7 @@ export function registerAutopilotResumeTool(server: FastMCP) { 'No workflow state found. Start a new workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -57,9 +55,7 @@ export function registerAutopilotResumeTool(server: FastMCP) { const status = await workflowService.resumeWorkflow(); const nextAction = workflowService.getNextAction(); - context.log.info( - `Workflow resumed successfully for task ${status.taskId}` - ); + log.info(`Workflow resumed successfully for task ${status.taskId}`); return handleApiResult({ result: { @@ -72,20 +68,20 @@ export function registerAutopilotResumeTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-resume: ${error.message}`); + log.error(`Error in autopilot-resume: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { success: false, error: { message: `Failed to resume workflow: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/start.tool.ts b/apps/mcp/src/tools/autopilot/start.tool.ts index 81df8b9f..21977db4 100644 --- a/apps/mcp/src/tools/autopilot/start.tool.ts +++ b/apps/mcp/src/tools/autopilot/start.tool.ts @@ -4,12 +4,8 @@ */ import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; -import { createTmCore } from '@tm/core'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; +import type { ToolContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; @@ -57,12 +53,13 @@ export function registerAutopilotStartTool(server: FastMCP) { description: 'Initialize and start a new TDD workflow for a task. Creates a git branch and sets up the workflow state machine.', parameters: StartWorkflowSchema, - execute: withNormalizedProjectRoot( - async (args: StartWorkflowArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-start', + async (args: StartWorkflowArgs, { log, tmCore }: ToolContext) => { const { taskId, projectRoot, maxAttempts, force } = args; try { - context.log.info( + log.info( `Starting autopilot workflow for task ${taskId} in ${projectRoot}` ); @@ -75,20 +72,15 @@ export function registerAutopilotStartTool(server: FastMCP) { message: `Task ID "${taskId}" is a subtask. Autopilot workflows can only be started for main tasks (e.g., "1", "2", "HAM-123"). Please provide the parent task ID instead.` } }, - log: context.log, + log, projectRoot }); } - // Load task data and get current tag - const core = await createTmCore({ - projectPath: projectRoot - }); - // Get current tag from ConfigManager - const currentTag = core.config.getActiveTag(); + const currentTag = tmCore.config.getActiveTag(); - const taskResult = await core.tasks.get(taskId); + const taskResult = await tmCore.tasks.get(taskId); if (!taskResult || !taskResult.task) { return handleApiResult({ @@ -96,7 +88,7 @@ export function registerAutopilotStartTool(server: FastMCP) { success: false, error: { message: `Task ${taskId} not found` } }, - log: context.log, + log, projectRoot }); } @@ -112,7 +104,7 @@ export function registerAutopilotStartTool(server: FastMCP) { message: `Task ${taskId} has no subtasks. Please use expand_task (with id="${taskId}") to create subtasks first. For improved results, consider running analyze_complexity before expanding the task.` } }, - log: context.log, + log, projectRoot }); } @@ -123,7 +115,7 @@ export function registerAutopilotStartTool(server: FastMCP) { // Check for existing workflow const hasWorkflow = await workflowService.hasWorkflow(); if (hasWorkflow && !force) { - context.log.warn('Workflow state already exists'); + log.warn('Workflow state already exists'); return handleApiResult({ result: { success: false, @@ -132,7 +124,7 @@ export function registerAutopilotStartTool(server: FastMCP) { 'Workflow already in progress. Use force=true to override or resume the existing workflow. Suggestion: Use autopilot_resume to continue the existing workflow' } }, - log: context.log, + log, projectRoot }); } @@ -152,7 +144,7 @@ export function registerAutopilotStartTool(server: FastMCP) { tag: currentTag // Pass current tag for branch naming }); - context.log.info(`Workflow started successfully for task ${taskId}`); + log.info(`Workflow started successfully for task ${taskId}`); // Get next action with guidance from WorkflowService const nextAction = workflowService.getNextAction(); @@ -172,20 +164,20 @@ export function registerAutopilotStartTool(server: FastMCP) { nextSteps: nextAction.nextSteps } }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-start: ${error.message}`); + log.error(`Error in autopilot-start: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { success: false, error: { message: `Failed to start workflow: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/autopilot/status.tool.ts b/apps/mcp/src/tools/autopilot/status.tool.ts index f12d6e10..4a29bb04 100644 --- a/apps/mcp/src/tools/autopilot/status.tool.ts +++ b/apps/mcp/src/tools/autopilot/status.tool.ts @@ -4,11 +4,8 @@ */ import { z } from 'zod'; -import { - handleApiResult, - withNormalizedProjectRoot -} from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; +import { handleApiResult, withToolContext } from '../../shared/utils.js'; +import type { ToolContext } from '../../shared/types.js'; import { WorkflowService } from '@tm/core'; import type { FastMCP } from 'fastmcp'; @@ -29,12 +26,13 @@ export function registerAutopilotStatusTool(server: FastMCP) { description: 'Get comprehensive workflow status including current phase, progress, subtask details, and activity history.', parameters: StatusSchema, - execute: withNormalizedProjectRoot( - async (args: StatusArgs, context: MCPContext) => { + execute: withToolContext( + 'autopilot-status', + async (args: StatusArgs, { log }: ToolContext) => { const { projectRoot } = args; try { - context.log.info(`Getting workflow status for ${projectRoot}`); + log.info(`Getting workflow status for ${projectRoot}`); const workflowService = new WorkflowService(projectRoot); @@ -48,7 +46,7 @@ export function registerAutopilotStatusTool(server: FastMCP) { 'No active workflow found. Start a workflow with autopilot_start' } }, - log: context.log, + log, projectRoot }); } @@ -59,22 +57,20 @@ export function registerAutopilotStatusTool(server: FastMCP) { // Get status const status = workflowService.getStatus(); - context.log.info( - `Workflow status retrieved for task ${status.taskId}` - ); + log.info(`Workflow status retrieved for task ${status.taskId}`); return handleApiResult({ result: { success: true, data: status }, - log: context.log, + log, projectRoot }); } catch (error: any) { - context.log.error(`Error in autopilot-status: ${error.message}`); + log.error(`Error in autopilot-status: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -83,7 +79,7 @@ export function registerAutopilotStatusTool(server: FastMCP) { message: `Failed to get workflow status: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/tasks/get-task.tool.ts b/apps/mcp/src/tools/tasks/get-task.tool.ts index c3e79a3a..a1cb1f9c 100644 --- a/apps/mcp/src/tools/tasks/get-task.tool.ts +++ b/apps/mcp/src/tools/tasks/get-task.tool.ts @@ -6,10 +6,10 @@ import { z } from 'zod'; import { handleApiResult, - withNormalizedProjectRoot + withToolContext } from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; -import { createTmCore, Subtask, type Task } from '@tm/core'; +import type { ToolContext } from '../../shared/types.js'; +import { Subtask, type Task } from '@tm/core'; import type { FastMCP } from 'fastmcp'; const GetTaskSchema = z.object({ @@ -40,24 +40,16 @@ export function registerGetTaskTool(server: FastMCP) { name: 'get_task', description: 'Get detailed information about a specific task', parameters: GetTaskSchema, - execute: withNormalizedProjectRoot( - async (args: GetTaskArgs, context: MCPContext) => { + execute: withToolContext( + 'get-task', + async (args: GetTaskArgs, { log, tmCore }: ToolContext) => { const { id, status, projectRoot, tag } = args; try { - context.log.info( + log.info( `Getting task details for ID: ${id}${status ? ` (filtering subtasks by status: ${status})` : ''} in root: ${projectRoot}` ); - // Create tm-core with logging callback - const tmCore = await createTmCore({ - projectPath: projectRoot, - loggerConfig: { - mcpMode: true, - logCallback: context.log - } - }); - // Handle comma-separated IDs - parallelize for better performance const taskIds = id.split(',').map((tid) => tid.trim()); const results = await Promise.all( @@ -83,7 +75,7 @@ export function registerGetTaskTool(server: FastMCP) { } if (tasks.length === 0) { - context.log.warn(`No tasks found for ID(s): ${id}`); + log.warn(`No tasks found for ID(s): ${id}`); return handleApiResult({ result: { success: false, @@ -91,12 +83,12 @@ export function registerGetTaskTool(server: FastMCP) { message: `No tasks found for ID(s): ${id}` } }, - log: context.log, + log, projectRoot }); } - context.log.info( + log.info( `Successfully retrieved ${tasks.length} task(s) for ID(s): ${id}` ); @@ -108,14 +100,14 @@ export function registerGetTaskTool(server: FastMCP) { success: true, data: responseData }, - log: context.log, + log, projectRoot, tag }); } catch (error: any) { - context.log.error(`Error in get-task: ${error.message}`); + log.error(`Error in get-task: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -124,7 +116,7 @@ export function registerGetTaskTool(server: FastMCP) { message: `Failed to get task: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/apps/mcp/src/tools/tasks/get-tasks.tool.ts b/apps/mcp/src/tools/tasks/get-tasks.tool.ts index 64222d20..f2b1ed2c 100644 --- a/apps/mcp/src/tools/tasks/get-tasks.tool.ts +++ b/apps/mcp/src/tools/tasks/get-tasks.tool.ts @@ -6,10 +6,10 @@ import { z } from 'zod'; import { handleApiResult, - withNormalizedProjectRoot + withToolContext } from '../../shared/utils.js'; -import type { MCPContext } from '../../shared/types.js'; -import { createTmCore, type TaskStatus, type Task } from '@tm/core'; +import type { ToolContext } from '../../shared/types.js'; +import type { TaskStatus, Task } from '@tm/core'; import type { FastMCP } from 'fastmcp'; const GetTasksSchema = z.object({ @@ -40,24 +40,16 @@ export function registerGetTasksTool(server: FastMCP) { description: 'Get all tasks from Task Master, optionally filtering by status and including subtasks.', parameters: GetTasksSchema, - execute: withNormalizedProjectRoot( - async (args: GetTasksArgs, context: MCPContext) => { + execute: withToolContext( + 'get-tasks', + async (args: GetTasksArgs, { log, tmCore }: ToolContext) => { const { projectRoot, status, withSubtasks, tag } = args; try { - context.log.info( + log.info( `Getting tasks from ${projectRoot}${status ? ` with status filter: ${status}` : ''}${tag ? ` for tag: ${tag}` : ''}` ); - // Create tm-core with logging callback - const tmCore = await createTmCore({ - projectPath: projectRoot, - loggerConfig: { - mcpMode: true, - logCallback: context.log - } - }); - // Build filter const filter = status && status !== 'all' @@ -75,7 +67,7 @@ export function registerGetTasksTool(server: FastMCP) { includeSubtasks: withSubtasks }); - context.log.info( + log.info( `Retrieved ${result.tasks?.length || 0} tasks (${result.filtered} filtered, ${result.total} total)` ); @@ -138,14 +130,14 @@ export function registerGetTasksTool(server: FastMCP) { } } }, - log: context.log, + log, projectRoot, tag: result.tag }); } catch (error: any) { - context.log.error(`Error in get-tasks: ${error.message}`); + log.error(`Error in get-tasks: ${error.message}`); if (error.stack) { - context.log.debug(error.stack); + log.debug(error.stack); } return handleApiResult({ result: { @@ -154,7 +146,7 @@ export function registerGetTasksTool(server: FastMCP) { message: `Failed to get tasks: ${error.message}` } }, - log: context.log, + log, projectRoot }); } diff --git a/mcp-server/src/tools/add-dependency.js b/mcp-server/src/tools/add-dependency.js index d922a3ef..712616fc 100644 --- a/mcp-server/src/tools/add-dependency.js +++ b/mcp-server/src/tools/add-dependency.js @@ -3,15 +3,11 @@ * Tool for adding a dependency to a task */ +import { createErrorResponse, handleApiResult, withToolContext } from '@tm/mcp'; import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { resolveTag } from '../../../scripts/modules/utils.js'; import { addDependencyDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; -import { resolveTag } from '../../../scripts/modules/utils.js'; /** * Register the addDependency tool with the MCP server @@ -37,62 +33,65 @@ export function registerAddDependencyTool(server) { .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { - try { - log.info( - `Adding dependency for task ${args.id} to depend on ${args.dependsOn}` - ); - const resolvedTag = resolveTag({ - projectRoot: args.projectRoot, - tag: args.tag - }); - let tasksJsonPath; + execute: withToolContext( + 'add-dependency', + async (args, { log, session }) => { try { - tasksJsonPath = findTasksPath( - { projectRoot: args.projectRoot, file: args.file }, - log + log.info( + `Adding dependency for task ${args.id} to depend on ${args.dependsOn}` ); - } catch (error) { - log.error(`Error finding tasks.json: ${error.message}`); - return createErrorResponse( - `Failed to find tasks.json: ${error.message}` - ); - } + const resolvedTag = resolveTag({ + projectRoot: args.projectRoot, + tag: args.tag + }); + let tasksJsonPath; + try { + tasksJsonPath = findTasksPath( + { projectRoot: args.projectRoot, file: args.file }, + log + ); + } catch (error) { + log.error(`Error finding tasks.json: ${error.message}`); + return createErrorResponse( + `Failed to find tasks.json: ${error.message}` + ); + } - // Call the direct function with the resolved path - const result = await addDependencyDirect( - { - // Pass the explicitly resolved path - tasksJsonPath: tasksJsonPath, - // Pass other relevant args - id: args.id, - dependsOn: args.dependsOn, + // Call the direct function with the resolved path + const result = await addDependencyDirect( + { + // Pass the explicitly resolved path + tasksJsonPath: tasksJsonPath, + // Pass other relevant args + id: args.id, + dependsOn: args.dependsOn, + projectRoot: args.projectRoot, + tag: resolvedTag + }, + log + // Remove context object + ); + + // Log result + if (result.success) { + log.info(`Successfully added dependency: ${result.data.message}`); + } else { + log.error(`Failed to add dependency: ${result.error.message}`); + } + + // Use handleApiResult to format the response + return handleApiResult({ + result, + log, + errorPrefix: 'Error adding dependency', projectRoot: args.projectRoot, tag: resolvedTag - }, - log - // Remove context object - ); - - // Log result - if (result.success) { - log.info(`Successfully added dependency: ${result.data.message}`); - } else { - log.error(`Failed to add dependency: ${result.error.message}`); + }); + } catch (error) { + log.error(`Error in addDependency tool: ${error.message}`); + return createErrorResponse(error.message); } - - // Use handleApiResult to format the response - return handleApiResult( - result, - log, - 'Error adding dependency', - undefined, - args.projectRoot - ); - } catch (error) { - log.error(`Error in addDependency tool: ${error.message}`); - return createErrorResponse(error.message); } - }) + ) }); } diff --git a/mcp-server/src/tools/add-subtask.js b/mcp-server/src/tools/add-subtask.js index 62ddffe8..7b1e7b12 100644 --- a/mcp-server/src/tools/add-subtask.js +++ b/mcp-server/src/tools/add-subtask.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { addSubtaskDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/add-tag.js b/mcp-server/src/tools/add-tag.js index 886d1a25..f01bc57f 100644 --- a/mcp-server/src/tools/add-tag.js +++ b/mcp-server/src/tools/add-tag.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { addTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/add-task.js b/mcp-server/src/tools/add-task.js index 3ad43a94..ae588529 100644 --- a/mcp-server/src/tools/add-task.js +++ b/mcp-server/src/tools/add-task.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { addTaskDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/analyze.js b/mcp-server/src/tools/analyze.js index 871c90da..eca4aa75 100644 --- a/mcp-server/src/tools/analyze.js +++ b/mcp-server/src/tools/analyze.js @@ -10,7 +10,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { analyzeTaskComplexityDirect } from '../core/task-master-core.js'; // Assuming core functions are exported via task-master-core.js import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/clear-subtasks.js b/mcp-server/src/tools/clear-subtasks.js index 6a0d0bff..8a53dd2f 100644 --- a/mcp-server/src/tools/clear-subtasks.js +++ b/mcp-server/src/tools/clear-subtasks.js @@ -4,11 +4,7 @@ */ import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { handleApiResult, createErrorResponse, withToolContext } from '@tm/mcp'; import { clearSubtasksDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; @@ -43,9 +39,11 @@ export function registerClearSubtasksTool(server) { message: "Either 'id' or 'all' parameter must be provided", path: ['id', 'all'] }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { + execute: withToolContext('clear-subtasks', async (args, context) => { try { - log.info(`Clearing subtasks with args: ${JSON.stringify(args)}`); + context.log.info( + `Clearing subtasks with args: ${JSON.stringify(args)}` + ); const resolvedTag = resolveTag({ projectRoot: args.projectRoot, @@ -57,10 +55,10 @@ export function registerClearSubtasksTool(server) { try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, - log + context.log ); } catch (error) { - log.error(`Error finding tasks.json: ${error.message}`); + context.log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); @@ -75,25 +73,29 @@ export function registerClearSubtasksTool(server) { projectRoot: args.projectRoot, tag: resolvedTag }, - log, - { session } + context.log, + { session: context.session } ); if (result.success) { - log.info(`Subtasks cleared successfully: ${result.data.message}`); + context.log.info( + `Subtasks cleared successfully: ${result.data.message}` + ); } else { - log.error(`Failed to clear subtasks: ${result.error.message}`); + context.log.error( + `Failed to clear subtasks: ${result.error.message}` + ); } return handleApiResult( result, - log, + context.log, 'Error clearing subtasks', undefined, args.projectRoot ); } catch (error) { - log.error(`Error in clearSubtasks tool: ${error.message}`); + context.log.error(`Error in clearSubtasks tool: ${error.message}`); return createErrorResponse(error.message); } }) diff --git a/mcp-server/src/tools/complexity-report.js b/mcp-server/src/tools/complexity-report.js index 0dfa401a..2f2fe8c2 100644 --- a/mcp-server/src/tools/complexity-report.js +++ b/mcp-server/src/tools/complexity-report.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { complexityReportDirect } from '../core/task-master-core.js'; import { COMPLEXITY_REPORT_FILE } from '../../../src/constants/paths.js'; import { findComplexityReportPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/copy-tag.js b/mcp-server/src/tools/copy-tag.js index 395d2bce..86d923c2 100644 --- a/mcp-server/src/tools/copy-tag.js +++ b/mcp-server/src/tools/copy-tag.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { copyTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/delete-tag.js b/mcp-server/src/tools/delete-tag.js index 24813a35..d684a960 100644 --- a/mcp-server/src/tools/delete-tag.js +++ b/mcp-server/src/tools/delete-tag.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { deleteTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/expand-all.js b/mcp-server/src/tools/expand-all.js index ee52607a..3043fa1a 100644 --- a/mcp-server/src/tools/expand-all.js +++ b/mcp-server/src/tools/expand-all.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { expandAllTasksDirect } from '../core/task-master-core.js'; import { findTasksPath, diff --git a/mcp-server/src/tools/expand-task.js b/mcp-server/src/tools/expand-task.js index b6cd5b1f..49d5d879 100644 --- a/mcp-server/src/tools/expand-task.js +++ b/mcp-server/src/tools/expand-task.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { expandTaskDirect } from '../core/task-master-core.js'; import { findTasksPath, diff --git a/mcp-server/src/tools/fix-dependencies.js b/mcp-server/src/tools/fix-dependencies.js index 92586355..243806a1 100644 --- a/mcp-server/src/tools/fix-dependencies.js +++ b/mcp-server/src/tools/fix-dependencies.js @@ -4,14 +4,11 @@ */ import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { handleApiResult, createErrorResponse, withToolContext } from '@tm/mcp'; import { fixDependenciesDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; + /** * Register the fixDependencies tool with the MCP server * @param {Object} server - FastMCP server instance @@ -27,9 +24,11 @@ export function registerFixDependenciesTool(server) { .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { + execute: withToolContext('fix-dependencies', async (args, context) => { try { - log.info(`Fixing dependencies with args: ${JSON.stringify(args)}`); + context.log.info( + `Fixing dependencies with args: ${JSON.stringify(args)}` + ); const resolvedTag = resolveTag({ projectRoot: args.projectRoot, @@ -41,10 +40,10 @@ export function registerFixDependenciesTool(server) { try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, - log + context.log ); } catch (error) { - log.error(`Error finding tasks.json: ${error.message}`); + context.log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); @@ -56,24 +55,28 @@ export function registerFixDependenciesTool(server) { projectRoot: args.projectRoot, tag: resolvedTag }, - log + context.log ); if (result.success) { - log.info(`Successfully fixed dependencies: ${result.data.message}`); + context.log.info( + `Successfully fixed dependencies: ${result.data.message}` + ); } else { - log.error(`Failed to fix dependencies: ${result.error.message}`); + context.log.error( + `Failed to fix dependencies: ${result.error.message}` + ); } return handleApiResult( result, - log, + context.log, 'Error fixing dependencies', undefined, args.projectRoot ); } catch (error) { - log.error(`Error in fixDependencies tool: ${error.message}`); + context.log.error(`Error in fixDependencies tool: ${error.message}`); return createErrorResponse(error.message); } }) diff --git a/mcp-server/src/tools/get-operation-status.js b/mcp-server/src/tools/get-operation-status.js index 7713c612..d871f095 100644 --- a/mcp-server/src/tools/get-operation-status.js +++ b/mcp-server/src/tools/get-operation-status.js @@ -1,6 +1,6 @@ // mcp-server/src/tools/get-operation-status.js import { z } from 'zod'; -import { createErrorResponse, createContentResponse } from './utils.js'; // Assuming these utils exist +import { createErrorResponse, createContentResponse } from '@tm/mcp'; // Assuming these utils exist /** * Register the get_operation_status tool. diff --git a/mcp-server/src/tools/initialize-project.js b/mcp-server/src/tools/initialize-project.js index 6bf380d6..c6d36ba6 100644 --- a/mcp-server/src/tools/initialize-project.js +++ b/mcp-server/src/tools/initialize-project.js @@ -3,7 +3,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { initializeProjectDirect } from '../core/task-master-core.js'; import { RULE_PROFILES } from '../../../src/constants/profiles.js'; diff --git a/mcp-server/src/tools/list-tags.js b/mcp-server/src/tools/list-tags.js index 4e12d5f6..e67fa0b4 100644 --- a/mcp-server/src/tools/list-tags.js +++ b/mcp-server/src/tools/list-tags.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { listTagsDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/models.js b/mcp-server/src/tools/models.js index f921d3de..96a99bfb 100644 --- a/mcp-server/src/tools/models.js +++ b/mcp-server/src/tools/models.js @@ -4,11 +4,7 @@ */ import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { handleApiResult, createErrorResponse, withToolContext } from '@tm/mcp'; import { modelsDirect } from '../core/task-master-core.js'; /** @@ -83,26 +79,28 @@ export function registerModelsTool(server) { 'Custom base URL for providers that support it (e.g., https://api.example.com/v1).' ) }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { + execute: withToolContext('models', async (args, context) => { try { - log.info(`Starting models tool with args: ${JSON.stringify(args)}`); + context.log.info( + `Starting models tool with args: ${JSON.stringify(args)}` + ); // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) const result = await modelsDirect( { ...args, projectRoot: args.projectRoot }, - log, - { session } + context.log, + { session: context.session } ); return handleApiResult( result, - log, + context.log, 'Error managing models', undefined, args.projectRoot ); } catch (error) { - log.error(`Error in models tool: ${error.message}`); + context.log.error(`Error in models tool: ${error.message}`); return createErrorResponse(error.message); } }) diff --git a/mcp-server/src/tools/move-task.js b/mcp-server/src/tools/move-task.js index dd944342..0c8b2835 100644 --- a/mcp-server/src/tools/move-task.js +++ b/mcp-server/src/tools/move-task.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { moveTaskDirect, moveTaskCrossTagDirect diff --git a/mcp-server/src/tools/next-task.js b/mcp-server/src/tools/next-task.js index b5453b08..c60e99e2 100644 --- a/mcp-server/src/tools/next-task.js +++ b/mcp-server/src/tools/next-task.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { nextTaskDirect } from '../core/task-master-core.js'; import { resolveTasksPath, diff --git a/mcp-server/src/tools/parse-prd.js b/mcp-server/src/tools/parse-prd.js index ebfabd1b..0108898e 100644 --- a/mcp-server/src/tools/parse-prd.js +++ b/mcp-server/src/tools/parse-prd.js @@ -9,7 +9,7 @@ import { withNormalizedProjectRoot, createErrorResponse, checkProgressCapability -} from './utils.js'; +} from '@tm/mcp'; import { parsePRDDirect } from '../core/task-master-core.js'; import { PRD_FILE, diff --git a/mcp-server/src/tools/remove-dependency.js b/mcp-server/src/tools/remove-dependency.js index 84c57462..efcd1c2e 100644 --- a/mcp-server/src/tools/remove-dependency.js +++ b/mcp-server/src/tools/remove-dependency.js @@ -3,15 +3,11 @@ * Tool for removing a dependency from a task */ +import { createErrorResponse, handleApiResult, withToolContext } from '@tm/mcp'; import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { resolveTag } from '../../../scripts/modules/utils.js'; import { removeDependencyDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; -import { resolveTag } from '../../../scripts/modules/utils.js'; /** * Register the removeDependency tool with the MCP server @@ -35,25 +31,25 @@ export function registerRemoveDependencyTool(server) { .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { + execute: withToolContext('remove-dependency', async (args, context) => { try { const resolvedTag = resolveTag({ projectRoot: args.projectRoot, tag: args.tag }); - log.info( + context.log.info( `Removing dependency for task ${args.id} from ${args.dependsOn} with args: ${JSON.stringify(args)}` ); - // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) + // Use args.projectRoot directly (guaranteed by withToolContext) let tasksJsonPath; try { tasksJsonPath = findTasksPath( { projectRoot: args.projectRoot, file: args.file }, - log + context.log ); } catch (error) { - log.error(`Error finding tasks.json: ${error.message}`); + context.log.error(`Error finding tasks.json: ${error.message}`); return createErrorResponse( `Failed to find tasks.json: ${error.message}` ); @@ -67,24 +63,28 @@ export function registerRemoveDependencyTool(server) { projectRoot: args.projectRoot, tag: resolvedTag }, - log + context.log ); if (result.success) { - log.info(`Successfully removed dependency: ${result.data.message}`); + context.log.info( + `Successfully removed dependency: ${result.data.message}` + ); } else { - log.error(`Failed to remove dependency: ${result.error.message}`); + context.log.error( + `Failed to remove dependency: ${result.error.message}` + ); } return handleApiResult( result, - log, + context.log, 'Error removing dependency', undefined, args.projectRoot ); } catch (error) { - log.error(`Error in removeDependency tool: ${error.message}`); + context.log.error(`Error in removeDependency tool: ${error.message}`); return createErrorResponse(error.message); } }) diff --git a/mcp-server/src/tools/remove-subtask.js b/mcp-server/src/tools/remove-subtask.js index ae83e650..a317e326 100644 --- a/mcp-server/src/tools/remove-subtask.js +++ b/mcp-server/src/tools/remove-subtask.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { removeSubtaskDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/remove-task.js b/mcp-server/src/tools/remove-task.js index 93b2e8f6..c824c38e 100644 --- a/mcp-server/src/tools/remove-task.js +++ b/mcp-server/src/tools/remove-task.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { removeTaskDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/rename-tag.js b/mcp-server/src/tools/rename-tag.js index e26ffcac..bc4dc3d0 100644 --- a/mcp-server/src/tools/rename-tag.js +++ b/mcp-server/src/tools/rename-tag.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { renameTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/research.js b/mcp-server/src/tools/research.js index 1fb61be9..c1a3a6bc 100644 --- a/mcp-server/src/tools/research.js +++ b/mcp-server/src/tools/research.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { researchDirect } from '../core/task-master-core.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/response-language.js b/mcp-server/src/tools/response-language.js index 42a8ee06..29435d43 100644 --- a/mcp-server/src/tools/response-language.js +++ b/mcp-server/src/tools/response-language.js @@ -3,7 +3,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { responseLanguageDirect } from '../core/direct-functions/response-language.js'; export function registerResponseLanguageTool(server) { @@ -36,7 +36,12 @@ export function registerResponseLanguageTool(server) { log, { session } ); - return handleApiResult(result, log, 'Error setting response language'); + return handleApiResult({ + result, + log, + errorPrefix: 'Error setting response language', + projectRoot: args.projectRoot + }); } catch (error) { log.error(`Error in response-language tool: ${error.message}`); return createErrorResponse(error.message); diff --git a/mcp-server/src/tools/rules.js b/mcp-server/src/tools/rules.js index ff3fed7a..030aa91d 100644 --- a/mcp-server/src/tools/rules.js +++ b/mcp-server/src/tools/rules.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { rulesDirect } from '../core/direct-functions/rules.js'; import { RULE_PROFILES } from '../../../src/constants/profiles.js'; @@ -49,7 +49,11 @@ export function registerRulesTool(server) { `[rules tool] Executing action: ${args.action} for profiles: ${args.profiles.join(', ')} in ${args.projectRoot}` ); const result = await rulesDirect(args, log, { session }); - return handleApiResult(result, log); + return handleApiResult({ + result, + log, + projectRoot: args.projectRoot + }); } catch (error) { log.error(`[rules tool] Error: ${error.message}`); return createErrorResponse(error.message, { details: error.stack }); diff --git a/mcp-server/src/tools/scope-down.js b/mcp-server/src/tools/scope-down.js index a982497e..fc2a45be 100644 --- a/mcp-server/src/tools/scope-down.js +++ b/mcp-server/src/tools/scope-down.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { scopeDownDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/scope-up.js b/mcp-server/src/tools/scope-up.js index 358b7d1b..5f3a6674 100644 --- a/mcp-server/src/tools/scope-up.js +++ b/mcp-server/src/tools/scope-up.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { scopeUpDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/set-task-status.js b/mcp-server/src/tools/set-task-status.js index ee293fed..616d7b8a 100644 --- a/mcp-server/src/tools/set-task-status.js +++ b/mcp-server/src/tools/set-task-status.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { setTaskStatusDirect, nextTaskDirect diff --git a/mcp-server/src/tools/update-subtask.js b/mcp-server/src/tools/update-subtask.js index 2624f4d1..c6c373d6 100644 --- a/mcp-server/src/tools/update-subtask.js +++ b/mcp-server/src/tools/update-subtask.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { updateSubtaskByIdDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/update-task.js b/mcp-server/src/tools/update-task.js index 2fb1feb7..f4eb8ada 100644 --- a/mcp-server/src/tools/update-task.js +++ b/mcp-server/src/tools/update-task.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { updateTaskByIdDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/update.js b/mcp-server/src/tools/update.js index f81a3755..39bf87ed 100644 --- a/mcp-server/src/tools/update.js +++ b/mcp-server/src/tools/update.js @@ -8,7 +8,7 @@ import { handleApiResult, createErrorResponse, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { updateTasksDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; import { resolveTag } from '../../../scripts/modules/utils.js'; diff --git a/mcp-server/src/tools/use-tag.js b/mcp-server/src/tools/use-tag.js index c8133dac..6aed5360 100644 --- a/mcp-server/src/tools/use-tag.js +++ b/mcp-server/src/tools/use-tag.js @@ -8,7 +8,7 @@ import { createErrorResponse, handleApiResult, withNormalizedProjectRoot -} from './utils.js'; +} from '@tm/mcp'; import { useTagDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; diff --git a/mcp-server/src/tools/validate-dependencies.js b/mcp-server/src/tools/validate-dependencies.js index 4b96c12b..ed088141 100644 --- a/mcp-server/src/tools/validate-dependencies.js +++ b/mcp-server/src/tools/validate-dependencies.js @@ -3,15 +3,11 @@ * Tool for validating task dependencies */ +import { createErrorResponse, handleApiResult, withToolContext } from '@tm/mcp'; import { z } from 'zod'; -import { - handleApiResult, - createErrorResponse, - withNormalizedProjectRoot -} from './utils.js'; +import { resolveTag } from '../../../scripts/modules/utils.js'; import { validateDependenciesDirect } from '../core/task-master-core.js'; import { findTasksPath } from '../core/utils/path-utils.js'; -import { resolveTag } from '../../../scripts/modules/utils.js'; /** * Register the validateDependencies tool with the MCP server @@ -29,56 +25,63 @@ export function registerValidateDependenciesTool(server) { .describe('The directory of the project. Must be an absolute path.'), tag: z.string().optional().describe('Tag context to operate on') }), - execute: withNormalizedProjectRoot(async (args, { log, session }) => { - try { - const resolvedTag = resolveTag({ - projectRoot: args.projectRoot, - tag: args.tag - }); - log.info(`Validating dependencies with args: ${JSON.stringify(args)}`); - - // Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot) - let tasksJsonPath; + execute: withToolContext( + 'validate-dependencies', + async (args, { log, session }) => { try { - tasksJsonPath = findTasksPath( - { projectRoot: args.projectRoot, file: args.file }, + const resolvedTag = resolveTag({ + projectRoot: args.projectRoot, + tag: args.tag + }); + log.info( + `Validating dependencies with args: ${JSON.stringify(args)}` + ); + + // Use args.projectRoot directly (guaranteed by withToolContext) + let tasksJsonPath; + try { + tasksJsonPath = findTasksPath( + { projectRoot: args.projectRoot, file: args.file }, + log + ); + } catch (error) { + log.error(`Error finding tasks.json: ${error.message}`); + return createErrorResponse( + `Failed to find tasks.json: ${error.message}` + ); + } + + const result = await validateDependenciesDirect( + { + tasksJsonPath: tasksJsonPath, + projectRoot: args.projectRoot, + tag: resolvedTag + }, log ); - } catch (error) { - log.error(`Error finding tasks.json: ${error.message}`); - return createErrorResponse( - `Failed to find tasks.json: ${error.message}` - ); - } - const result = await validateDependenciesDirect( - { - tasksJsonPath: tasksJsonPath, + if (result.success) { + log.info( + `Successfully validated dependencies: ${result.data.message}` + ); + } else { + log.error( + `Failed to validate dependencies: ${result.error.message}` + ); + } + + return handleApiResult({ + result, + log, + errorPrefix: 'Error validating dependencies', projectRoot: args.projectRoot, tag: resolvedTag - }, - log - ); - - if (result.success) { - log.info( - `Successfully validated dependencies: ${result.data.message}` - ); - } else { - log.error(`Failed to validate dependencies: ${result.error.message}`); + }); + } catch (error) { + log.error(`Error in validateDependencies tool: ${error.message}`); + return createErrorResponse(error.message); } - - return handleApiResult( - result, - log, - 'Error validating dependencies', - undefined, - args.projectRoot - ); - } catch (error) { - log.error(`Error in validateDependencies tool: ${error.message}`); - return createErrorResponse(error.message); } - }) + ) }); } diff --git a/package-lock.json b/package-lock.json index eef834ed..ed89a76a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "@aws-sdk/credential-providers": "^3.895.0", "@inquirer/search": "^3.0.15", "@openrouter/ai-sdk-provider": "^1.2.0", + "@sentry/node": "^10.25.0", "@streamparser/json": "^0.0.22", "@supabase/supabase-js": "^2.57.4", "ai": "^5.0.51", @@ -1939,6 +1940,46 @@ "dev": true, "license": "MIT" }, + "node_modules/@apm-js-collab/code-transformer": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.8.2.tgz", + "integrity": "sha512-YRjJjNq5KFSjDUoqu5pFUWrrsvGOxl6c3bu+uMFc9HNNptZ2rNU/TI2nLw4jnhQNtka972Ee2m3uqbvDQtPeCA==", + "license": "Apache-2.0" + }, + "node_modules/@apm-js-collab/tracing-hooks": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.3.1.tgz", + "integrity": "sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw==", + "license": "Apache-2.0", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.8.0", + "debug": "^4.4.1", + "module-details-from-path": "^1.0.4" + } + }, + "node_modules/@apm-js-collab/tracing-hooks/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@apm-js-collab/tracing-hooks/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/@ark/schema": { "version": "0.49.0", "devOptional": true, @@ -7067,6 +7108,488 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.51.0.tgz", + "integrity": "sha512-XGmjYwjVRktD4agFnWBWQXo9SiYHKBxR6Ag3MLXwtLE4R99N3a08kGKM5SC1qOFKIELcQDGFEFT9ydXMH00Luw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.48.0.tgz", + "integrity": "sha512-OMjc3SFL4pC16PeK+tDhwP7MRvDPalYCGSvGqUhX5rASkI2H0RuxZHOWElYeXkV0WP+70Gw6JHWac/2Zqwmhdw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.22.0.tgz", + "integrity": "sha512-bXnTcwtngQsI1CvodFkTemrrRSQjAjZxqHVc+CJZTDnidT0T6wt3jkKhnsjU/Kkkc0lacr6VdRpCu2CUWa0OKw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.53.0.tgz", + "integrity": "sha512-r/PBafQmFYRjuxLYEHJ3ze1iBnP2GDA1nXOSS6E02KnYNZAVjj6WcDA1MSthtdAUUK0XnotHvvWM8/qz7DMO5A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.24.0.tgz", + "integrity": "sha512-HjIxJ6CBRD770KNVaTdMXIv29Sjz4C1kPCCK5x1Ujpc6SNnLGPqUVyJYZ3LUhhnHAqdbrl83ogVWjCgeT4Q0yw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.48.0.tgz", + "integrity": "sha512-TLv/On8pufynNR+pUbpkyvuESVASZZKMlqCm4bBImTpXKTpqXaJJ3o/MUDeMlM91rpen+PEv2SeyOKcHCSlgag==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.52.0.tgz", + "integrity": "sha512-3fEJ8jOOMwopvldY16KuzHbRhPk8wSsOTSF0v2psmOCGewh6ad+ZbkTx/xyUK9rUdUMWAxRVU0tFpj4Wx1vkPA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.51.0.tgz", + "integrity": "sha512-qyf27DaFNL1Qhbo/da+04MSCw982B02FhuOS5/UF+PMhM61CcOiu7fPuXj8TvbqyReQuJFljXE6UirlvoT/62g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/instrumentation-http": { "version": "0.52.1", "license": "Apache-2.0", @@ -7083,6 +7606,769 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.52.0.tgz", + "integrity": "sha512-rUvlyZwI90HRQPYicxpDGhT8setMrlHKokCtBtZgYxQWRF5RBbG4q0pGtbZvd7kyseuHbFpA3I/5z7M8b/5ywg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/redis-common": "^0.38.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.14.0.tgz", + "integrity": "sha512-kbB5yXS47dTIdO/lfbbXlzhvHFturbux4EpP0+6H78Lk0Bn4QXiZQW7rmZY1xBCY16mNcCb8Yt0mhz85hTnSVA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.49.0.tgz", + "integrity": "sha512-NKsRRT27fbIYL4Ix+BjjP8h4YveyKc+2gD6DMZbr5R5rUeDqfC8+DTfIt3c3ex3BIc5Vvek4rqHnN7q34ZetLQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.52.0.tgz", + "integrity": "sha512-JJSBYLDx/mNSy8Ibi/uQixu2rH0bZODJa8/cz04hEhRaiZQoeJ5UrOhO/mS87IdgVsHrnBOsZ6vDu09znupyuA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.49.0.tgz", + "integrity": "sha512-ctXu+O/1HSadAxtjoEg2w307Z5iPyLOMM8IRNwjaKrIpNAthYGSOanChbk1kqY6zU5CrpkPHGdAT6jk8dXiMqw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.57.0.tgz", + "integrity": "sha512-KD6Rg0KSHWDkik+qjIOWoksi1xqSpix8TSPfquIK1DTmd9OTFb5PHmMkzJe16TAPVEuElUW8gvgP59cacFcrMQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.51.0.tgz", + "integrity": "sha512-gwWaAlhhV2By7XcbyU3DOLMvzsgeaymwP/jktDC+/uPkCmgB61zurwqOQdeiRq9KAf22Y2dtE5ZLXxytJRbEVA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.50.0.tgz", + "integrity": "sha512-duKAvMRI3vq6u9JwzIipY9zHfikN20bX05sL7GjDeLKr2qV0LQ4ADtKST7KStdGcQ+MTN5wghWbbVdLgNcB3rA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.51.0.tgz", + "integrity": "sha512-zT2Wg22Xn43RyfU3NOUmnFtb5zlDI0fKcijCj9AcK9zuLZ4ModgtLXOyBJSSfO+hsOCZSC1v/Fxwj+nZJFdzLQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.41.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.57.0.tgz", + "integrity": "sha512-dWLGE+r5lBgm2A8SaaSYDE3OKJ/kwwy5WLyGyzor8PLhUL9VnJRiY6qhp4njwhnljiLtzeffRtG2Mf/YyWLeTw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.0", + "@types/pg": "8.15.5", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.53.0.tgz", + "integrity": "sha512-WUHV8fr+8yo5RmzyU7D5BIE1zwiaNQcTyZPwtxlfr7px6NYYx7IIpSihJK7WA60npWynfxxK1T67RAVF0Gdfjg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/redis-common": "^0.38.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.23.0.tgz", + "integrity": "sha512-3TMTk/9VtlRonVTaU4tCzbg4YqW+Iq/l5VnN2e5whP6JgEg/PKfrGbqQ+CxQWNLfLaQYIUgEZqAn5gk/inh1uQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.15.0.tgz", + "integrity": "sha512-sNFGA/iCDlVkNjzTzPRcudmI11vT/WAfAguRdZY9IspCw02N4WSC72zTuQhSMheh2a1gdeM9my1imnKRvEEvEg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.204.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/otlp-exporter-base": { "version": "0.52.1", "license": "Apache-2.0", @@ -7158,6 +8444,15 @@ "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, "node_modules/@opentelemetry/resources": { "version": "1.25.1", "license": "Apache-2.0", @@ -7267,6 +8562,45 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@opentelemetry/sql-common/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sql-common/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@oxc-project/types": { "version": "0.93.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.93.0.tgz", @@ -7330,6 +8664,18 @@ "node": ">=12" } }, + "node_modules/@prisma/instrumentation": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.15.0.tgz", + "integrity": "sha512-6TXaH6OmDkMOQvOxwLZ8XS51hU2v4A3vmE2pSijCIiGRJYyNeMcL6nMHQMyYdZRD8wl7LF3Wzc+AMPMV/9Oo7A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "license": "BSD-3-Clause" @@ -8373,6 +9719,235 @@ "url": "https://ko-fi.com/killymxi" } }, + "node_modules/@sentry/core": { + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.25.0.tgz", + "integrity": "sha512-mGi4BYIPwZjWdOXHrPoXz1AW4/cQbFoiuW/m+OOATmtSoGTDnWYwP+qZU7VLlL+v8ZEzxfPi2C1NPfJtPj7QWA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.25.0.tgz", + "integrity": "sha512-++mugiYF8X7CLtpymGN3N4J40SvQVIsVa6K7pURhooT4eX1QXYOBJSaOqvOXk5GN4qed5wETHNBkZuXSO0RARQ==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^2.1.0", + "@opentelemetry/core": "^2.1.0", + "@opentelemetry/instrumentation": "^0.204.0", + "@opentelemetry/instrumentation-amqplib": "0.51.0", + "@opentelemetry/instrumentation-connect": "0.48.0", + "@opentelemetry/instrumentation-dataloader": "0.22.0", + "@opentelemetry/instrumentation-express": "0.53.0", + "@opentelemetry/instrumentation-fs": "0.24.0", + "@opentelemetry/instrumentation-generic-pool": "0.48.0", + "@opentelemetry/instrumentation-graphql": "0.52.0", + "@opentelemetry/instrumentation-hapi": "0.51.0", + "@opentelemetry/instrumentation-http": "0.204.0", + "@opentelemetry/instrumentation-ioredis": "0.52.0", + "@opentelemetry/instrumentation-kafkajs": "0.14.0", + "@opentelemetry/instrumentation-knex": "0.49.0", + "@opentelemetry/instrumentation-koa": "0.52.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.49.0", + "@opentelemetry/instrumentation-mongodb": "0.57.0", + "@opentelemetry/instrumentation-mongoose": "0.51.0", + "@opentelemetry/instrumentation-mysql": "0.50.0", + "@opentelemetry/instrumentation-mysql2": "0.51.0", + "@opentelemetry/instrumentation-pg": "0.57.0", + "@opentelemetry/instrumentation-redis": "0.53.0", + "@opentelemetry/instrumentation-tedious": "0.23.0", + "@opentelemetry/instrumentation-undici": "0.15.0", + "@opentelemetry/resources": "^2.1.0", + "@opentelemetry/sdk-trace-base": "^2.1.0", + "@opentelemetry/semantic-conventions": "^1.37.0", + "@prisma/instrumentation": "6.15.0", + "@sentry/core": "10.25.0", + "@sentry/node-core": "10.25.0", + "@sentry/opentelemetry": "10.25.0", + "import-in-the-middle": "^1.14.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/context-async-hooks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.2.0.tgz", + "integrity": "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/core": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", + "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.204.0.tgz", + "integrity": "sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-http": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.204.0.tgz", + "integrity": "sha512-1afJYyGRA4OmHTv0FfNTrTAzoEjPQUYgd+8ih/lX0LlZBnGio/O80vxA0lN3knsJPS7FiDrsDrWq25K7oAzbkw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.1.0", + "@opentelemetry/instrumentation": "0.204.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.1.0.tgz", + "integrity": "sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/resources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.2.0.tgz", + "integrity": "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.2.0.tgz", + "integrity": "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.2.0", + "@opentelemetry/resources": "2.2.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", + "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/node/node_modules/@sentry/node-core": { + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.25.0.tgz", + "integrity": "sha512-Hk0s7r9pkotZ1yfUc9+XX0ALDQ/bjaYsWF23O2q8Yfc4m8NcQio54ztAmdI+Yf+YiHLpt0x9Hlgwpl3AaRvwIA==", + "license": "MIT", + "dependencies": { + "@apm-js-collab/tracing-hooks": "^0.3.1", + "@sentry/core": "10.25.0", + "@sentry/opentelemetry": "10.25.0", + "import-in-the-middle": "^1.14.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + } + }, + "node_modules/@sentry/node/node_modules/@sentry/opentelemetry": { + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.25.0.tgz", + "integrity": "sha512-AWCRzUIzvI+0RHXTmGvVx+MUtyyjwmC6F6d6XCnWhBKWGO52I+ucz1X8INIZxCrK05dpviFpeLZy+pzfgw892g==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.25.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + } + }, "node_modules/@shikijs/core": { "version": "3.13.0", "dev": true, @@ -9697,6 +11272,15 @@ "@types/deep-eql": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cors": { "version": "2.8.19", "dev": true, @@ -9895,6 +11479,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/nlcst": { "version": "2.0.3", "dev": true, @@ -9919,6 +11512,26 @@ "form-data": "^4.0.4" } }, + "node_modules/@types/pg": { + "version": "8.15.5", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.5.tgz", + "integrity": "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/phoenix": { "version": "1.6.6", "license": "MIT" @@ -9948,6 +11561,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/through": { "version": "0.0.33", "dev": true, @@ -15463,6 +17085,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, "node_modules/fraction.js": { "version": "4.3.7", "dev": true, @@ -22682,6 +24310,37 @@ "dev": true, "license": "MIT" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "license": "ISC" @@ -22901,6 +24560,45 @@ "dev": true, "license": "MIT" }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prebuild-install": { "version": "7.1.3", "dev": true, @@ -27871,6 +29569,15 @@ "node": ">=4.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "license": "ISC", diff --git a/packages/tm-core/src/index.ts b/packages/tm-core/src/index.ts index 4cb66a16..fbeb5bf6 100644 --- a/packages/tm-core/src/index.ts +++ b/packages/tm-core/src/index.ts @@ -82,6 +82,12 @@ export type { } from './modules/auth/types.js'; export { AuthenticationError } from './modules/auth/types.js'; +// Auth constants +export { + LOCAL_ONLY_COMMANDS, + type LocalOnlyCommand +} from './modules/auth/index.js'; + // Brief types export type { Brief } from './modules/briefs/types.js'; export type { TagWithStats } from './modules/briefs/services/brief-service.js'; diff --git a/packages/tm-core/src/modules/auth/auth-domain.ts b/packages/tm-core/src/modules/auth/auth-domain.ts index 74f0bb8f..f2d81e08 100644 --- a/packages/tm-core/src/modules/auth/auth-domain.ts +++ b/packages/tm-core/src/modules/auth/auth-domain.ts @@ -16,6 +16,7 @@ import type { OAuthFlowOptions, UserContext } from './types.js'; +import { checkAuthBlock, type AuthBlockResult } from './command.guard.js'; /** * Display information for storage context @@ -225,6 +226,41 @@ export class AuthDomain { return `${baseUrl}/home/${context.orgSlug}/briefs/create`; } + // ========== Command Guards ========== + + /** + * Check if a local-only command should be blocked when using API storage + * + * Local-only commands (like dependency management) are blocked when authenticated + * with Hamster and using API storage, since Hamster manages these features remotely. + * + * @param commandName - Name of the command to check + * @param storageType - Current storage type being used + * @returns Guard result with blocking decision and context + * + * @example + * ```ts + * const result = await tmCore.auth.guardCommand('add-dependency', tmCore.tasks.getStorageType()); + * if (result.isBlocked) { + * console.log(`Command blocked: ${result.briefName}`); + * } + * ``` + */ + async guardCommand( + commandName: string, + storageType: StorageType + ): Promise { + const hasValidSession = await this.hasValidSession(); + const context = this.getContext(); + + return checkAuthBlock({ + hasValidSession, + briefName: context?.briefName, + storageType, + commandName + }); + } + /** * Get web app base URL from environment configuration * @private diff --git a/packages/tm-core/src/modules/auth/command.guard.ts b/packages/tm-core/src/modules/auth/command.guard.ts new file mode 100644 index 00000000..588208b9 --- /dev/null +++ b/packages/tm-core/src/modules/auth/command.guard.ts @@ -0,0 +1,77 @@ +/** + * @fileoverview Command guard - Core logic for blocking local-only commands + * Pure business logic - no presentation layer concerns + */ + +import type { StorageType } from '../../common/types/index.js'; +import { LOCAL_ONLY_COMMANDS, type LocalOnlyCommand } from './constants.js'; + +/** + * Result from checking if a command should be blocked + */ +export interface AuthBlockResult { + /** Whether the command should be blocked */ + isBlocked: boolean; + /** Brief name if authenticated with Hamster */ + briefName?: string; + /** Command name that was checked */ + commandName: string; +} + +/** + * Check if a command is local-only + */ +export function isLocalOnlyCommand( + commandName: string +): commandName is LocalOnlyCommand { + return LOCAL_ONLY_COMMANDS.includes(commandName as LocalOnlyCommand); +} + +/** + * Parameters for auth block check + */ +export interface AuthBlockParams { + /** Whether user has a valid auth session */ + hasValidSession: boolean; + /** Brief name from auth context */ + briefName?: string; + /** Current storage type being used */ + storageType: StorageType; + /** Command name to check */ + commandName: string; +} + +/** + * Check if a command should be blocked because user is authenticated with Hamster + * + * This is pure business logic with dependency injection - returns data only, no display/formatting + * Presentation layers (CLI, MCP) should format the response appropriately + * + * @param params - Auth block parameters + * @returns AuthBlockResult with blocking decision and context + */ +export function checkAuthBlock(params: AuthBlockParams): AuthBlockResult { + const { hasValidSession, briefName, storageType, commandName } = params; + + // Only check auth for local-only commands + if (!isLocalOnlyCommand(commandName)) { + return { isBlocked: false, commandName }; + } + + // Not authenticated - command is allowed + if (!hasValidSession) { + return { isBlocked: false, commandName }; + } + + // Authenticated but using file storage - command is allowed + if (storageType !== 'api') { + return { isBlocked: false, commandName }; + } + + // User is authenticated AND using API storage - block the command + return { + isBlocked: true, + briefName: briefName || 'remote brief', + commandName + }; +} diff --git a/packages/tm-core/src/modules/auth/constants.ts b/packages/tm-core/src/modules/auth/constants.ts new file mode 100644 index 00000000..81171184 --- /dev/null +++ b/packages/tm-core/src/modules/auth/constants.ts @@ -0,0 +1,18 @@ +/** + * @fileoverview Auth module constants + */ + +/** + * Commands that are only available for local file storage + * These commands are blocked when using Hamster (API storage) + */ +export const LOCAL_ONLY_COMMANDS = [ + 'add-dependency', + 'remove-dependency', + 'validate-dependencies', + 'fix-dependencies', + 'clear-subtasks', + 'models' +] as const; + +export type LocalOnlyCommand = (typeof LOCAL_ONLY_COMMANDS)[number]; diff --git a/packages/tm-core/src/modules/auth/index.ts b/packages/tm-core/src/modules/auth/index.ts index 665b7e3d..99cd5ae8 100644 --- a/packages/tm-core/src/modules/auth/index.ts +++ b/packages/tm-core/src/modules/auth/index.ts @@ -26,3 +26,9 @@ export { DEFAULT_AUTH_CONFIG, getAuthConfig } from './config.js'; + +// Command guard types and utilities +export { isLocalOnlyCommand, type AuthBlockResult } from './command.guard.js'; + +// Auth constants +export { LOCAL_ONLY_COMMANDS, type LocalOnlyCommand } from './constants.js'; diff --git a/scripts/modules/commands.js b/scripts/modules/commands.js index 71e87a5e..9b53534a 100644 --- a/scripts/modules/commands.js +++ b/scripts/modules/commands.js @@ -3,139 +3,142 @@ * Command-line interface for the Task Master CLI */ -import { Command } from 'commander'; -import path from 'path'; -import chalk from 'chalk'; -import boxen from 'boxen'; import fs from 'fs'; +import path from 'path'; +import boxen from 'boxen'; +import chalk from 'chalk'; +import { Command } from 'commander'; import inquirer from 'inquirer'; -import { log, readJSON } from './utils.js'; // Import command registry and utilities from @tm/cli import { - registerAllCommands, checkForUpdate, - performAutoUpdate, - displayUpgradeNotification, - restartWithNewVersion, displayError, + displayUpgradeNotification, + performAutoUpdate, + registerAllCommands, + restartWithNewVersion, runInteractiveSetup } from '@tm/cli'; +import { log, readJSON } from './utils.js'; import { - parsePRD, - updateTasks, - expandTask, - expandAllTasks, - clearSubtasks, - addTask, addSubtask, - removeSubtask, + addTask, analyzeTaskComplexity, - updateTaskById, - updateSubtaskById, - removeTask, + clearSubtasks, + expandAllTasks, + expandTask, findTaskById, - taskExists, - moveTask, migrateProject, - setResponseLanguage, - scopeUpTask, + moveTask, + parsePRD, + removeSubtask, + removeTask, scopeDownTask, + scopeUpTask, + setResponseLanguage, + taskExists, + updateSubtaskById, + updateTaskById, + updateTasks, validateStrength } from './task-manager.js'; import { moveTasksBetweenTags } from './task-manager/move-task.js'; import { + copyTag, createTag, deleteTag, - tags, - useTag, renameTag, - copyTag + tags, + useTag } from './task-manager/tag-management.js'; import { addDependency, + fixDependenciesCommand, removeDependency, - validateDependenciesCommand, - fixDependenciesCommand + validateDependenciesCommand } from './dependency-manager.js'; +import { checkAndBlockIfAuthenticated } from '@tm/cli'; +import { LOCAL_ONLY_COMMANDS } from '@tm/core'; + import { - isApiKeySet, - getDebugFlag, ConfigurationError, - isConfigFilePresent, - getDefaultNumTasks + getDebugFlag, + getDefaultNumTasks, + isApiKeySet, + isConfigFilePresent } from './config-manager.js'; import { CUSTOM_PROVIDERS } from '@tm/core'; import { COMPLEXITY_REPORT_FILE, - TASKMASTER_TASKS_FILE, - TASKMASTER_DOCS_DIR + TASKMASTER_DOCS_DIR, + TASKMASTER_TASKS_FILE } from '../../src/constants/paths.js'; import { initTaskMaster } from '../../src/task-master.js'; -import { - displayBanner, - displayHelp, - displayComplexityReport, - getStatusWithColor, - confirmTaskOverwrite, - startLoadingIndicator, - stopLoadingIndicator, - displayModelConfiguration, - displayAvailableModels, - displayApiKeyStatus, - displayTaggedTasksFYI, - displayCurrentTagIndicator, - displayCrossTagDependencyError, - displaySubtaskMoveError, - displayInvalidTagCombinationError, - displayDependencyValidationHints -} from './ui.js'; import { confirmProfilesRemove, confirmRemoveAllRemainingProfiles } from '../../src/ui/confirm.js'; import { - wouldRemovalLeaveNoProfiles, - getInstalledProfiles + getInstalledProfiles, + wouldRemovalLeaveNoProfiles } from '../../src/utils/profiles.js'; +import { + confirmTaskOverwrite, + displayApiKeyStatus, + displayAvailableModels, + displayBanner, + displayComplexityReport, + displayCrossTagDependencyError, + displayCurrentTagIndicator, + displayDependencyValidationHints, + displayHelp, + displayInvalidTagCombinationError, + displayModelConfiguration, + displaySubtaskMoveError, + displayTaggedTasksFYI, + getStatusWithColor, + startLoadingIndicator, + stopLoadingIndicator +} from './ui.js'; -import { initializeProject } from '../init.js'; -import { - getModelConfiguration, - getAvailableModelsList, - setModel, - getApiKeyStatusReport -} from './task-manager/models.js'; -import { - isValidRulesAction, - RULES_ACTIONS, - RULES_SETUP_ACTION -} from '../../src/constants/rules-actions.js'; -import { getTaskMasterVersion } from '../../src/utils/getVersion.js'; -import { syncTasksToReadme } from './sync-readme.js'; import { RULE_PROFILES } from '../../src/constants/profiles.js'; import { - convertAllRulesToProfileRules, - removeProfileRules, - isValidProfile, - getRulesProfile -} from '../../src/utils/rule-transformer.js'; + RULES_ACTIONS, + RULES_SETUP_ACTION, + isValidRulesAction +} from '../../src/constants/rules-actions.js'; +import { getTaskMasterVersion } from '../../src/utils/getVersion.js'; import { - runInteractiveProfilesSetup, - generateProfileSummary, categorizeProfileResults, + categorizeRemovalResults, generateProfileRemovalSummary, - categorizeRemovalResults + generateProfileSummary, + runInteractiveProfilesSetup } from '../../src/utils/profiles.js'; +import { + convertAllRulesToProfileRules, + getRulesProfile, + isValidProfile, + removeProfileRules +} from '../../src/utils/rule-transformer.js'; +import { initializeProject } from '../init.js'; +import { syncTasksToReadme } from './sync-readme.js'; +import { + getApiKeyStatusReport, + getAvailableModelsList, + getModelConfiguration, + setModel +} from './task-manager/models.js'; /** * Configure and register CLI commands @@ -154,6 +157,23 @@ function registerCommands(programInstance) { process.exit(1); }); + // Add global command guard for local-only commands + programInstance.hook('preAction', async (thisCommand, actionCommand) => { + const commandName = actionCommand.name(); + + // Only check if it's a local-only command + if (LOCAL_ONLY_COMMANDS.includes(commandName)) { + const taskMaster = initTaskMaster(actionCommand.opts()); + const isBlocked = await checkAndBlockIfAuthenticated( + commandName, + taskMaster.getProjectRoot() + ); + if (isBlocked) { + process.exit(1); + } + } + }); + // parse-prd command programInstance .command('parse-prd')