@specforge/canary-cli 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ function registerDebugCommands(program) {
9
9
  `
10
10
  Examples:
11
11
  $ specforge call list_projects
12
- $ specforge call get_ticket --args='{"ticketId":"abc123"}'
12
+ $ specforge call get --args='{"type":"ticket","id":"abc123"}'
13
13
  $ specforge call list_tickets --format toon
14
14
  $ specforge call get_specification --args='{"specificationId":"spec-1"}' --raw
15
15
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/cli/commands/debug/register.ts"],"sourcesContent":["/**\n * Debug Command Registration\n *\n * Registers all debug commands with the CLI framework.\n */\n\nimport { Command } from 'commander';\nimport { withErrorHandler } from '../../middleware/error-handler.js';\nimport { callCommand } from './call.js';\nimport { toolsCommand } from './tools.js';\nimport { testCommand } from './test.js';\nimport { whoamiCommand } from './whoami.js';\nimport type { CallOptions, ToolsOptions, WhoamiOptions } from './types.js';\n\n/**\n * Register all debug commands with the CLI\n */\nexport function registerDebugCommands(program: Command): void {\n // Call command - directly call MCP tools\n program\n .command('call <tool>')\n .description('Directly call an MCP tool')\n .option('--args <json>', 'Tool arguments as JSON')\n .option('--format <format>', 'Output format (json, toon)', 'json')\n .option('--raw', 'Show raw API response')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge call list_projects\n $ specforge call get_ticket --args='{\"ticketId\":\"abc123\"}'\n $ specforge call list_tickets --format toon\n $ specforge call get_specification --args='{\"specificationId\":\"spec-1\"}' --raw\n\nThe call command allows you to directly invoke MCP tools with JSON arguments.\nThis is useful for testing, debugging, and scripting. Output can be formatted\nas JSON (default), TOON, or raw API response.\n`\n )\n .action(\n withErrorHandler(async (tool: string, options: CallOptions) => {\n await callCommand(tool, options);\n })\n );\n\n // Tools command - list available MCP tools\n program\n .command('tools')\n .description('List available MCP tools')\n .option('--category <category>', 'Filter by category')\n .option('--search <query>', 'Search tool names/descriptions')\n .option('--json', 'Output as JSON')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge tools\n $ specforge tools --category context\n $ specforge tools --search ticket\n $ specforge tools --json\n\nThe tools command lists all available MCP tools grouped by category.\nUse filters to narrow down the list. This command doesn't require\nauthentication since it lists locally defined tools.\n`\n )\n .action(\n withErrorHandler(async (options: ToolsOptions) => {\n await toolsCommand(options);\n })\n );\n\n // Test command - test API connection\n program\n .command('test')\n .description('Test API connection and authentication')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge test\n\nThe test command verifies your API connection and authentication.\nIt displays response time, user information, and accessible projects.\nHelpful error messages are provided for common connection issues.\n`\n )\n .action(\n withErrorHandler(async () => {\n await testCommand();\n })\n );\n\n // Whoami command - show current user and config\n program\n .command('whoami')\n .description('Show current user and configuration')\n .option('--json', 'Output as JSON')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge whoami\n $ specforge whoami --json\n\nThe whoami command displays your current user information, configuration\nsettings, and config file paths. Useful for debugging authentication and\nconfiguration issues.\n`\n )\n .action(\n withErrorHandler(async (options: WhoamiOptions) => {\n await whoamiCommand(options);\n })\n );\n}\n"],"mappings":"AAOA,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAMvB,SAAS,sBAAsB,SAAwB;AAE5D,UACG,QAAQ,aAAa,EACrB,YAAY,2BAA2B,EACvC,OAAO,iBAAiB,wBAAwB,EAChD,OAAO,qBAAqB,8BAA8B,MAAM,EAChE,OAAO,SAAS,uBAAuB,EACvC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWF,EACC;AAAA,IACC,iBAAiB,OAAO,MAAc,YAAyB;AAC7D,YAAM,YAAY,MAAM,OAAO;AAAA,IACjC,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,OAAO,EACf,YAAY,0BAA0B,EACtC,OAAO,yBAAyB,oBAAoB,EACpD,OAAO,oBAAoB,gCAAgC,EAC3D,OAAO,UAAU,gBAAgB,EACjC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWF,EACC;AAAA,IACC,iBAAiB,OAAO,YAA0B;AAChD,YAAM,aAAa,OAAO;AAAA,IAC5B,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQF,EACC;AAAA,IACC,iBAAiB,YAAY;AAC3B,YAAM,YAAY;AAAA,IACpB,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,QAAQ,EAChB,YAAY,qCAAqC,EACjD,OAAO,UAAU,gBAAgB,EACjC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASF,EACC;AAAA,IACC,iBAAiB,OAAO,YAA2B;AACjD,YAAM,cAAc,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/cli/commands/debug/register.ts"],"sourcesContent":["/**\n * Debug Command Registration\n *\n * Registers all debug commands with the CLI framework.\n */\n\nimport { Command } from 'commander';\nimport { withErrorHandler } from '../../middleware/error-handler.js';\nimport { callCommand } from './call.js';\nimport { toolsCommand } from './tools.js';\nimport { testCommand } from './test.js';\nimport { whoamiCommand } from './whoami.js';\nimport type { CallOptions, ToolsOptions, WhoamiOptions } from './types.js';\n\n/**\n * Register all debug commands with the CLI\n */\nexport function registerDebugCommands(program: Command): void {\n // Call command - directly call MCP tools\n program\n .command('call <tool>')\n .description('Directly call an MCP tool')\n .option('--args <json>', 'Tool arguments as JSON')\n .option('--format <format>', 'Output format (json, toon)', 'json')\n .option('--raw', 'Show raw API response')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge call list_projects\n $ specforge call get --args='{\"type\":\"ticket\",\"id\":\"abc123\"}'\n $ specforge call list_tickets --format toon\n $ specforge call get_specification --args='{\"specificationId\":\"spec-1\"}' --raw\n\nThe call command allows you to directly invoke MCP tools with JSON arguments.\nThis is useful for testing, debugging, and scripting. Output can be formatted\nas JSON (default), TOON, or raw API response.\n`\n )\n .action(\n withErrorHandler(async (tool: string, options: CallOptions) => {\n await callCommand(tool, options);\n })\n );\n\n // Tools command - list available MCP tools\n program\n .command('tools')\n .description('List available MCP tools')\n .option('--category <category>', 'Filter by category')\n .option('--search <query>', 'Search tool names/descriptions')\n .option('--json', 'Output as JSON')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge tools\n $ specforge tools --category context\n $ specforge tools --search ticket\n $ specforge tools --json\n\nThe tools command lists all available MCP tools grouped by category.\nUse filters to narrow down the list. This command doesn't require\nauthentication since it lists locally defined tools.\n`\n )\n .action(\n withErrorHandler(async (options: ToolsOptions) => {\n await toolsCommand(options);\n })\n );\n\n // Test command - test API connection\n program\n .command('test')\n .description('Test API connection and authentication')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge test\n\nThe test command verifies your API connection and authentication.\nIt displays response time, user information, and accessible projects.\nHelpful error messages are provided for common connection issues.\n`\n )\n .action(\n withErrorHandler(async () => {\n await testCommand();\n })\n );\n\n // Whoami command - show current user and config\n program\n .command('whoami')\n .description('Show current user and configuration')\n .option('--json', 'Output as JSON')\n .addHelpText(\n 'after',\n `\nExamples:\n $ specforge whoami\n $ specforge whoami --json\n\nThe whoami command displays your current user information, configuration\nsettings, and config file paths. Useful for debugging authentication and\nconfiguration issues.\n`\n )\n .action(\n withErrorHandler(async (options: WhoamiOptions) => {\n await whoamiCommand(options);\n })\n );\n}\n"],"mappings":"AAOA,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAMvB,SAAS,sBAAsB,SAAwB;AAE5D,UACG,QAAQ,aAAa,EACrB,YAAY,2BAA2B,EACvC,OAAO,iBAAiB,wBAAwB,EAChD,OAAO,qBAAqB,8BAA8B,MAAM,EAChE,OAAO,SAAS,uBAAuB,EACvC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWF,EACC;AAAA,IACC,iBAAiB,OAAO,MAAc,YAAyB;AAC7D,YAAM,YAAY,MAAM,OAAO;AAAA,IACjC,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,OAAO,EACf,YAAY,0BAA0B,EACtC,OAAO,yBAAyB,oBAAoB,EACpD,OAAO,oBAAoB,gCAAgC,EAC3D,OAAO,UAAU,gBAAgB,EACjC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWF,EACC;AAAA,IACC,iBAAiB,OAAO,YAA0B;AAChD,YAAM,aAAa,OAAO;AAAA,IAC5B,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQF,EACC;AAAA,IACC,iBAAiB,YAAY;AAC3B,YAAM,YAAY;AAAA,IACpB,CAAC;AAAA,EACH;AAGF,UACG,QAAQ,QAAQ,EAChB,YAAY,qCAAqC,EACjD,OAAO,UAAU,gBAAgB,EACjC;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASF,EACC;AAAA,IACC,iBAAiB,OAAO,YAA2B;AACjD,YAAM,cAAc,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AACJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/debug/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,gCAAgC;IAChC,aAAa,EAAE,iBAAiB,CAAC;IACjC,+BAA+B;IAC/B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cA+B7B,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/debug/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,gCAAgC;IAChC,aAAa,EAAE,iBAAiB,CAAC;IACjC,+BAA+B;IAC/B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cA8B7B,CAAC"}
@@ -11,7 +11,6 @@ const TOOL_CATEGORIES = {
11
11
  "create_epic",
12
12
  "update_epic",
13
13
  "list_tickets",
14
- "get_ticket",
15
14
  "create_ticket",
16
15
  "update_ticket",
17
16
  "search_tickets"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/cli/commands/debug/types.ts"],"sourcesContent":["/**\n * Debug Command Types & Interfaces\n *\n * Type definitions for debug commands including call, tools, test, and whoami.\n */\n\n/**\n * Options for the call command\n */\nexport interface CallOptions {\n /** Tool arguments as JSON string */\n args?: string;\n /** Output format (json, toon) */\n format?: 'json' | 'toon';\n /** Show raw API response */\n raw?: boolean;\n}\n\n/**\n * Options for the tools command\n */\nexport interface ToolsOptions {\n /** Filter by category */\n category?: string;\n /** Search tool names/descriptions */\n search?: string;\n /** Output as JSON */\n json?: boolean;\n}\n\n/**\n * Tool information structure\n */\nexport interface ToolInfo {\n /** Tool name */\n name: string;\n /** Tool description */\n description: string;\n /** Tool category */\n category: string;\n}\n\n/**\n * Tool categories mapping\n */\nexport type ToolCategories = Record<string, string[]>;\n\n/**\n * Options for the whoami command\n */\nexport interface WhoamiOptions {\n /** Output as JSON */\n json?: boolean;\n}\n\n/**\n * User information structure\n */\nexport interface UserInfo {\n /** User display name */\n name?: string;\n /** User email address */\n email: string;\n /** Masked API key */\n apiKey: string;\n}\n\n/**\n * Configuration information structure\n */\nexport interface ConfigurationInfo {\n /** Configuration source (environment, global, project) */\n source: string;\n /** Current project ID if set */\n projectId?: string;\n /** Current project name if set */\n projectName?: string;\n /** Current specification ID if set */\n specificationId?: string;\n /** Current specification title if set */\n specificationTitle?: string;\n /** Resolved local MCP response encoding (json or toon) */\n mcpOutputFormat: string;\n}\n\n/**\n * Configuration file paths\n */\nexport interface ConfigPaths {\n /** Project config path (.specforge.json) */\n projectConfig: string;\n /** MCP config path (.mcp.json) */\n mcpConfig: string;\n /** Global config path (~/.specforge/config.json) */\n globalConfig: string;\n}\n\n/**\n * Full whoami information structure\n */\nexport interface WhoamiInfo {\n /** User information */\n user: UserInfo;\n /** Configuration information */\n configuration: ConfigurationInfo;\n /** Configuration file paths */\n paths: ConfigPaths;\n}\n\n/**\n * Test command result\n */\nexport interface TestResult {\n /** Whether connection was successful */\n success: boolean;\n /** Response time in milliseconds */\n responseTime?: number;\n /** User email from API */\n userEmail?: string;\n /** Number of accessible projects */\n projectCount?: number;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Default tool categories\n */\nexport const TOOL_CATEGORIES: ToolCategories = {\n 'Core Operations': [\n 'list_projects',\n 'get_project',\n 'list_specifications',\n 'get_specification',\n 'create_specification',\n 'update_specification',\n 'list_epics',\n 'get_epic',\n 'create_epic',\n 'update_epic',\n 'list_tickets',\n 'get_ticket',\n 'create_ticket',\n 'update_ticket',\n 'search_tickets',\n ],\n 'Context & AI': [\n 'get_working_context',\n 'set_working_context',\n 'get_implementation_context',\n 'get_full_context',\n 'get_pattern_chain',\n ],\n 'Sessions & Workflow': [\n 'start_ticket',\n 'complete_ticket',\n 'update_ticket_progress',\n ],\n Validation: ['validate_ticket', 'validate_acceptance_criteria'],\n};\n"],"mappings":"AAgIO,MAAM,kBAAkC;AAAA,EAC7C,mBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,uBAAuB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,YAAY,CAAC,mBAAmB,8BAA8B;AAChE;","names":[]}
1
+ {"version":3,"sources":["../../../../src/cli/commands/debug/types.ts"],"sourcesContent":["/**\n * Debug Command Types & Interfaces\n *\n * Type definitions for debug commands including call, tools, test, and whoami.\n */\n\n/**\n * Options for the call command\n */\nexport interface CallOptions {\n /** Tool arguments as JSON string */\n args?: string;\n /** Output format (json, toon) */\n format?: 'json' | 'toon';\n /** Show raw API response */\n raw?: boolean;\n}\n\n/**\n * Options for the tools command\n */\nexport interface ToolsOptions {\n /** Filter by category */\n category?: string;\n /** Search tool names/descriptions */\n search?: string;\n /** Output as JSON */\n json?: boolean;\n}\n\n/**\n * Tool information structure\n */\nexport interface ToolInfo {\n /** Tool name */\n name: string;\n /** Tool description */\n description: string;\n /** Tool category */\n category: string;\n}\n\n/**\n * Tool categories mapping\n */\nexport type ToolCategories = Record<string, string[]>;\n\n/**\n * Options for the whoami command\n */\nexport interface WhoamiOptions {\n /** Output as JSON */\n json?: boolean;\n}\n\n/**\n * User information structure\n */\nexport interface UserInfo {\n /** User display name */\n name?: string;\n /** User email address */\n email: string;\n /** Masked API key */\n apiKey: string;\n}\n\n/**\n * Configuration information structure\n */\nexport interface ConfigurationInfo {\n /** Configuration source (environment, global, project) */\n source: string;\n /** Current project ID if set */\n projectId?: string;\n /** Current project name if set */\n projectName?: string;\n /** Current specification ID if set */\n specificationId?: string;\n /** Current specification title if set */\n specificationTitle?: string;\n /** Resolved local MCP response encoding (json or toon) */\n mcpOutputFormat: string;\n}\n\n/**\n * Configuration file paths\n */\nexport interface ConfigPaths {\n /** Project config path (.specforge.json) */\n projectConfig: string;\n /** MCP config path (.mcp.json) */\n mcpConfig: string;\n /** Global config path (~/.specforge/config.json) */\n globalConfig: string;\n}\n\n/**\n * Full whoami information structure\n */\nexport interface WhoamiInfo {\n /** User information */\n user: UserInfo;\n /** Configuration information */\n configuration: ConfigurationInfo;\n /** Configuration file paths */\n paths: ConfigPaths;\n}\n\n/**\n * Test command result\n */\nexport interface TestResult {\n /** Whether connection was successful */\n success: boolean;\n /** Response time in milliseconds */\n responseTime?: number;\n /** User email from API */\n userEmail?: string;\n /** Number of accessible projects */\n projectCount?: number;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Default tool categories\n */\nexport const TOOL_CATEGORIES: ToolCategories = {\n 'Core Operations': [\n 'list_projects',\n 'get_project',\n 'list_specifications',\n 'get_specification',\n 'create_specification',\n 'update_specification',\n 'list_epics',\n 'get_epic',\n 'create_epic',\n 'update_epic',\n 'list_tickets',\n 'create_ticket',\n 'update_ticket',\n 'search_tickets',\n ],\n 'Context & AI': [\n 'get_working_context',\n 'set_working_context',\n 'get_implementation_context',\n 'get_full_context',\n 'get_pattern_chain',\n ],\n 'Sessions & Workflow': [\n 'start_ticket',\n 'complete_ticket',\n 'update_ticket_progress',\n ],\n Validation: ['validate_ticket', 'validate_acceptance_criteria'],\n};\n"],"mappings":"AAgIO,MAAM,kBAAkC;AAAA,EAC7C,mBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,uBAAuB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,YAAY,CAAC,mBAAmB,8BAA8B;AAChE;","names":[]}
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Template for committing changes with SpecForge ticket metadata.
5
5
  */
6
- export declare const SF_COMMIT_CONTENT = "# Commit Changes (SpecForge)\n\nCreate a git commit with SpecForge ticket metadata.\n\n## Arguments\n- `$ARGUMENTS` - Optional: Ticket ID (uses context if not provided)\n\n## Task\n\n### 1. Get Ticket Context\n\n**MCP Calls:**\n```typescript\nif ($ARGUMENTS) {\n get_ticket({ ticketId: $ARGUMENTS })\n} else {\n // Read active ticket from .specforge.json or find active ticket\n const config = readFile('.specforge.json')\n const specificationId = config.activeSpecification?.id\n // Find the currently active ticket\n list_tickets({ specificationId, status: [\"active\"] })\n // Use the active ticket\n get_ticket({ ticketId: activeTicket.id })\n}\n```\n\n### 2. Generate Commit Message\n\n**Logic:**\n- Format: `feat(scope): description (TICKET-ID)`\n- Extract scope from epic\n- Use ticket title as description\n- Add ticket ID reference\n\n### 3. Create Commit\n\n**Shell:**\n```bash\ngit add .\ngit commit -m \"{type}({scope}): {description} ({ticketId})\"\n```\n\n### 4. Update Ticket Status\n\n**MCP Calls:**\n```typescript\ncomplete_work_session({\n ticketId: ticket.id\n})\n```\n\n### 5. Display Commit Result\n\n**Output:**\n```\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nCOMMIT CREATED\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nTicket: E{n}-T{m}\nMessage: {commitMessage}\nHash: {commitHash}\n\nTICKET COMPLETED\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2713 E{n}-T{m} marked as done\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\nNext: Run /sf-next for the next ticket\n```\n\n## Notes\n- Automatically completes the work session\n- Uses conventional commit format\n- Includes ticket ID for traceability\n";
6
+ export declare const SF_COMMIT_CONTENT = "# Commit Changes (SpecForge)\n\nCreate a git commit with SpecForge ticket metadata.\n\n## Arguments\n- `$ARGUMENTS` - Optional: Ticket ID (uses context if not provided)\n\n## Task\n\n### 1. Get Ticket Context\n\n**MCP Calls:**\n```typescript\nif ($ARGUMENTS) {\n get({ type: 'ticket', id: $ARGUMENTS })\n} else {\n // Read active ticket from .specforge.json or find active ticket\n const config = readFile('.specforge.json')\n const specificationId = config.activeSpecification?.id\n // Find the currently active ticket\n list_tickets({ specificationId, status: [\"active\"] })\n // Use the active ticket\n get({ type: 'ticket', id: activeTicket.id })\n}\n```\n\n### 2. Generate Commit Message\n\n**Logic:**\n- Format: `feat(scope): description (TICKET-ID)`\n- Extract scope from epic\n- Use ticket title as description\n- Add ticket ID reference\n\n### 3. Create Commit\n\n**Shell:**\n```bash\ngit add .\ngit commit -m \"{type}({scope}): {description} ({ticketId})\"\n```\n\n### 4. Update Ticket Status\n\n**MCP Calls:**\n```typescript\ncomplete_work_session({\n ticketId: ticket.id\n})\n```\n\n### 5. Display Commit Result\n\n**Output:**\n```\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nCOMMIT CREATED\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nTicket: E{n}-T{m}\nMessage: {commitMessage}\nHash: {commitHash}\n\nTICKET COMPLETED\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\u2713 E{n}-T{m} marked as done\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\nNext: Run /sf-next for the next ticket\n```\n\n## Notes\n- Automatically completes the work session\n- Uses conventional commit format\n- Includes ticket ID for traceability\n";
7
7
  //# sourceMappingURL=sf-commit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sf-commit.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/content/sf-commit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,iBAAiB,+sFA0E7B,CAAC"}
1
+ {"version":3,"file":"sf-commit.d.ts","sourceRoot":"","sources":["../../../../src/cli/templates/content/sf-commit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,iBAAiB,qtFA0E7B,CAAC"}
@@ -12,7 +12,7 @@ Create a git commit with SpecForge ticket metadata.
12
12
  **MCP Calls:**
13
13
  \`\`\`typescript
14
14
  if ($ARGUMENTS) {
15
- get_ticket({ ticketId: $ARGUMENTS })
15
+ get({ type: 'ticket', id: $ARGUMENTS })
16
16
  } else {
17
17
  // Read active ticket from .specforge.json or find active ticket
18
18
  const config = readFile('.specforge.json')
@@ -20,7 +20,7 @@ if ($ARGUMENTS) {
20
20
  // Find the currently active ticket
21
21
  list_tickets({ specificationId, status: ["active"] })
22
22
  // Use the active ticket
23
- get_ticket({ ticketId: activeTicket.id })
23
+ get({ type: 'ticket', id: activeTicket.id })
24
24
  }
25
25
  \`\`\`
26
26
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/cli/templates/content/sf-commit.ts"],"sourcesContent":["/**\n * SF-Commit Command Template\n *\n * Template for committing changes with SpecForge ticket metadata.\n */\n\nexport const SF_COMMIT_CONTENT = `# Commit Changes (SpecForge)\n\nCreate a git commit with SpecForge ticket metadata.\n\n## Arguments\n- \\`$ARGUMENTS\\` - Optional: Ticket ID (uses context if not provided)\n\n## Task\n\n### 1. Get Ticket Context\n\n**MCP Calls:**\n\\`\\`\\`typescript\nif ($ARGUMENTS) {\n get_ticket({ ticketId: $ARGUMENTS })\n} else {\n // Read active ticket from .specforge.json or find active ticket\n const config = readFile('.specforge.json')\n const specificationId = config.activeSpecification?.id\n // Find the currently active ticket\n list_tickets({ specificationId, status: [\"active\"] })\n // Use the active ticket\n get_ticket({ ticketId: activeTicket.id })\n}\n\\`\\`\\`\n\n### 2. Generate Commit Message\n\n**Logic:**\n- Format: \\`feat(scope): description (TICKET-ID)\\`\n- Extract scope from epic\n- Use ticket title as description\n- Add ticket ID reference\n\n### 3. Create Commit\n\n**Shell:**\n\\`\\`\\`bash\ngit add .\ngit commit -m \"{type}({scope}): {description} ({ticketId})\"\n\\`\\`\\`\n\n### 4. Update Ticket Status\n\n**MCP Calls:**\n\\`\\`\\`typescript\ncomplete_work_session({\n ticketId: ticket.id\n})\n\\`\\`\\`\n\n### 5. Display Commit Result\n\n**Output:**\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nCOMMIT CREATED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nTicket: E{n}-T{m}\nMessage: {commitMessage}\nHash: {commitHash}\n\nTICKET COMPLETED\n─────────────────────────────────────────────────────────────────\n✓ E{n}-T{m} marked as done\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nNext: Run /sf-next for the next ticket\n\\`\\`\\`\n\n## Notes\n- Automatically completes the work session\n- Uses conventional commit format\n- Includes ticket ID for traceability\n`;\n"],"mappings":"AAMO,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../../src/cli/templates/content/sf-commit.ts"],"sourcesContent":["/**\n * SF-Commit Command Template\n *\n * Template for committing changes with SpecForge ticket metadata.\n */\n\nexport const SF_COMMIT_CONTENT = `# Commit Changes (SpecForge)\n\nCreate a git commit with SpecForge ticket metadata.\n\n## Arguments\n- \\`$ARGUMENTS\\` - Optional: Ticket ID (uses context if not provided)\n\n## Task\n\n### 1. Get Ticket Context\n\n**MCP Calls:**\n\\`\\`\\`typescript\nif ($ARGUMENTS) {\n get({ type: 'ticket', id: $ARGUMENTS })\n} else {\n // Read active ticket from .specforge.json or find active ticket\n const config = readFile('.specforge.json')\n const specificationId = config.activeSpecification?.id\n // Find the currently active ticket\n list_tickets({ specificationId, status: [\"active\"] })\n // Use the active ticket\n get({ type: 'ticket', id: activeTicket.id })\n}\n\\`\\`\\`\n\n### 2. Generate Commit Message\n\n**Logic:**\n- Format: \\`feat(scope): description (TICKET-ID)\\`\n- Extract scope from epic\n- Use ticket title as description\n- Add ticket ID reference\n\n### 3. Create Commit\n\n**Shell:**\n\\`\\`\\`bash\ngit add .\ngit commit -m \"{type}({scope}): {description} ({ticketId})\"\n\\`\\`\\`\n\n### 4. Update Ticket Status\n\n**MCP Calls:**\n\\`\\`\\`typescript\ncomplete_work_session({\n ticketId: ticket.id\n})\n\\`\\`\\`\n\n### 5. Display Commit Result\n\n**Output:**\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nCOMMIT CREATED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nTicket: E{n}-T{m}\nMessage: {commitMessage}\nHash: {commitHash}\n\nTICKET COMPLETED\n─────────────────────────────────────────────────────────────────\n✓ E{n}-T{m} marked as done\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nNext: Run /sf-next for the next ticket\n\\`\\`\\`\n\n## Notes\n- Automatically completes the work session\n- Uses conventional commit format\n- Includes ticket ID for traceability\n`;\n"],"mappings":"AAMO,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
@@ -82,7 +82,7 @@ const CREATION_WORKFLOW = {
82
82
  },
83
83
  {
84
84
  step: 7,
85
- name: "add_dependencies",
85
+ name: "create_dependencies",
86
86
  description: "Link ticket to its dependencies",
87
87
  tools: ["dependency.add"],
88
88
  tips: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/workflow-definitions.ts"],"sourcesContent":["// mcp/src/lib/workflow-definitions.ts\n/**\n * Workflow Definitions\n *\n * Contains the workflow definitions as data structures for guiding AI agents\n * through SpecForge workflows.\n */\n\nexport interface WorkflowStep {\n step: number;\n name: string;\n description: string;\n tools: string[];\n tips: string[];\n}\n\nexport interface WorkflowDefinition {\n name: string;\n description: string;\n philosophy: string[];\n steps: WorkflowStep[];\n antiPatterns: string[];\n}\n\nexport interface ReviewChecklistItem {\n name: string;\n description: string;\n}\n\nexport interface ReviewWorkflowDefinition extends WorkflowDefinition {\n checklist: ReviewChecklistItem[];\n}\n\nexport interface FinalizeWorkflowDefinition extends WorkflowDefinition {\n prerequisites: string[];\n}\n\nexport const CREATION_WORKFLOW: WorkflowDefinition = {\n name: 'creation',\n description: 'Create specifications, epics, and tickets with rich context',\n philosophy: [\n 'One entity at a time - never bulk create',\n 'More context = better AI implementation',\n 'When in doubt, ask the user',\n 'Invest in planning for first-run success',\n ],\n steps: [\n {\n step: 1,\n name: 'understand_requirements',\n description: 'Gather comprehensive requirements from user',\n tools: [],\n tips: [\n 'Ask about the problem being solved',\n 'Understand the target users',\n 'Clarify scope boundaries',\n 'Identify constraints and risks',\n ],\n },\n {\n step: 2,\n name: 'create_specification',\n description: 'Create specification with full context',\n tools: ['specification.create'],\n tips: [\n 'Include background and goals',\n 'Define guardrails (what NOT to do)',\n 'Set codeStandards for consistency',\n 'Add architecture overview',\n ],\n },\n {\n step: 3,\n name: 'plan_epics',\n description: 'Identify logical phases/groupings, discuss with user',\n tools: [],\n tips: [\n 'Break work into cohesive units',\n 'Consider dependencies between phases',\n 'Discuss timeline and priority with user',\n 'Keep epic count manageable (3-7 typical)',\n ],\n },\n {\n step: 4,\n name: 'create_epic',\n description: 'Create ONE epic with full context',\n tools: ['epic.create'],\n tips: [\n 'Define clear objective',\n 'Set scope boundaries',\n 'Include sharedPatterns for consistency',\n 'Add any epic-specific guardrails',\n ],\n },\n {\n step: 5,\n name: 'plan_tickets',\n description: 'Break epic into tickets, discuss dependencies with user',\n tools: [],\n tips: [\n 'Keep tickets small and focused',\n 'Identify clear acceptance criteria',\n 'Map out dependencies before creating',\n 'Discuss complexity with user',\n ],\n },\n {\n step: 6,\n name: 'create_ticket',\n description: 'Create ONE ticket with full details',\n tools: ['ticket.create'],\n tips: [\n 'Write detailed acceptanceCriteria',\n 'Include implementation hints',\n 'Add technicalDetails for complex logic',\n 'Specify files to modify if known',\n ],\n },\n {\n step: 7,\n name: 'add_dependencies',\n description: 'Link ticket to its dependencies',\n tools: ['dependency.add'],\n tips: [\n 'Only add true blocking dependencies',\n 'Avoid circular dependency chains',\n 'Keep dependency graph shallow when possible',\n ],\n },\n {\n step: 8,\n name: 'repeat',\n description: 'Continue tickets for current epic, then next epic',\n tools: [],\n tips: [\n 'Complete all tickets for an epic before moving on',\n 'Review epic completion before starting next',\n 'Adjust estimates as you learn more',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER use bulk creation - always one at a time',\n 'NEVER skip asking user when details are unclear',\n 'NEVER create tickets without acceptance criteria',\n 'NEVER proceed without understanding dependencies',\n ],\n};\n\nexport const IMPLEMENTATION_WORKFLOW: WorkflowDefinition = {\n name: 'implementation',\n description: 'Implement tickets with session management',\n philosophy: [\n 'Always get full context before starting',\n 'Start session before making changes',\n 'Report progress during implementation',\n 'Validate before completing',\n ],\n steps: [\n {\n step: 1,\n name: 'get_context',\n description: 'Understand current working context',\n tools: ['context.working'],\n tips: [\n 'Check for active sessions',\n 'Note the current specification/epic focus',\n 'Understand what has already been done',\n ],\n },\n {\n step: 2,\n name: 'check_session',\n description: 'Check if spec has an open session',\n tools: ['context.working'],\n tips: [\n 'If session exists, continue with that session ID',\n 'If no session, will start new one after selecting ticket',\n 'Only ONE session per spec at a time',\n ],\n },\n {\n step: 3,\n name: 'find_work',\n description: 'Find tickets ready to work on',\n tools: ['workflow.next_actionable'],\n tips: [\n 'Focus on unblocked tickets',\n 'Consider priority and complexity',\n 'Check if any tickets are already in progress',\n ],\n },\n {\n step: 4,\n name: 'review_ticket',\n description: 'Get full implementation context',\n tools: ['context.implementation'],\n tips: [\n 'Use depth=full for rich context',\n 'Read all related patterns',\n 'Understand acceptance criteria',\n ],\n },\n {\n step: 5,\n name: 'clarify',\n description: 'Ask user about unclear requirements',\n tools: [],\n tips: [\n 'ASK THE USER before proceeding if unclear',\n 'Confirm test environment preference',\n 'Verify any assumptions',\n ],\n },\n {\n step: 6,\n name: 'start_session',\n description: 'Start or continue implementation session',\n tools: ['session.start'],\n tips: [\n 'Session locks the specification',\n 'Prevents concurrent work conflicts',\n 'Tracks your progress and changes',\n ],\n },\n {\n step: 7,\n name: 'implement',\n description: 'Do the work, report progress',\n tools: ['session.progress'],\n tips: [\n 'Follow the patterns from context',\n 'Report meaningful progress updates',\n 'Commit logically grouped changes',\n ],\n },\n {\n step: 8,\n name: 'validate',\n description: 'Run tests, lint, typecheck',\n tools: [],\n tips: [\n 'Run validation as specified in ticket',\n 'Fix any failing tests before completing',\n 'Ensure no regressions',\n ],\n },\n {\n step: 9,\n name: 'complete_ticket',\n description: 'Complete the ticket with summary',\n tools: ['session.complete'],\n tips: [\n 'Include summary of what was done',\n 'Report validation results',\n 'Note any follow-up items',\n ],\n },\n {\n step: 10,\n name: 'repeat_tickets',\n description: 'Continue with next ticket in epic',\n tools: ['workflow.next_actionable'],\n tips: [\n 'Check what tickets are now unblocked',\n 'Continue until epic is complete',\n 'Then proceed to epic completion',\n ],\n },\n {\n step: 11,\n name: 'epic_review',\n description: 'Review all changes made in epic',\n tools: ['epic.get'],\n tips: [\n 'Check all tickets are done',\n 'Review integration between tickets',\n 'Run full test suite for epic scope',\n 'Check for regressions',\n ],\n },\n {\n step: 12,\n name: 'epic_commit',\n description: 'Create commit for the epic',\n tools: [],\n tips: [\n 'Stage all changes from epic tickets',\n 'Write descriptive commit message referencing epic',\n 'Include ticket numbers in commit',\n ],\n },\n {\n step: 13,\n name: 'next_epic',\n description: 'Move to next epic',\n tools: ['epic.list', 'workflow.next_actionable'],\n tips: [\n 'Find the next epic to work on',\n 'Repeat from step 3 (find_work)',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER implement without reading full ticket context',\n 'NEVER skip session.start - it tracks your work',\n 'NEVER complete without running validation',\n 'NEVER assume - ask the user if unclear',\n ],\n};\n\nexport const REVIEW_WORKFLOW: ReviewWorkflowDefinition = {\n name: 'review',\n description: 'Review tickets for completeness and consistency before implementation',\n philosophy: [\n 'Catch issues before implementation, not during',\n 'Consistency across all layers (DB, API, types)',\n 'Always ask about test environment preference',\n 'Document findings in ticket notes',\n ],\n checklist: [\n { name: 'missing_points', description: 'Acceptance criteria complete? Edge cases?' },\n { name: 'blind_spots', description: 'Security implications? What could go wrong?' },\n { name: 'auth_patterns', description: 'Token handling? Permission checks?' },\n { name: 'db_permissions', description: 'Row-level security? Audit requirements?' },\n { name: 'field_naming', description: 'DB (snake_case) <-> API (camelCase) <-> Types match?' },\n { name: 'documentation', description: 'API docs? README? Architecture docs need update?' },\n { name: 'test_environment', description: 'ASK USER: Sandbox or local mocks?' },\n ],\n steps: [\n {\n step: 1,\n name: 'select_ticket',\n description: 'Choose ticket to review',\n tools: ['ticket.get', 'workflow.next_actionable'],\n tips: [\n 'Review tickets before they are implemented',\n 'Can review all pending tickets in an epic',\n ],\n },\n {\n step: 2,\n name: 'load_context',\n description: 'Get full implementation context with patterns',\n tools: ['context.implementation'],\n tips: [\n 'Use depth=full for comprehensive review',\n 'Understand the broader context',\n ],\n },\n {\n step: 3,\n name: 'run_checklist',\n description: 'Go through each review point systematically',\n tools: [],\n tips: [\n 'Check each item in the review checklist',\n 'Be thorough - issues found now save time later',\n ],\n },\n {\n step: 4,\n name: 'identify_gaps',\n description: 'List missing items, inconsistencies, concerns',\n tools: [],\n tips: [\n 'Document all findings',\n 'Prioritize by impact',\n 'Note any blocking issues',\n ],\n },\n {\n step: 5,\n name: 'ask_user',\n description: 'Clarify test environment preference',\n tools: [],\n tips: [\n 'ALWAYS ask about test environment',\n 'Sandbox (real services) vs local mocks',\n 'Document the decision',\n ],\n },\n {\n step: 6,\n name: 'update_ticket',\n description: 'Add findings to ticket notes or update acceptance criteria',\n tools: ['ticket.update'],\n tips: [\n 'Add findings to notes field',\n 'Update acceptance criteria if needed',\n 'Mark items that need user input',\n ],\n },\n {\n step: 7,\n name: 'repeat',\n description: 'Review next ticket',\n tools: [],\n tips: [\n 'Continue until all relevant tickets reviewed',\n 'Consider reviewing related tickets together',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER skip the review checklist',\n 'NEVER assume test environment - always ask user',\n 'NEVER ignore field naming mismatches',\n 'NEVER proceed if auth patterns are unclear',\n ],\n};\n\nexport const FINALIZE_WORKFLOW: FinalizeWorkflowDefinition = {\n name: 'finalize',\n description: 'Verify implementation, mark spec done, and create PR',\n philosophy: [\n 'All epics must be complete before finalizing',\n 'Run full validation suite before PR',\n 'PR description should tell the full story',\n 'End session cleanly after PR creation',\n ],\n prerequisites: [\n 'All epics in specification are done',\n 'All tickets are completed',\n 'All epic commits have been made',\n ],\n steps: [\n {\n step: 1,\n name: 'verify_completion',\n description: 'Check all epics and tickets are done',\n tools: ['specification.get', 'epic.list'],\n tips: [\n 'Verify all epics are marked done',\n 'Check all tickets are completed',\n 'Look for any pending dependencies',\n ],\n },\n {\n step: 2,\n name: 'full_validation',\n description: 'Run complete test suite',\n tools: [],\n tips: [\n 'Run: npm test (or equivalent)',\n 'Run: npm run lint',\n 'Run: npm run build',\n 'All must pass before proceeding',\n ],\n },\n {\n step: 3,\n name: 'integration_review',\n description: 'Review cross-epic integration',\n tools: [],\n tips: [\n 'Check APIs work together',\n 'Verify data flows correctly',\n 'Look for regressions from epic interactions',\n ],\n },\n {\n step: 4,\n name: 'documentation_check',\n description: 'Verify all docs are updated',\n tools: [],\n tips: [\n 'API documentation updated',\n 'README changes if needed',\n 'Architecture docs if changed',\n ],\n },\n {\n step: 5,\n name: 'final_commit',\n description: 'Commit any cleanup changes',\n tools: [],\n tips: [\n 'Stage final changes',\n 'Commit with spec reference',\n 'Only if cleanup needed',\n ],\n },\n {\n step: 6,\n name: 'mark_spec_done',\n description: 'Update specification status',\n tools: ['specification.update'],\n tips: [\n 'Set status to done',\n 'This marks the specification complete',\n ],\n },\n {\n step: 7,\n name: 'create_pr',\n description: 'Create pull request with full context',\n tools: ['link.pull_request'],\n tips: [\n 'Title references specification',\n 'Description includes all epics and key tickets',\n 'Link to specification for context',\n 'Request reviewers if configured',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER create PR with failing tests',\n 'NEVER skip documentation check',\n 'NEVER forget to link PR to specification',\n ],\n};\n\n/**\n * Get a workflow definition by type\n */\nexport function getWorkflowDefinition(\n workflowType: string\n): WorkflowDefinition | ReviewWorkflowDefinition | FinalizeWorkflowDefinition | null {\n switch (workflowType) {\n case 'creation':\n return CREATION_WORKFLOW;\n case 'implementation':\n return IMPLEMENTATION_WORKFLOW;\n case 'review':\n return REVIEW_WORKFLOW;\n case 'finalize':\n return FINALIZE_WORKFLOW;\n default:\n return null;\n }\n}\n\nexport const WORKFLOW_TYPES = ['creation', 'implementation', 'review', 'finalize'] as const;\nexport type WorkflowType = (typeof WORKFLOW_TYPES)[number];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/lib/workflow-definitions.ts"],"sourcesContent":["// mcp/src/lib/workflow-definitions.ts\n/**\n * Workflow Definitions\n *\n * Contains the workflow definitions as data structures for guiding AI agents\n * through SpecForge workflows.\n */\n\nexport interface WorkflowStep {\n step: number;\n name: string;\n description: string;\n tools: string[];\n tips: string[];\n}\n\nexport interface WorkflowDefinition {\n name: string;\n description: string;\n philosophy: string[];\n steps: WorkflowStep[];\n antiPatterns: string[];\n}\n\nexport interface ReviewChecklistItem {\n name: string;\n description: string;\n}\n\nexport interface ReviewWorkflowDefinition extends WorkflowDefinition {\n checklist: ReviewChecklistItem[];\n}\n\nexport interface FinalizeWorkflowDefinition extends WorkflowDefinition {\n prerequisites: string[];\n}\n\nexport const CREATION_WORKFLOW: WorkflowDefinition = {\n name: 'creation',\n description: 'Create specifications, epics, and tickets with rich context',\n philosophy: [\n 'One entity at a time - never bulk create',\n 'More context = better AI implementation',\n 'When in doubt, ask the user',\n 'Invest in planning for first-run success',\n ],\n steps: [\n {\n step: 1,\n name: 'understand_requirements',\n description: 'Gather comprehensive requirements from user',\n tools: [],\n tips: [\n 'Ask about the problem being solved',\n 'Understand the target users',\n 'Clarify scope boundaries',\n 'Identify constraints and risks',\n ],\n },\n {\n step: 2,\n name: 'create_specification',\n description: 'Create specification with full context',\n tools: ['specification.create'],\n tips: [\n 'Include background and goals',\n 'Define guardrails (what NOT to do)',\n 'Set codeStandards for consistency',\n 'Add architecture overview',\n ],\n },\n {\n step: 3,\n name: 'plan_epics',\n description: 'Identify logical phases/groupings, discuss with user',\n tools: [],\n tips: [\n 'Break work into cohesive units',\n 'Consider dependencies between phases',\n 'Discuss timeline and priority with user',\n 'Keep epic count manageable (3-7 typical)',\n ],\n },\n {\n step: 4,\n name: 'create_epic',\n description: 'Create ONE epic with full context',\n tools: ['epic.create'],\n tips: [\n 'Define clear objective',\n 'Set scope boundaries',\n 'Include sharedPatterns for consistency',\n 'Add any epic-specific guardrails',\n ],\n },\n {\n step: 5,\n name: 'plan_tickets',\n description: 'Break epic into tickets, discuss dependencies with user',\n tools: [],\n tips: [\n 'Keep tickets small and focused',\n 'Identify clear acceptance criteria',\n 'Map out dependencies before creating',\n 'Discuss complexity with user',\n ],\n },\n {\n step: 6,\n name: 'create_ticket',\n description: 'Create ONE ticket with full details',\n tools: ['ticket.create'],\n tips: [\n 'Write detailed acceptanceCriteria',\n 'Include implementation hints',\n 'Add technicalDetails for complex logic',\n 'Specify files to modify if known',\n ],\n },\n {\n step: 7,\n name: 'create_dependencies',\n description: 'Link ticket to its dependencies',\n tools: ['dependency.add'],\n tips: [\n 'Only add true blocking dependencies',\n 'Avoid circular dependency chains',\n 'Keep dependency graph shallow when possible',\n ],\n },\n {\n step: 8,\n name: 'repeat',\n description: 'Continue tickets for current epic, then next epic',\n tools: [],\n tips: [\n 'Complete all tickets for an epic before moving on',\n 'Review epic completion before starting next',\n 'Adjust estimates as you learn more',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER use bulk creation - always one at a time',\n 'NEVER skip asking user when details are unclear',\n 'NEVER create tickets without acceptance criteria',\n 'NEVER proceed without understanding dependencies',\n ],\n};\n\nexport const IMPLEMENTATION_WORKFLOW: WorkflowDefinition = {\n name: 'implementation',\n description: 'Implement tickets with session management',\n philosophy: [\n 'Always get full context before starting',\n 'Start session before making changes',\n 'Report progress during implementation',\n 'Validate before completing',\n ],\n steps: [\n {\n step: 1,\n name: 'get_context',\n description: 'Understand current working context',\n tools: ['context.working'],\n tips: [\n 'Check for active sessions',\n 'Note the current specification/epic focus',\n 'Understand what has already been done',\n ],\n },\n {\n step: 2,\n name: 'check_session',\n description: 'Check if spec has an open session',\n tools: ['context.working'],\n tips: [\n 'If session exists, continue with that session ID',\n 'If no session, will start new one after selecting ticket',\n 'Only ONE session per spec at a time',\n ],\n },\n {\n step: 3,\n name: 'find_work',\n description: 'Find tickets ready to work on',\n tools: ['workflow.next_actionable'],\n tips: [\n 'Focus on unblocked tickets',\n 'Consider priority and complexity',\n 'Check if any tickets are already in progress',\n ],\n },\n {\n step: 4,\n name: 'review_ticket',\n description: 'Get full implementation context',\n tools: ['context.implementation'],\n tips: [\n 'Use depth=full for rich context',\n 'Read all related patterns',\n 'Understand acceptance criteria',\n ],\n },\n {\n step: 5,\n name: 'clarify',\n description: 'Ask user about unclear requirements',\n tools: [],\n tips: [\n 'ASK THE USER before proceeding if unclear',\n 'Confirm test environment preference',\n 'Verify any assumptions',\n ],\n },\n {\n step: 6,\n name: 'start_session',\n description: 'Start or continue implementation session',\n tools: ['session.start'],\n tips: [\n 'Session locks the specification',\n 'Prevents concurrent work conflicts',\n 'Tracks your progress and changes',\n ],\n },\n {\n step: 7,\n name: 'implement',\n description: 'Do the work, report progress',\n tools: ['session.progress'],\n tips: [\n 'Follow the patterns from context',\n 'Report meaningful progress updates',\n 'Commit logically grouped changes',\n ],\n },\n {\n step: 8,\n name: 'validate',\n description: 'Run tests, lint, typecheck',\n tools: [],\n tips: [\n 'Run validation as specified in ticket',\n 'Fix any failing tests before completing',\n 'Ensure no regressions',\n ],\n },\n {\n step: 9,\n name: 'complete_ticket',\n description: 'Complete the ticket with summary',\n tools: ['session.complete'],\n tips: [\n 'Include summary of what was done',\n 'Report validation results',\n 'Note any follow-up items',\n ],\n },\n {\n step: 10,\n name: 'repeat_tickets',\n description: 'Continue with next ticket in epic',\n tools: ['workflow.next_actionable'],\n tips: [\n 'Check what tickets are now unblocked',\n 'Continue until epic is complete',\n 'Then proceed to epic completion',\n ],\n },\n {\n step: 11,\n name: 'epic_review',\n description: 'Review all changes made in epic',\n tools: ['epic.get'],\n tips: [\n 'Check all tickets are done',\n 'Review integration between tickets',\n 'Run full test suite for epic scope',\n 'Check for regressions',\n ],\n },\n {\n step: 12,\n name: 'epic_commit',\n description: 'Create commit for the epic',\n tools: [],\n tips: [\n 'Stage all changes from epic tickets',\n 'Write descriptive commit message referencing epic',\n 'Include ticket numbers in commit',\n ],\n },\n {\n step: 13,\n name: 'next_epic',\n description: 'Move to next epic',\n tools: ['epic.list', 'workflow.next_actionable'],\n tips: [\n 'Find the next epic to work on',\n 'Repeat from step 3 (find_work)',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER implement without reading full ticket context',\n 'NEVER skip session.start - it tracks your work',\n 'NEVER complete without running validation',\n 'NEVER assume - ask the user if unclear',\n ],\n};\n\nexport const REVIEW_WORKFLOW: ReviewWorkflowDefinition = {\n name: 'review',\n description: 'Review tickets for completeness and consistency before implementation',\n philosophy: [\n 'Catch issues before implementation, not during',\n 'Consistency across all layers (DB, API, types)',\n 'Always ask about test environment preference',\n 'Document findings in ticket notes',\n ],\n checklist: [\n { name: 'missing_points', description: 'Acceptance criteria complete? Edge cases?' },\n { name: 'blind_spots', description: 'Security implications? What could go wrong?' },\n { name: 'auth_patterns', description: 'Token handling? Permission checks?' },\n { name: 'db_permissions', description: 'Row-level security? Audit requirements?' },\n { name: 'field_naming', description: 'DB (snake_case) <-> API (camelCase) <-> Types match?' },\n { name: 'documentation', description: 'API docs? README? Architecture docs need update?' },\n { name: 'test_environment', description: 'ASK USER: Sandbox or local mocks?' },\n ],\n steps: [\n {\n step: 1,\n name: 'select_ticket',\n description: 'Choose ticket to review',\n tools: ['ticket.get', 'workflow.next_actionable'],\n tips: [\n 'Review tickets before they are implemented',\n 'Can review all pending tickets in an epic',\n ],\n },\n {\n step: 2,\n name: 'load_context',\n description: 'Get full implementation context with patterns',\n tools: ['context.implementation'],\n tips: [\n 'Use depth=full for comprehensive review',\n 'Understand the broader context',\n ],\n },\n {\n step: 3,\n name: 'run_checklist',\n description: 'Go through each review point systematically',\n tools: [],\n tips: [\n 'Check each item in the review checklist',\n 'Be thorough - issues found now save time later',\n ],\n },\n {\n step: 4,\n name: 'identify_gaps',\n description: 'List missing items, inconsistencies, concerns',\n tools: [],\n tips: [\n 'Document all findings',\n 'Prioritize by impact',\n 'Note any blocking issues',\n ],\n },\n {\n step: 5,\n name: 'ask_user',\n description: 'Clarify test environment preference',\n tools: [],\n tips: [\n 'ALWAYS ask about test environment',\n 'Sandbox (real services) vs local mocks',\n 'Document the decision',\n ],\n },\n {\n step: 6,\n name: 'update_ticket',\n description: 'Add findings to ticket notes or update acceptance criteria',\n tools: ['ticket.update'],\n tips: [\n 'Add findings to notes field',\n 'Update acceptance criteria if needed',\n 'Mark items that need user input',\n ],\n },\n {\n step: 7,\n name: 'repeat',\n description: 'Review next ticket',\n tools: [],\n tips: [\n 'Continue until all relevant tickets reviewed',\n 'Consider reviewing related tickets together',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER skip the review checklist',\n 'NEVER assume test environment - always ask user',\n 'NEVER ignore field naming mismatches',\n 'NEVER proceed if auth patterns are unclear',\n ],\n};\n\nexport const FINALIZE_WORKFLOW: FinalizeWorkflowDefinition = {\n name: 'finalize',\n description: 'Verify implementation, mark spec done, and create PR',\n philosophy: [\n 'All epics must be complete before finalizing',\n 'Run full validation suite before PR',\n 'PR description should tell the full story',\n 'End session cleanly after PR creation',\n ],\n prerequisites: [\n 'All epics in specification are done',\n 'All tickets are completed',\n 'All epic commits have been made',\n ],\n steps: [\n {\n step: 1,\n name: 'verify_completion',\n description: 'Check all epics and tickets are done',\n tools: ['specification.get', 'epic.list'],\n tips: [\n 'Verify all epics are marked done',\n 'Check all tickets are completed',\n 'Look for any pending dependencies',\n ],\n },\n {\n step: 2,\n name: 'full_validation',\n description: 'Run complete test suite',\n tools: [],\n tips: [\n 'Run: npm test (or equivalent)',\n 'Run: npm run lint',\n 'Run: npm run build',\n 'All must pass before proceeding',\n ],\n },\n {\n step: 3,\n name: 'integration_review',\n description: 'Review cross-epic integration',\n tools: [],\n tips: [\n 'Check APIs work together',\n 'Verify data flows correctly',\n 'Look for regressions from epic interactions',\n ],\n },\n {\n step: 4,\n name: 'documentation_check',\n description: 'Verify all docs are updated',\n tools: [],\n tips: [\n 'API documentation updated',\n 'README changes if needed',\n 'Architecture docs if changed',\n ],\n },\n {\n step: 5,\n name: 'final_commit',\n description: 'Commit any cleanup changes',\n tools: [],\n tips: [\n 'Stage final changes',\n 'Commit with spec reference',\n 'Only if cleanup needed',\n ],\n },\n {\n step: 6,\n name: 'mark_spec_done',\n description: 'Update specification status',\n tools: ['specification.update'],\n tips: [\n 'Set status to done',\n 'This marks the specification complete',\n ],\n },\n {\n step: 7,\n name: 'create_pr',\n description: 'Create pull request with full context',\n tools: ['link.pull_request'],\n tips: [\n 'Title references specification',\n 'Description includes all epics and key tickets',\n 'Link to specification for context',\n 'Request reviewers if configured',\n ],\n },\n ],\n antiPatterns: [\n 'NEVER create PR with failing tests',\n 'NEVER skip documentation check',\n 'NEVER forget to link PR to specification',\n ],\n};\n\n/**\n * Get a workflow definition by type\n */\nexport function getWorkflowDefinition(\n workflowType: string\n): WorkflowDefinition | ReviewWorkflowDefinition | FinalizeWorkflowDefinition | null {\n switch (workflowType) {\n case 'creation':\n return CREATION_WORKFLOW;\n case 'implementation':\n return IMPLEMENTATION_WORKFLOW;\n case 'review':\n return REVIEW_WORKFLOW;\n case 'finalize':\n return FINALIZE_WORKFLOW;\n default:\n return null;\n }\n}\n\nexport const WORKFLOW_TYPES = ['creation', 'implementation', 'review', 'finalize'] as const;\nexport type WorkflowType = (typeof WORKFLOW_TYPES)[number];\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAML,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAUhC;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,IAAI,EAAE,CAoqCjC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CACjB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AA6EtB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAyU7B;AAiBD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,CAAC,CA4DlB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAOrC;AAGD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAML,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAUhC;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,IAAI,EAAE,CAmtCjC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CACjB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AA6EtB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAyU7B;AAiBD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,CAAC,CA4DlB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAOrC;AAGD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC"}
@@ -310,6 +310,7 @@ Format options:
310
310
  "unlink_step_snippet",
311
311
  "create_dependencies",
312
312
  "delete_dependencies",
313
+ "apply_creator_election",
313
314
  "justify",
314
315
  "unjustify",
315
316
  "get_planning_status"
@@ -452,6 +453,52 @@ Format options:
452
453
  },
453
454
  required: ["type", "dependencyIds"]
454
455
  },
456
+ // apply_creator_election (MB.16.1) — the atomic creator-election batch: file
457
+ // moves + producing steps + ordering deps in ONE cross-phase op. Only the
458
+ // status:'clean' partition is applied; conflicts are excluded + surfaced to
459
+ // get_ticket. `dependencies` may be empty (single-toucher flips).
460
+ {
461
+ properties: {
462
+ type: { const: "apply_creator_election" },
463
+ elections: {
464
+ type: "array",
465
+ minItems: 1,
466
+ maxItems: 5e3,
467
+ description: "The per-file creator elections. Each moves an orphan shared file to filesToBeCreated on its elected creator ticket + declares the producing step so the moved file is not a new orphan.",
468
+ items: {
469
+ type: "object",
470
+ properties: {
471
+ path: { type: "string", description: "The orphan shared file path to resolve." },
472
+ kind: { type: "string", enum: ["toBeCreated", "toBeModified", "toBeDeleted", "toBeReferenced"], description: "The target file-change kind on the elected ticket (normally toBeCreated)." },
473
+ creatorTicketId: { type: "string", description: "The elected creator ticket (topologically-earliest toucher)." },
474
+ producingStep: {
475
+ type: "object",
476
+ description: "The step that produces the moved file: pass an existing step id to link it, OR text to create-and-link a new step.",
477
+ properties: {
478
+ text: { type: "string", description: "Text of a NEW producing step to create + link." },
479
+ stepId: { type: "string", description: "Id of an EXISTING step to link to the moved file." }
480
+ }
481
+ }
482
+ },
483
+ required: ["path", "kind", "creatorTicketId", "producingStep"]
484
+ }
485
+ },
486
+ dependencies: {
487
+ type: "array",
488
+ maxItems: 5e3,
489
+ description: `The ordering deps (each a "requires" edge). May be empty. Only the CLEAN partition's deps are persisted (recomputed + cycle-checked server-side).`,
490
+ items: {
491
+ type: "object",
492
+ properties: {
493
+ fromTicketId: { type: "string", description: "The dependent ticket (a non-elected toucher)." },
494
+ toTicketId: { type: "string", description: "The elected creator it depends on." }
495
+ },
496
+ required: ["fromTicketId", "toTicketId"]
497
+ }
498
+ }
499
+ },
500
+ required: ["type", "elections", "dependencies"]
501
+ },
455
502
  {
456
503
  properties: {
457
504
  type: { const: "create_blueprint" },
@@ -591,7 +638,7 @@ Format options:
591
638
  },
592
639
  {
593
640
  name: "start_work_session",
594
- description: "Start working on a ticket. Returns full ticket details (description, implementation steps, AC, technicalDetails, codeReferences, typeReferences, tags, notes, complexity, priority) alongside checklistState and workSessionId. No need to call get_ticket separately. Returns error with statusReason if ticket is pending.",
641
+ description: "Start working on a ticket. Returns full ticket details (description, implementation steps, AC, technicalDetails, codeReferences, typeReferences, tags, notes, complexity, priority) alongside checklistState and workSessionId. No need to call the `get` tool (type:'ticket') separately. Returns error with statusReason if ticket is pending.",
595
642
  inputSchema: {
596
643
  type: "object",
597
644
  properties: {
@@ -1003,7 +1050,7 @@ Set getTicket: true to fetch full ticket details in the response \u2014 useful f
1003
1050
  },
1004
1051
  {
1005
1052
  name: "reopen_specification",
1006
- description: 'Reopen a specification in "ready" status, regressing to "planning". After reopening, call start_planning_session to begin a new planning session.',
1053
+ description: 'Reopen a specification in "ready" status, regressing to "planning". Use when action_planning_session reports the spec is no longer in planning. After reopening, call start_planning_session to begin a new planning session.',
1007
1054
  inputSchema: {
1008
1055
  type: "object",
1009
1056
  properties: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tools/index.ts"],"sourcesContent":["import { appendFileSync } from 'node:fs';\n/**\n * MCP Tools Registry\n *\n * This module defines and exports all available MCP tools.\n * 22 tools organized into: Queries, Lifecycle, Mutation, Utilities, Orchestration.\n */\n\nimport { ApiClient } from '../client/api-client.js';\nimport {\n ValidationError,\n ApiError,\n validateToolArgs,\n formatMCPError,\n transformError,\n MCPErrorResponse,\n} from '../validation/index.js';\nimport { injectContext, injectContextRequired } from './core/context-helper.js';\nimport { probeExistingFiles } from './core/file-existence-injection.js';\nimport { readWorktreeGitEvidence, readHeadCommitSha } from './core/git-injection.js';\nimport { tryLoadProjectConfig, saveProjectConfig } from '../cli/config/index.js';\nimport {\n appendPlanningSessionRegistry,\n markPlanningSessionRegistryCompleted,\n} from '../cli/config/planning-sessions-registry.js';\n\n/**\n * Tool definition matching MCP protocol schema\n */\nexport interface Tool {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/**\n * Get list of all available tools\n *\n * @returns Array of tool definitions (22 tools)\n */\nexport function getTools(): Tool[] {\n const tools: Tool[] = [\n // ========================================================================\n // Queries (6)\n // ========================================================================\n {\n name: 'get',\n description: 'Get a single entity by type and ID.',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['project', 'specification', 'epic', 'ticket', 'blueprint'],\n description: 'Entity type to retrieve',\n },\n id: {\n type: 'string',\n description: 'Entity ID',\n },\n },\n required: ['type', 'id'],\n },\n },\n {\n name: 'list',\n description: 'List entities by type.',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['projects', 'specifications', 'epics', 'tickets', 'blueprints'],\n description: 'Entity type to list',\n },\n projectId: {\n type: 'string',\n description: 'Filter by project (for specifications)',\n },\n specificationId: {\n type: 'string',\n description: 'Filter by specification (for epics, tickets)',\n },\n epicId: {\n type: 'string',\n description: 'Filter by epic (for tickets)',\n },\n },\n required: ['type'],\n },\n },\n {\n name: 'search',\n description: `Unified ticket search with multiple filter options.\n\nCombines:\n- Full-text search (query)\n- File matching (files) - replaces find_tickets_by_file\n- Tag filtering (tags) - replaces find_tickets_by_tag\n- Related tickets (relatedTo) - replaces find_related_tickets\n- Status, complexity, priority filters\n\nAt least one of: query, files, tags, or relatedTo is required.\nAt least one scope filter (projectId, specificationId, or epicId) is required.`,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Full-text search query',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'Glob patterns to match ticket files (e.g., \"**/channel/*.ts\")',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags to filter by',\n },\n matchAllTags: {\n type: 'boolean',\n description: 'If true, match all tags (AND). If false, match any (OR). Default: false',\n },\n relatedTo: {\n type: 'string',\n description: 'Find tickets related to this ticket ID (by tags, files, tech stack)',\n },\n status: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['pending', 'ready', 'active', 'done', 'blocked'],\n },\n description: 'Filter by status',\n },\n complexity: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['small', 'medium', 'large', 'xlarge'],\n },\n description: 'Filter by complexity',\n },\n projectId: {\n type: 'string',\n description: 'Limit search to project',\n },\n specificationId: {\n type: 'string',\n description: 'Limit search to specification',\n },\n epicId: {\n type: 'string',\n description: 'Limit search to epic',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20, max: 100)',\n },\n offset: {\n type: 'number',\n description: 'Pagination offset (default: 0)',\n },\n fields: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'id',\n 'epicId',\n 'ticketNumber',\n 'title',\n 'description',\n 'status',\n 'priority',\n 'complexity',\n 'estimatedHours',\n 'actualHours',\n 'acceptanceCriteria',\n 'implementation',\n 'technicalDetails',\n 'notes',\n 'tags',\n 'progress',\n 'testsPassed',\n 'order',\n 'startedAt',\n 'completedAt',\n 'createdAt',\n 'updatedAt',\n ],\n },\n description:\n 'Select specific fields to return. Returns all fields if not specified. id is always included.',\n },\n },\n },\n },\n {\n name: 'get_next_actionable_tickets',\n description: 'Get tickets with status \"ready\" (all dependencies satisfied). Use start_work_session() to begin work on these tickets.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification (optional if projectId provided)',\n },\n projectId: {\n type: 'string',\n description: 'The ID of the project to get actionable tickets across all specifications',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of tickets to return (default: 5)',\n },\n },\n },\n },\n {\n name: 'get_blocked_tickets',\n description: 'Get tickets with status \"pending\", each with the `blockedBy` list of unsatisfied dependency tickets computed from the dependency tree.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'get_report',\n description: `Generate unified reports for implementation, time tracking, blockers, work summary, or active sessions.\n\nReport types:\n- 'implementation': Progress, velocity, completions (replaces get_implementation_summary)\n- 'time': Estimated vs actual hours (replaces get_time_report)\n- 'blockers': Blocked tickets with reasons (replaces get_blockers_report)\n- 'work': Completed work summary from WorkSession records (replaces get_work_summary)\n- 'sessions': Live planning/work/review sessions for a project (requires scope='project')\n\nFormat options:\n- 'json': Full structured data (default)\n- 'summary': Condensed text summary`,\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['implementation', 'time', 'blockers', 'work', 'sessions'],\n description: 'Type of report to generate',\n },\n scope: {\n type: 'string',\n enum: ['project', 'specification', 'epic'],\n description: \"Scope of the report. 'sessions' requires scope='project'.\",\n },\n scopeId: {\n type: 'string',\n description: 'ID of the scoped entity (projectId, specificationId, or epicId)',\n },\n startDate: {\n type: 'string',\n description: 'Start date for work report (ISO 8601)',\n },\n endDate: {\n type: 'string',\n description: 'End date for work report (ISO 8601)',\n },\n format: {\n type: 'string',\n enum: ['json', 'summary'],\n description: \"Response format: 'json' (default) or 'summary'.\",\n },\n },\n required: ['type', 'scope', 'scopeId'],\n },\n },\n\n // ========================================================================\n // Lifecycle (10)\n // ========================================================================\n {\n name: 'start_planning_session',\n description: 'Start or resume a guided planning session for a specification. Project-scoped lock: only one active planning session per project. Calling with the same spec resumes the existing session (idempotent). Calling with a different spec while one is active returns a rejection with the active session details. Planning is independent of implementation and review — they can run concurrently.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The specification to plan. Optional — defaults to the active spec in the local config (.specforge/config.json), so you normally omit it.',\n },\n projectId: {\n type: 'string',\n description: 'The owning project. Optional — defaults to the active project in the local config (.specforge/config.json); injected automatically, so you normally omit it.',\n },\n },\n // Nothing is required: specificationId/projectId fall back to local config, and\n // the returned sessionId is persisted + injected into subsequent calls.\n required: [],\n },\n },\n {\n name: 'action_planning_session',\n description: \"Execute a planning action within an active session. Wraps all planning operations (create/update/delete epics, tickets, dependencies, blueprints) plus get_planning_status (readiness X-ray, worst-first) with automatic status tracking. The operation.type IS the backend PlanningOperationName. The spec status advances or regresses automatically based on the action type and gate checks. Returns updated progress, blockers, and next suggested actions after every call. To read a single ticket, use the `get` tool (type:'ticket').\",\n inputSchema: {\n type: 'object',\n properties: {\n operation: {\n type: 'object',\n description: 'The operation to perform. Must include a \"type\" field. Per-op required fields are declared in `oneOf` below — agents should consult their own tool schema parser for the exact shape per type. Do NOT pass sessionId/projectId/specificationId: the active planning session is injected from local config.',\n properties: {\n type: {\n type: 'string',\n enum: [\n 'update_spec',\n 'create_epic',\n 'update_epic',\n 'delete_epic',\n 'create_ticket',\n 'update_ticket',\n 'delete_ticket',\n 'create_blueprint',\n 'update_blueprint',\n 'delete_blueprint',\n 'link_blueprint_to_tickets',\n 'unlink_blueprint_to_tickets',\n 'link_step_file',\n 'unlink_step_file',\n 'link_step_snippet',\n 'unlink_step_snippet',\n 'create_dependencies',\n 'delete_dependencies',\n 'justify',\n 'unjustify',\n 'get_planning_status',\n ],\n description: 'The planning operation to perform (lifecycle vocabulary). The type IS the backend PlanningOperationName; remaining fields are the operation payload.',\n },\n },\n required: ['type'],\n oneOf: [\n {\n properties: {\n type: { const: 'update_spec' },\n fields: { type: 'object', description: 'Partial spec update — only the keys you send are changed (e.g. background, goals, nonGoals, constraints, successCriteria). Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.' },\n },\n required: ['type', 'fields'],\n },\n // create_epic — SHELL only (epic_decomposition). Body fields are authored\n // by update_epic in epic_expansion; only title/description/objective are\n // persisted on create, so only those are advertised.\n {\n properties: {\n type: { const: 'create_epic' },\n title: { type: 'string', minLength: 1, description: 'Epic title (non-empty)' },\n description: { type: 'string', description: 'What this epic delivers' },\n objective: { type: 'string', description: 'Goal achieved for the user' },\n },\n required: ['type', 'title'],\n },\n {\n properties: {\n type: { const: 'update_epic' },\n id: { type: 'string', description: 'Epic id (use list_epics / lookup_epic to find).' },\n fields: {\n type: 'object',\n description: 'Partial epic update — only the keys you send are changed. Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.',\n properties: {\n title: { type: 'string' },\n description: { type: 'string' },\n objective: { type: 'string', description: 'Goal achieved for the user.' },\n architecture: { type: 'string', description: 'Structural approach specific to this epic.' },\n scope: { type: 'object', description: 'Epic scope.', properties: { inScope: { type: 'array', items: { type: 'string' } }, outOfScope: { type: 'array', items: { type: 'string' } }, assumptions: { type: 'array', items: { type: 'string' } }, externalDependencies: { type: 'array', items: { type: 'string' } } } },\n goals: { type: 'array', description: 'Epic goals as objects (Epic.goals is a json object[], not string[]).', items: { type: 'object', properties: { title: { type: 'string' }, description: { type: 'string' }, type: { type: 'string', enum: ['business', 'technical', 'user', 'operational'] }, successCriteria: { type: 'array', items: { type: 'string' } } }, required: ['title', 'description'] } },\n acceptanceCriteria: { type: 'array', description: 'BDD criteria objects (Epic.acceptanceCriteria is a json object[], not string[]).', items: { type: 'object', properties: { given: { type: 'string' }, when: { type: 'string' }, then: { type: 'string' } }, required: ['given', 'when', 'then'] } },\n validationCommands: { type: 'array', items: { type: 'string' }, description: 'Commands that verify this epic end-to-end.' },\n apiContracts: { type: 'array', description: 'API contracts this epic exposes.', items: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, type: { type: 'string' }, description: { type: 'string' } } } },\n sharedPatterns: { type: 'array', description: 'Reusable patterns the epic\\'s tickets should follow.', items: { type: 'object' } },\n fileStructures: { type: 'array', description: 'Concrete files this epic creates/modifies.', items: { type: 'object', properties: { id: { type: 'string' }, scope: { type: 'string' }, description: { type: 'string' }, content: { type: 'string' } } } },\n requirementsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec requirement ids this epic covers.' },\n nfrsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec NFR ids this epic covers.' },\n goalsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec goal ids this epic advances.' },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n // create_ticket — SHELL (ticket_decomposition): epicId/title/description\n // + ticketType (the impl/verification decision, set HERE and immutable via\n // update_ticket). The remaining body fields are authored by update_ticket in\n // ticket_expansion; dependencies via create_dependencies in cross_validation.\n {\n properties: {\n type: { const: 'create_ticket' },\n epicId: { type: 'string', description: 'Parent epic id' },\n title: { type: 'string', minLength: 1, description: 'Ticket title (non-empty)' },\n description: { type: 'string' },\n ticketType: { type: 'string', enum: ['implementation', 'verification'], description: 'Ticket type — set here (decomposition); defaults to implementation. Not changeable via update_ticket.' },\n },\n required: ['type', 'epicId', 'title'],\n },\n {\n properties: {\n type: { const: 'update_ticket' },\n id: { type: 'string', description: 'Ticket id (use list_tickets / lookup_ticket to find).' },\n fields: {\n type: 'object',\n description: 'Partial ticket update — only the keys you send are changed. Child-backed arrays (acceptanceCriteria, implementationSteps, filesToBe*, testSpecification.testTypes, codeSnippets, typeSnippets) replace the whole set. Blueprint links are NOT settable here — use link_blueprint_to_tickets (from ticket_decomposition onward), the sole writer of the blueprint↔ticket relation. Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.',\n properties: {\n title: { type: 'string' },\n description: { type: 'string' },\n complexity: { type: 'string', enum: ['small', 'medium', 'large', 'xlarge'] },\n estimatedMinutes: { type: 'integer', minimum: 0 },\n acceptanceCriteria: { type: 'array', items: { type: 'object', properties: { given: { type: 'string' }, when: { type: 'string' }, then: { type: 'string' } }, required: ['given', 'when', 'then'] } },\n implementationSteps: { type: 'array', description: 'Ordered build steps. Declare the file(s) each step produces INLINE via `producesFiles: [path]` (each path must also appear in filesToBeCreated/filesToBeModified) — links the step↔file in the SAME call so the ticket_expansion gate passes without a second pass. Every step MUST link ≥1 file and every produced file MUST be linked by ≥1 step (hard gates). `link_step_file` remains for post-hoc edits.', items: { type: 'object', properties: { text: { type: 'string' }, producesFiles: { type: 'array', items: { type: 'string' }, description: 'Paths this step produces — each must match an entry in filesToBeCreated/filesToBeModified; links the step↔file inline (path-based).' } }, required: ['text'] } },\n filesToBeCreated: { type: 'array', items: { type: 'string' } },\n filesToBeModified: { type: 'array', items: { type: 'string' } },\n filesToBeDeleted: { type: 'array', items: { type: 'string' } },\n filesToBeReferenced: { type: 'array', items: { type: 'string' } },\n guardrails: { type: 'array', items: { type: 'string' } },\n testSpecification: { type: 'object', properties: { testTypes: { type: 'array', items: { type: 'string', enum: ['unit', 'integration', 'e2e', 'typecheck', 'lint', 'build', 'contract', 'structural', 'layout', 'a11y', 'performance'] } }, qualityGates: { type: 'array', items: { type: 'string' } }, testCommands: { type: 'array', items: { type: 'string' } }, coverageTarget: { type: 'integer', minimum: 0, maximum: 100 } } },\n codeReferences: { type: 'array', description: 'Existing code to reuse/anchor on.', items: { type: 'object', properties: { filePath: { type: 'string' }, symbol: { type: 'string' }, description: { type: 'string' } }, required: ['filePath'] } },\n typeReferences: { type: 'array', description: 'Existing types to use.', items: { type: 'object', properties: { filePath: { type: 'string' }, typeName: { type: 'string' }, description: { type: 'string' } }, required: ['filePath', 'typeName'] } },\n codeSnippets: { type: 'array', description: 'Concrete code to write. Attach a snippet to its step INLINE via `stepId` (create-and-link); a snippet linking NO step is dangling and blocks the ticket.', items: { type: 'object', properties: { language: { type: 'string' }, content: { type: 'string' }, description: { type: 'string' }, stepId: { type: 'string', description: 'Implementation step id this snippet follows — links the snippet↔step inline.' } }, required: ['language', 'content'] } },\n typeSnippets: { type: 'array', description: 'Type/interface definitions to write. Attach to a step INLINE via `stepId` (create-and-link); a snippet linking NO step is dangling and blocks the ticket.', items: { type: 'object', properties: { language: { type: 'string' }, content: { type: 'string' }, description: { type: 'string' }, stepId: { type: 'string', description: 'Implementation step id this snippet follows — links the snippet↔step inline.' } }, required: ['language', 'content'] } },\n tags: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n {\n properties: {\n type: { const: 'delete_epic' },\n id: { type: 'string', description: 'Epic id; cascades to all tickets in the epic.' },\n cascadeRemoveDependencies: { type: 'boolean', description: 'Confirm removing dependency edges pointing at this epic\\'s tickets from outside the epic. Required (true) when such referrers exist, else the delete is denied.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'delete_ticket' },\n id: { type: 'string', description: 'Ticket id (use list_tickets / lookup_ticket to find).' },\n cascadeRemoveDependencies: { type: 'boolean', description: 'Confirm removing dependency edges from other tickets that point at this ticket. Required (true) when such referrers exist, else the delete is denied.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'create_dependencies' },\n dependencies: {\n type: 'array',\n minItems: 1,\n maxItems: 5000,\n description: 'Up to 5000 dependency pairs, each a \"requires\" edge (fromTicketId depends on toTicketId). The batch is validated atomically: a cycle or an all-duplicate batch is rejected with guidance; already-existing edges are skipped.',\n items: {\n type: 'object',\n properties: {\n fromTicketId: { type: 'string', description: 'The dependent ticket (this one depends on the other).' },\n toTicketId: { type: 'string', description: 'The blocker ticket it depends on.' },\n },\n required: ['fromTicketId', 'toTicketId'],\n },\n },\n },\n required: ['type', 'dependencies'],\n },\n {\n properties: {\n type: { const: 'delete_dependencies' },\n dependencyIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'TicketDependency ids to remove (use lookup/list to find).' },\n },\n required: ['type', 'dependencyIds'],\n },\n {\n properties: {\n type: { const: 'create_blueprint' },\n title: { type: 'string', minLength: 1, description: 'Blueprint title (non-empty)' },\n content: { type: 'string', description: 'Body — diagram source or markdown, persisted as-is on create.' },\n format: { type: 'string', enum: ['markdown', 'mermaid', 'ascii', 'mixed', 'html', 'svg', 'image'], description: 'Defaults to \"mermaid\"' },\n category: { type: 'string', enum: ['flowchart', 'architecture', 'state', 'sequence', 'erd', 'mockup', 'adr', 'component', 'deployment', 'api', 'algorithm', 'protocol', 'glossary', 'design_system'], description: 'Blueprint category (SpecificationBlueprint.category model enum).' },\n description: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n required: ['type', 'title', 'category'],\n },\n {\n properties: {\n type: { const: 'update_blueprint' },\n id: { type: 'string', description: 'Blueprint id.' },\n fields: {\n type: 'object',\n description: 'Partial blueprint update — only the keys you send are changed.',\n properties: {\n title: { type: 'string' },\n content: { type: 'string' },\n category: { type: 'string' },\n description: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n {\n properties: {\n type: { const: 'delete_blueprint' },\n id: { type: 'string', description: 'Blueprint id.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'link_blueprint_to_tickets' },\n blueprintId: { type: 'string', description: 'Blueprint to link.' },\n ticketIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'Tickets to link the blueprint to.' },\n },\n required: ['type', 'blueprintId', 'ticketIds'],\n },\n {\n properties: {\n type: { const: 'unlink_blueprint_to_tickets' },\n blueprintId: { type: 'string', description: 'Blueprint to unlink.' },\n ticketIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'Tickets to unlink the blueprint from.' },\n },\n required: ['type', 'blueprintId', 'ticketIds'],\n },\n // MB.14.1 — step↔artifact link verbs (create/delete a join row keyed on\n // stepId + fileChangeId/snippetId). Get the ids from the ticket read-shape.\n {\n properties: {\n type: { const: 'link_step_file' },\n stepId: { type: 'string', description: 'Implementation step id (the functional unit of work).' },\n fileChangeId: { type: 'string', description: 'Declared file-change id the step produces (from the ticket read-shape).' },\n },\n required: ['type', 'stepId', 'fileChangeId'],\n },\n {\n properties: {\n type: { const: 'unlink_step_file' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n fileChangeId: { type: 'string', description: 'Declared file-change id to unlink from the step.' },\n },\n required: ['type', 'stepId', 'fileChangeId'],\n },\n {\n properties: {\n type: { const: 'link_step_snippet' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n snippetType: { type: 'string', enum: ['code', 'type'], description: \"'code' → TicketCodeSnippet, 'type' → TicketTypeSnippet.\" },\n snippetId: { type: 'string', description: 'Code/type snippet id the step follows (recommended, not required per step — but a snippet linking NO step is dangling and blocks the ticket; link or drop it).' },\n },\n required: ['type', 'stepId', 'snippetType', 'snippetId'],\n },\n {\n properties: {\n type: { const: 'unlink_step_snippet' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n snippetType: { type: 'string', enum: ['code', 'type'], description: 'Which snippet table to unlink from.' },\n snippetId: { type: 'string', description: 'Code/type snippet id to unlink from the step.' },\n },\n required: ['type', 'stepId', 'snippetType', 'snippetId'],\n },\n // justify — declare a field N/A (the paired declare op; unjustify removes it).\n // Structural-neutral: it writes only the fieldDeclarations[scope] declaration,\n // so it is native in EVERY planning phase and never rolls back. `scope` is the\n // canonical field name the checks read (e.g. dependencies, codeReferences,\n // apiContracts) — NOT a `fieldDeclarations`-shaped payload on update_*.\n {\n properties: {\n type: { const: 'justify' },\n scope: { type: 'string', description: \"Canonical field name to mark not-applicable (e.g. 'dependencies', 'codeReferences', 'apiContracts').\" },\n entityId: { type: 'string', description: 'The spec/epic/ticket id the field belongs to (resolved server-side; ids are unique across the spec).' },\n reason: { type: 'string', description: 'Why the field does not apply (must be at least 20 characters).' },\n },\n required: ['type', 'scope', 'entityId', 'reason'],\n },\n // unjustify — remove a previously declared N/A (clears fieldDeclarations[scope]).\n // A no-op if the scope was never justified. No reason (a delete is unconditional).\n {\n properties: {\n type: { const: 'unjustify' },\n scope: { type: 'string', description: 'Canonical field name whose not-applicable declaration to remove.' },\n entityId: { type: 'string', description: 'The spec/epic/ticket id the field belongs to.' },\n },\n required: ['type', 'scope', 'entityId'],\n },\n {\n // Read-only poll/resume. To read a single ticket, use the `get` tool (type:'ticket').\n properties: {\n type: { const: 'get_planning_status' },\n },\n required: ['type'],\n },\n ],\n },\n },\n required: ['operation'],\n },\n },\n {\n name: 'complete_planning_session',\n description: \"Complete the planning session and submit the spec for final review. Spec must be in 'planning' status. Runs the planning gate (consistency checks + readinessThreshold from project/spec settings). Transitions the spec directly to 'ready' on pass. Takes no arguments — the active planning session is injected from local config.\",\n inputSchema: {\n type: 'object',\n // No inputs: the active planning session (sessionId) is injected from\n // local config (.specforge/config.json). Do NOT pass sessionId/projectId/specificationId.\n properties: {},\n required: [],\n },\n },\n {\n name: 'start_work_session',\n description: 'Start working on a ticket. Returns full ticket details (description, implementation steps, AC, technicalDetails, codeReferences, typeReferences, tags, notes, complexity, priority) alongside checklistState and workSessionId. No need to call get_ticket separately. Returns error with statusReason if ticket is pending.',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket to start',\n },\n },\n required: ['ticketId'],\n },\n },\n {\n name: 'action_work_session',\n description: `Update checklist state during an active WorkSession. Combines step completion, AC validation, test result reporting, file tracking, reference review confirmation, and discovery reporting into a single atomic operation. All state changes are recorded on the WorkSession and its related validation/completion records.\n\nUse this instead of calling update_ticket for checklist changes. Provides:\n- Step completion (individual or bulk via WorkSessionImplStepCompletion)\n- Acceptance criteria validation (individual or bulk via WorkSessionAcceptanceCheck)\n- Test result reporting (merged by test type via WorkSessionTestResult)\n- File tracking (created, modified, deleted on WorkSession)\n- Discovery reporting (create discoveries for blockers, bugs, tech debt)\n- Blocker management (set block reason; requires existing discovery)\n- Reference review tracking (codeSnippetsReviewed, typeReferencesReviewed)\n- Auto-calculated progress percentage\n- Completion readiness hints\n\nIMPORTANT: All acceptance criteria must be validated and all implementation steps must be completed via this tool before calling complete_work_session. The completion gate enforces this.\n\nIf the ticket has codeReferences or typeReferences, set codeSnippetsReviewed/typeReferencesReviewed to true after reviewing them — completion readiness will block until these are confirmed.\n\nSet getTicket: true to fetch full ticket details in the response — useful for re-reading ticket context mid-implementation. Can be the sole operation or combined with other actions.`,\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket being worked on (must be in active status)',\n },\n action: {\n type: 'object',\n description:\n 'The assay action to record — the AWS action vocabulary. `action` (the discriminator) is one of: mark_implementation_step_completion, mark_acceptance_check, record_test_result, add_skip_justification, amend_skip_justification, add_failure_justification, amend_failure_justification, record_file_change, add_file_change_justification, amend_file_change_justification, create_discovery (with `blocking`), update_discovery, set_discovery_resolved. Include `workSessionId` and the per-action fields. Forwarded verbatim as the lifecycle inner payload.',\n properties: {\n action: {\n type: 'string',\n enum: [\n 'mark_implementation_step_completion',\n 'mark_acceptance_check',\n 'record_test_result',\n 'add_skip_justification',\n 'amend_skip_justification',\n 'add_failure_justification',\n 'amend_failure_justification',\n 'record_file_change',\n 'add_file_change_justification',\n 'amend_file_change_justification',\n 'create_discovery',\n 'update_discovery',\n 'set_discovery_resolved',\n ],\n description: 'The AWS action discriminator.',\n },\n workSessionId: { type: 'string', description: 'The active WorkSession id (from start_work_session).' },\n },\n required: ['action'],\n },\n steps: {\n type: 'array',\n description: 'Individual step completion updates',\n items: {\n type: 'object',\n properties: {\n index: {\n type: 'number',\n description: \"Zero-based index of the step among the ticket's implementation steps (TicketImplementationStep rows, ordered by `order`)\",\n },\n completed: {\n type: 'boolean',\n description: 'Whether the step is completed',\n },\n notes: {\n type: 'string',\n description: 'Optional note about this step',\n },\n },\n required: ['index', 'completed'],\n },\n },\n allStepsDone: {\n type: 'boolean',\n description: 'Shortcut: mark all steps as completed',\n },\n acceptanceCriteria: {\n type: 'array',\n description: 'Individual AC validation updates',\n items: {\n type: 'object',\n properties: {\n index: {\n type: 'number',\n description: 'Zero-based index of the AC in the acceptanceCriteria array',\n },\n validated: {\n type: 'boolean',\n description: 'Whether the AC is validated',\n },\n notes: {\n type: 'string',\n description: 'Optional note about this AC',\n },\n },\n required: ['index', 'validated'],\n },\n },\n allACValidated: {\n type: 'boolean',\n description: 'Shortcut: mark all acceptance criteria as validated',\n },\n testResults: {\n type: 'array',\n description: 'Test result reports to append (merged by testType)',\n items: {\n type: 'object',\n properties: {\n testType: {\n type: 'string',\n description: 'Type of test (e.g., \"unit\", \"integration\", \"e2e\", \"lint\", \"typeCheck\")',\n },\n passed: {\n type: 'number',\n description: 'Number of tests that passed',\n },\n failed: {\n type: 'number',\n description: 'Number of tests that failed',\n },\n skipped: {\n type: 'number',\n description: 'Number of tests skipped',\n },\n command: {\n type: 'string',\n description: 'Command used to run the tests',\n },\n output: {\n type: 'string',\n description: 'Test output (truncated if needed)',\n },\n duration: {\n type: 'number',\n description: 'Duration in milliseconds',\n },\n suites: {\n type: 'array',\n description: 'Optional suite-level breakdown',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Suite name' },\n passed: { type: 'number', description: 'Passed tests in suite' },\n failed: { type: 'number', description: 'Failed tests in suite' },\n skipped: { type: 'number', description: 'Skipped tests in suite' },\n duration: { type: 'number', description: 'Suite duration in ms' },\n },\n required: ['name', 'passed', 'failed'],\n },\n },\n tests: {\n type: 'array',\n description: 'Optional individual test breakdown',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Test name' },\n suite: { type: 'string', description: 'Parent suite name' },\n status: { type: 'string', enum: ['passed', 'failed', 'skipped'], description: 'Test result' },\n duration: { type: 'number', description: 'Test duration in ms' },\n },\n required: ['name', 'status'],\n },\n },\n },\n required: ['testType', 'passed', 'failed'],\n },\n },\n notes: {\n type: 'string',\n description: 'Additional notes to append to the ticket',\n },\n filesCreated: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files created during this session. Accumulated incrementally.',\n },\n filesModified: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files modified during this session. Accumulated incrementally.',\n },\n filesDeleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files deleted during this session. Accumulated incrementally.',\n },\n discovery: {\n type: 'object',\n description: 'Create a discovery (observation about the implementation). Use this to report blockers, bugs, tech debt, scope changes, etc.',\n properties: {\n description: { type: 'string', description: 'Description of the discovery' },\n type: { type: 'string', description: 'Discovery type: bug, tech_debt, blocker, clarification, scope_change, dependency, risk, ticket, epic' },\n severity: { type: 'string', description: 'Severity: blocker, critical, major, minor' },\n suggestedTitle: { type: 'string', description: 'Suggested title for the new ticket/epic' },\n suggestedPriority: { type: 'string', description: 'Suggested priority: high, medium, low' },\n relatedFiles: { type: 'array', items: { type: 'string' }, description: 'Related file paths' },\n notes: { type: 'string', description: 'Additional notes' },\n },\n required: ['description'],\n },\n blockReason: {\n type: 'string',\n description: 'Set a blocker on this ticket. Requires an existing discovery (create via discovery parameter first).',\n },\n getTicket: {\n type: 'boolean',\n description: 'Fetch full ticket details. Can be the sole operation or combined with other actions.',\n },\n includeFullContext: {\n type: 'boolean',\n description: 'Include full implementation context in response',\n },\n codeSnippetsReviewed: {\n type: 'boolean',\n description: 'Confirm that code snippets (codeReferences) on the ticket have been reviewed. Required before completion when the ticket has non-empty codeReferences.',\n },\n typeReferencesReviewed: {\n type: 'boolean',\n description: 'Confirm that type references (typeReferences) on the ticket have been reviewed. Required before completion when the ticket has non-empty typeReferences.',\n },\n },\n required: ['ticketId'],\n },\n },\n {\n name: 'complete_work_session',\n description:\n 'Mark a ticket as complete and finalize the active WorkSession. Transitions active -> done. Session data (files, test results, time) is stored on the WorkSession record.\\n\\n' +\n 'All acceptance criteria must be validated and all implementation steps must be completed via action_work_session before calling this. The completion gate enforces this — shortcuts are not available.\\n\\n' +\n 'Automatically recalculates status for dependent tickets and returns cascade info.\\n\\n' +\n 'Optional validation flags can be provided to report test results inline:\\n' +\n '- tests: Unit/integration test results\\n' +\n '- lint: Linting results\\n' +\n '- typeCheck: TypeScript type checking\\n' +\n '- build: Build/compilation results',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket',\n },\n summary: {\n type: 'string',\n description: 'Summary of work completed',\n },\n filesModified: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files modified',\n },\n filesCreated: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files created',\n },\n filesDeleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files deleted',\n },\n actualHours: {\n type: 'number',\n description: 'Actual hours spent on the ticket',\n },\n validation: {\n type: 'object',\n description: 'Detailed validation flags for reporting test/lint/build results',\n properties: {\n tests: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Unit/integration test results',\n },\n lint: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Linting results',\n },\n typeCheck: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'TypeScript type checking results',\n },\n build: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Build/compilation results',\n },\n notes: {\n type: 'string',\n description: 'Additional validation notes',\n },\n },\n },\n },\n required: ['ticketId', 'summary'],\n },\n },\n {\n name: 'start_review_session',\n description: 'Start the implementation review lifecycle. Runs the implementation gate and either auto-transitions to \"reviewed\" (on pass) or transitions to \"in_review\" with an active ReviewSession (on fail). Creates correction tickets via action_review_session, then call complete_review_session.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification to review (must be in ready_for_review status)',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'action_review_session',\n description: 'Address findings in an active review session. Create correction tickets inline or dismiss findings with justification. Only available when specification is in \"in_review\" status.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n reviewSessionId: {\n type: 'string',\n description: 'The review session ID (auto-detected if omitted)',\n },\n findingsAddressed: {\n type: 'array',\n description: 'Findings to address in this action',\n items: {\n type: 'object',\n properties: {\n findingId: {\n type: 'string',\n description: 'The finding ID to address',\n },\n action: {\n type: 'string',\n enum: ['correction_ticket', 'dismissed'],\n description: 'How to address the finding',\n },\n correctionTicket: {\n type: 'object',\n description: 'Inline ticket creation params (required for correction_ticket action)',\n properties: {\n epicId: { type: 'string', description: 'Epic to add the correction ticket to' },\n title: { type: 'string', description: 'Ticket title' },\n description: { type: 'string', description: 'Ticket description' },\n ticketType: { type: 'string', enum: ['implementation', 'verification'], description: 'Ticket type — defaults to implementation.' },\n complexity: { type: 'string', enum: ['small', 'medium', 'large', 'xlarge'] },\n estimatedMinutes: { type: 'integer', minimum: 0 },\n acceptanceCriteria: { type: 'array', items: { type: 'string' } },\n implementationSteps: { type: 'array', items: { type: 'string' }, description: 'Implementation steps; persisted as TicketImplementationStep rows' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n required: ['epicId', 'title'],\n },\n justification: {\n type: 'string',\n description: 'Required justification when action is \"dismissed\"',\n },\n },\n required: ['findingId', 'action'],\n },\n },\n notes: {\n type: 'string',\n description: 'Optional notes for this review action',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'complete_review_session',\n description: 'Complete an active review session. All error-severity findings must be addressed. If correction tickets exist, transitions to \"in_progress\". If all findings dismissed, triggers user confirmation flow.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n reviewSessionId: {\n type: 'string',\n description: 'The review session ID (auto-detected if omitted)',\n },\n summary: {\n type: 'string',\n description: 'Optional completion summary',\n },\n confirmAllDismissed: {\n type: 'boolean',\n description: 'Set to true when all findings were dismissed to trigger user confirmation flow',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'reopen_specification',\n description: 'Reopen a specification in \"ready\" status, regressing to \"planning\". After reopening, call start_planning_session to begin a new planning session.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification to reopen',\n },\n },\n required: ['specificationId'],\n },\n },\n\n // Spec creation is a HUMAN bootstrap step, NOT an agent MCP tool: specs are\n // created via `specforge init` (cli-rest surface), which also writes the new\n // spec id into the local config so the agent's per-call injection finds it.\n // The agent assumes the spec already exists and starts from\n // `start_planning_session`. (Backend keeps `create_specification` REST-only;\n // it was never dispatchable on /local.)\n\n // ========================================================================\n // Utilities (3)\n // ========================================================================\n {\n name: 'feedback',\n description: `Submit and manage feedback about MCP tools. Operations:\n- submit: Submit new feedback (requires category, summary)\n- list: List recent feedback entries\n- get: Get a specific feedback entry by ID`,\n inputSchema: {\n type: 'object',\n properties: {\n operation: {\n type: 'string',\n enum: ['submit', 'list', 'get'],\n description: 'The operation to perform',\n },\n // For submit operation\n category: {\n type: 'string',\n enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],\n description: 'Feedback category (required for submit)',\n },\n summary: {\n type: 'string',\n description: 'Brief summary of the feedback (required for submit)',\n },\n severity: {\n type: 'string',\n enum: ['critical', 'high', 'medium', 'low'],\n description: 'Severity level (default: medium)',\n },\n tool: {\n type: 'string',\n description: 'Which MCP tool this relates to',\n },\n toolOperation: {\n type: 'string',\n description: 'Specific operation within the tool',\n },\n details: {\n type: 'string',\n description: 'Extended description',\n },\n expected: {\n type: 'string',\n description: 'Expected behavior',\n },\n actual: {\n type: 'string',\n description: 'Actual behavior',\n },\n errorMessage: {\n type: 'string',\n description: 'Error message if reporting a bug',\n },\n ticketId: {\n type: 'string',\n description: 'Related ticket ID',\n },\n // For list operation\n limit: {\n type: 'number',\n description: 'Maximum entries to return (default: 10)',\n },\n categoryFilter: {\n type: 'string',\n enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],\n description: 'Filter by category',\n },\n // For get operation\n feedbackId: {\n type: 'string',\n description: 'Feedback ID to retrieve (required for get)',\n },\n },\n required: ['operation'],\n },\n },\n {\n name: 'link_pull_request',\n description: 'Associate a pull request with a ticket',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket',\n },\n prNumber: {\n type: 'number',\n description: 'PR number (provide this or prUrl)',\n },\n prUrl: {\n type: 'string',\n description: 'Full PR URL (GitHub, GitLab, or Bitbucket)',\n },\n title: {\n type: 'string',\n description: 'PR title',\n },\n author: {\n type: 'string',\n description: 'PR author',\n },\n repoUrl: {\n type: 'string',\n description: 'Repository URL (required if using prNumber)',\n },\n },\n required: ['ticketId'],\n },\n },\n\n // ========================================================================\n // Orchestration (2)\n // ========================================================================\n {\n name: 'get_critical_path',\n description: 'Get the critical execution path for a specification.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'Specification ID',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'get_dependency_tree',\n description: 'Get the full dependency tree for a specification.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'Specification ID',\n },\n },\n required: ['specificationId'],\n },\n },\n ];\n\n // Mark the 7 work+review verbs as in_development — mirrors @specforge/core\n // getToolDefinitions so a mcp-local agent also gets the \"coming soon\" affordance\n // (calling them returns a typed stub) instead of believing they are stable.\n const IN_DEVELOPMENT_PLANNED_FOR: Record<string, string> = {\n start_work_session: '0.2.0',\n action_work_session: '0.2.0',\n complete_work_session: '0.2.0',\n start_review_session: '0.3.0',\n action_review_session: '0.3.0',\n complete_review_session: '0.3.0',\n };\n for (const t of tools) {\n const plannedFor = IN_DEVELOPMENT_PLANNED_FOR[t.name];\n if (plannedFor) {\n t.description =\n `**In development — ships with ${plannedFor}.** Calling returns a typed stub ` +\n `response the client should render as a \"coming soon\" affordance.\\n\\n${t.description}`;\n }\n }\n\n return tools;\n}\n\n/**\n * Tool handler type - processes arguments and returns a result\n */\ntype ToolHandler = (\n apiClient: ApiClient,\n args: Record<string, unknown>\n) => Promise<unknown>;\n\n/**\n * Retry configuration for transient failures\n */\nconst RETRY_CONFIG = {\n maxRetries: 3,\n initialDelayMs: 500,\n maxDelayMs: 5000,\n backoffMultiplier: 2,\n};\n\n/**\n * Transient error patterns that should trigger retry\n */\nconst TRANSIENT_ERROR_PATTERNS = [\n /ETIMEDOUT/i,\n /ECONNRESET/i,\n /ECONNREFUSED/i,\n /socket hang up/i,\n /network error/i,\n /too many requests/i,\n /rate limit/i,\n /5\\d{2}/, // 5xx status codes\n];\n\n/**\n * Check if an error is transient and should be retried\n */\nfunction isTransientError(error: Error): boolean {\n return TRANSIENT_ERROR_PATTERNS.some(pattern =>\n pattern.test(error.message)\n );\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Execute a function with retry logic for transient failures\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n toolName: string,\n debug: boolean\n): Promise<T> {\n let lastError: Error | null = null;\n let delay = RETRY_CONFIG.initialDelayMs;\n\n for (let attempt = 1; attempt <= RETRY_CONFIG.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < RETRY_CONFIG.maxRetries && isTransientError(lastError)) {\n if (debug) {\n console.error(\n `[DEBUG] Tool ${toolName} attempt ${attempt} failed with transient error, retrying in ${delay}ms:`,\n lastError.message\n );\n }\n await sleep(delay);\n delay = Math.min(delay * RETRY_CONFIG.backoffMultiplier, RETRY_CONFIG.maxDelayMs);\n } else {\n break;\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Create tool handlers that call the API with proper request formatting\n *\n * @param apiClient - The API client to use for making requests\n * @returns Record of tool handlers keyed by tool name\n */\nexport function createToolHandlers(\n apiClient: ApiClient\n): Record<string, ToolHandler> {\n // Agent `/local` path (M9, approach A): the transport returns the raw M8 body;\n // interpret the envelope here. Lifecycle → unwrap to `agentResponse`; standard\n // error → throw the composed guidance prose (M9.3); raw success → pass through.\n const callLocal = async <T = unknown>(\n op: string,\n args: Record<string, unknown>,\n ): Promise<T> => {\n // SPECFORGE_DEBUG=true → trace the EXACT wire request/response for what a tool handler\n // forwards to /local after its arg-mapping (e.g. the inner `payload` shape\n // `action_work_session` sends). Prefers a file (SPECFORGE_DEBUG_FILE) since an MCP-serve\n // subprocess's stderr may be swallowed by the host; falls back to stderr (stdout is the\n // MCP JSON protocol and must stay clean).\n const debug = process.env.SPECFORGE_DEBUG === 'true';\n const debugFile = process.env.SPECFORGE_DEBUG_FILE;\n const trace = (line: string) => {\n if (!debug) return;\n if (debugFile) { try { appendFileSync(debugFile, line + '\\n'); return; } catch { /* fall through */ } }\n process.stderr.write(line + '\\n');\n };\n trace(`[cli:wire →] ${op} ${JSON.stringify(args)}`);\n const body = await apiClient.getTransport().execute<Record<string, unknown>>(op, args);\n trace(`[cli:wire ←] ${op} ${JSON.stringify(body).slice(0, 800)}`);\n if (body && typeof body === 'object') {\n if (body.kind === 'standard_error') {\n // M9.3: the error-guidance composer's `guidance.prose` is the canonical\n // agent-facing message (same verbatim convention as lifecycle guidance);\n // surface it for query-tool errors, falling back to `message` (and to a\n // generic line for INTERNAL, where guidance is always null).\n const guidance = body.guidance as { prose?: unknown } | null | undefined;\n const prose = guidance && typeof guidance.prose === 'string' ? guidance.prose : undefined;\n throw new Error(\n prose ?? (typeof body.message === 'string' ? body.message : `Operation failed: ${op}`),\n );\n }\n if (body.kind === 'lifecycle' && 'agentResponse' in body) {\n return body.agentResponse as T;\n }\n }\n return body as T;\n };\n\n return {\n // ========================================================================\n // Queries — forward the canonical super-tools straight through (the backend\n // owns the `type` dispatch; M9 dropped the old granular-op fan-out).\n // ========================================================================\n get: async (_client, args) => {\n if (!args.type) throw new Error('Missing required argument: type');\n // Project/spec ids inject from config when the agent omits them.\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n return await callLocal('get', withCtx);\n },\n\n list: async (_client, args) => {\n if (!args.type) throw new Error('Missing required argument: type');\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n return await callLocal('list', withCtx);\n },\n\n search: async (_client, args) => {\n if (!args.query && !args.files && !args.tags && !args.relatedTo) {\n throw new Error('At least one filter is required: query, files, tags, or relatedTo');\n }\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n if (!withCtx.projectId && !withCtx.specificationId && !withCtx.epicId) {\n throw new Error('One of projectId, specificationId, or epicId is required. Run \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('search', withCtx);\n },\n\n get_next_actionable_tickets: async (_client, args) => {\n // Inject projectId/specificationId from .specforge.json if not provided\n const argsWithContext = injectContext(args, ['projectId', 'specificationId']);\n\n // Either specificationId or projectId is required (after injection)\n if (!argsWithContext.specificationId && !argsWithContext.projectId) {\n throw new Error('Either specificationId or projectId is required. Set working context with \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('get_next_actionable_tickets', {\n specificationId: argsWithContext.specificationId,\n projectId: argsWithContext.projectId,\n limit: argsWithContext.limit ?? 5,\n });\n },\n\n get_blocked_tickets: async (_client, args) => {\n // Inject specificationId from .specforge.json if not provided\n const argsWithContext = injectContext(args, ['specificationId']);\n\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required. Set working context with \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('get_blocked_tickets', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n get_report: async (_client, args) => {\n validateRequired(args, 'type', 'scope', 'scopeId');\n return await callLocal('get_report', {\n type: args.type,\n scope: args.scope,\n scopeId: args.scopeId,\n format: args.format ?? 'json',\n startDate: args.startDate,\n endDate: args.endDate,\n });\n },\n\n // ========================================================================\n // Lifecycle\n // ========================================================================\n // Planning lifecycle (M9.6b) — identity/session injected from the\n // `.specforge` config; SPS persists the session id, a `closed` status\n // clears it. Payloads match the post-M8 boundary (SPS {specificationId};\n // APS {sessionId, operation:{type,...}}; CPS {sessionId}).\n start_planning_session: async (_client, args) => {\n const cfg = tryLoadProjectConfig();\n const specificationId = (args.specificationId as string) ?? cfg?.specificationId;\n if (!specificationId) {\n throw new Error('No active specification. Run `specforge switch <spec-id>` or pass specificationId.');\n }\n // projectId is injected from local config (client-authoritative scope);\n // SPS no longer derives it server-side from the spec row.\n const projectId = (args.projectId as string) ?? cfg?.projectId;\n if (!projectId) {\n throw new Error('No active project. Run `specforge switch <spec-id>` or pass projectId.');\n }\n const agentResponse = await callLocal<{ sessionId?: string }>(\n 'start_planning_session',\n { projectId, specificationId },\n );\n if (agentResponse?.sessionId) {\n saveProjectConfig({ planningSessionId: agentResponse.sessionId });\n appendPlanningSessionRegistry({\n specificationId,\n planningSessionId: agentResponse.sessionId,\n startedAt: new Date().toISOString(),\n });\n }\n return agentResponse;\n },\n\n action_planning_session: async (_client, args) => {\n if (!args.operation || typeof args.operation !== 'object') {\n throw new Error('Missing required argument: operation (e.g. { type: \"get_planning_status\" })');\n }\n const cfg = tryLoadProjectConfig();\n const sessionId = (args.sessionId as string) ?? cfg?.planningSessionId;\n if (!sessionId) {\n throw new Error('No active planning session. Call start_planning_session first.');\n }\n const agentResponse = await callLocal<{ planningStatus?: string }>(\n 'action_planning_session',\n { sessionId, operation: args.operation },\n );\n // Close detection: clear the persisted session id once it closes.\n if (agentResponse?.planningStatus === 'closed' && cfg?.specificationId) {\n saveProjectConfig({ planningSessionId: undefined });\n markPlanningSessionRegistryCompleted({\n specificationId: cfg.specificationId,\n completedAt: new Date().toISOString(),\n });\n }\n return agentResponse;\n },\n\n complete_planning_session: async (_client, args) => {\n const cfg = tryLoadProjectConfig();\n const sessionId = (args.sessionId as string) ?? cfg?.planningSessionId;\n if (!sessionId) {\n throw new Error('No active planning session. Call start_planning_session first.');\n }\n // CPS-success flips to awaiting_human_review (not closed) — keep the id.\n // MB.10.5 — grep double-call. Pass-1 sends NO evidence: in cross_validation\n // the server may reply `evidence_required` with a `grepRequest` (the exact\n // paths it can't resolve spec-internally). Probe JUST those paths locally,\n // then re-call CPS with the existing subset injected as `existingFiles`\n // (pass-2, the committing verdict). Outside a worktree the probe returns []\n // → re-call with [] → strict verdict (never blocks a repo-less caller).\n // From the agent's view this stays ONE tool call: only pass-2 is returned.\n const first = await callLocal<{ outcome?: string; grepRequest?: { paths?: string[] } }>(\n 'complete_planning_session',\n { sessionId },\n );\n if (first?.outcome !== 'evidence_required') {\n return first;\n }\n const requested = Array.isArray(first.grepRequest?.paths) ? first.grepRequest.paths : [];\n const existingFiles = probeExistingFiles(requested);\n return await callLocal('complete_planning_session', { sessionId, existingFiles });\n },\n\n start_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId');\n // MCP-local git injection (M23.2): the CLM/agent runs on the worktree the\n // Lambda can't see, so THIS process reads the git evidence and injects it —\n // `gitClean` feeds the SWS git-clean precondition; `worktreePath`/`branch`\n // are persisted onto the WorkSession (M16.2). Provenance is `null` when the\n // agent is not inside a git worktree (SWS still records the session).\n const git = readWorktreeGitEvidence();\n return await callLocal('start_work_session', {\n ticketId: args.ticketId,\n gitClean: git.gitClean,\n worktreePath: git.worktreePath,\n branch: git.branch,\n });\n },\n\n action_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId');\n // The AWS action vocab (mark_implementation_step_completion / mark_acceptance_check /\n // record_test_result / add_*_justification / record_file_change / create_discovery\n // (with `blocking`) / update_discovery / set_discovery_resolved) rides in `action`\n // — the discriminated `AwsActionInput`. The CLI forwards it verbatim as the inner\n // `payload` (the work analog of action_planning_session forwarding `operation`);\n // the lifecycle dispatches on `payload.action`.\n return await callLocal('action_work_session', {\n ticketId: args.ticketId,\n payload: args.action ?? args.payload,\n });\n },\n\n complete_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId', 'summary');\n // MCP-local git-commit binding (M23.2): the deployed Lambda has no worktree, so\n // THIS process reads the HEAD commit hash and injects it as `commitSha`. CWS's\n // git-evidence gate binds it onto the WorkSession and finalizes — without it a\n // passing session holds forever (\"commit your work first\"). `null` when the agent\n // is not inside a git worktree (the gate then holds, as intended for non-git callers).\n const commitSha = readHeadCommitSha();\n return await callLocal('complete_work_session', {\n ticketId: args.ticketId,\n summary: args.summary,\n filesModified: args.filesModified,\n filesCreated: args.filesCreated,\n filesDeleted: args.filesDeleted,\n actualHours: args.actualHours,\n validation: args.validation,\n ...(commitSha !== null && { commitSha }),\n });\n },\n\n start_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('start_review_session', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n action_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('action_review_session', {\n specificationId: argsWithContext.specificationId,\n reviewSessionId: args.reviewSessionId,\n findingsAddressed: args.findingsAddressed,\n notes: args.notes,\n });\n },\n\n complete_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('complete_review_session', {\n specificationId: argsWithContext.specificationId,\n reviewSessionId: args.reviewSessionId,\n summary: args.summary,\n confirmAllDismissed: args.confirmAllDismissed,\n });\n },\n\n reopen_specification: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('reopen_specification', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n // ========================================================================\n // Mutation\n // ========================================================================\n\n // ========================================================================\n // Utilities\n // ========================================================================\n feedback: async (_client, args) => {\n // M9.7: origin is server-derived from the `X-SpecForge-Origin` header\n // (default `mcp` on the agent transport) — never a request-body `source`.\n return await callLocal('feedback', args);\n },\n\n link_pull_request: async (_client, args) => {\n validateRequired(args, 'ticketId');\n if (!args.prNumber && !args.prUrl) {\n throw new Error('Either prNumber or prUrl must be provided');\n }\n return await callLocal('link_pull_request', {\n ticketId: args.ticketId,\n prNumber: args.prNumber,\n prUrl: args.prUrl,\n title: args.title,\n author: args.author,\n repoUrl: args.repoUrl,\n });\n },\n\n // ========================================================================\n // Orchestration\n // ========================================================================\n get_critical_path: async (_client, args) => {\n const argsWithContext = injectContext(args, ['specificationId']);\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required');\n }\n return await callLocal('get_critical_path', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n get_dependency_tree: async (_client, args) => {\n const argsWithContext = injectContext(args, ['specificationId']);\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required');\n }\n return await callLocal('get_dependency_tree', {\n specificationId: argsWithContext.specificationId,\n });\n },\n };\n}\n\n/**\n * Validate that required arguments are present\n * @throws Error if any required argument is missing\n */\nfunction validateRequired(args: Record<string, unknown>, ...required: string[]): void {\n for (const field of required) {\n if (args[field] === undefined || args[field] === null || args[field] === '') {\n throw new Error(`Missing required argument: ${field}`);\n }\n }\n}\n\n// Create a cached instance of tool handlers\nlet cachedHandlers: Record<string, ToolHandler> | null = null;\n\n/**\n * Reset the cached tool handlers (for testing purposes)\n */\nexport function resetToolHandlers(): void {\n cachedHandlers = null;\n}\n\n/**\n * Handle a tool call by routing to the appropriate handler\n *\n * @param apiClient - The API client to use for making requests\n * @param toolName - Name of the tool being called\n * @param args - Arguments passed to the tool\n * @param debug - Whether to enable debug logging\n * @returns Promise resolving to the tool result\n */\nexport async function handleToolCall(\n apiClient: ApiClient,\n toolName: string,\n args: Record<string, unknown>,\n debug: boolean = false\n): Promise<unknown> {\n const startTime = Date.now();\n\n // Create handlers if not cached\n if (!cachedHandlers) {\n cachedHandlers = createToolHandlers(apiClient);\n }\n\n // Get the handler for this tool\n const handler = cachedHandlers[toolName];\n if (!handler) {\n throw new Error(`Unknown tool: ${toolName}`);\n }\n\n if (debug) {\n console.error(`[DEBUG] Calling tool: ${toolName}`, {\n args: JSON.stringify(args),\n });\n }\n\n try {\n // Run comprehensive validation before executing\n validateToolArgs(toolName, args);\n\n // Execute with retry logic\n const result = await withRetry(\n () => handler(apiClient, args),\n toolName,\n debug\n );\n\n const duration = Date.now() - startTime;\n if (debug) {\n console.error(`[DEBUG] Tool ${toolName} completed in ${duration}ms`);\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Transform error for proper handling\n const transformedError = transformError(error);\n const message = transformedError.message;\n\n if (debug) {\n console.error(`[DEBUG] Tool ${toolName} failed after ${duration}ms:`, message);\n if (transformedError instanceof ValidationError) {\n console.error(`[DEBUG] Validation field: ${transformedError.field}, code: ${transformedError.code}`);\n }\n }\n\n // Rethrow with context\n if (transformedError instanceof ValidationError) {\n throw transformedError;\n }\n if (transformedError instanceof ApiError) {\n throw transformedError;\n }\n throw new Error(`Tool ${toolName} failed: ${message}`);\n }\n}\n\n/**\n * Handle a tool call and return MCP-formatted response\n * This wraps handleToolCall with proper error formatting for MCP protocol\n */\nexport async function handleToolCallSafe(\n apiClient: ApiClient,\n toolName: string,\n args: Record<string, unknown>,\n debug: boolean = false\n): Promise<unknown | MCPErrorResponse> {\n try {\n return await handleToolCall(apiClient, toolName, args, debug);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n return formatMCPError(err);\n }\n}\n\n// Re-export validation utilities for use by other modules\nexport {\n ValidationError,\n ApiError,\n validateToolArgs,\n formatMCPError,\n transformError,\n type MCPErrorResponse,\n} from '../validation/index.js';\n"],"mappings":"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","names":["ValidationError","ApiError","validateToolArgs","formatMCPError","transformError"]}
1
+ {"version":3,"sources":["../../src/tools/index.ts"],"sourcesContent":["import { appendFileSync } from 'node:fs';\n/**\n * MCP Tools Registry\n *\n * This module defines and exports all available MCP tools.\n * 22 tools organized into: Queries, Lifecycle, Mutation, Utilities, Orchestration.\n */\n\nimport { ApiClient } from '../client/api-client.js';\nimport {\n ValidationError,\n ApiError,\n validateToolArgs,\n formatMCPError,\n transformError,\n MCPErrorResponse,\n} from '../validation/index.js';\nimport { injectContext, injectContextRequired } from './core/context-helper.js';\nimport { probeExistingFiles } from './core/file-existence-injection.js';\nimport { readWorktreeGitEvidence, readHeadCommitSha } from './core/git-injection.js';\nimport { tryLoadProjectConfig, saveProjectConfig } from '../cli/config/index.js';\nimport {\n appendPlanningSessionRegistry,\n markPlanningSessionRegistryCompleted,\n} from '../cli/config/planning-sessions-registry.js';\n\n/**\n * Tool definition matching MCP protocol schema\n */\nexport interface Tool {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/**\n * Get list of all available tools\n *\n * @returns Array of tool definitions (22 tools)\n */\nexport function getTools(): Tool[] {\n const tools: Tool[] = [\n // ========================================================================\n // Queries (6)\n // ========================================================================\n {\n name: 'get',\n description: 'Get a single entity by type and ID.',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['project', 'specification', 'epic', 'ticket', 'blueprint'],\n description: 'Entity type to retrieve',\n },\n id: {\n type: 'string',\n description: 'Entity ID',\n },\n },\n required: ['type', 'id'],\n },\n },\n {\n name: 'list',\n description: 'List entities by type.',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['projects', 'specifications', 'epics', 'tickets', 'blueprints'],\n description: 'Entity type to list',\n },\n projectId: {\n type: 'string',\n description: 'Filter by project (for specifications)',\n },\n specificationId: {\n type: 'string',\n description: 'Filter by specification (for epics, tickets)',\n },\n epicId: {\n type: 'string',\n description: 'Filter by epic (for tickets)',\n },\n },\n required: ['type'],\n },\n },\n {\n name: 'search',\n description: `Unified ticket search with multiple filter options.\n\nCombines:\n- Full-text search (query)\n- File matching (files) - replaces find_tickets_by_file\n- Tag filtering (tags) - replaces find_tickets_by_tag\n- Related tickets (relatedTo) - replaces find_related_tickets\n- Status, complexity, priority filters\n\nAt least one of: query, files, tags, or relatedTo is required.\nAt least one scope filter (projectId, specificationId, or epicId) is required.`,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Full-text search query',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'Glob patterns to match ticket files (e.g., \"**/channel/*.ts\")',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags to filter by',\n },\n matchAllTags: {\n type: 'boolean',\n description: 'If true, match all tags (AND). If false, match any (OR). Default: false',\n },\n relatedTo: {\n type: 'string',\n description: 'Find tickets related to this ticket ID (by tags, files, tech stack)',\n },\n status: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['pending', 'ready', 'active', 'done', 'blocked'],\n },\n description: 'Filter by status',\n },\n complexity: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['small', 'medium', 'large', 'xlarge'],\n },\n description: 'Filter by complexity',\n },\n projectId: {\n type: 'string',\n description: 'Limit search to project',\n },\n specificationId: {\n type: 'string',\n description: 'Limit search to specification',\n },\n epicId: {\n type: 'string',\n description: 'Limit search to epic',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20, max: 100)',\n },\n offset: {\n type: 'number',\n description: 'Pagination offset (default: 0)',\n },\n fields: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'id',\n 'epicId',\n 'ticketNumber',\n 'title',\n 'description',\n 'status',\n 'priority',\n 'complexity',\n 'estimatedHours',\n 'actualHours',\n 'acceptanceCriteria',\n 'implementation',\n 'technicalDetails',\n 'notes',\n 'tags',\n 'progress',\n 'testsPassed',\n 'order',\n 'startedAt',\n 'completedAt',\n 'createdAt',\n 'updatedAt',\n ],\n },\n description:\n 'Select specific fields to return. Returns all fields if not specified. id is always included.',\n },\n },\n },\n },\n {\n name: 'get_next_actionable_tickets',\n description: 'Get tickets with status \"ready\" (all dependencies satisfied). Use start_work_session() to begin work on these tickets.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification (optional if projectId provided)',\n },\n projectId: {\n type: 'string',\n description: 'The ID of the project to get actionable tickets across all specifications',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of tickets to return (default: 5)',\n },\n },\n },\n },\n {\n name: 'get_blocked_tickets',\n description: 'Get tickets with status \"pending\", each with the `blockedBy` list of unsatisfied dependency tickets computed from the dependency tree.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'get_report',\n description: `Generate unified reports for implementation, time tracking, blockers, work summary, or active sessions.\n\nReport types:\n- 'implementation': Progress, velocity, completions (replaces get_implementation_summary)\n- 'time': Estimated vs actual hours (replaces get_time_report)\n- 'blockers': Blocked tickets with reasons (replaces get_blockers_report)\n- 'work': Completed work summary from WorkSession records (replaces get_work_summary)\n- 'sessions': Live planning/work/review sessions for a project (requires scope='project')\n\nFormat options:\n- 'json': Full structured data (default)\n- 'summary': Condensed text summary`,\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['implementation', 'time', 'blockers', 'work', 'sessions'],\n description: 'Type of report to generate',\n },\n scope: {\n type: 'string',\n enum: ['project', 'specification', 'epic'],\n description: \"Scope of the report. 'sessions' requires scope='project'.\",\n },\n scopeId: {\n type: 'string',\n description: 'ID of the scoped entity (projectId, specificationId, or epicId)',\n },\n startDate: {\n type: 'string',\n description: 'Start date for work report (ISO 8601)',\n },\n endDate: {\n type: 'string',\n description: 'End date for work report (ISO 8601)',\n },\n format: {\n type: 'string',\n enum: ['json', 'summary'],\n description: \"Response format: 'json' (default) or 'summary'.\",\n },\n },\n required: ['type', 'scope', 'scopeId'],\n },\n },\n\n // ========================================================================\n // Lifecycle (10)\n // ========================================================================\n {\n name: 'start_planning_session',\n description: 'Start or resume a guided planning session for a specification. Project-scoped lock: only one active planning session per project. Calling with the same spec resumes the existing session (idempotent). Calling with a different spec while one is active returns a rejection with the active session details. Planning is independent of implementation and review — they can run concurrently.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The specification to plan. Optional — defaults to the active spec in the local config (.specforge/config.json), so you normally omit it.',\n },\n projectId: {\n type: 'string',\n description: 'The owning project. Optional — defaults to the active project in the local config (.specforge/config.json); injected automatically, so you normally omit it.',\n },\n },\n // Nothing is required: specificationId/projectId fall back to local config, and\n // the returned sessionId is persisted + injected into subsequent calls.\n required: [],\n },\n },\n {\n name: 'action_planning_session',\n description: \"Execute a planning action within an active session. Wraps all planning operations (create/update/delete epics, tickets, dependencies, blueprints) plus get_planning_status (readiness X-ray, worst-first) with automatic status tracking. The operation.type IS the backend PlanningOperationName. The spec status advances or regresses automatically based on the action type and gate checks. Returns updated progress, blockers, and next suggested actions after every call. To read a single ticket, use the `get` tool (type:'ticket').\",\n inputSchema: {\n type: 'object',\n properties: {\n operation: {\n type: 'object',\n description: 'The operation to perform. Must include a \"type\" field. Per-op required fields are declared in `oneOf` below — agents should consult their own tool schema parser for the exact shape per type. Do NOT pass sessionId/projectId/specificationId: the active planning session is injected from local config.',\n properties: {\n type: {\n type: 'string',\n enum: [\n 'update_spec',\n 'create_epic',\n 'update_epic',\n 'delete_epic',\n 'create_ticket',\n 'update_ticket',\n 'delete_ticket',\n 'create_blueprint',\n 'update_blueprint',\n 'delete_blueprint',\n 'link_blueprint_to_tickets',\n 'unlink_blueprint_to_tickets',\n 'link_step_file',\n 'unlink_step_file',\n 'link_step_snippet',\n 'unlink_step_snippet',\n 'create_dependencies',\n 'delete_dependencies',\n 'apply_creator_election',\n 'justify',\n 'unjustify',\n 'get_planning_status',\n ],\n description: 'The planning operation to perform (lifecycle vocabulary). The type IS the backend PlanningOperationName; remaining fields are the operation payload.',\n },\n },\n required: ['type'],\n oneOf: [\n {\n properties: {\n type: { const: 'update_spec' },\n fields: { type: 'object', description: 'Partial spec update — only the keys you send are changed (e.g. background, goals, nonGoals, constraints, successCriteria). Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.' },\n },\n required: ['type', 'fields'],\n },\n // create_epic — SHELL only (epic_decomposition). Body fields are authored\n // by update_epic in epic_expansion; only title/description/objective are\n // persisted on create, so only those are advertised.\n {\n properties: {\n type: { const: 'create_epic' },\n title: { type: 'string', minLength: 1, description: 'Epic title (non-empty)' },\n description: { type: 'string', description: 'What this epic delivers' },\n objective: { type: 'string', description: 'Goal achieved for the user' },\n },\n required: ['type', 'title'],\n },\n {\n properties: {\n type: { const: 'update_epic' },\n id: { type: 'string', description: 'Epic id (use list_epics / lookup_epic to find).' },\n fields: {\n type: 'object',\n description: 'Partial epic update — only the keys you send are changed. Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.',\n properties: {\n title: { type: 'string' },\n description: { type: 'string' },\n objective: { type: 'string', description: 'Goal achieved for the user.' },\n architecture: { type: 'string', description: 'Structural approach specific to this epic.' },\n scope: { type: 'object', description: 'Epic scope.', properties: { inScope: { type: 'array', items: { type: 'string' } }, outOfScope: { type: 'array', items: { type: 'string' } }, assumptions: { type: 'array', items: { type: 'string' } }, externalDependencies: { type: 'array', items: { type: 'string' } } } },\n goals: { type: 'array', description: 'Epic goals as objects (Epic.goals is a json object[], not string[]).', items: { type: 'object', properties: { title: { type: 'string' }, description: { type: 'string' }, type: { type: 'string', enum: ['business', 'technical', 'user', 'operational'] }, successCriteria: { type: 'array', items: { type: 'string' } } }, required: ['title', 'description'] } },\n acceptanceCriteria: { type: 'array', description: 'BDD criteria objects (Epic.acceptanceCriteria is a json object[], not string[]).', items: { type: 'object', properties: { given: { type: 'string' }, when: { type: 'string' }, then: { type: 'string' } }, required: ['given', 'when', 'then'] } },\n validationCommands: { type: 'array', items: { type: 'string' }, description: 'Commands that verify this epic end-to-end.' },\n apiContracts: { type: 'array', description: 'API contracts this epic exposes.', items: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, type: { type: 'string' }, description: { type: 'string' } } } },\n sharedPatterns: { type: 'array', description: 'Reusable patterns the epic\\'s tickets should follow.', items: { type: 'object' } },\n fileStructures: { type: 'array', description: 'Concrete files this epic creates/modifies.', items: { type: 'object', properties: { id: { type: 'string' }, scope: { type: 'string' }, description: { type: 'string' }, content: { type: 'string' } } } },\n requirementsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec requirement ids this epic covers.' },\n nfrsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec NFR ids this epic covers.' },\n goalsCovered: { type: 'array', items: { type: 'string' }, description: 'Spec goal ids this epic advances.' },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n // create_ticket — SHELL (ticket_decomposition): epicId/title/description\n // + ticketType (the impl/verification decision, set HERE and immutable via\n // update_ticket). The remaining body fields are authored by update_ticket in\n // ticket_expansion; dependencies via create_dependencies in cross_validation.\n {\n properties: {\n type: { const: 'create_ticket' },\n epicId: { type: 'string', description: 'Parent epic id' },\n title: { type: 'string', minLength: 1, description: 'Ticket title (non-empty)' },\n description: { type: 'string' },\n ticketType: { type: 'string', enum: ['implementation', 'verification'], description: 'Ticket type — set here (decomposition); defaults to implementation. Not changeable via update_ticket.' },\n },\n required: ['type', 'epicId', 'title'],\n },\n {\n properties: {\n type: { const: 'update_ticket' },\n id: { type: 'string', description: 'Ticket id (use list_tickets / lookup_ticket to find).' },\n fields: {\n type: 'object',\n description: 'Partial ticket update — only the keys you send are changed. Child-backed arrays (acceptanceCriteria, implementationSteps, filesToBe*, testSpecification.testTypes, codeSnippets, typeSnippets) replace the whole set. Blueprint links are NOT settable here — use link_blueprint_to_tickets (from ticket_decomposition onward), the sole writer of the blueprint↔ticket relation. Fields that do not apply are declared with the `justify` op (undo with `unjustify`), never by writing values here.',\n properties: {\n title: { type: 'string' },\n description: { type: 'string' },\n complexity: { type: 'string', enum: ['small', 'medium', 'large', 'xlarge'] },\n estimatedMinutes: { type: 'integer', minimum: 0 },\n acceptanceCriteria: { type: 'array', items: { type: 'object', properties: { given: { type: 'string' }, when: { type: 'string' }, then: { type: 'string' } }, required: ['given', 'when', 'then'] } },\n implementationSteps: { type: 'array', description: 'Ordered build steps. Declare the file(s) each step produces INLINE via `producesFiles: [path]` (each path must also appear in filesToBeCreated/filesToBeModified) — links the step↔file in the SAME call so the ticket_expansion gate passes without a second pass. Every step MUST link ≥1 file and every produced file MUST be linked by ≥1 step (hard gates). `link_step_file` remains for post-hoc edits.', items: { type: 'object', properties: { text: { type: 'string' }, producesFiles: { type: 'array', items: { type: 'string' }, description: 'Paths this step produces — each must match an entry in filesToBeCreated/filesToBeModified; links the step↔file inline (path-based).' } }, required: ['text'] } },\n filesToBeCreated: { type: 'array', items: { type: 'string' } },\n filesToBeModified: { type: 'array', items: { type: 'string' } },\n filesToBeDeleted: { type: 'array', items: { type: 'string' } },\n filesToBeReferenced: { type: 'array', items: { type: 'string' } },\n guardrails: { type: 'array', items: { type: 'string' } },\n testSpecification: { type: 'object', properties: { testTypes: { type: 'array', items: { type: 'string', enum: ['unit', 'integration', 'e2e', 'typecheck', 'lint', 'build', 'contract', 'structural', 'layout', 'a11y', 'performance'] } }, qualityGates: { type: 'array', items: { type: 'string' } }, testCommands: { type: 'array', items: { type: 'string' } }, coverageTarget: { type: 'integer', minimum: 0, maximum: 100 } } },\n codeReferences: { type: 'array', description: 'Existing code to reuse/anchor on.', items: { type: 'object', properties: { filePath: { type: 'string' }, symbol: { type: 'string' }, description: { type: 'string' } }, required: ['filePath'] } },\n typeReferences: { type: 'array', description: 'Existing types to use.', items: { type: 'object', properties: { filePath: { type: 'string' }, typeName: { type: 'string' }, description: { type: 'string' } }, required: ['filePath', 'typeName'] } },\n codeSnippets: { type: 'array', description: 'Concrete code to write. Attach a snippet to its step INLINE via `stepId` (create-and-link); a snippet linking NO step is dangling and blocks the ticket.', items: { type: 'object', properties: { language: { type: 'string' }, content: { type: 'string' }, description: { type: 'string' }, stepId: { type: 'string', description: 'Implementation step id this snippet follows — links the snippet↔step inline.' } }, required: ['language', 'content'] } },\n typeSnippets: { type: 'array', description: 'Type/interface definitions to write. Attach to a step INLINE via `stepId` (create-and-link); a snippet linking NO step is dangling and blocks the ticket.', items: { type: 'object', properties: { language: { type: 'string' }, content: { type: 'string' }, description: { type: 'string' }, stepId: { type: 'string', description: 'Implementation step id this snippet follows — links the snippet↔step inline.' } }, required: ['language', 'content'] } },\n tags: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n {\n properties: {\n type: { const: 'delete_epic' },\n id: { type: 'string', description: 'Epic id; cascades to all tickets in the epic.' },\n cascadeRemoveDependencies: { type: 'boolean', description: 'Confirm removing dependency edges pointing at this epic\\'s tickets from outside the epic. Required (true) when such referrers exist, else the delete is denied.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'delete_ticket' },\n id: { type: 'string', description: 'Ticket id (use list_tickets / lookup_ticket to find).' },\n cascadeRemoveDependencies: { type: 'boolean', description: 'Confirm removing dependency edges from other tickets that point at this ticket. Required (true) when such referrers exist, else the delete is denied.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'create_dependencies' },\n dependencies: {\n type: 'array',\n minItems: 1,\n maxItems: 5000,\n description: 'Up to 5000 dependency pairs, each a \"requires\" edge (fromTicketId depends on toTicketId). The batch is validated atomically: a cycle or an all-duplicate batch is rejected with guidance; already-existing edges are skipped.',\n items: {\n type: 'object',\n properties: {\n fromTicketId: { type: 'string', description: 'The dependent ticket (this one depends on the other).' },\n toTicketId: { type: 'string', description: 'The blocker ticket it depends on.' },\n },\n required: ['fromTicketId', 'toTicketId'],\n },\n },\n },\n required: ['type', 'dependencies'],\n },\n {\n properties: {\n type: { const: 'delete_dependencies' },\n dependencyIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'TicketDependency ids to remove (use lookup/list to find).' },\n },\n required: ['type', 'dependencyIds'],\n },\n // apply_creator_election (MB.16.1) — the atomic creator-election batch: file\n // moves + producing steps + ordering deps in ONE cross-phase op. Only the\n // status:'clean' partition is applied; conflicts are excluded + surfaced to\n // get_ticket. `dependencies` may be empty (single-toucher flips).\n {\n properties: {\n type: { const: 'apply_creator_election' },\n elections: {\n type: 'array',\n minItems: 1,\n maxItems: 5000,\n description: 'The per-file creator elections. Each moves an orphan shared file to filesToBeCreated on its elected creator ticket + declares the producing step so the moved file is not a new orphan.',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'The orphan shared file path to resolve.' },\n kind: { type: 'string', enum: ['toBeCreated', 'toBeModified', 'toBeDeleted', 'toBeReferenced'], description: 'The target file-change kind on the elected ticket (normally toBeCreated).' },\n creatorTicketId: { type: 'string', description: 'The elected creator ticket (topologically-earliest toucher).' },\n producingStep: {\n type: 'object',\n description: 'The step that produces the moved file: pass an existing step id to link it, OR text to create-and-link a new step.',\n properties: {\n text: { type: 'string', description: 'Text of a NEW producing step to create + link.' },\n stepId: { type: 'string', description: 'Id of an EXISTING step to link to the moved file.' },\n },\n },\n },\n required: ['path', 'kind', 'creatorTicketId', 'producingStep'],\n },\n },\n dependencies: {\n type: 'array',\n maxItems: 5000,\n description: 'The ordering deps (each a \"requires\" edge). May be empty. Only the CLEAN partition\\'s deps are persisted (recomputed + cycle-checked server-side).',\n items: {\n type: 'object',\n properties: {\n fromTicketId: { type: 'string', description: 'The dependent ticket (a non-elected toucher).' },\n toTicketId: { type: 'string', description: 'The elected creator it depends on.' },\n },\n required: ['fromTicketId', 'toTicketId'],\n },\n },\n },\n required: ['type', 'elections', 'dependencies'],\n },\n {\n properties: {\n type: { const: 'create_blueprint' },\n title: { type: 'string', minLength: 1, description: 'Blueprint title (non-empty)' },\n content: { type: 'string', description: 'Body — diagram source or markdown, persisted as-is on create.' },\n format: { type: 'string', enum: ['markdown', 'mermaid', 'ascii', 'mixed', 'html', 'svg', 'image'], description: 'Defaults to \"mermaid\"' },\n category: { type: 'string', enum: ['flowchart', 'architecture', 'state', 'sequence', 'erd', 'mockup', 'adr', 'component', 'deployment', 'api', 'algorithm', 'protocol', 'glossary', 'design_system'], description: 'Blueprint category (SpecificationBlueprint.category model enum).' },\n description: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n required: ['type', 'title', 'category'],\n },\n {\n properties: {\n type: { const: 'update_blueprint' },\n id: { type: 'string', description: 'Blueprint id.' },\n fields: {\n type: 'object',\n description: 'Partial blueprint update — only the keys you send are changed.',\n properties: {\n title: { type: 'string' },\n content: { type: 'string' },\n category: { type: 'string' },\n description: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n required: ['type', 'id', 'fields'],\n },\n {\n properties: {\n type: { const: 'delete_blueprint' },\n id: { type: 'string', description: 'Blueprint id.' },\n },\n required: ['type', 'id'],\n },\n {\n properties: {\n type: { const: 'link_blueprint_to_tickets' },\n blueprintId: { type: 'string', description: 'Blueprint to link.' },\n ticketIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'Tickets to link the blueprint to.' },\n },\n required: ['type', 'blueprintId', 'ticketIds'],\n },\n {\n properties: {\n type: { const: 'unlink_blueprint_to_tickets' },\n blueprintId: { type: 'string', description: 'Blueprint to unlink.' },\n ticketIds: { type: 'array', minItems: 1, items: { type: 'string' }, description: 'Tickets to unlink the blueprint from.' },\n },\n required: ['type', 'blueprintId', 'ticketIds'],\n },\n // MB.14.1 — step↔artifact link verbs (create/delete a join row keyed on\n // stepId + fileChangeId/snippetId). Get the ids from the ticket read-shape.\n {\n properties: {\n type: { const: 'link_step_file' },\n stepId: { type: 'string', description: 'Implementation step id (the functional unit of work).' },\n fileChangeId: { type: 'string', description: 'Declared file-change id the step produces (from the ticket read-shape).' },\n },\n required: ['type', 'stepId', 'fileChangeId'],\n },\n {\n properties: {\n type: { const: 'unlink_step_file' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n fileChangeId: { type: 'string', description: 'Declared file-change id to unlink from the step.' },\n },\n required: ['type', 'stepId', 'fileChangeId'],\n },\n {\n properties: {\n type: { const: 'link_step_snippet' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n snippetType: { type: 'string', enum: ['code', 'type'], description: \"'code' → TicketCodeSnippet, 'type' → TicketTypeSnippet.\" },\n snippetId: { type: 'string', description: 'Code/type snippet id the step follows (recommended, not required per step — but a snippet linking NO step is dangling and blocks the ticket; link or drop it).' },\n },\n required: ['type', 'stepId', 'snippetType', 'snippetId'],\n },\n {\n properties: {\n type: { const: 'unlink_step_snippet' },\n stepId: { type: 'string', description: 'Implementation step id.' },\n snippetType: { type: 'string', enum: ['code', 'type'], description: 'Which snippet table to unlink from.' },\n snippetId: { type: 'string', description: 'Code/type snippet id to unlink from the step.' },\n },\n required: ['type', 'stepId', 'snippetType', 'snippetId'],\n },\n // justify — declare a field N/A (the paired declare op; unjustify removes it).\n // Structural-neutral: it writes only the fieldDeclarations[scope] declaration,\n // so it is native in EVERY planning phase and never rolls back. `scope` is the\n // canonical field name the checks read (e.g. dependencies, codeReferences,\n // apiContracts) — NOT a `fieldDeclarations`-shaped payload on update_*.\n {\n properties: {\n type: { const: 'justify' },\n scope: { type: 'string', description: \"Canonical field name to mark not-applicable (e.g. 'dependencies', 'codeReferences', 'apiContracts').\" },\n entityId: { type: 'string', description: 'The spec/epic/ticket id the field belongs to (resolved server-side; ids are unique across the spec).' },\n reason: { type: 'string', description: 'Why the field does not apply (must be at least 20 characters).' },\n },\n required: ['type', 'scope', 'entityId', 'reason'],\n },\n // unjustify — remove a previously declared N/A (clears fieldDeclarations[scope]).\n // A no-op if the scope was never justified. No reason (a delete is unconditional).\n {\n properties: {\n type: { const: 'unjustify' },\n scope: { type: 'string', description: 'Canonical field name whose not-applicable declaration to remove.' },\n entityId: { type: 'string', description: 'The spec/epic/ticket id the field belongs to.' },\n },\n required: ['type', 'scope', 'entityId'],\n },\n {\n // Read-only poll/resume. To read a single ticket, use the `get` tool (type:'ticket').\n properties: {\n type: { const: 'get_planning_status' },\n },\n required: ['type'],\n },\n ],\n },\n },\n required: ['operation'],\n },\n },\n {\n name: 'complete_planning_session',\n description: \"Complete the planning session and submit the spec for final review. Spec must be in 'planning' status. Runs the planning gate (consistency checks + readinessThreshold from project/spec settings). Transitions the spec directly to 'ready' on pass. Takes no arguments — the active planning session is injected from local config.\",\n inputSchema: {\n type: 'object',\n // No inputs: the active planning session (sessionId) is injected from\n // local config (.specforge/config.json). Do NOT pass sessionId/projectId/specificationId.\n properties: {},\n required: [],\n },\n },\n {\n name: 'start_work_session',\n description: \"Start working on a ticket. Returns full ticket details (description, implementation steps, AC, technicalDetails, codeReferences, typeReferences, tags, notes, complexity, priority) alongside checklistState and workSessionId. No need to call the `get` tool (type:'ticket') separately. Returns error with statusReason if ticket is pending.\",\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket to start',\n },\n },\n required: ['ticketId'],\n },\n },\n {\n name: 'action_work_session',\n description: `Update checklist state during an active WorkSession. Combines step completion, AC validation, test result reporting, file tracking, reference review confirmation, and discovery reporting into a single atomic operation. All state changes are recorded on the WorkSession and its related validation/completion records.\n\nUse this instead of calling update_ticket for checklist changes. Provides:\n- Step completion (individual or bulk via WorkSessionImplStepCompletion)\n- Acceptance criteria validation (individual or bulk via WorkSessionAcceptanceCheck)\n- Test result reporting (merged by test type via WorkSessionTestResult)\n- File tracking (created, modified, deleted on WorkSession)\n- Discovery reporting (create discoveries for blockers, bugs, tech debt)\n- Blocker management (set block reason; requires existing discovery)\n- Reference review tracking (codeSnippetsReviewed, typeReferencesReviewed)\n- Auto-calculated progress percentage\n- Completion readiness hints\n\nIMPORTANT: All acceptance criteria must be validated and all implementation steps must be completed via this tool before calling complete_work_session. The completion gate enforces this.\n\nIf the ticket has codeReferences or typeReferences, set codeSnippetsReviewed/typeReferencesReviewed to true after reviewing them — completion readiness will block until these are confirmed.\n\nSet getTicket: true to fetch full ticket details in the response — useful for re-reading ticket context mid-implementation. Can be the sole operation or combined with other actions.`,\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket being worked on (must be in active status)',\n },\n action: {\n type: 'object',\n description:\n 'The assay action to record — the AWS action vocabulary. `action` (the discriminator) is one of: mark_implementation_step_completion, mark_acceptance_check, record_test_result, add_skip_justification, amend_skip_justification, add_failure_justification, amend_failure_justification, record_file_change, add_file_change_justification, amend_file_change_justification, create_discovery (with `blocking`), update_discovery, set_discovery_resolved. Include `workSessionId` and the per-action fields. Forwarded verbatim as the lifecycle inner payload.',\n properties: {\n action: {\n type: 'string',\n enum: [\n 'mark_implementation_step_completion',\n 'mark_acceptance_check',\n 'record_test_result',\n 'add_skip_justification',\n 'amend_skip_justification',\n 'add_failure_justification',\n 'amend_failure_justification',\n 'record_file_change',\n 'add_file_change_justification',\n 'amend_file_change_justification',\n 'create_discovery',\n 'update_discovery',\n 'set_discovery_resolved',\n ],\n description: 'The AWS action discriminator.',\n },\n workSessionId: { type: 'string', description: 'The active WorkSession id (from start_work_session).' },\n },\n required: ['action'],\n },\n steps: {\n type: 'array',\n description: 'Individual step completion updates',\n items: {\n type: 'object',\n properties: {\n index: {\n type: 'number',\n description: \"Zero-based index of the step among the ticket's implementation steps (TicketImplementationStep rows, ordered by `order`)\",\n },\n completed: {\n type: 'boolean',\n description: 'Whether the step is completed',\n },\n notes: {\n type: 'string',\n description: 'Optional note about this step',\n },\n },\n required: ['index', 'completed'],\n },\n },\n allStepsDone: {\n type: 'boolean',\n description: 'Shortcut: mark all steps as completed',\n },\n acceptanceCriteria: {\n type: 'array',\n description: 'Individual AC validation updates',\n items: {\n type: 'object',\n properties: {\n index: {\n type: 'number',\n description: 'Zero-based index of the AC in the acceptanceCriteria array',\n },\n validated: {\n type: 'boolean',\n description: 'Whether the AC is validated',\n },\n notes: {\n type: 'string',\n description: 'Optional note about this AC',\n },\n },\n required: ['index', 'validated'],\n },\n },\n allACValidated: {\n type: 'boolean',\n description: 'Shortcut: mark all acceptance criteria as validated',\n },\n testResults: {\n type: 'array',\n description: 'Test result reports to append (merged by testType)',\n items: {\n type: 'object',\n properties: {\n testType: {\n type: 'string',\n description: 'Type of test (e.g., \"unit\", \"integration\", \"e2e\", \"lint\", \"typeCheck\")',\n },\n passed: {\n type: 'number',\n description: 'Number of tests that passed',\n },\n failed: {\n type: 'number',\n description: 'Number of tests that failed',\n },\n skipped: {\n type: 'number',\n description: 'Number of tests skipped',\n },\n command: {\n type: 'string',\n description: 'Command used to run the tests',\n },\n output: {\n type: 'string',\n description: 'Test output (truncated if needed)',\n },\n duration: {\n type: 'number',\n description: 'Duration in milliseconds',\n },\n suites: {\n type: 'array',\n description: 'Optional suite-level breakdown',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Suite name' },\n passed: { type: 'number', description: 'Passed tests in suite' },\n failed: { type: 'number', description: 'Failed tests in suite' },\n skipped: { type: 'number', description: 'Skipped tests in suite' },\n duration: { type: 'number', description: 'Suite duration in ms' },\n },\n required: ['name', 'passed', 'failed'],\n },\n },\n tests: {\n type: 'array',\n description: 'Optional individual test breakdown',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Test name' },\n suite: { type: 'string', description: 'Parent suite name' },\n status: { type: 'string', enum: ['passed', 'failed', 'skipped'], description: 'Test result' },\n duration: { type: 'number', description: 'Test duration in ms' },\n },\n required: ['name', 'status'],\n },\n },\n },\n required: ['testType', 'passed', 'failed'],\n },\n },\n notes: {\n type: 'string',\n description: 'Additional notes to append to the ticket',\n },\n filesCreated: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files created during this session. Accumulated incrementally.',\n },\n filesModified: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files modified during this session. Accumulated incrementally.',\n },\n filesDeleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files deleted during this session. Accumulated incrementally.',\n },\n discovery: {\n type: 'object',\n description: 'Create a discovery (observation about the implementation). Use this to report blockers, bugs, tech debt, scope changes, etc.',\n properties: {\n description: { type: 'string', description: 'Description of the discovery' },\n type: { type: 'string', description: 'Discovery type: bug, tech_debt, blocker, clarification, scope_change, dependency, risk, ticket, epic' },\n severity: { type: 'string', description: 'Severity: blocker, critical, major, minor' },\n suggestedTitle: { type: 'string', description: 'Suggested title for the new ticket/epic' },\n suggestedPriority: { type: 'string', description: 'Suggested priority: high, medium, low' },\n relatedFiles: { type: 'array', items: { type: 'string' }, description: 'Related file paths' },\n notes: { type: 'string', description: 'Additional notes' },\n },\n required: ['description'],\n },\n blockReason: {\n type: 'string',\n description: 'Set a blocker on this ticket. Requires an existing discovery (create via discovery parameter first).',\n },\n getTicket: {\n type: 'boolean',\n description: 'Fetch full ticket details. Can be the sole operation or combined with other actions.',\n },\n includeFullContext: {\n type: 'boolean',\n description: 'Include full implementation context in response',\n },\n codeSnippetsReviewed: {\n type: 'boolean',\n description: 'Confirm that code snippets (codeReferences) on the ticket have been reviewed. Required before completion when the ticket has non-empty codeReferences.',\n },\n typeReferencesReviewed: {\n type: 'boolean',\n description: 'Confirm that type references (typeReferences) on the ticket have been reviewed. Required before completion when the ticket has non-empty typeReferences.',\n },\n },\n required: ['ticketId'],\n },\n },\n {\n name: 'complete_work_session',\n description:\n 'Mark a ticket as complete and finalize the active WorkSession. Transitions active -> done. Session data (files, test results, time) is stored on the WorkSession record.\\n\\n' +\n 'All acceptance criteria must be validated and all implementation steps must be completed via action_work_session before calling this. The completion gate enforces this — shortcuts are not available.\\n\\n' +\n 'Automatically recalculates status for dependent tickets and returns cascade info.\\n\\n' +\n 'Optional validation flags can be provided to report test results inline:\\n' +\n '- tests: Unit/integration test results\\n' +\n '- lint: Linting results\\n' +\n '- typeCheck: TypeScript type checking\\n' +\n '- build: Build/compilation results',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket',\n },\n summary: {\n type: 'string',\n description: 'Summary of work completed',\n },\n filesModified: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files modified',\n },\n filesCreated: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files created',\n },\n filesDeleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of files deleted',\n },\n actualHours: {\n type: 'number',\n description: 'Actual hours spent on the ticket',\n },\n validation: {\n type: 'object',\n description: 'Detailed validation flags for reporting test/lint/build results',\n properties: {\n tests: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Unit/integration test results',\n },\n lint: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Linting results',\n },\n typeCheck: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'TypeScript type checking results',\n },\n build: {\n type: 'string',\n enum: ['passed', 'failed', 'partial', 'pending'],\n description: 'Build/compilation results',\n },\n notes: {\n type: 'string',\n description: 'Additional validation notes',\n },\n },\n },\n },\n required: ['ticketId', 'summary'],\n },\n },\n {\n name: 'start_review_session',\n description: 'Start the implementation review lifecycle. Runs the implementation gate and either auto-transitions to \"reviewed\" (on pass) or transitions to \"in_review\" with an active ReviewSession (on fail). Creates correction tickets via action_review_session, then call complete_review_session.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification to review (must be in ready_for_review status)',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'action_review_session',\n description: 'Address findings in an active review session. Create correction tickets inline or dismiss findings with justification. Only available when specification is in \"in_review\" status.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n reviewSessionId: {\n type: 'string',\n description: 'The review session ID (auto-detected if omitted)',\n },\n findingsAddressed: {\n type: 'array',\n description: 'Findings to address in this action',\n items: {\n type: 'object',\n properties: {\n findingId: {\n type: 'string',\n description: 'The finding ID to address',\n },\n action: {\n type: 'string',\n enum: ['correction_ticket', 'dismissed'],\n description: 'How to address the finding',\n },\n correctionTicket: {\n type: 'object',\n description: 'Inline ticket creation params (required for correction_ticket action)',\n properties: {\n epicId: { type: 'string', description: 'Epic to add the correction ticket to' },\n title: { type: 'string', description: 'Ticket title' },\n description: { type: 'string', description: 'Ticket description' },\n ticketType: { type: 'string', enum: ['implementation', 'verification'], description: 'Ticket type — defaults to implementation.' },\n complexity: { type: 'string', enum: ['small', 'medium', 'large', 'xlarge'] },\n estimatedMinutes: { type: 'integer', minimum: 0 },\n acceptanceCriteria: { type: 'array', items: { type: 'string' } },\n implementationSteps: { type: 'array', items: { type: 'string' }, description: 'Implementation steps; persisted as TicketImplementationStep rows' },\n tags: { type: 'array', items: { type: 'string' } },\n },\n required: ['epicId', 'title'],\n },\n justification: {\n type: 'string',\n description: 'Required justification when action is \"dismissed\"',\n },\n },\n required: ['findingId', 'action'],\n },\n },\n notes: {\n type: 'string',\n description: 'Optional notes for this review action',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'complete_review_session',\n description: 'Complete an active review session. All error-severity findings must be addressed. If correction tickets exist, transitions to \"in_progress\". If all findings dismissed, triggers user confirmation flow.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification',\n },\n reviewSessionId: {\n type: 'string',\n description: 'The review session ID (auto-detected if omitted)',\n },\n summary: {\n type: 'string',\n description: 'Optional completion summary',\n },\n confirmAllDismissed: {\n type: 'boolean',\n description: 'Set to true when all findings were dismissed to trigger user confirmation flow',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'reopen_specification',\n description: 'Reopen a specification in \"ready\" status, regressing to \"planning\". Use when action_planning_session reports the spec is no longer in planning. After reopening, call start_planning_session to begin a new planning session.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'The ID of the specification to reopen',\n },\n },\n required: ['specificationId'],\n },\n },\n\n // Spec creation is a HUMAN bootstrap step, NOT an agent MCP tool: specs are\n // created via `specforge init` (cli-rest surface), which also writes the new\n // spec id into the local config so the agent's per-call injection finds it.\n // The agent assumes the spec already exists and starts from\n // `start_planning_session`. (Backend keeps `create_specification` REST-only;\n // it was never dispatchable on /local.)\n\n // ========================================================================\n // Utilities (3)\n // ========================================================================\n {\n name: 'feedback',\n description: `Submit and manage feedback about MCP tools. Operations:\n- submit: Submit new feedback (requires category, summary)\n- list: List recent feedback entries\n- get: Get a specific feedback entry by ID`,\n inputSchema: {\n type: 'object',\n properties: {\n operation: {\n type: 'string',\n enum: ['submit', 'list', 'get'],\n description: 'The operation to perform',\n },\n // For submit operation\n category: {\n type: 'string',\n enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],\n description: 'Feedback category (required for submit)',\n },\n summary: {\n type: 'string',\n description: 'Brief summary of the feedback (required for submit)',\n },\n severity: {\n type: 'string',\n enum: ['critical', 'high', 'medium', 'low'],\n description: 'Severity level (default: medium)',\n },\n tool: {\n type: 'string',\n description: 'Which MCP tool this relates to',\n },\n toolOperation: {\n type: 'string',\n description: 'Specific operation within the tool',\n },\n details: {\n type: 'string',\n description: 'Extended description',\n },\n expected: {\n type: 'string',\n description: 'Expected behavior',\n },\n actual: {\n type: 'string',\n description: 'Actual behavior',\n },\n errorMessage: {\n type: 'string',\n description: 'Error message if reporting a bug',\n },\n ticketId: {\n type: 'string',\n description: 'Related ticket ID',\n },\n // For list operation\n limit: {\n type: 'number',\n description: 'Maximum entries to return (default: 10)',\n },\n categoryFilter: {\n type: 'string',\n enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],\n description: 'Filter by category',\n },\n // For get operation\n feedbackId: {\n type: 'string',\n description: 'Feedback ID to retrieve (required for get)',\n },\n },\n required: ['operation'],\n },\n },\n {\n name: 'link_pull_request',\n description: 'Associate a pull request with a ticket',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: {\n type: 'string',\n description: 'The ID of the ticket',\n },\n prNumber: {\n type: 'number',\n description: 'PR number (provide this or prUrl)',\n },\n prUrl: {\n type: 'string',\n description: 'Full PR URL (GitHub, GitLab, or Bitbucket)',\n },\n title: {\n type: 'string',\n description: 'PR title',\n },\n author: {\n type: 'string',\n description: 'PR author',\n },\n repoUrl: {\n type: 'string',\n description: 'Repository URL (required if using prNumber)',\n },\n },\n required: ['ticketId'],\n },\n },\n\n // ========================================================================\n // Orchestration (2)\n // ========================================================================\n {\n name: 'get_critical_path',\n description: 'Get the critical execution path for a specification.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'Specification ID',\n },\n },\n required: ['specificationId'],\n },\n },\n {\n name: 'get_dependency_tree',\n description: 'Get the full dependency tree for a specification.',\n inputSchema: {\n type: 'object',\n properties: {\n specificationId: {\n type: 'string',\n description: 'Specification ID',\n },\n },\n required: ['specificationId'],\n },\n },\n ];\n\n // Mark the 7 work+review verbs as in_development — mirrors @specforge/core\n // getToolDefinitions so a mcp-local agent also gets the \"coming soon\" affordance\n // (calling them returns a typed stub) instead of believing they are stable.\n const IN_DEVELOPMENT_PLANNED_FOR: Record<string, string> = {\n start_work_session: '0.2.0',\n action_work_session: '0.2.0',\n complete_work_session: '0.2.0',\n start_review_session: '0.3.0',\n action_review_session: '0.3.0',\n complete_review_session: '0.3.0',\n };\n for (const t of tools) {\n const plannedFor = IN_DEVELOPMENT_PLANNED_FOR[t.name];\n if (plannedFor) {\n t.description =\n `**In development — ships with ${plannedFor}.** Calling returns a typed stub ` +\n `response the client should render as a \"coming soon\" affordance.\\n\\n${t.description}`;\n }\n }\n\n return tools;\n}\n\n/**\n * Tool handler type - processes arguments and returns a result\n */\ntype ToolHandler = (\n apiClient: ApiClient,\n args: Record<string, unknown>\n) => Promise<unknown>;\n\n/**\n * Retry configuration for transient failures\n */\nconst RETRY_CONFIG = {\n maxRetries: 3,\n initialDelayMs: 500,\n maxDelayMs: 5000,\n backoffMultiplier: 2,\n};\n\n/**\n * Transient error patterns that should trigger retry\n */\nconst TRANSIENT_ERROR_PATTERNS = [\n /ETIMEDOUT/i,\n /ECONNRESET/i,\n /ECONNREFUSED/i,\n /socket hang up/i,\n /network error/i,\n /too many requests/i,\n /rate limit/i,\n /5\\d{2}/, // 5xx status codes\n];\n\n/**\n * Check if an error is transient and should be retried\n */\nfunction isTransientError(error: Error): boolean {\n return TRANSIENT_ERROR_PATTERNS.some(pattern =>\n pattern.test(error.message)\n );\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Execute a function with retry logic for transient failures\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n toolName: string,\n debug: boolean\n): Promise<T> {\n let lastError: Error | null = null;\n let delay = RETRY_CONFIG.initialDelayMs;\n\n for (let attempt = 1; attempt <= RETRY_CONFIG.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < RETRY_CONFIG.maxRetries && isTransientError(lastError)) {\n if (debug) {\n console.error(\n `[DEBUG] Tool ${toolName} attempt ${attempt} failed with transient error, retrying in ${delay}ms:`,\n lastError.message\n );\n }\n await sleep(delay);\n delay = Math.min(delay * RETRY_CONFIG.backoffMultiplier, RETRY_CONFIG.maxDelayMs);\n } else {\n break;\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Create tool handlers that call the API with proper request formatting\n *\n * @param apiClient - The API client to use for making requests\n * @returns Record of tool handlers keyed by tool name\n */\nexport function createToolHandlers(\n apiClient: ApiClient\n): Record<string, ToolHandler> {\n // Agent `/local` path (M9, approach A): the transport returns the raw M8 body;\n // interpret the envelope here. Lifecycle → unwrap to `agentResponse`; standard\n // error → throw the composed guidance prose (M9.3); raw success → pass through.\n const callLocal = async <T = unknown>(\n op: string,\n args: Record<string, unknown>,\n ): Promise<T> => {\n // SPECFORGE_DEBUG=true → trace the EXACT wire request/response for what a tool handler\n // forwards to /local after its arg-mapping (e.g. the inner `payload` shape\n // `action_work_session` sends). Prefers a file (SPECFORGE_DEBUG_FILE) since an MCP-serve\n // subprocess's stderr may be swallowed by the host; falls back to stderr (stdout is the\n // MCP JSON protocol and must stay clean).\n const debug = process.env.SPECFORGE_DEBUG === 'true';\n const debugFile = process.env.SPECFORGE_DEBUG_FILE;\n const trace = (line: string) => {\n if (!debug) return;\n if (debugFile) { try { appendFileSync(debugFile, line + '\\n'); return; } catch { /* fall through */ } }\n process.stderr.write(line + '\\n');\n };\n trace(`[cli:wire →] ${op} ${JSON.stringify(args)}`);\n const body = await apiClient.getTransport().execute<Record<string, unknown>>(op, args);\n trace(`[cli:wire ←] ${op} ${JSON.stringify(body).slice(0, 800)}`);\n if (body && typeof body === 'object') {\n if (body.kind === 'standard_error') {\n // M9.3: the error-guidance composer's `guidance.prose` is the canonical\n // agent-facing message (same verbatim convention as lifecycle guidance);\n // surface it for query-tool errors, falling back to `message` (and to a\n // generic line for INTERNAL, where guidance is always null).\n const guidance = body.guidance as { prose?: unknown } | null | undefined;\n const prose = guidance && typeof guidance.prose === 'string' ? guidance.prose : undefined;\n throw new Error(\n prose ?? (typeof body.message === 'string' ? body.message : `Operation failed: ${op}`),\n );\n }\n if (body.kind === 'lifecycle' && 'agentResponse' in body) {\n return body.agentResponse as T;\n }\n }\n return body as T;\n };\n\n return {\n // ========================================================================\n // Queries — forward the canonical super-tools straight through (the backend\n // owns the `type` dispatch; M9 dropped the old granular-op fan-out).\n // ========================================================================\n get: async (_client, args) => {\n if (!args.type) throw new Error('Missing required argument: type');\n // Project/spec ids inject from config when the agent omits them.\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n return await callLocal('get', withCtx);\n },\n\n list: async (_client, args) => {\n if (!args.type) throw new Error('Missing required argument: type');\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n return await callLocal('list', withCtx);\n },\n\n search: async (_client, args) => {\n if (!args.query && !args.files && !args.tags && !args.relatedTo) {\n throw new Error('At least one filter is required: query, files, tags, or relatedTo');\n }\n const withCtx = injectContext(args, ['projectId', 'specificationId']);\n if (!withCtx.projectId && !withCtx.specificationId && !withCtx.epicId) {\n throw new Error('One of projectId, specificationId, or epicId is required. Run \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('search', withCtx);\n },\n\n get_next_actionable_tickets: async (_client, args) => {\n // Inject projectId/specificationId from .specforge.json if not provided\n const argsWithContext = injectContext(args, ['projectId', 'specificationId']);\n\n // Either specificationId or projectId is required (after injection)\n if (!argsWithContext.specificationId && !argsWithContext.projectId) {\n throw new Error('Either specificationId or projectId is required. Set working context with \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('get_next_actionable_tickets', {\n specificationId: argsWithContext.specificationId,\n projectId: argsWithContext.projectId,\n limit: argsWithContext.limit ?? 5,\n });\n },\n\n get_blocked_tickets: async (_client, args) => {\n // Inject specificationId from .specforge.json if not provided\n const argsWithContext = injectContext(args, ['specificationId']);\n\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required. Set working context with \"specforge switch\" or provide explicitly.');\n }\n return await callLocal('get_blocked_tickets', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n get_report: async (_client, args) => {\n validateRequired(args, 'type', 'scope', 'scopeId');\n return await callLocal('get_report', {\n type: args.type,\n scope: args.scope,\n scopeId: args.scopeId,\n format: args.format ?? 'json',\n startDate: args.startDate,\n endDate: args.endDate,\n });\n },\n\n // ========================================================================\n // Lifecycle\n // ========================================================================\n // Planning lifecycle (M9.6b) — identity/session injected from the\n // `.specforge` config; SPS persists the session id, a `closed` status\n // clears it. Payloads match the post-M8 boundary (SPS {specificationId};\n // APS {sessionId, operation:{type,...}}; CPS {sessionId}).\n start_planning_session: async (_client, args) => {\n const cfg = tryLoadProjectConfig();\n const specificationId = (args.specificationId as string) ?? cfg?.specificationId;\n if (!specificationId) {\n throw new Error('No active specification. Run `specforge switch <spec-id>` or pass specificationId.');\n }\n // projectId is injected from local config (client-authoritative scope);\n // SPS no longer derives it server-side from the spec row.\n const projectId = (args.projectId as string) ?? cfg?.projectId;\n if (!projectId) {\n throw new Error('No active project. Run `specforge switch <spec-id>` or pass projectId.');\n }\n const agentResponse = await callLocal<{ sessionId?: string }>(\n 'start_planning_session',\n { projectId, specificationId },\n );\n if (agentResponse?.sessionId) {\n saveProjectConfig({ planningSessionId: agentResponse.sessionId });\n appendPlanningSessionRegistry({\n specificationId,\n planningSessionId: agentResponse.sessionId,\n startedAt: new Date().toISOString(),\n });\n }\n return agentResponse;\n },\n\n action_planning_session: async (_client, args) => {\n if (!args.operation || typeof args.operation !== 'object') {\n throw new Error('Missing required argument: operation (e.g. { type: \"get_planning_status\" })');\n }\n const cfg = tryLoadProjectConfig();\n const sessionId = (args.sessionId as string) ?? cfg?.planningSessionId;\n if (!sessionId) {\n throw new Error('No active planning session. Call start_planning_session first.');\n }\n const agentResponse = await callLocal<{ planningStatus?: string }>(\n 'action_planning_session',\n { sessionId, operation: args.operation },\n );\n // Close detection: clear the persisted session id once it closes.\n if (agentResponse?.planningStatus === 'closed' && cfg?.specificationId) {\n saveProjectConfig({ planningSessionId: undefined });\n markPlanningSessionRegistryCompleted({\n specificationId: cfg.specificationId,\n completedAt: new Date().toISOString(),\n });\n }\n return agentResponse;\n },\n\n complete_planning_session: async (_client, args) => {\n const cfg = tryLoadProjectConfig();\n const sessionId = (args.sessionId as string) ?? cfg?.planningSessionId;\n if (!sessionId) {\n throw new Error('No active planning session. Call start_planning_session first.');\n }\n // CPS-success flips to awaiting_human_review (not closed) — keep the id.\n // MB.10.5 — grep double-call. Pass-1 sends NO evidence: in cross_validation\n // the server may reply `evidence_required` with a `grepRequest` (the exact\n // paths it can't resolve spec-internally). Probe JUST those paths locally,\n // then re-call CPS with the existing subset injected as `existingFiles`\n // (pass-2, the committing verdict). Outside a worktree the probe returns []\n // → re-call with [] → strict verdict (never blocks a repo-less caller).\n // From the agent's view this stays ONE tool call: only pass-2 is returned.\n const first = await callLocal<{ outcome?: string; grepRequest?: { paths?: string[] } }>(\n 'complete_planning_session',\n { sessionId },\n );\n if (first?.outcome !== 'evidence_required') {\n return first;\n }\n const requested = Array.isArray(first.grepRequest?.paths) ? first.grepRequest.paths : [];\n const existingFiles = probeExistingFiles(requested);\n return await callLocal('complete_planning_session', { sessionId, existingFiles });\n },\n\n start_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId');\n // MCP-local git injection (M23.2): the CLM/agent runs on the worktree the\n // Lambda can't see, so THIS process reads the git evidence and injects it —\n // `gitClean` feeds the SWS git-clean precondition; `worktreePath`/`branch`\n // are persisted onto the WorkSession (M16.2). Provenance is `null` when the\n // agent is not inside a git worktree (SWS still records the session).\n const git = readWorktreeGitEvidence();\n return await callLocal('start_work_session', {\n ticketId: args.ticketId,\n gitClean: git.gitClean,\n worktreePath: git.worktreePath,\n branch: git.branch,\n });\n },\n\n action_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId');\n // The AWS action vocab (mark_implementation_step_completion / mark_acceptance_check /\n // record_test_result / add_*_justification / record_file_change / create_discovery\n // (with `blocking`) / update_discovery / set_discovery_resolved) rides in `action`\n // — the discriminated `AwsActionInput`. The CLI forwards it verbatim as the inner\n // `payload` (the work analog of action_planning_session forwarding `operation`);\n // the lifecycle dispatches on `payload.action`.\n return await callLocal('action_work_session', {\n ticketId: args.ticketId,\n payload: args.action ?? args.payload,\n });\n },\n\n complete_work_session: async (_client, args) => {\n validateRequired(args, 'ticketId', 'summary');\n // MCP-local git-commit binding (M23.2): the deployed Lambda has no worktree, so\n // THIS process reads the HEAD commit hash and injects it as `commitSha`. CWS's\n // git-evidence gate binds it onto the WorkSession and finalizes — without it a\n // passing session holds forever (\"commit your work first\"). `null` when the agent\n // is not inside a git worktree (the gate then holds, as intended for non-git callers).\n const commitSha = readHeadCommitSha();\n return await callLocal('complete_work_session', {\n ticketId: args.ticketId,\n summary: args.summary,\n filesModified: args.filesModified,\n filesCreated: args.filesCreated,\n filesDeleted: args.filesDeleted,\n actualHours: args.actualHours,\n validation: args.validation,\n ...(commitSha !== null && { commitSha }),\n });\n },\n\n start_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('start_review_session', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n action_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('action_review_session', {\n specificationId: argsWithContext.specificationId,\n reviewSessionId: args.reviewSessionId,\n findingsAddressed: args.findingsAddressed,\n notes: args.notes,\n });\n },\n\n complete_review_session: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('complete_review_session', {\n specificationId: argsWithContext.specificationId,\n reviewSessionId: args.reviewSessionId,\n summary: args.summary,\n confirmAllDismissed: args.confirmAllDismissed,\n });\n },\n\n reopen_specification: async (_client, args) => {\n const argsWithContext = injectContextRequired(args, ['specificationId']);\n return await callLocal('reopen_specification', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n // ========================================================================\n // Mutation\n // ========================================================================\n\n // ========================================================================\n // Utilities\n // ========================================================================\n feedback: async (_client, args) => {\n // M9.7: origin is server-derived from the `X-SpecForge-Origin` header\n // (default `mcp` on the agent transport) — never a request-body `source`.\n return await callLocal('feedback', args);\n },\n\n link_pull_request: async (_client, args) => {\n validateRequired(args, 'ticketId');\n if (!args.prNumber && !args.prUrl) {\n throw new Error('Either prNumber or prUrl must be provided');\n }\n return await callLocal('link_pull_request', {\n ticketId: args.ticketId,\n prNumber: args.prNumber,\n prUrl: args.prUrl,\n title: args.title,\n author: args.author,\n repoUrl: args.repoUrl,\n });\n },\n\n // ========================================================================\n // Orchestration\n // ========================================================================\n get_critical_path: async (_client, args) => {\n const argsWithContext = injectContext(args, ['specificationId']);\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required');\n }\n return await callLocal('get_critical_path', {\n specificationId: argsWithContext.specificationId,\n });\n },\n\n get_dependency_tree: async (_client, args) => {\n const argsWithContext = injectContext(args, ['specificationId']);\n if (!argsWithContext.specificationId) {\n throw new Error('specificationId is required');\n }\n return await callLocal('get_dependency_tree', {\n specificationId: argsWithContext.specificationId,\n });\n },\n };\n}\n\n/**\n * Validate that required arguments are present\n * @throws Error if any required argument is missing\n */\nfunction validateRequired(args: Record<string, unknown>, ...required: string[]): void {\n for (const field of required) {\n if (args[field] === undefined || args[field] === null || args[field] === '') {\n throw new Error(`Missing required argument: ${field}`);\n }\n }\n}\n\n// Create a cached instance of tool handlers\nlet cachedHandlers: Record<string, ToolHandler> | null = null;\n\n/**\n * Reset the cached tool handlers (for testing purposes)\n */\nexport function resetToolHandlers(): void {\n cachedHandlers = null;\n}\n\n/**\n * Handle a tool call by routing to the appropriate handler\n *\n * @param apiClient - The API client to use for making requests\n * @param toolName - Name of the tool being called\n * @param args - Arguments passed to the tool\n * @param debug - Whether to enable debug logging\n * @returns Promise resolving to the tool result\n */\nexport async function handleToolCall(\n apiClient: ApiClient,\n toolName: string,\n args: Record<string, unknown>,\n debug: boolean = false\n): Promise<unknown> {\n const startTime = Date.now();\n\n // Create handlers if not cached\n if (!cachedHandlers) {\n cachedHandlers = createToolHandlers(apiClient);\n }\n\n // Get the handler for this tool\n const handler = cachedHandlers[toolName];\n if (!handler) {\n throw new Error(`Unknown tool: ${toolName}`);\n }\n\n if (debug) {\n console.error(`[DEBUG] Calling tool: ${toolName}`, {\n args: JSON.stringify(args),\n });\n }\n\n try {\n // Run comprehensive validation before executing\n validateToolArgs(toolName, args);\n\n // Execute with retry logic\n const result = await withRetry(\n () => handler(apiClient, args),\n toolName,\n debug\n );\n\n const duration = Date.now() - startTime;\n if (debug) {\n console.error(`[DEBUG] Tool ${toolName} completed in ${duration}ms`);\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Transform error for proper handling\n const transformedError = transformError(error);\n const message = transformedError.message;\n\n if (debug) {\n console.error(`[DEBUG] Tool ${toolName} failed after ${duration}ms:`, message);\n if (transformedError instanceof ValidationError) {\n console.error(`[DEBUG] Validation field: ${transformedError.field}, code: ${transformedError.code}`);\n }\n }\n\n // Rethrow with context\n if (transformedError instanceof ValidationError) {\n throw transformedError;\n }\n if (transformedError instanceof ApiError) {\n throw transformedError;\n }\n throw new Error(`Tool ${toolName} failed: ${message}`);\n }\n}\n\n/**\n * Handle a tool call and return MCP-formatted response\n * This wraps handleToolCall with proper error formatting for MCP protocol\n */\nexport async function handleToolCallSafe(\n apiClient: ApiClient,\n toolName: string,\n args: Record<string, unknown>,\n debug: boolean = false\n): Promise<unknown | MCPErrorResponse> {\n try {\n return await handleToolCall(apiClient, toolName, args, debug);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n return formatMCPError(err);\n }\n}\n\n// Re-export validation utilities for use by other modules\nexport {\n ValidationError,\n ApiError,\n validateToolArgs,\n formatMCPError,\n transformError,\n type MCPErrorResponse,\n} from '../validation/index.js';\n"],"mappings":"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","names":["ValidationError","ApiError","validateToolArgs","formatMCPError","transformError"]}
@@ -1,6 +1,6 @@
1
- export declare const PLANNING_MUTATING_OPERATIONS: readonly ["update_spec", "create_epic", "update_epic", "delete_epic", "create_ticket", "update_ticket", "delete_ticket", "create_blueprint", "update_blueprint", "delete_blueprint", "link_blueprint_to_tickets", "unlink_blueprint_to_tickets", "create_dependencies", "delete_dependencies", "justify", "unjustify", "link_step_file", "unlink_step_file", "link_step_snippet", "unlink_step_snippet"];
1
+ export declare const PLANNING_MUTATING_OPERATIONS: readonly ["update_spec", "create_epic", "update_epic", "delete_epic", "create_ticket", "update_ticket", "delete_ticket", "create_blueprint", "update_blueprint", "delete_blueprint", "link_blueprint_to_tickets", "unlink_blueprint_to_tickets", "create_dependencies", "delete_dependencies", "justify", "unjustify", "link_step_file", "unlink_step_file", "link_step_snippet", "unlink_step_snippet", "apply_creator_election"];
2
2
  export declare const PLANNING_READ_ONLY_OPERATIONS: readonly ["get_planning_status"];
3
3
  export declare const PLANNING_SYNTHETIC_OPERATIONS: readonly ["start_planning_session", "complete_planning_session", "phase_complete", "phase_advance", "phase_rollback", "human_approve", "human_reject_with_feedback", "human_reject_no_feedback", "session_closed"];
4
- export declare const PLANNING_OPERATIONS: readonly ["update_spec", "create_epic", "update_epic", "delete_epic", "create_ticket", "update_ticket", "delete_ticket", "create_blueprint", "update_blueprint", "delete_blueprint", "link_blueprint_to_tickets", "unlink_blueprint_to_tickets", "create_dependencies", "delete_dependencies", "justify", "unjustify", "link_step_file", "unlink_step_file", "link_step_snippet", "unlink_step_snippet", "get_planning_status", "start_planning_session", "complete_planning_session", "phase_complete", "phase_advance", "phase_rollback", "human_approve", "human_reject_with_feedback", "human_reject_no_feedback", "session_closed"];
4
+ export declare const PLANNING_OPERATIONS: readonly ["update_spec", "create_epic", "update_epic", "delete_epic", "create_ticket", "update_ticket", "delete_ticket", "create_blueprint", "update_blueprint", "delete_blueprint", "link_blueprint_to_tickets", "unlink_blueprint_to_tickets", "create_dependencies", "delete_dependencies", "justify", "unjustify", "link_step_file", "unlink_step_file", "link_step_snippet", "unlink_step_snippet", "apply_creator_election", "get_planning_status", "start_planning_session", "complete_planning_session", "phase_complete", "phase_advance", "phase_rollback", "human_approve", "human_reject_with_feedback", "human_reject_no_feedback", "session_closed"];
5
5
  export type PlanningOperationName = typeof PLANNING_OPERATIONS[number];
6
6
  //# sourceMappingURL=planning-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"planning-operations.d.ts","sourceRoot":"","sources":["../../src/runtime/planning-operations.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,0YAoB/B,CAAC;AAEX,eAAO,MAAM,6BAA6B,kCAAmC,CAAC;AAE9E,eAAO,MAAM,6BAA6B,oNAUhC,CAAC;AAEX,eAAO,MAAM,mBAAmB,0mBAItB,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"planning-operations.d.ts","sourceRoot":"","sources":["../../src/runtime/planning-operations.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,oaA6B/B,CAAC;AAEX,eAAO,MAAM,6BAA6B,kCAAmC,CAAC;AAE9E,eAAO,MAAM,6BAA6B,oNAUhC,CAAC;AAEX,eAAO,MAAM,mBAAmB,ooBAItB,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC"}
@@ -18,6 +18,15 @@ export const PLANNING_MUTATING_OPERATIONS = [
18
18
  // operations-registry.ts.
19
19
  'link_step_file', 'unlink_step_file',
20
20
  'link_step_snippet', 'unlink_step_snippet',
21
+ // MB.16.1 — the ATOMIC creator-election batch verb. Applies the whole
22
+ // `electFileCreators` plan in ONE op: moves each CLEAN orphan shared file to
23
+ // `filesToBeCreated` on its elected ticket (ticket_expansion write), links the
24
+ // producing step inline (MB.15.3 `producesFiles`), AND declares the ordering deps
25
+ // (cross_validation write). Native across the `ticket_expansion` → `cross_validation`
26
+ // band (same pattern as link_step_file / link_blueprint_to_tickets) so the cross-phase
27
+ // fix never rolls back. `conflict`-status files are excluded (routed to get_ticket) —
28
+ // see operations-registry.ts + creator-election-batch.ts.
29
+ 'apply_creator_election',
21
30
  ];
22
31
  export const PLANNING_READ_ONLY_OPERATIONS = ['get_planning_status'];
23
32
  export const PLANNING_SYNTHETIC_OPERATIONS = [
@@ -1 +1 @@
1
- {"version":3,"file":"planning-operations.js","sourceRoot":"","sources":["../../src/runtime/planning-operations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,aAAa;IACb,aAAa,EAAE,aAAa,EAAE,aAAa;IAC3C,eAAe,EAAE,eAAe,EAAE,eAAe;IACjD,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB;IAC1D,2BAA2B,EAAE,6BAA6B;IAC1D,qBAAqB,EAAE,qBAAqB;IAC5C,0EAA0E;IAC1E,iFAAiF;IACjF,qFAAqF;IACrF,kFAAkF;IAClF,kFAAkF;IAClF,SAAS,EAAE,WAAW;IACtB,+EAA+E;IAC/E,+EAA+E;IAC/E,kFAAkF;IAClF,2EAA2E;IAC3E,0BAA0B;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,qBAAqB;CAClC,CAAC;AAEX,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,qBAAqB,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,wBAAwB;IACxB,2BAA2B;IAC3B,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,4BAA4B;IAC5B,0BAA0B;IAC1B,gBAAgB;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,4BAA4B;IAC/B,GAAG,6BAA6B;IAChC,GAAG,6BAA6B;CACxB,CAAC"}
1
+ {"version":3,"file":"planning-operations.js","sourceRoot":"","sources":["../../src/runtime/planning-operations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,aAAa;IACb,aAAa,EAAE,aAAa,EAAE,aAAa;IAC3C,eAAe,EAAE,eAAe,EAAE,eAAe;IACjD,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB;IAC1D,2BAA2B,EAAE,6BAA6B;IAC1D,qBAAqB,EAAE,qBAAqB;IAC5C,0EAA0E;IAC1E,iFAAiF;IACjF,qFAAqF;IACrF,kFAAkF;IAClF,kFAAkF;IAClF,SAAS,EAAE,WAAW;IACtB,+EAA+E;IAC/E,+EAA+E;IAC/E,kFAAkF;IAClF,2EAA2E;IAC3E,0BAA0B;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,qBAAqB;IAC1C,sEAAsE;IACtE,6EAA6E;IAC7E,+EAA+E;IAC/E,kFAAkF;IAClF,sFAAsF;IACtF,uFAAuF;IACvF,sFAAsF;IACtF,0DAA0D;IAC1D,wBAAwB;CAChB,CAAC;AAEX,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,qBAAqB,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,wBAAwB;IACxB,2BAA2B;IAC3B,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,4BAA4B;IAC5B,0BAA0B;IAC1B,gBAAgB;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,4BAA4B;IAC/B,GAAG,6BAA6B;IAChC,GAAG,6BAA6B;CACxB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specforge/session-types",
3
- "version": "0.2.60",
3
+ "version": "0.2.62",
4
4
  "description": "Session type definitions for SpecForge work/planning/review sessions.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specforge/canary-cli",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "MCP server for SpecForge - AI agent integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "inquirer": "^9.3.8",
18
18
  "minimatch": "^10.1.1",
19
19
  "ora": "^8.2.0",
20
- "@specforge/session-types": "0.2.60",
20
+ "@specforge/session-types": "0.2.62",
21
21
  "@specforge/types": "1.0.2"
22
22
  },
23
23
  "devDependencies": {
@@ -30,7 +30,7 @@
30
30
  "tsx": "^4.7.0",
31
31
  "typescript": "^5.0.0",
32
32
  "vitest": "4.0.18",
33
- "@specforge/lifecycle": "0.1.84"
33
+ "@specforge/lifecycle": "0.1.86"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=18.0.0"
@@ -56,7 +56,7 @@
56
56
  "@specforge/types",
57
57
  "@specforge/session-types"
58
58
  ],
59
- "gitHead": "3800a1c8eceda2f53b3c1f85b2d63bcd1b67620a",
59
+ "gitHead": "df3b83315fbd3eefe05c1f7b6136d1481bdf66f9",
60
60
  "scripts": {
61
61
  "build": "tsup && tsc --emitDeclarationOnly --outDir dist",
62
62
  "typecheck": "tsc --noEmit",
@@ -18,7 +18,7 @@ Create a git commit with SpecForge ticket metadata.
18
18
  **MCP Calls:**
19
19
  \`\`\`typescript
20
20
  if ($ARGUMENTS) {
21
- get_ticket({ ticketId: $ARGUMENTS })
21
+ get({ type: 'ticket', id: $ARGUMENTS })
22
22
  } else {
23
23
  // Read active ticket from .specforge.json or find active ticket
24
24
  const config = readFile('.specforge.json')
@@ -26,7 +26,7 @@ if ($ARGUMENTS) {
26
26
  // Find the currently active ticket
27
27
  list_tickets({ specificationId, status: ["active"] })
28
28
  // Use the active ticket
29
- get_ticket({ ticketId: activeTicket.id })
29
+ get({ type: 'ticket', id: activeTicket.id })
30
30
  }
31
31
  \`\`\`
32
32