intention-coding 0.6.1 → 0.6.3

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.
package/dist/index.cjs CHANGED
@@ -7616,8 +7616,18 @@ ${pageStyle}
7616
7616
  return cleanHtml.trim();
7617
7617
  }
7618
7618
  const requirementAnalyzerTool = {
7619
- name: "requirement-analyzer-report",
7620
- description: `\u{667A}\u{80FD}\u{5206}\u{6790}\u{9700}\u{6C42}\u{5E76}\u{751F}\u{6210}API\u{6587}\u{6863}\u{548C}HTML\u{9875}\u{9762}\u{8BBE}\u{8BA1}\u{6587}\u{6863}\u{3002}\u{652F}\u{6301}PC\u{7AEF}\u{3001}\u{79FB}\u{52A8}\u{7AEF}\u{7B49}\u{591A}\u{79CD}\u{9875}\u{9762}\u{7C7B}\u{578B}\u{3002}`,
7619
+ name: "generate_design_doc",
7620
+ description: `\u{6839}\u{636E}\u{9700}\u{6C42}\u{5206}\u{6790}\u{7ED3}\u{679C}\u{FF0C}\u{751F}\u{6210} API \u{6280}\u{672F}\u{8BBE}\u{8BA1}\u{6587}\u{6863}\u{548C}\u{53EF}\u{4EA4}\u{4E92} HTML \u{9875}\u{9762}\u{539F}\u{578B}\u{3002}
7621
+
7622
+ \u{89E6}\u{53D1}\u{8BCD}: \u{751F}\u{6210}\u{8BBE}\u{8BA1}\u{6587}\u{6863}\u{3001}\u{751F}\u{6210}API\u{6587}\u{6863}\u{3001}\u{9700}\u{6C42}\u{8F6C}\u{8BBE}\u{8BA1}\u{3001}\u{751F}\u{6210}\u{6280}\u{672F}\u{65B9}\u{6848}\u{3001}\u{751F}\u{6210}\u{9875}\u{9762}\u{539F}\u{578B}
7623
+
7624
+ \u{4F7F}\u{7528}\u{6D41}\u{7A0B}:
7625
+ 1. \u{5148}\u{8C03}\u{7528} requirement_identifier \u{5206}\u{6790}\u{539F}\u{59CB}\u{9700}\u{6C42}
7626
+ 2. \u{5C06}\u{5206}\u{6790}\u{7ED3}\u{679C}\u{4F20}\u{5165}\u{672C}\u{5DE5}\u{5177}\u{751F}\u{6210}\u{8BBE}\u{8BA1}\u{6587}\u{6863}
7627
+
7628
+ \u{8F93}\u{51FA}:
7629
+ - API \u{6280}\u{672F}\u{9700}\u{6C42}\u{6587}\u{6863} (Markdown)
7630
+ - \u{53EF}\u{4EA4}\u{4E92} HTML \u{9875}\u{9762}\u{539F}\u{578B}`,
7621
7631
  inputSchema: {
7622
7632
  requirement_analysis: stringType().describe("requirement-identifier\u751F\u6210\u7684\u9700\u6C42\u5206\u6790\u7ED3\u679C\uFF08\u5305\u542B\u5F53\u524D\u9700\u6C42\u4E0E\u9879\u76EE\u60C5\u51B5\u7684\u5B8C\u6574\u5206\u6790\uFF09"),
7623
7633
  current_project_path: stringType().describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF08\u5FC5\u586B\uFF09\uFF0C\u9700\u6C42\u62A5\u544A\u5C06\u751F\u6210\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/design\u76EE\u5F55"),
@@ -10942,6 +10952,103 @@ ${requirement_description}
10942
10952
  }
10943
10953
  return external_path_namespaceObject.resolve(currentDir, "\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u6A21\u677F.docx");
10944
10954
  }
10955
+ function isEmptySection(section) {
10956
+ if (!section) return true;
10957
+ if ('object' != typeof section) return true;
10958
+ const keys = Object.keys(section);
10959
+ if (0 === keys.length) return true;
10960
+ return keys.every((key)=>{
10961
+ const val = section[key];
10962
+ return !val || '' === val || "\u65E0" === val || "\u4E0D\u6D89\u53CA" === val || "\u4E0D\u6D89\u53CA\u3002" === val;
10963
+ });
10964
+ }
10965
+ function prepareSubSectionData(section, defaultValue = "\u4E0D\u6D89\u53CA\u3002") {
10966
+ if (isEmptySection(section)) return {
10967
+ constraint: defaultValue,
10968
+ useCase: defaultValue,
10969
+ design: defaultValue,
10970
+ intro: defaultValue,
10971
+ dataEstimation: defaultValue,
10972
+ sharding: defaultValue,
10973
+ designIdea: defaultValue,
10974
+ implementation: defaultValue
10975
+ };
10976
+ const normalizeValue = (val)=>{
10977
+ if (!val || '' === val || "\u65E0" === val) return defaultValue;
10978
+ return String(val);
10979
+ };
10980
+ return {
10981
+ constraint: normalizeValue(section.constraint),
10982
+ useCase: normalizeValue(section.useCase),
10983
+ design: normalizeValue(section.design),
10984
+ intro: normalizeValue(section.intro),
10985
+ dataEstimation: normalizeValue(section.dataEstimation),
10986
+ sharding: normalizeValue(section.sharding),
10987
+ designIdea: normalizeValue(section.designIdea),
10988
+ implementation: normalizeValue(section.implementation)
10989
+ };
10990
+ }
10991
+ function flattenSubSection(parentKey, sectionName, section) {
10992
+ const result = {};
10993
+ for (const [key, value] of Object.entries(section))result[`${parentKey}_${sectionName}_${key}`] = value;
10994
+ return result;
10995
+ }
10996
+ function prepareRenderData(data) {
10997
+ const defaultNotInvolved = "\u4E0D\u6D89\u53CA\u3002";
10998
+ const techSolution = data.techSolution || {};
10999
+ const flattenedData = {
11000
+ techSolution_trafficEstimation: techSolution.trafficEstimation || defaultNotInvolved
11001
+ };
11002
+ const subSections = [
11003
+ {
11004
+ name: 'messageQueue',
11005
+ data: prepareSubSectionData(techSolution.messageQueue, defaultNotInvolved)
11006
+ },
11007
+ {
11008
+ name: 'databaseSplit',
11009
+ data: prepareSubSectionData(techSolution.databaseSplit, defaultNotInvolved)
11010
+ },
11011
+ {
11012
+ name: 'distributedTransaction',
11013
+ data: prepareSubSectionData(techSolution.distributedTransaction, defaultNotInvolved)
11014
+ },
11015
+ {
11016
+ name: 'distributedLock',
11017
+ data: prepareSubSectionData(techSolution.distributedLock, defaultNotInvolved)
11018
+ },
11019
+ {
11020
+ name: 'scheduledTask',
11021
+ data: prepareSubSectionData(techSolution.scheduledTask, defaultNotInvolved)
11022
+ },
11023
+ {
11024
+ name: 'delayTask',
11025
+ data: prepareSubSectionData(techSolution.delayTask, defaultNotInvolved)
11026
+ },
11027
+ {
11028
+ name: 'cacheDesign',
11029
+ data: prepareSubSectionData(techSolution.cacheDesign, defaultNotInvolved)
11030
+ }
11031
+ ];
11032
+ for (const { name, data: sectionData } of subSections)Object.assign(flattenedData, flattenSubSection('techSolution', name, sectionData));
11033
+ flattenedData.businessException_content = data.businessException?.content || defaultNotInvolved;
11034
+ flattenedData.appendix_exceptionCodeList = data.appendix?.exceptionCodeList || [];
11035
+ flattenedData.appendix_codeValueList = data.appendix?.codeValueList || [];
11036
+ const renderData = {
11037
+ projectName: data.projectName,
11038
+ moduleName: data.moduleName,
11039
+ year: data.year,
11040
+ month: data.month,
11041
+ referDoc: data.referDoc,
11042
+ serviceInterfaceList: data.serviceInterfaceList || [],
11043
+ designDetailList: data.designDetailList || [],
11044
+ tableInfoList: data.tableInfoList || [],
11045
+ ...flattenedData
11046
+ };
11047
+ logger.debug("\u6E32\u67D3\u6570\u636E", {
11048
+ flattenedData
11049
+ });
11050
+ return renderData;
11051
+ }
10945
11052
  async function renderTechSpecDoc(data, outputDir) {
10946
11053
  try {
10947
11054
  const templatePath = getTemplatePath();
@@ -10960,19 +11067,20 @@ ${requirement_description}
10960
11067
  paragraphLoop: true,
10961
11068
  linebreaks: true,
10962
11069
  delimiters: {
10963
- start: '{',
10964
- end: '}'
11070
+ start: "{",
11071
+ end: "}"
10965
11072
  }
10966
11073
  });
10967
- doc.render(data);
11074
+ const renderData = prepareRenderData(data);
11075
+ doc.render(renderData);
10968
11076
  const output = doc.getZip().generate({
10969
- type: 'nodebuffer',
10970
- compression: 'DEFLATE'
11077
+ type: "nodebuffer",
11078
+ compression: "DEFLATE"
10971
11079
  });
10972
11080
  await promises_namespaceObject.mkdir(outputDir, {
10973
11081
  recursive: true
10974
11082
  });
10975
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
11083
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
10976
11084
  const outputFileName = `\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}_${data.projectName}_${data.moduleName}_${timestamp}.docx`;
10977
11085
  const outputPath = external_path_namespaceObject.join(outputDir, outputFileName);
10978
11086
  await promises_namespaceObject.writeFile(outputPath, output);
@@ -10988,7 +11096,7 @@ ${requirement_description}
10988
11096
  error: error.message
10989
11097
  });
10990
11098
  if (error.properties && error.properties.errors) {
10991
- const errorMessages = error.properties.errors.map((e)=>e.properties?.explanation || e.message).join('; ');
11099
+ const errorMessages = error.properties.errors.map((e)=>e.properties?.explanation || e.message).join("; ");
10992
11100
  return {
10993
11101
  success: false,
10994
11102
  outputPath: null,
@@ -11002,6 +11110,11 @@ ${requirement_description}
11002
11110
  };
11003
11111
  }
11004
11112
  }
11113
+ const PROJECT_PATH_DESCRIPTION = "\u9879\u76EE\u6839\u76EE\u5F55\u8DEF\u5F84\uFF0C\u751F\u6210\u7684\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u4FDD\u5B58\u5230\u9879\u76EE\u6839\u76EE\u5F55\u7684.aico/tech\u4E0B\uFF0C\u6CE8\u610F\u4E0D\u662F\u7528\u6237\u8F93\u5165\u7684\u6A21\u5757\u76EE\u5F55\uFF0C\u662F\u6574\u4E2A\u9879\u76EE\u7684\u6839\u76EE\u5F55";
11114
+ const TECH_SPEC_OUTPUT_DIR = ".aico/tech";
11115
+ function getTechSpecOutputDir(projectPath) {
11116
+ return `${projectPath}/${TECH_SPEC_OUTPUT_DIR}`;
11117
+ }
11005
11118
  const TableFieldDetailSchema = objectType({
11006
11119
  id: stringType().describe("\u5E8F\u53F7"),
11007
11120
  fieldName: stringType().describe("\u5B57\u6BB5\u540D"),
@@ -11057,20 +11170,454 @@ ${requirement_description}
11057
11170
  serviceDescription: stringType().describe("\u670D\u52A1\u63CF\u8FF0"),
11058
11171
  interfaceDetailList: arrayType(InterfaceDetailSchema).default([]).describe("\u63A5\u53E3\u8BE6\u60C5\u5217\u8868")
11059
11172
  });
11060
- const techSpecGeneratorTool = {
11061
- name: 'tech-spec-generator',
11062
- description: `\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{751F}\u{6210}\u{5DE5}\u{5177} - \u{6839}\u{636E}\u{6536}\u{96C6}\u{7684}\u{4EE3}\u{7801}\u{4FE1}\u{606F}\u{751F}\u{6210}\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{3002}
11063
-
11064
- \u{4F7F}\u{7528}\u{6D41}\u{7A0B}\u{FF1A}
11065
- 1. MCP\u{5BA2}\u{6237}\u{7AEF}\u{5148}\u{8BFB}\u{53D6}\u{76EE}\u{6807}\u{4EE3}\u{7801}\u{76EE}\u{5F55}\u{FF0C}\u{5206}\u{6790}\u{5E76}\u{6536}\u{96C6}\u{4EE5}\u{4E0B}\u{4FE1}\u{606F}\u{FF1A}
11066
- - \u{6570}\u{636E}\u{8868}\u{8BBE}\u{8BA1}\u{FF08}\u{8868}\u{540D}\u{3001}\u{5B57}\u{6BB5}\u{4FE1}\u{606F}\u{7B49}\u{FF09}
11067
- - \u{670D}\u{52A1}\u{63A5}\u{53E3}\u{8BBE}\u{8BA1}\u{FF08}\u{670D}\u{52A1}\u{540D}\u{3001}\u{63A5}\u{53E3}\u{65B9}\u{6CD5}\u{3001}\u{53C2}\u{6570}\u{3001}\u{8FD4}\u{56DE}\u{503C}\u{7B49}\u{FF09}
11068
- - \u{529F}\u{80FD}\u{8BBE}\u{8BA1}\u{8BE6}\u{60C5}\u{FF08}\u{529F}\u{80FD}\u{540D}\u{79F0}\u{3001}\u{63CF}\u{8FF0}\u{3001}\u{5B9E}\u{73B0}\u{903B}\u{8F91}\u{7B49}\u{FF09}
11069
- 2. \u{5C06}\u{6536}\u{96C6}\u{7684}\u{6570}\u{636E}\u{901A}\u{8FC7} techSpecData \u{53C2}\u{6570}\u{4F20}\u{9012}\u{7ED9}\u{8BE5}\u{5DE5}\u{5177}
11070
- 3. \u{5DE5}\u{5177}\u{4F7F}\u{7528} .aico/create-tect-docs/\u{6280}\u{672F}\u{89C4}\u{683C}\u{8BF4}\u{660E}\u{4E66}\u{6A21}\u{677F}.docx \u{6A21}\u{677F}\u{6E32}\u{67D3}\u{751F}\u{6210}\u{6587}\u{6863}
11071
- 4. \u{6587}\u{6863}\u{8F93}\u{51FA}\u{5230} projectPath/.aico/tect/ \u{76EE}\u{5F55}`,
11173
+ objectType({
11174
+ description: stringType().describe("\u63CF\u8FF0"),
11175
+ qps: stringType().describe("\u9884\u4F30QPS"),
11176
+ peakQps: stringType().describe("\u5CF0\u503CQPS"),
11177
+ dailyVolume: stringType().describe("\u65E5\u8BF7\u6C42\u91CF")
11178
+ });
11179
+ const SubSectionContentSchema = objectType({
11180
+ constraint: stringType().optional().describe("\u7EA6\u675F"),
11181
+ useCase: stringType().optional().describe("\u4F7F\u7528\u573A\u666F"),
11182
+ design: stringType().optional().describe("\u65B9\u6848\u8BBE\u8BA1"),
11183
+ intro: stringType().optional().describe("\u7AE0\u8282\u7B80\u4ECB"),
11184
+ dataEstimation: stringType().optional().describe("\u6570\u636E\u91CF\u4F30\u7B97"),
11185
+ sharding: stringType().optional().describe("\u5206\u5E93\u5206\u8868\u8BBE\u8BA1"),
11186
+ designIdea: stringType().optional().describe("\u8BBE\u8BA1\u601D\u8DEF"),
11187
+ implementation: stringType().optional().describe("\u5177\u4F53\u5B9E\u73B0")
11188
+ });
11189
+ const TechSolutionSchema = objectType({
11190
+ content: stringType().optional().describe("\u6280\u672F\u65B9\u6848\u5B8C\u6574\u5185\u5BB9\uFF08\u7B80\u5316\u6A21\u5F0F\uFF09"),
11191
+ trafficEstimation: stringType().optional().describe("6.1 \u6D41\u91CF\u4F30\u7B97\u5206\u6790"),
11192
+ messageQueue: SubSectionContentSchema.optional().describe("6.2 \u6D88\u606F\u961F\u5217"),
11193
+ databaseSplit: SubSectionContentSchema.optional().describe("6.3 \u6570\u636E\u5E93\u62C6\u5206\u8BBE\u8BA1"),
11194
+ distributedTransaction: SubSectionContentSchema.optional().describe("6.4 \u5206\u5E03\u5F0F\u4E8B\u52A1"),
11195
+ distributedLock: SubSectionContentSchema.optional().describe("6.5 \u5206\u5E03\u5F0F\u9501"),
11196
+ scheduledTask: SubSectionContentSchema.optional().describe("6.6 \u5B9A\u65F6\u4EFB\u52A1"),
11197
+ delayTask: SubSectionContentSchema.optional().describe("6.7 \u5EF6\u65F6\u4EFB\u52A1"),
11198
+ cacheDesign: SubSectionContentSchema.optional().describe("6.8 \u7F13\u5B58\u65B9\u6848")
11199
+ });
11200
+ const BusinessExceptionSchema = objectType({
11201
+ content: stringType().describe("\u4E1A\u52A1\u5F02\u5E38\u5904\u7406\u5B8C\u6574\u5185\u5BB9")
11202
+ });
11203
+ const ExceptionCodeSchema = objectType({
11204
+ id: stringType().optional().describe("\u5E8F\u53F7"),
11205
+ exceptionCode: stringType().describe("\u5F02\u5E38\u7F16\u7801"),
11206
+ exceptionDescription: stringType().describe("\u5F02\u5E38\u63CF\u8FF0")
11207
+ });
11208
+ const CodeValueSchema = objectType({
11209
+ id: stringType().optional().describe("\u5E8F\u53F7"),
11210
+ propertyName: stringType().describe("\u5C5E\u6027"),
11211
+ codeValue: stringType().describe("\u7801\u503C")
11212
+ });
11213
+ const AppendixSchema = objectType({
11214
+ content: stringType().optional().describe("\u9644\u5F55\u5B8C\u6574\u5185\u5BB9\uFF08\u7B80\u5316\u6A21\u5F0F\uFF09"),
11215
+ exceptionCodeList: arrayType(ExceptionCodeSchema).optional().describe("\u5F02\u5E38\u7801\u8868\u5217\u8868"),
11216
+ codeValueList: arrayType(CodeValueSchema).optional().describe("\u7801\u503C\u5217\u8868")
11217
+ });
11218
+ function extractDtoTypeName(typeStr) {
11219
+ if (!typeStr) return null;
11220
+ const genericMatch = typeStr.match(/(?:List|Set|Collection|TableDataInfo|PageInfo|Page|R|Result|Response|Optional)<([^<>]+)>/i);
11221
+ if (genericMatch) return extractDtoTypeName(genericMatch[1]) || genericMatch[1];
11222
+ return typeStr;
11223
+ }
11224
+ function isDtoTypeName(typeName) {
11225
+ if (!typeName) return false;
11226
+ return /(?:DTO|Request|Response|Vo|Bo|Dto|Query|Param|Result|Entity|Model|Info|Key|Form)$/i.test(typeName);
11227
+ }
11228
+ function expandDtoFields(fieldList, dtoDefinitions, mode) {
11229
+ const expandedList = [];
11230
+ let idCounter = 1;
11231
+ for (const field of fieldList){
11232
+ const fieldType = field.propertyType || field.type || "";
11233
+ const fieldName = field.propertyName || field.name || "";
11234
+ const fieldDesc = field.propertyDesc || field.description || "";
11235
+ const fieldRequired = field.required || "\u5426";
11236
+ const dtoTypeName = extractDtoTypeName(fieldType);
11237
+ const isDtoType = dtoTypeName && isDtoTypeName(dtoTypeName);
11238
+ let dtoFields = null;
11239
+ if (isDtoType && dtoTypeName) {
11240
+ const possibleNames = [
11241
+ dtoTypeName,
11242
+ dtoTypeName.replace(/Vo$|Bo$|Dto$/i, ""),
11243
+ dtoTypeName.replace(/Vo$/i, "Bo"),
11244
+ dtoTypeName.replace(/Bo$/i, "Vo")
11245
+ ];
11246
+ for (const name of possibleNames)if (dtoDefinitions[name]) {
11247
+ dtoFields = dtoDefinitions[name];
11248
+ break;
11249
+ }
11250
+ }
11251
+ if (dtoFields && dtoFields.length > 0) for (const dtoField of dtoFields){
11252
+ const dtoFieldName = dtoField.name || dtoField.propertyName || dtoField.fieldName || "";
11253
+ const dtoFieldType = dtoField.type || dtoField.propertyType || dtoField.fieldType || "";
11254
+ const dtoFieldDesc = dtoField.description || dtoField.propertyDesc || dtoField.fieldDescription || "";
11255
+ if ("param" === mode) expandedList.push({
11256
+ id: String(idCounter++),
11257
+ propertyType: dtoFieldType,
11258
+ propertyName: `${fieldName}.${dtoFieldName}`,
11259
+ required: dtoField.required || "\u5426",
11260
+ propertyDesc: dtoFieldDesc
11261
+ });
11262
+ else expandedList.push({
11263
+ id: String(idCounter++),
11264
+ propertyType: dtoFieldType,
11265
+ propertyName: `${fieldName}.${dtoFieldName}`,
11266
+ propertyDesc: dtoFieldDesc
11267
+ });
11268
+ }
11269
+ else if ("param" === mode) expandedList.push({
11270
+ id: field.id || String(idCounter++),
11271
+ propertyType: fieldType,
11272
+ propertyName: fieldName,
11273
+ required: fieldRequired,
11274
+ propertyDesc: fieldDesc
11275
+ });
11276
+ else expandedList.push({
11277
+ id: field.id || String(idCounter++),
11278
+ propertyType: fieldType,
11279
+ propertyName: fieldName,
11280
+ propertyDesc: fieldDesc
11281
+ });
11282
+ }
11283
+ return expandedList;
11284
+ }
11285
+ function generateDtoDefinitionsFromTables(tableInfoList) {
11286
+ const definitions = {};
11287
+ if (!Array.isArray(tableInfoList)) return definitions;
11288
+ for (const table of tableInfoList){
11289
+ const entityName = table.entityName || "";
11290
+ if (!entityName) continue;
11291
+ const fields = table.tableDetailList || table.fieldList || table.fields || [];
11292
+ const dtoFields = fields.map((field)=>({
11293
+ name: field.fieldName || "",
11294
+ type: field.fieldType || "",
11295
+ description: field.fieldDescription || field.fieldDesc || "",
11296
+ required: "\u5426"
11297
+ }));
11298
+ const variations = [
11299
+ entityName,
11300
+ `${entityName}Vo`,
11301
+ `${entityName}Bo`,
11302
+ `${entityName}Dto`,
11303
+ `${entityName}Query`,
11304
+ `${entityName}Form`
11305
+ ];
11306
+ for (const name of variations)definitions[name] = dtoFields;
11307
+ }
11308
+ return definitions;
11309
+ }
11310
+ function normalizeInputData(input) {
11311
+ const result = {
11312
+ ...input
11313
+ };
11314
+ if (Array.isArray(input.tableInfoList)) result.tableInfoList = input.tableInfoList.map((table, tableIndex)=>{
11315
+ const normalizedTable = {
11316
+ id: table.id || String(tableIndex + 1),
11317
+ tableName: table.tableName || "",
11318
+ entityName: table.entityName || table.tableName || "",
11319
+ tableDescription: table.tableDescription || table.tableDesc || table.tableComment || table.comment || "",
11320
+ tableDetailList: []
11321
+ };
11322
+ const fieldList = table.tableDetailList || table.fieldList || table.fields || [];
11323
+ normalizedTable.tableDetailList = fieldList.map((field, fieldIndex)=>({
11324
+ id: field.id || String(fieldIndex + 1),
11325
+ fieldName: field.fieldName || "",
11326
+ fieldType: field.fieldType || "",
11327
+ fieldDescription: field.fieldDescription || field.fieldDesc || field.fieldComment || field.comment || "",
11328
+ fieldLength: field.fieldLength || "-"
11329
+ }));
11330
+ return normalizedTable;
11331
+ });
11332
+ if (Array.isArray(input.serviceInterfaceList)) result.serviceInterfaceList = input.serviceInterfaceList.map((service, serviceIndex)=>{
11333
+ if (void 0 !== service.serviceEnglishName) return service;
11334
+ const normalizedService = {
11335
+ id: service.id || String(serviceIndex + 1),
11336
+ serviceType: service.serviceType || "REST",
11337
+ serviceEnglishName: service.interfaceName || service.serviceEnglishName || "",
11338
+ serviceChineseName: service.serviceChineseName || service.interfaceDesc || service.interfaceComment || service.interfaceName || "",
11339
+ serviceDescription: service.serviceDescription || service.interfaceDesc || service.interfaceComment || "",
11340
+ interfaceDetailList: []
11341
+ };
11342
+ const methodList = service.interfaceDetailList || service.methodList || service.methods || [];
11343
+ normalizedService.interfaceDetailList = methodList.map((method, methodIndex)=>({
11344
+ id: method.id || String(methodIndex + 1),
11345
+ functionDescription: method.functionDescription || method.methodDesc || method.methodComment || method.comment || "",
11346
+ serviceName: method.serviceName || service.interfaceName || service.serviceEnglishName || "",
11347
+ methodName: method.methodName || ""
11348
+ }));
11349
+ return normalizedService;
11350
+ });
11351
+ if (Array.isArray(input.designDetailList)) {
11352
+ let dtoDefinitions = input.dtoDefinitions || {};
11353
+ if (0 === Object.keys(dtoDefinitions).length && Array.isArray(input.tableInfoList)) dtoDefinitions = generateDtoDefinitionsFromTables(input.tableInfoList);
11354
+ result.designDetailList = input.designDetailList.map((design)=>{
11355
+ const normalizedDesign = {
11356
+ serviceName: design.serviceName || design.moduleName || design.designName || "",
11357
+ serviceDesc: design.serviceDesc || design.moduleDesc || design.designDesc || "",
11358
+ interfaceDesignDetailList: []
11359
+ };
11360
+ const interfaceList = design.interfaceDesignDetailList || [];
11361
+ normalizedDesign.interfaceDesignDetailList = interfaceList.map((iface)=>{
11362
+ const expandedParamList = expandDtoFields(iface.parameterList || [], dtoDefinitions, "param");
11363
+ const expandedReturnList = expandDtoFields(iface.returnResultList || [], dtoDefinitions, "return");
11364
+ return {
11365
+ functionName: iface.functionName || "",
11366
+ interfaceDesc: iface.interfaceDesc || "",
11367
+ className: iface.className || "",
11368
+ methodName: iface.methodName || "",
11369
+ parameterList: expandedParamList,
11370
+ returnResultList: expandedReturnList,
11371
+ implementLogic: iface.implementLogic || ""
11372
+ };
11373
+ });
11374
+ return normalizedDesign;
11375
+ });
11376
+ }
11377
+ if (Array.isArray(input.businessExceptionList)) result.businessExceptionList = input.businessExceptionList.map((exception, index)=>{
11378
+ if (void 0 !== exception.sceneName) return exception;
11379
+ return {
11380
+ id: exception.id || String(index + 1),
11381
+ sceneName: exception.sceneName || exception.exceptionCode || "",
11382
+ exceptionType: exception.exceptionType || "BusinessException",
11383
+ handleStrategy: exception.handleStrategy || exception.solution || exception.exceptionSolution || "",
11384
+ description: exception.description || exception.exceptionDesc || ""
11385
+ };
11386
+ });
11387
+ if (input.techSolution) if ("string" == typeof input.techSolution) result.techSolution = {
11388
+ content: input.techSolution
11389
+ };
11390
+ else if (input.techSolution.content) result.techSolution = input.techSolution;
11391
+ else result.techSolution = {
11392
+ content: "\u6280\u672F\u65B9\u6848\u5185\u5BB9\u9700\u8981\u7531MCP\u5BA2\u6237\u7AEF\u751F\u6210"
11393
+ };
11394
+ if (input.businessException) if ("string" == typeof input.businessException) result.businessException = {
11395
+ content: input.businessException
11396
+ };
11397
+ else result.businessException = input.businessException;
11398
+ else if (input.businessExceptionList) result.businessException = {
11399
+ content: "\u4E1A\u52A1\u5F02\u5E38\u5904\u7406\u5185\u5BB9\u9700\u8981\u7531MCP\u5BA2\u6237\u7AEF\u751F\u6210"
11400
+ };
11401
+ if (input.appendix) if ("string" == typeof input.appendix) result.appendix = {
11402
+ content: input.appendix
11403
+ };
11404
+ else if (input.appendix.content) result.appendix = input.appendix;
11405
+ else result.appendix = {
11406
+ content: "\u9644\u5F55\u5185\u5BB9\u9700\u8981\u7531MCP\u5BA2\u6237\u7AEF\u751F\u6210"
11407
+ };
11408
+ return result;
11409
+ }
11410
+ const analyzeProjectContextTool = {
11411
+ name: "analyze_project_context",
11412
+ description: "\u5206\u6790\u9879\u76EE\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF0C\u4E3A\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u505A\u51C6\u5907",
11413
+ inputSchema: {
11414
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11415
+ },
11416
+ handler: async (args)=>{
11417
+ const { projectPath } = args;
11418
+ if (!projectPath) return {
11419
+ content: [
11420
+ {
11421
+ type: "text",
11422
+ text: JSON.stringify({
11423
+ success: false,
11424
+ message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1AprojectPath"
11425
+ })
11426
+ }
11427
+ ],
11428
+ isError: true
11429
+ };
11430
+ return {
11431
+ content: [
11432
+ {
11433
+ type: "text",
11434
+ text: JSON.stringify({
11435
+ success: true,
11436
+ message: "\u9879\u76EE\u4E0A\u4E0B\u6587\u5206\u6790\u6307\u5BFC",
11437
+ data: {
11438
+ analysisSteps: [
11439
+ {
11440
+ step: 1,
11441
+ action: "\u8BFB\u53D6\u9879\u76EE\u6587\u6863",
11442
+ files: [
11443
+ `${projectPath}/README.md`,
11444
+ `${projectPath}/package.json`
11445
+ ]
11446
+ },
11447
+ {
11448
+ step: 2,
11449
+ action: "\u5206\u6790\u9879\u76EE\u7ED3\u6784",
11450
+ directories: [
11451
+ `${projectPath}/src`
11452
+ ]
11453
+ }
11454
+ ],
11455
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11456
+ }
11457
+ })
11458
+ }
11459
+ ]
11460
+ };
11461
+ }
11462
+ };
11463
+ const collectServiceInterfacesTool = {
11464
+ name: "collect_service_interfaces",
11465
+ description: "\u6536\u96C6\u9879\u76EE\u4E2D\u7684\u670D\u52A1\u63A5\u53E3\u6E05\u5355",
11466
+ inputSchema: {
11467
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11468
+ },
11469
+ handler: async (args)=>({
11470
+ content: [
11471
+ {
11472
+ type: "text",
11473
+ text: JSON.stringify({
11474
+ success: true,
11475
+ message: "\u670D\u52A1\u63A5\u53E3\u6536\u96C6\u6307\u5BFC",
11476
+ data: {
11477
+ scanTargets: [
11478
+ "**/*Controller.{ts,js}",
11479
+ "**/*Service.{ts,js}"
11480
+ ],
11481
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11482
+ }
11483
+ })
11484
+ }
11485
+ ]
11486
+ })
11487
+ };
11488
+ const generateInterfaceDesignsTool = {
11489
+ name: "generate_interface_designs",
11490
+ description: "\u57FA\u4E8E\u670D\u52A1\u63A5\u53E3\u6E05\u5355\u751F\u6210\u8BE6\u7EC6\u7684\u63A5\u53E3\u8BBE\u8BA1",
11491
+ inputSchema: {
11492
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION),
11493
+ serviceInterfaceList: arrayType(ServiceInterfaceSchema).describe("\u670D\u52A1\u63A5\u53E3\u6E05\u5355")
11494
+ },
11495
+ handler: async (args)=>({
11496
+ content: [
11497
+ {
11498
+ type: "text",
11499
+ text: JSON.stringify({
11500
+ success: true,
11501
+ message: "\u63A5\u53E3\u8BBE\u8BA1\u8BE6\u60C5\u751F\u6210\u6307\u5BFC",
11502
+ data: {
11503
+ designPrinciples: [
11504
+ "\u53C2\u6570\u7C7B\u578B\u5FC5\u987B\u5C55\u5F00\u5177\u4F53\u5B57\u6BB5\uFF0C\u7981\u6B62\u4F7F\u7528DTO\u7B49\u7B80\u5316\u540D\u79F0"
11505
+ ],
11506
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11507
+ }
11508
+ })
11509
+ }
11510
+ ]
11511
+ })
11512
+ };
11513
+ const collectDatabaseSchemaTool = {
11514
+ name: "collect_database_schema",
11515
+ description: "\u6536\u96C6\u9879\u76EE\u7684\u6570\u636E\u5E93\u8868\u7ED3\u6784\u4FE1\u606F",
11516
+ inputSchema: {
11517
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11518
+ },
11519
+ handler: async (args)=>({
11520
+ content: [
11521
+ {
11522
+ type: "text",
11523
+ text: JSON.stringify({
11524
+ success: true,
11525
+ message: "\u6570\u636E\u5E93\u7ED3\u6784\u6536\u96C6\u6307\u5BFC",
11526
+ data: {
11527
+ scanTargets: [
11528
+ "**/migrations/**/*.sql",
11529
+ "**/*Entity.{ts,js}"
11530
+ ],
11531
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11532
+ }
11533
+ })
11534
+ }
11535
+ ]
11536
+ })
11537
+ };
11538
+ const analyzeTechSolutionTool = {
11539
+ name: "analyze_tech_solution",
11540
+ description: "\u5206\u6790\u9879\u76EE\u7684\u6280\u672F\u65B9\u6848\uFF0C\u6839\u636E\u5B9E\u9645\u60C5\u51B5\u751F\u6210\u6280\u672F\u67B6\u6784\u8BBE\u8BA1",
11541
+ inputSchema: {
11542
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11543
+ },
11544
+ handler: async (args)=>({
11545
+ content: [
11546
+ {
11547
+ type: "text",
11548
+ text: JSON.stringify({
11549
+ success: true,
11550
+ message: "\u6280\u672F\u65B9\u6848\u5206\u6790\u6307\u5BFC",
11551
+ data: {
11552
+ analysisAreas: [
11553
+ "\u6D41\u91CF\u4F30\u7B97\u5206\u6790",
11554
+ "\u6280\u672F\u67B6\u6784\u8BBE\u8BA1",
11555
+ "\u4E2D\u95F4\u4EF6\u9009\u578B"
11556
+ ],
11557
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11558
+ }
11559
+ })
11560
+ }
11561
+ ]
11562
+ })
11563
+ };
11564
+ const collectBusinessExceptionsTool = {
11565
+ name: "collect_business_exceptions",
11566
+ description: "\u6536\u96C6\u9879\u76EE\u4E2D\u7684\u4E1A\u52A1\u5F02\u5E38\u5904\u7406\u60C5\u51B5",
11567
+ inputSchema: {
11568
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11569
+ },
11570
+ handler: async (args)=>({
11571
+ content: [
11572
+ {
11573
+ type: "text",
11574
+ text: JSON.stringify({
11575
+ success: true,
11576
+ message: "\u4E1A\u52A1\u5F02\u5E38\u5904\u7406\u6536\u96C6\u6307\u5BFC",
11577
+ data: {
11578
+ scanTargets: [
11579
+ "**/*Exception.{ts,js}",
11580
+ "**/errors/**/*.{ts,js}"
11581
+ ],
11582
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11583
+ }
11584
+ })
11585
+ }
11586
+ ]
11587
+ })
11588
+ };
11589
+ const generateAppendixTool = {
11590
+ name: "generate_appendix",
11591
+ description: "\u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u7684\u9644\u5F55\u5185\u5BB9",
11592
+ inputSchema: {
11593
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION)
11594
+ },
11595
+ handler: async (args)=>({
11596
+ content: [
11597
+ {
11598
+ type: "text",
11599
+ text: JSON.stringify({
11600
+ success: true,
11601
+ message: "\u9644\u5F55\u5185\u5BB9\u751F\u6210\u6307\u5BFC",
11602
+ data: {
11603
+ contentAreas: [
11604
+ "\u9519\u8BEF\u7801\u8868",
11605
+ "\u914D\u7F6E\u53C2\u6570\u8868",
11606
+ "\u6570\u636E\u5B57\u5178",
11607
+ "\u6280\u672F\u672F\u8BED\u8868"
11608
+ ],
11609
+ nextStep: "\u8C03\u7528 generate_final_document \u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66"
11610
+ }
11611
+ })
11612
+ }
11613
+ ]
11614
+ })
11615
+ };
11616
+ const generateFinalDocumentTool = {
11617
+ name: "generate_final_document",
11618
+ description: "\u6574\u5408\u6240\u6709\u6536\u96C6\u7684\u4FE1\u606F\uFF0C\u751F\u6210\u5B8C\u6574\u7684\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66",
11072
11619
  inputSchema: {
11073
- projectPath: stringType().min(1).describe("\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF0C\u751F\u6210\u7684\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u4FDD\u5B58\u5230\u8BE5\u8DEF\u5F84\u4E0B\u7684.aico/tect\u76EE\u5F55"),
11620
+ projectPath: stringType().min(1).describe(PROJECT_PATH_DESCRIPTION),
11074
11621
  techSpecData: objectType({
11075
11622
  projectName: stringType().describe("\u9879\u76EE\u540D\u79F0"),
11076
11623
  moduleName: stringType().describe("\u6A21\u5757\u540D\u79F0"),
@@ -11079,63 +11626,56 @@ ${requirement_description}
11079
11626
  referDoc: stringType().optional().describe("\u53C2\u8003\u6587\u6863"),
11080
11627
  serviceInterfaceList: arrayType(ServiceInterfaceSchema).default([]).describe("\u670D\u52A1\u63A5\u53E3\u6E05\u5355"),
11081
11628
  designDetailList: arrayType(DesignDetailSchema).default([]).describe("\u670D\u52A1\u63A5\u53E3\u8BBE\u8BA1\u8BE6\u60C5"),
11082
- tableInfoList: arrayType(TableInfoSchema).default([]).describe("\u6570\u636E\u5E93\u8868\u4FE1\u606F\u5217\u8868")
11083
- }).describe("\u6280\u672F\u89C4\u683C\u6570\u636E\uFF0C\u7531MCP\u5BA2\u6237\u7AEF\u901A\u8FC7\u5206\u6790\u4EE3\u7801\u76EE\u5F55\u6536\u96C6")
11629
+ tableInfoList: arrayType(TableInfoSchema).default([]).describe("\u6570\u636E\u5E93\u8868\u4FE1\u606F\u5217\u8868"),
11630
+ techSolution: TechSolutionSchema.optional().describe("\u6280\u672F\u65B9\u6848"),
11631
+ businessException: BusinessExceptionSchema.optional().describe("\u4E1A\u52A1\u5F02\u5E38\u5904\u7406"),
11632
+ appendix: AppendixSchema.optional().describe("\u9644\u5F55"),
11633
+ dtoDefinitions: recordType(stringType(), arrayType(objectType({
11634
+ name: stringType().optional().describe("\u5B57\u6BB5\u540D"),
11635
+ type: stringType().optional().describe("\u5B57\u6BB5\u7C7B\u578B"),
11636
+ required: stringType().optional().describe("\u662F\u5426\u5FC5\u586B"),
11637
+ description: stringType().optional().describe("\u5B57\u6BB5\u63CF\u8FF0")
11638
+ }))).optional().describe("DTO\u5B9A\u4E49\u6620\u5C04\uFF0C\u7528\u4E8E\u5C55\u5F00\u63A5\u53E3\u53C2\u6570\u4E2D\u7684DTO\u4E3A\u5177\u4F53\u5B57\u6BB5")
11639
+ }).describe("\u5B8C\u6574\u7684\u6280\u672F\u89C4\u683C\u6570\u636E")
11084
11640
  },
11085
11641
  handler: async (args)=>{
11086
11642
  try {
11087
- const { projectPath, techSpecData } = args;
11088
- if (!projectPath) return {
11643
+ const { projectPath } = args;
11644
+ let { techSpecData } = args;
11645
+ if (!projectPath || !techSpecData) return {
11089
11646
  content: [
11090
11647
  {
11091
- type: 'text',
11092
- text: JSON.stringify({
11093
- success: false,
11094
- message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1AprojectPath",
11095
- data: null
11096
- })
11097
- }
11098
- ],
11099
- isError: true
11100
- };
11101
- if (!techSpecData) return {
11102
- content: [
11103
- {
11104
- type: 'text',
11648
+ type: "text",
11105
11649
  text: JSON.stringify({
11106
11650
  success: false,
11107
- message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1AtechSpecData",
11108
- data: null
11651
+ message: "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570"
11109
11652
  })
11110
11653
  }
11111
11654
  ],
11112
11655
  isError: true
11113
11656
  };
11657
+ if ("string" == typeof techSpecData) techSpecData = JSON.parse(techSpecData);
11114
11658
  const now = new Date();
11659
+ const normalizedData = normalizeInputData(techSpecData);
11115
11660
  const data = {
11116
- projectName: techSpecData.projectName || "\u672A\u547D\u540D\u9879\u76EE",
11117
- moduleName: techSpecData.moduleName || "\u672A\u547D\u540D\u6A21\u5757",
11118
- year: techSpecData.year || String(now.getFullYear()),
11119
- month: techSpecData.month || String(now.getMonth() + 1).padStart(2, '0'),
11120
- referDoc: techSpecData.referDoc || "\u65E0",
11121
- serviceInterfaceList: techSpecData.serviceInterfaceList || [],
11122
- designDetailList: techSpecData.designDetailList || [],
11123
- tableInfoList: techSpecData.tableInfoList || []
11661
+ projectName: normalizedData.projectName || "\u672A\u547D\u540D\u9879\u76EE",
11662
+ moduleName: normalizedData.moduleName || "\u672A\u547D\u540D\u6A21\u5757",
11663
+ year: normalizedData.year || String(now.getFullYear()),
11664
+ month: normalizedData.month || String(now.getMonth() + 1).padStart(2, "0"),
11665
+ referDoc: normalizedData.referDoc || "\u65E0",
11666
+ serviceInterfaceList: normalizedData.serviceInterfaceList || [],
11667
+ designDetailList: normalizedData.designDetailList || [],
11668
+ tableInfoList: normalizedData.tableInfoList || [],
11669
+ techSolution: normalizedData.techSolution || void 0,
11670
+ businessException: normalizedData.businessException || void 0,
11671
+ appendix: normalizedData.appendix || void 0
11124
11672
  };
11125
- const outputDir = external_path_namespaceObject.join(projectPath, '.aico', 'tect');
11126
- logger.info("\u5F00\u59CB\u751F\u6210\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66", {
11127
- projectPath,
11128
- outputDir,
11129
- projectName: data.projectName,
11130
- moduleName: data.moduleName,
11131
- tableCount: data.tableInfoList.length,
11132
- serviceCount: data.serviceInterfaceList.length
11133
- });
11673
+ const outputDir = getTechSpecOutputDir(projectPath);
11134
11674
  const result = await renderTechSpecDoc(data, outputDir);
11135
11675
  if (result.success) return {
11136
11676
  content: [
11137
11677
  {
11138
- type: 'text',
11678
+ type: "text",
11139
11679
  text: JSON.stringify({
11140
11680
  success: true,
11141
11681
  message: "\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u6210\u529F",
@@ -11146,7 +11686,10 @@ ${requirement_description}
11146
11686
  statistics: {
11147
11687
  tableCount: data.tableInfoList.length,
11148
11688
  serviceCount: data.serviceInterfaceList.length,
11149
- designCount: data.designDetailList.length
11689
+ designCount: data.designDetailList.length,
11690
+ hasTechSolution: !!data.techSolution,
11691
+ hasBusinessException: !!data.businessException,
11692
+ hasAppendix: !!data.appendix
11150
11693
  }
11151
11694
  }
11152
11695
  })
@@ -11156,28 +11699,23 @@ ${requirement_description}
11156
11699
  return {
11157
11700
  content: [
11158
11701
  {
11159
- type: 'text',
11702
+ type: "text",
11160
11703
  text: JSON.stringify({
11161
11704
  success: false,
11162
- message: result.error || "\u6587\u6863\u751F\u6210\u5931\u8D25",
11163
- data: null
11705
+ message: result.error || "\u6587\u6863\u751F\u6210\u5931\u8D25"
11164
11706
  })
11165
11707
  }
11166
11708
  ],
11167
11709
  isError: true
11168
11710
  };
11169
11711
  } catch (error) {
11170
- logger.error("\u6280\u672F\u89C4\u683C\u8BF4\u660E\u4E66\u751F\u6210\u5F02\u5E38", {
11171
- error: error.message
11172
- });
11173
11712
  return {
11174
11713
  content: [
11175
11714
  {
11176
- type: 'text',
11715
+ type: "text",
11177
11716
  text: JSON.stringify({
11178
11717
  success: false,
11179
- message: error.message || "\u751F\u6210\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF",
11180
- data: null
11718
+ message: error.message || "\u751F\u6210\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF"
11181
11719
  })
11182
11720
  }
11183
11721
  ],
@@ -11186,6 +11724,16 @@ ${requirement_description}
11186
11724
  }
11187
11725
  }
11188
11726
  };
11727
+ const techSpecGeneratorTools = [
11728
+ analyzeProjectContextTool,
11729
+ collectServiceInterfacesTool,
11730
+ generateInterfaceDesignsTool,
11731
+ collectDatabaseSchemaTool,
11732
+ analyzeTechSolutionTool,
11733
+ collectBusinessExceptionsTool,
11734
+ generateAppendixTool,
11735
+ generateFinalDocumentTool
11736
+ ];
11189
11737
  function createMcpServer() {
11190
11738
  const server = new mcp_js_namespaceObject.McpServer({
11191
11739
  name: SERVICE_CONFIG.name,
@@ -11204,7 +11752,7 @@ ${requirement_description}
11204
11752
  requirementIdentifierTool,
11205
11753
  requirementAlignerTool,
11206
11754
  taskExecutorTool,
11207
- techSpecGeneratorTool
11755
+ ...techSpecGeneratorTools
11208
11756
  ];
11209
11757
  tools.forEach((tool)=>{
11210
11758
  server.tool(tool.name, tool.description, tool.inputSchema, tool.handler);