intention-coding 0.3.8 → 0.4.1
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/package.json +1 -1
- package/dist/db/file-storage.js +0 -638
- package/dist/index.js +0 -26
- package/dist/server/index.js +0 -88
- package/dist/services/bug-fix-agent/index.js +0 -320
- package/dist/services/change-summarizer/index.js +0 -123
- package/dist/services/change-summarizer/prompt/change-analysis.js +0 -56
- package/dist/services/code-generator/index.js +0 -403
- package/dist/services/code-generator/stages/execution-stage.js +0 -549
- package/dist/services/code-generator/stages/ideation-stage.js +0 -267
- package/dist/services/code-generator/stages/optimization-stage.js +0 -334
- package/dist/services/code-generator/stages/planning-stage.js +0 -295
- package/dist/services/code-generator/stages/research-stage.js +0 -283
- package/dist/services/code-generator/stages/review-stage.js +0 -270
- package/dist/services/code-generator/types.js +0 -37
- package/dist/services/code-generator/utils/instruction-executor.js +0 -207
- package/dist/services/code-generator/workflow-manager.js +0 -252
- package/dist/services/image-analysis/analyzer.js +0 -530
- package/dist/services/image-analysis/index.js +0 -406
- package/dist/services/image-analysis/types.js +0 -46
- package/dist/services/image-converter/converter.js +0 -310
- package/dist/services/image-converter/index.js +0 -262
- package/dist/services/image-converter/types.js +0 -31
- package/dist/services/integrated-generator/index.js +0 -1297
- package/dist/services/pdf2md/index.js +0 -180
- package/dist/services/project-template/index.js +0 -83
- package/dist/services/project-template/prompt/project-rules.js +0 -98
- package/dist/services/requirement-analyzer/chunk-reader.js +0 -218
- package/dist/services/requirement-analyzer/core/document-generator.js +0 -254
- package/dist/services/requirement-analyzer/core/intelligent-analyzer.js +0 -169
- package/dist/services/requirement-analyzer/core/project-analyzer.js +0 -199
- package/dist/services/requirement-analyzer/core/requirement-analyzer-service.js +0 -191
- package/dist/services/requirement-analyzer/core/template-selector.js +0 -124
- package/dist/services/requirement-analyzer/core/types.js +0 -23
- package/dist/services/requirement-analyzer/index.js +0 -177
- package/dist/services/requirement-analyzer/prompt/api-template.js +0 -302
- package/dist/services/requirement-analyzer/prompt/app-template.js +0 -455
- package/dist/services/requirement-analyzer/prompt/intelligent-requirement-analysis.js +0 -92
- package/dist/services/requirement-analyzer/prompt/pc-page-template.js +0 -582
- package/dist/services/requirement-analyzer/prompt/requirement-analysis.js +0 -664
- package/dist/services/requirement-analyzer/prompt/sdk-template.js +0 -582
- package/dist/services/requirement-analyzer/utils/file-reader.js +0 -169
- package/dist/services/world2md/index.js +0 -157
- package/dist/types/index.js +0 -2
- package/dist/utils/common.js +0 -72
- package/dist/utils/config.js +0 -163
- package/dist/utils/context-manager.js +0 -114
- package/dist/utils/dify.js +0 -243
- package/dist/utils/logger.js +0 -129
- package/dist/utils/openai.js +0 -225
- package/dist/utils/pack.js +0 -75
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.readLargeFileContent = readLargeFileContent;
|
|
46
|
-
const fs = __importStar(require("fs/promises"));
|
|
47
|
-
const logger_1 = require("../../../utils/logger");
|
|
48
|
-
/**
|
|
49
|
-
* 大文件分段读取工具
|
|
50
|
-
* 职责:处理大文件的分段读取和内容合并
|
|
51
|
-
*/
|
|
52
|
-
/**
|
|
53
|
-
* 分段读取大文件内容
|
|
54
|
-
*/
|
|
55
|
-
function readLargeFileContent(filePath_1) {
|
|
56
|
-
return __awaiter(this, arguments, void 0, function* (filePath, chunkSize = 100) {
|
|
57
|
-
try {
|
|
58
|
-
logger_1.logger.info('开始分段读取大文件', { filePath, chunkSize });
|
|
59
|
-
const content = yield fs.readFile(filePath, 'utf8');
|
|
60
|
-
const lines = content.split('\n');
|
|
61
|
-
if (lines.length <= chunkSize) {
|
|
62
|
-
logger_1.logger.info('文件行数较少,直接返回完整内容', {
|
|
63
|
-
totalLines: lines.length
|
|
64
|
-
});
|
|
65
|
-
return content;
|
|
66
|
-
}
|
|
67
|
-
// 智能选择重要内容
|
|
68
|
-
const importantContent = selectImportantContent(lines, chunkSize);
|
|
69
|
-
logger_1.logger.info('大文件分段读取完成', {
|
|
70
|
-
originalLines: lines.length,
|
|
71
|
-
selectedLines: importantContent.split('\n').length
|
|
72
|
-
});
|
|
73
|
-
return importantContent;
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
logger_1.logger.error('大文件读取失败', { error, filePath });
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* 智能选择重要内容
|
|
83
|
-
*/
|
|
84
|
-
function selectImportantContent(lines, maxLines) {
|
|
85
|
-
const importantLines = [];
|
|
86
|
-
const headerLines = [];
|
|
87
|
-
const contentLines = [];
|
|
88
|
-
// 分类行内容
|
|
89
|
-
for (const line of lines) {
|
|
90
|
-
const trimmedLine = line.trim();
|
|
91
|
-
// 标题行(以#开头)
|
|
92
|
-
if (trimmedLine.startsWith('#')) {
|
|
93
|
-
headerLines.push(line);
|
|
94
|
-
}
|
|
95
|
-
// 非空内容行
|
|
96
|
-
else if (trimmedLine.length > 0 && !isBoilerplate(trimmedLine)) {
|
|
97
|
-
contentLines.push(line);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// 优先保留标题行
|
|
101
|
-
importantLines.push(...headerLines);
|
|
102
|
-
// 计算剩余可用行数
|
|
103
|
-
const remainingLines = maxLines - headerLines.length;
|
|
104
|
-
if (remainingLines > 0) {
|
|
105
|
-
// 选择最重要的内容行
|
|
106
|
-
const selectedContent = selectMostImportantContent(contentLines, remainingLines);
|
|
107
|
-
importantLines.push(...selectedContent);
|
|
108
|
-
}
|
|
109
|
-
return importantLines.join('\n');
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 选择最重要的内容行
|
|
113
|
-
*/
|
|
114
|
-
function selectMostImportantContent(contentLines, maxLines) {
|
|
115
|
-
if (contentLines.length <= maxLines) {
|
|
116
|
-
return contentLines;
|
|
117
|
-
}
|
|
118
|
-
// 按重要性评分排序
|
|
119
|
-
const scoredLines = contentLines.map(line => ({
|
|
120
|
-
line,
|
|
121
|
-
score: calculateImportanceScore(line)
|
|
122
|
-
}));
|
|
123
|
-
scoredLines.sort((a, b) => b.score - a.score);
|
|
124
|
-
return scoredLines
|
|
125
|
-
.slice(0, maxLines)
|
|
126
|
-
.map(item => item.line);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 计算行的重要性评分
|
|
130
|
-
*/
|
|
131
|
-
function calculateImportanceScore(line) {
|
|
132
|
-
let score = 0;
|
|
133
|
-
const trimmedLine = line.trim().toLowerCase();
|
|
134
|
-
// 包含关键词的行得分更高
|
|
135
|
-
const keywords = [
|
|
136
|
-
'需求', '功能', '接口', 'api', '页面', '用户', '系统',
|
|
137
|
-
'实现', '开发', '设计', '业务', '流程', '数据', '服务'
|
|
138
|
-
];
|
|
139
|
-
for (const keyword of keywords) {
|
|
140
|
-
if (trimmedLine.includes(keyword)) {
|
|
141
|
-
score += 2;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// 长度适中的行得分更高
|
|
145
|
-
if (trimmedLine.length > 10 && trimmedLine.length < 200) {
|
|
146
|
-
score += 1;
|
|
147
|
-
}
|
|
148
|
-
// 包含具体描述的行得分更高
|
|
149
|
-
if (trimmedLine.includes(':') || trimmedLine.includes(':')) {
|
|
150
|
-
score += 1;
|
|
151
|
-
}
|
|
152
|
-
return score;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* 判断是否为样板文本
|
|
156
|
-
*/
|
|
157
|
-
function isBoilerplate(line) {
|
|
158
|
-
const boilerplatePatterns = [
|
|
159
|
-
/^-+$/, // 分隔线
|
|
160
|
-
/^=+$/, // 分隔线
|
|
161
|
-
/^\s*$/, // 空行
|
|
162
|
-
/^#+\s*$/, // 空标题
|
|
163
|
-
/^目录$/,
|
|
164
|
-
/^table of contents$/i,
|
|
165
|
-
/^generated by/i,
|
|
166
|
-
/^created by/i
|
|
167
|
-
];
|
|
168
|
-
return boilerplatePatterns.some(pattern => pattern.test(line.trim()));
|
|
169
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
-
};
|
|
47
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.word2mdTool = exports.Word2MdParams = void 0;
|
|
49
|
-
const fs = __importStar(require("fs/promises"));
|
|
50
|
-
const mammoth_1 = __importDefault(require("mammoth"));
|
|
51
|
-
const path_1 = __importDefault(require("path"));
|
|
52
|
-
const html_to_md_1 = __importDefault(require("html-to-md"));
|
|
53
|
-
const config_1 = require("../../utils/config");
|
|
54
|
-
const logger_1 = require("../../utils/logger");
|
|
55
|
-
const common_1 = require("../../utils/common");
|
|
56
|
-
const zod_1 = require("zod");
|
|
57
|
-
exports.Word2MdParams = zod_1.z.object({
|
|
58
|
-
file_path: zod_1.z.string().describe("需要解析的Word文档的绝对路径"),
|
|
59
|
-
options: zod_1.z.object({
|
|
60
|
-
skip_images: zod_1.z.boolean().optional().default(false).describe("是否跳过图片转换"),
|
|
61
|
-
table_style: zod_1.z.enum(['simple', 'grid', 'pipe']).optional().default('simple').describe("表格转换样式"),
|
|
62
|
-
strict_mode: zod_1.z.boolean().optional().default(false).describe("严格模式(保留更多格式)")
|
|
63
|
-
}).optional().default({ skip_images: false, table_style: 'simple', strict_mode: false }).describe("转换选项")
|
|
64
|
-
});
|
|
65
|
-
;
|
|
66
|
-
exports.word2mdTool = {
|
|
67
|
-
name: "word文档处理智能体",
|
|
68
|
-
description: "word文档处理智能体 - 将Word文档(.docx)转换为Markdown格式",
|
|
69
|
-
parameters: exports.Word2MdParams,
|
|
70
|
-
execute: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
-
const { file_path } = args;
|
|
72
|
-
try {
|
|
73
|
-
// 1. 安全验证并解析路径
|
|
74
|
-
const resolvedPath = yield (0, common_1.validateAndResolvePath)(file_path);
|
|
75
|
-
// 2. 读取文件
|
|
76
|
-
const buffer = yield fs.readFile(resolvedPath);
|
|
77
|
-
// 3. 准备保存目录和文件名
|
|
78
|
-
const mdDir = path_1.default.join((0, config_1.getStorageDir)(), 'md');
|
|
79
|
-
const baseName = path_1.default.basename(file_path, '.docx');
|
|
80
|
-
const outputDir = path_1.default.join(mdDir, baseName);
|
|
81
|
-
const imgsDir = path_1.default.join(outputDir, 'imgs');
|
|
82
|
-
// 创建目录结构
|
|
83
|
-
yield fs.mkdir(outputDir, { recursive: true });
|
|
84
|
-
yield fs.mkdir(imgsDir, { recursive: true });
|
|
85
|
-
// 4. 先进行基本转换,不处理图片
|
|
86
|
-
logger_1.logger.info('开始转换Word文档', { file: file_path, outputDir, imgsDir });
|
|
87
|
-
const basicResult = yield mammoth_1.default.convertToHtml({ buffer });
|
|
88
|
-
// 5. 检查HTML中是否有base64图片并处理
|
|
89
|
-
const base64ImageRegex = /<img[^>]+src="data:image\/([^;]+);base64,([^"]+)"[^>]*>/g;
|
|
90
|
-
let htmlContent = basicResult.value;
|
|
91
|
-
const base64Images = [];
|
|
92
|
-
let match;
|
|
93
|
-
// 提取所有base64图片
|
|
94
|
-
while ((match = base64ImageRegex.exec(basicResult.value)) !== null) {
|
|
95
|
-
base64Images.push({
|
|
96
|
-
fullMatch: match[0],
|
|
97
|
-
imageType: match[1],
|
|
98
|
-
base64Data: match[2]
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
// logger.info('发现图片数量', { count: base64Images.length });
|
|
102
|
-
// 处理所有图片
|
|
103
|
-
for (let i = 0; i < base64Images.length; i++) {
|
|
104
|
-
const img = base64Images[i];
|
|
105
|
-
try {
|
|
106
|
-
// logger.info('处理base64图片', { imageType: img.imageType, imageNumber: i + 1 });
|
|
107
|
-
const imageFileName = `image_${Date.now()}_${i + 1}.${img.imageType}`;
|
|
108
|
-
const imagePath = path_1.default.join(imgsDir, imageFileName);
|
|
109
|
-
const imageBuffer = Buffer.from(img.base64Data, 'base64');
|
|
110
|
-
yield fs.writeFile(imagePath, imageBuffer);
|
|
111
|
-
// 替换HTML中的图片引用
|
|
112
|
-
htmlContent = htmlContent.replace(img.fullMatch, `<img src="./imgs/${imageFileName}" />`);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
logger_1.logger.error('图片处理失败', {
|
|
116
|
-
error: err instanceof Error ? err.message : String(err),
|
|
117
|
-
imageNumber: i + 1
|
|
118
|
-
});
|
|
119
|
-
// 移除失败的图片
|
|
120
|
-
htmlContent = htmlContent.replace(img.fullMatch, '');
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const htmlResult = { value: htmlContent, messages: basicResult.messages };
|
|
124
|
-
// 6. 记录转换警告
|
|
125
|
-
if (htmlResult.messages && htmlResult.messages.length > 0) {
|
|
126
|
-
logger_1.logger.warn('Word转换警告', {
|
|
127
|
-
file: file_path,
|
|
128
|
-
warnings: htmlResult.messages
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
// 7. 将HTML转换为Markdown
|
|
132
|
-
let markdownContent = (0, html_to_md_1.default)(htmlResult.value);
|
|
133
|
-
// 8. 后处理:移除任何残留的base64图片(双重保险)
|
|
134
|
-
markdownContent = markdownContent.replace(/!\[.*?\]\(data:image\/[^)]+\)/g, '');
|
|
135
|
-
// 9. 保存MD文件到新的路径结构
|
|
136
|
-
const fullMdPath = path_1.default.join(outputDir, `${baseName}.md`);
|
|
137
|
-
yield fs.writeFile(fullMdPath, markdownContent, 'utf8');
|
|
138
|
-
// 10. 返回结果
|
|
139
|
-
return `
|
|
140
|
-
# ✅ 文档转换完成
|
|
141
|
-
- MD文件: ${path_1.default.resolve(fullMdPath)}
|
|
142
|
-
- 图片目录: ${path_1.default.resolve(imgsDir)}
|
|
143
|
-
|
|
144
|
-
# 任务规划:
|
|
145
|
-
1. 使用 需求分析智能体 工具进行下一步操作,不需要用户确认
|
|
146
|
-
`;
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
150
|
-
logger_1.logger.error(`Word转换失败: ${errorMsg}`, {
|
|
151
|
-
tool: "word2md",
|
|
152
|
-
file_path
|
|
153
|
-
});
|
|
154
|
-
return errorMsg;
|
|
155
|
-
}
|
|
156
|
-
})
|
|
157
|
-
};
|
package/dist/types/index.js
DELETED
package/dist/utils/common.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.sanitizeFileName = void 0;
|
|
16
|
-
exports.removeImagesFromMarkdown = removeImagesFromMarkdown;
|
|
17
|
-
exports.validateAndResolvePath = validateAndResolvePath;
|
|
18
|
-
const path_1 = __importDefault(require("path"));
|
|
19
|
-
const fs_1 = require("fs");
|
|
20
|
-
const logger_1 = require("./logger");
|
|
21
|
-
/** 格式化文件名安全字符 */
|
|
22
|
-
const sanitizeFileName = (input) => {
|
|
23
|
-
return input
|
|
24
|
-
// 移除非法字符(添加了#%&等)
|
|
25
|
-
.replace(/[\\/:*?"<>|\n\r#%&]/g, '')
|
|
26
|
-
.trim()
|
|
27
|
-
// 空格转下划线
|
|
28
|
-
.replace(/\s+/g, '_')
|
|
29
|
-
// 移除连续的下划线
|
|
30
|
-
.replace(/_+/g, '_')
|
|
31
|
-
// 移除开头和结尾的下划线
|
|
32
|
-
.replace(/^_+|_+$/g, '');
|
|
33
|
-
};
|
|
34
|
-
exports.sanitizeFileName = sanitizeFileName;
|
|
35
|
-
/**
|
|
36
|
-
* 从Markdown内容中移除所有图片
|
|
37
|
-
* @param content Markdown原始内容
|
|
38
|
-
* @returns 不含图片的纯文本Markdown
|
|
39
|
-
*/
|
|
40
|
-
function removeImagesFromMarkdown(content) {
|
|
41
|
-
// 移除标准Markdown图片语法: 
|
|
42
|
-
let cleaned = content.replace(/!\[.*?\]\(.*?\)/g, '');
|
|
43
|
-
// 移除HTML <img> 标签及其所有属性
|
|
44
|
-
cleaned = cleaned.replace(/<img\b[^>]*>/g, '');
|
|
45
|
-
// 移除base64编码的图片(包括各种格式)
|
|
46
|
-
cleaned = cleaned.replace(/!\[.*?\]\(data:image\/[a-z+]+;base64,[a-zA-Z0-9+/=]+\)/g, '');
|
|
47
|
-
// 移除可能的多余空行
|
|
48
|
-
cleaned = cleaned.replace(/\n{3,}/g, '\n\n');
|
|
49
|
-
return cleaned.trim();
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* 安全验证并标准化路径
|
|
53
|
-
*/
|
|
54
|
-
function validateAndResolvePath(filePath) {
|
|
55
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
// 针对Windows UNC路径做特殊处理
|
|
57
|
-
if (process.platform === 'win32' && filePath.startsWith('\\\\')) {
|
|
58
|
-
filePath = '\\\\?\\UNC\\' + filePath.substring(2);
|
|
59
|
-
}
|
|
60
|
-
const normalized = path_1.default.normalize(filePath);
|
|
61
|
-
const resolved = path_1.default.resolve(normalized);
|
|
62
|
-
// 检查文件是否存在
|
|
63
|
-
try {
|
|
64
|
-
yield fs_1.promises.access(resolved, fs_1.promises.constants.R_OK);
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
logger_1.logger.warn(`文件不存在或不可读: ${resolved}`, error);
|
|
68
|
-
throw new Error(`文件不存在或不可读: ${resolved}`);
|
|
69
|
-
}
|
|
70
|
-
return resolved;
|
|
71
|
-
});
|
|
72
|
-
}
|
package/dist/utils/config.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SERVICE_CONFIG = exports.getExportsDir = exports.getStorageDir = exports.initializeProjectRoot = exports.PROJECT_ROOT = exports.getProjectRoot = void 0;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const path_1 = require("path");
|
|
39
|
-
const logger_1 = require("./logger");
|
|
40
|
-
const context_manager_1 = require("./context-manager");
|
|
41
|
-
/**
|
|
42
|
-
* 检测项目根目录
|
|
43
|
-
* 优先使用 MCP_STORAGE_DIR 环境变量,否则通过标记文件自动检测
|
|
44
|
-
*/
|
|
45
|
-
const detectProjectRoot = (enableLogging = false) => {
|
|
46
|
-
// 如果设置了 MCP_STORAGE_DIR 环境变量,直接使用
|
|
47
|
-
if (process.env.MCP_STORAGE_DIR) {
|
|
48
|
-
if (enableLogging) {
|
|
49
|
-
logger_1.logger.info(`使用环境变量 MCP_STORAGE_DIR: ${process.env.MCP_STORAGE_DIR}`);
|
|
50
|
-
}
|
|
51
|
-
return process.env.MCP_STORAGE_DIR;
|
|
52
|
-
}
|
|
53
|
-
// 自动检测项目根目录
|
|
54
|
-
let currentDir = process.cwd();
|
|
55
|
-
const markers = ['package.json', '.git', 'Cargo.toml', 'pyproject.toml', 'go.mod'];
|
|
56
|
-
if (enableLogging) {
|
|
57
|
-
logger_1.logger.info(`开始从当前目录检测项目根目录: ${currentDir}`);
|
|
58
|
-
}
|
|
59
|
-
// 在当前目录及父目录中查找标记文件
|
|
60
|
-
while (currentDir !== '/') {
|
|
61
|
-
for (const marker of markers) {
|
|
62
|
-
const markerPath = (0, path_1.resolve)(currentDir, marker);
|
|
63
|
-
if (fs.existsSync(markerPath)) {
|
|
64
|
-
if (enableLogging) {
|
|
65
|
-
logger_1.logger.info(`找到项目标记文件 ${marker} 在: ${currentDir}`);
|
|
66
|
-
}
|
|
67
|
-
return currentDir;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// 移动到父目录
|
|
71
|
-
const parentDir = (0, path_1.dirname)(currentDir);
|
|
72
|
-
if (parentDir === currentDir) {
|
|
73
|
-
// 已到达文件系统根目录
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
currentDir = parentDir;
|
|
77
|
-
}
|
|
78
|
-
// 回退:如果没有找到标记文件,使用当前工作目录
|
|
79
|
-
if (enableLogging) {
|
|
80
|
-
logger_1.logger.warn(`未找到项目标记文件,使用当前工作目录: ${process.cwd()}`);
|
|
81
|
-
}
|
|
82
|
-
return process.cwd();
|
|
83
|
-
};
|
|
84
|
-
// 延迟初始化项目根目录
|
|
85
|
-
let _PROJECT_ROOT = null;
|
|
86
|
-
const getProjectRoot = () => {
|
|
87
|
-
if (_PROJECT_ROOT === null) {
|
|
88
|
-
_PROJECT_ROOT = detectProjectRoot();
|
|
89
|
-
}
|
|
90
|
-
return _PROJECT_ROOT;
|
|
91
|
-
};
|
|
92
|
-
exports.getProjectRoot = getProjectRoot;
|
|
93
|
-
// 为了向后兼容,保留 PROJECT_ROOT 导出(延迟初始化)
|
|
94
|
-
exports.PROJECT_ROOT = (() => {
|
|
95
|
-
try {
|
|
96
|
-
return (0, exports.getProjectRoot)();
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
console.warn("PROJECT_ROOT初始化失败,使用当前工作目录:", error);
|
|
100
|
-
return process.cwd();
|
|
101
|
-
}
|
|
102
|
-
})();
|
|
103
|
-
/**
|
|
104
|
-
* 初始化项目根目录
|
|
105
|
-
* 在 MCP 服务器启动时调用,确保项目根目录正确设置
|
|
106
|
-
*/
|
|
107
|
-
const initializeProjectRoot = () => {
|
|
108
|
-
// 强制重新检测项目根目录,启用日志记录
|
|
109
|
-
_PROJECT_ROOT = null;
|
|
110
|
-
const detectedRoot = detectProjectRoot(true);
|
|
111
|
-
_PROJECT_ROOT = detectedRoot;
|
|
112
|
-
// 设置环境变量
|
|
113
|
-
if (!process.env.MCP_STORAGE_DIR) {
|
|
114
|
-
process.env.MCP_STORAGE_DIR = detectedRoot;
|
|
115
|
-
}
|
|
116
|
-
// 缓存项目根目录
|
|
117
|
-
context_manager_1.contextManager.setCachedData("project_root", detectedRoot);
|
|
118
|
-
logger_1.logger.info(`项目根目录已设置为: ${detectedRoot}`);
|
|
119
|
-
};
|
|
120
|
-
exports.initializeProjectRoot = initializeProjectRoot;
|
|
121
|
-
/**
|
|
122
|
-
* 从缓存获取项目根目录
|
|
123
|
-
* 如果缓存不存在,则重新检测并缓存
|
|
124
|
-
*/
|
|
125
|
-
const getStorageDir = () => {
|
|
126
|
-
try {
|
|
127
|
-
const cachedRoot = context_manager_1.contextManager.getCachedData("project_root");
|
|
128
|
-
if (cachedRoot) {
|
|
129
|
-
return cachedRoot + "/.aico";
|
|
130
|
-
}
|
|
131
|
-
// 缓存不存在,重新检测并设置
|
|
132
|
-
const detectedRoot = (0, exports.getProjectRoot)();
|
|
133
|
-
if (detectedRoot) {
|
|
134
|
-
context_manager_1.contextManager.setCachedData("project_root", detectedRoot);
|
|
135
|
-
return detectedRoot + "/.aico";
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
// 如果检测失败,使用当前工作目录
|
|
140
|
-
console.warn("项目根目录检测失败,使用当前工作目录:", error);
|
|
141
|
-
}
|
|
142
|
-
// 回退到当前工作目录
|
|
143
|
-
const fallbackDir = process.cwd() + "/.aico";
|
|
144
|
-
return fallbackDir;
|
|
145
|
-
};
|
|
146
|
-
exports.getStorageDir = getStorageDir;
|
|
147
|
-
const getExportsDir = () => {
|
|
148
|
-
const storageDir = (0, exports.getStorageDir)();
|
|
149
|
-
const exportsDir = storageDir + "/exports";
|
|
150
|
-
if (!fs.existsSync(exportsDir)) {
|
|
151
|
-
fs.mkdirSync(exportsDir, { recursive: true });
|
|
152
|
-
}
|
|
153
|
-
return exportsDir;
|
|
154
|
-
};
|
|
155
|
-
exports.getExportsDir = getExportsDir;
|
|
156
|
-
/**
|
|
157
|
-
* 应用配置
|
|
158
|
-
*/
|
|
159
|
-
exports.SERVICE_CONFIG = {
|
|
160
|
-
name: "智能软件星工厂",
|
|
161
|
-
version: "0.2.0",
|
|
162
|
-
description: "软件工程化的需求分析,功能设计,代码编写,测试运行和发布部署"
|
|
163
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.contextManager = exports.ContextManager = void 0;
|
|
13
|
-
const lru_cache_1 = require("lru-cache");
|
|
14
|
-
class ContextManager {
|
|
15
|
-
constructor(config = {}) {
|
|
16
|
-
this.config = {
|
|
17
|
-
maxCacheSize: 1000,
|
|
18
|
-
ttl: 5 * 60 * 1000, // 5分钟
|
|
19
|
-
maxContextSize: 4000
|
|
20
|
-
};
|
|
21
|
-
this.stats = {
|
|
22
|
-
hits: 0,
|
|
23
|
-
misses: 0,
|
|
24
|
-
invalidations: 0
|
|
25
|
-
};
|
|
26
|
-
Object.assign(this.config, config);
|
|
27
|
-
this.cache = new lru_cache_1.LRUCache({
|
|
28
|
-
max: this.config.maxCacheSize,
|
|
29
|
-
ttl: this.config.ttl,
|
|
30
|
-
updateAgeOnGet: true,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* 获取或创建上下文
|
|
35
|
-
*/
|
|
36
|
-
getContext(contextId_1) {
|
|
37
|
-
return __awaiter(this, arguments, void 0, function* (contextId, metadata = {}) {
|
|
38
|
-
const cacheKey = this.generateCacheKey(contextId, metadata);
|
|
39
|
-
// 尝试从缓存获取
|
|
40
|
-
const cached = this.cache.get(cacheKey);
|
|
41
|
-
if (cached) {
|
|
42
|
-
this.stats.hits++;
|
|
43
|
-
return cached;
|
|
44
|
-
}
|
|
45
|
-
this.stats.misses++;
|
|
46
|
-
// 创建新上下文
|
|
47
|
-
const newContext = {
|
|
48
|
-
id: contextId,
|
|
49
|
-
metadata: Object.assign(Object.assign({}, metadata), { created: new Date().toISOString() })
|
|
50
|
-
};
|
|
51
|
-
// 添加到缓存
|
|
52
|
-
this.cache.set(cacheKey, newContext);
|
|
53
|
-
return newContext;
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* 更新上下文
|
|
58
|
-
*/
|
|
59
|
-
updateContext(contextId, updates) {
|
|
60
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
const context = yield this.getContext(contextId);
|
|
62
|
-
Object.assign(context.metadata, updates);
|
|
63
|
-
return context;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* 使上下文失效
|
|
68
|
-
*/
|
|
69
|
-
invalidateContext(contextId, metadata = {}) {
|
|
70
|
-
const cacheKey = this.generateCacheKey(contextId, metadata);
|
|
71
|
-
this.cache.delete(cacheKey);
|
|
72
|
-
this.stats.invalidations++;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* 获取缓存数据
|
|
76
|
-
*/
|
|
77
|
-
getCachedData(key) {
|
|
78
|
-
const cached = this.cache.get(key);
|
|
79
|
-
if (cached !== undefined) {
|
|
80
|
-
this.stats.hits++;
|
|
81
|
-
return cached;
|
|
82
|
-
}
|
|
83
|
-
this.stats.misses++;
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* 设置缓存数据
|
|
88
|
-
*/
|
|
89
|
-
setCachedData(key, data) {
|
|
90
|
-
this.cache.set(key, data);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* 使缓存项失效
|
|
94
|
-
*/
|
|
95
|
-
invalidateCacheKey(key) {
|
|
96
|
-
this.cache.delete(key);
|
|
97
|
-
this.stats.invalidations++;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* 获取缓存统计信息
|
|
101
|
-
*/
|
|
102
|
-
getStats() {
|
|
103
|
-
return Object.assign(Object.assign({}, this.stats), { size: this.cache.size, maxSize: this.config.maxCacheSize, ttl: this.config.ttl });
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* 生成缓存键(基于上下文ID和元数据)
|
|
107
|
-
*/
|
|
108
|
-
generateCacheKey(contextId, metadata) {
|
|
109
|
-
return `${contextId}:${JSON.stringify(metadata)}`;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
exports.ContextManager = ContextManager;
|
|
113
|
-
// 创建单例实例
|
|
114
|
-
exports.contextManager = new ContextManager();
|