@syke1/mcp-server 1.4.14 → 1.4.16

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.
@@ -38,7 +38,6 @@ const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const provider_1 = require("./provider");
40
40
  const context_extractor_1 = require("./context-extractor");
41
- const config_1 = require("../config");
42
41
  function readFileContent(filePath) {
43
42
  try {
44
43
  return fs.readFileSync(filePath, "utf-8");
@@ -49,27 +48,6 @@ function readFileContent(filePath) {
49
48
  }
50
49
  function buildSystemPrompt(languages) {
51
50
  const langNames = languages.length > 0 ? languages.join("/") : "source";
52
- const ko = (0, config_1.getLanguage)() === "ko";
53
- if (ko) {
54
- return `당신은 ${langNames} 코드 영향도 분석 전문가입니다.
55
- 주어진 파일의 소스코드와 이 파일에 의존하는 파일들의 코드를 분석하여,
56
- 이 파일을 수정할 때 어떤 부분이 깨질 수 있는지 구체적으로 설명해주세요.
57
-
58
- 분석 포맷:
59
- ## 핵심 역할
60
- 이 파일이 프로젝트에서 하는 역할을 한 문장으로 설명
61
-
62
- ## 수정 시 위험 포인트
63
- 수정 시 깨질 수 있는 구체적인 부분들 (함수명, 클래스명 포함)
64
-
65
- ## 영향받는 파일 분석
66
- 의존 파일들이 이 파일의 어떤 부분을 사용하는지 구체적으로
67
-
68
- ## 안전한 수정 가이드
69
- 이 파일을 수정할 때 주의할 점과 추천 접근법
70
-
71
- 한국어로 답변하세요. 간결하되 구체적으로 작성하세요.`;
72
- }
73
51
  return `You are an expert in ${langNames} code impact analysis.
74
52
  Analyze the source code of the given file and its dependents to identify
75
53
  what could break when this file is modified.
@@ -91,17 +69,12 @@ Be concise but specific.`;
91
69
  }
92
70
  async function analyzeWithAI(filePath, impactResult, graph) {
93
71
  const provider = (0, provider_1.getAIProvider)();
94
- const ko = (0, config_1.getLanguage)() === "ko";
95
72
  if (!provider) {
96
- return ko
97
- ? "AI 분석 비활성화 — GEMINI_KEY, OPENAI_KEY, 또는 ANTHROPIC_KEY를 설정하세요."
98
- : "AI analysis disabled — set GEMINI_KEY, OPENAI_KEY, or ANTHROPIC_KEY.";
73
+ return "AI analysis disabled — set GEMINI_KEY, OPENAI_KEY, or ANTHROPIC_KEY.";
99
74
  }
100
75
  const targetSource = readFileContent(filePath);
101
76
  if (!targetSource) {
102
- return ko
103
- ? `파일을 읽을 수 없습니다: ${filePath}`
104
- : `Cannot read file: ${filePath}`;
77
+ return `Cannot read file: ${filePath}`;
105
78
  }
106
79
  const codeBlockLang = graph.languages[0] || "text";
107
80
  // Build smart context for the target file
@@ -117,20 +90,7 @@ async function analyzeWithAI(filePath, impactResult, graph) {
117
90
  dependentSources.push(`### ${rel}\n\`\`\`${codeBlockLang}\n${smartDep}\n\`\`\``);
118
91
  }
119
92
  }
120
- const userPrompt = ko
121
- ? `## 분석 대상 파일: ${impactResult.relativePath}
122
- - 위험도: ${impactResult.riskLevel}
123
- - 직접 의존 파일 수: ${impactResult.directDependents.length}
124
- - 전이적 의존 파일 수: ${impactResult.transitiveDependents.length}
125
- - 총 영향 파일 수: ${impactResult.totalImpacted}
126
-
127
- ### 대상 파일 소스코드
128
- \`\`\`${codeBlockLang}
129
- ${smartTarget}
130
- \`\`\`
131
-
132
- ${dependentSources.length > 0 ? `### 이 파일에 의존하는 파일들 (상위 ${dependentSources.length}개)\n${dependentSources.join("\n\n")}` : "이 파일에 의존하는 내부 파일이 없습니다."}`
133
- : `## Target file: ${impactResult.relativePath}
93
+ const userPrompt = `## Target file: ${impactResult.relativePath}
134
94
  - Risk level: ${impactResult.riskLevel}
135
95
  - Direct dependents: ${impactResult.directDependents.length}
136
96
  - Transitive dependents: ${impactResult.transitiveDependents.length}
@@ -147,8 +107,6 @@ ${dependentSources.length > 0 ? `### Files depending on this file (top ${depende
147
107
  return await provider.analyze(systemPrompt, userPrompt);
148
108
  }
149
109
  catch (err) {
150
- return ko
151
- ? `AI 분석 중 오류 발생: ${err.message || err}`
152
- : `AI analysis error: ${err.message || err}`;
110
+ return `AI analysis error: ${err.message || err}`;
153
111
  }
154
112
  }
@@ -38,38 +38,7 @@ const analyze_impact_1 = require("../tools/analyze-impact");
38
38
  const path = __importStar(require("path"));
39
39
  const provider_1 = require("./provider");
40
40
  const context_extractor_1 = require("./context-extractor");
41
- const config_1 = require("../config");
42
41
  function getSystemPrompt() {
43
- const ko = (0, config_1.getLanguage)() === "ko";
44
- if (ko) {
45
- return `당신은 20년 경력의 풀스택 아키텍트이자, 코드 영향도 감시 AI입니다.
46
- 역할: 파일이 수정/추가/삭제될 때, 빌드 전에 잠재적 오류와 연쇄 영향을 감지합니다.
47
-
48
- 분석 원칙:
49
- 1. import/export 깨짐: 삭제/이름변경된 클래스/함수/변수가 다른 파일에서 참조되는지 확인
50
- 2. 타입 불일치: 매개변수 타입, 반환 타입 변경이 호출부와 맞는지 확인
51
- 3. 상태 관리 연쇄: Provider/Notifier 변경이 UI와 비즈니스 로직에 미치는 영향
52
- 4. 라우팅 영향: GoRouter 경로/매개변수 변경이 네비게이션에 미치는 영향
53
- 5. 누락된 초기화: 새로 추가된 Provider가 적절히 등록되었는지
54
-
55
- 응답 형식 (반드시 JSON):
56
- {
57
- "riskLevel": "CRITICAL|HIGH|MEDIUM|LOW|SAFE",
58
- "summary": "한 줄 요약",
59
- "brokenImports": ["깨질 수 있는 import 목록"],
60
- "sideEffects": ["예상되는 부작용 목록"],
61
- "warnings": ["주의사항 목록"],
62
- "suggestion": "추천 조치"
63
- }
64
-
65
- CRITICAL: 빌드 실패 확실
66
- HIGH: 런타임 오류 가능
67
- MEDIUM: 기능 동작 변경 가능
68
- LOW: 사소한 영향
69
- SAFE: 안전한 변경
70
-
71
- JSON만 응답하세요. 설명 텍스트 없이 순수 JSON만.`;
72
- }
73
42
  return `You are a senior full-stack architect and code impact monitoring AI with 20 years of experience.
74
43
  Role: Detect potential errors and cascading impacts before build when files are modified/added/deleted.
75
44
 
@@ -106,7 +75,6 @@ async function analyzeChangeRealtime(change, graph, getFileContent) {
106
75
  const start = Date.now();
107
76
  const relPath = change.relativePath;
108
77
  const codeBlockLang = graph.languages[0] || "text";
109
- const ko = (0, config_1.getLanguage)() === "ko";
110
78
  // Get impacted files from graph
111
79
  const absPath = path.normalize(path.join(graph.sourceDir, relPath));
112
80
  let affectedNodes = [];
@@ -130,13 +98,11 @@ async function analyzeChangeRealtime(change, graph, getFileContent) {
130
98
  // Build diff summary with signature changes
131
99
  let diffSummary = "";
132
100
  if (change.type === "deleted") {
133
- const label = ko ? "파일이 삭제됨. 이전 내용:" : "File deleted. Previous content:";
134
- diffSummary = `${label}\n\`\`\`${codeBlockLang}\n${(change.oldContent || "").split("\n").slice(0, 40).join("\n")}\n\`\`\``;
101
+ diffSummary = `File deleted. Previous content:\n\`\`\`${codeBlockLang}\n${(change.oldContent || "").split("\n").slice(0, 40).join("\n")}\n\`\`\``;
135
102
  }
136
103
  else if (change.type === "added") {
137
104
  const smartNew = (0, context_extractor_1.buildSmartContext)(change.newContent || "", codeBlockLang);
138
- const label = ko ? "새 파일 추가됨:" : "New file added:";
139
- diffSummary = `${label}\n\`\`\`${codeBlockLang}\n${smartNew}\n\`\`\``;
105
+ diffSummary = `New file added:\n\`\`\`${codeBlockLang}\n${smartNew}\n\`\`\``;
140
106
  }
141
107
  else {
142
108
  // Modified — include signature diff
@@ -147,50 +113,31 @@ async function analyzeChangeRealtime(change, graph, getFileContent) {
147
113
  return `- L${d.line}: ${d.old}`;
148
114
  return `~ L${d.line}: ${d.old} → ${d.new}`;
149
115
  });
150
- const label = ko
151
- ? `변경된 라인 (${change.diff.length}개 중 상위 30개):`
152
- : `Changed lines (top 30 of ${change.diff.length}):`;
153
- diffSummary = `${label}\n\`\`\`\n${diffLines.join("\n")}\n\`\`\``;
116
+ diffSummary = `Changed lines (top 30 of ${change.diff.length}):\n\`\`\`\n${diffLines.join("\n")}\n\`\`\``;
154
117
  // Add structural signature changes
155
118
  if (change.oldContent && change.newContent) {
156
119
  const sigChanges = (0, context_extractor_1.diffSignatures)(change.oldContent, change.newContent, codeBlockLang);
157
120
  if (sigChanges.length > 0) {
158
- diffSummary += ko
159
- ? "\n\n### 구조적 변경 (시그니처 비교)"
160
- : "\n\n### Structural changes (signature diff)";
121
+ diffSummary += "\n\n### Structural changes (signature diff)";
161
122
  for (const sc of sigChanges) {
162
123
  if (sc.type === "added") {
163
- diffSummary += ko ? `\n+ 추가: ${sc.newSignature}` : `\n+ Added: ${sc.newSignature}`;
124
+ diffSummary += `\n+ Added: ${sc.newSignature}`;
164
125
  }
165
126
  else if (sc.type === "removed") {
166
- diffSummary += ko ? `\n- 삭제: ${sc.oldSignature}` : `\n- Removed: ${sc.oldSignature}`;
127
+ diffSummary += `\n- Removed: ${sc.oldSignature}`;
167
128
  }
168
129
  else {
169
- diffSummary += ko
170
- ? `\n~ 변경: ${sc.oldSignature}\n → ${sc.newSignature}`
171
- : `\n~ Changed: ${sc.oldSignature}\n → ${sc.newSignature}`;
130
+ diffSummary += `\n~ Changed: ${sc.oldSignature}\n → ${sc.newSignature}`;
172
131
  }
173
132
  }
174
133
  }
175
134
  }
176
135
  if (change.newContent) {
177
136
  const smartNew = (0, context_extractor_1.buildSmartContext)(change.newContent, codeBlockLang);
178
- const label2 = ko ? "전체 수정 후 파일:" : "Full file after modification:";
179
- diffSummary += `\n\n${label2}\n\`\`\`${codeBlockLang}\n${smartNew}\n\`\`\``;
137
+ diffSummary += `\n\nFull file after modification:\n\`\`\`${codeBlockLang}\n${smartNew}\n\`\`\``;
180
138
  }
181
139
  }
182
- const userPrompt = ko
183
- ? `## 파일 변경 감지: ${relPath}
184
- 변경 유형: ${change.type.toUpperCase()}
185
- 프로젝트 언어: ${graph.languages.join(", ") || "unknown"}
186
- 영향받는 파일 수: ${affectedNodes.length}
187
-
188
- ${diffSummary}
189
-
190
- ${connectedFiles.length > 0 ? `## 연결된 파일들 (${connectedFiles.length}개)\n${connectedFiles.join("\n\n")}` : "연결된 파일 없음"}
191
-
192
- 이 변경이 프로젝트에 미치는 영향을 분석하세요.`
193
- : `## File change detected: ${relPath}
140
+ const userPrompt = `## File change detected: ${relPath}
194
141
  Change type: ${change.type.toUpperCase()}
195
142
  Project languages: ${graph.languages.join(", ") || "unknown"}
196
143
  Affected files: ${affectedNodes.length}
@@ -212,7 +159,7 @@ Analyze the impact of this change on the project.`;
212
159
  changeType: change.type,
213
160
  timestamp: change.timestamp,
214
161
  riskLevel: parsed.riskLevel || "LOW",
215
- summary: parsed.summary || (ko ? "분석 완료" : "Analysis complete"),
162
+ summary: parsed.summary || "Analysis complete",
216
163
  brokenImports: parsed.brokenImports || [],
217
164
  sideEffects: parsed.sideEffects || [],
218
165
  warnings: parsed.warnings || [],
@@ -229,13 +176,11 @@ Analyze the impact of this change on the project.`;
229
176
  changeType: change.type,
230
177
  timestamp: change.timestamp,
231
178
  riskLevel: affectedNodes.length >= 10 ? "HIGH" : affectedNodes.length >= 5 ? "MEDIUM" : "LOW",
232
- summary: ko
233
- ? `AI 분석 실패 — 그래프 기반 분석: ${affectedNodes.length}개 파일 영향`
234
- : `AI analysis failed — graph-based analysis: ${affectedNodes.length} files impacted`,
179
+ summary: `AI analysis failed — graph-based analysis: ${affectedNodes.length} files impacted`,
235
180
  brokenImports: [],
236
181
  sideEffects: [],
237
- warnings: [ko ? `AI 분석 오류: ${err.message}` : `AI analysis error: ${err.message}`],
238
- suggestion: ko ? "수동 확인 필요" : "Manual review required",
182
+ warnings: [`AI analysis error: ${err.message}`],
183
+ suggestion: "Manual review required",
239
184
  affectedNodes,
240
185
  analysisMs,
241
186
  };
package/dist/config.d.ts CHANGED
@@ -4,7 +4,6 @@ interface SykeConfig {
4
4
  openaiKey?: string;
5
5
  anthropicKey?: string;
6
6
  aiProvider?: string;
7
- language?: string;
8
7
  port?: number;
9
8
  }
10
9
  /**
@@ -19,10 +18,6 @@ export declare function getAllConfig(): Record<string, string | undefined>;
19
18
  * Set a config value in ~/.syke/config.json
20
19
  */
21
20
  export declare function setConfig(key: keyof SykeConfig, value: string | null): void;
22
- /**
23
- * Detect language: config > env > system locale > default "en"
24
- */
25
- export declare function getLanguage(): "ko" | "en";
26
21
  export declare const CONFIG_DIR_PATH: string;
27
22
  export declare const CONFIG_FILE_PATH: string;
28
23
  export {};
package/dist/config.js CHANGED
@@ -37,7 +37,6 @@ exports.CONFIG_FILE_PATH = exports.CONFIG_DIR_PATH = void 0;
37
37
  exports.getConfig = getConfig;
38
38
  exports.getAllConfig = getAllConfig;
39
39
  exports.setConfig = setConfig;
40
- exports.getLanguage = getLanguage;
41
40
  /**
42
41
  * Central config reader for SYKE MCP Server.
43
42
  *
@@ -118,21 +117,5 @@ function setConfig(key, value) {
118
117
  // ignore write errors
119
118
  }
120
119
  }
121
- /**
122
- * Detect language: config > env > system locale > default "en"
123
- */
124
- function getLanguage() {
125
- const configured = getConfig("language", "SYKE_LANGUAGE");
126
- if (configured) {
127
- return configured.startsWith("ko") ? "ko" : "en";
128
- }
129
- // System locale detection
130
- const locale = (process.env.LANG ||
131
- process.env.LC_ALL ||
132
- process.env.LANGUAGE ||
133
- Intl.DateTimeFormat().resolvedOptions().locale ||
134
- "").toLowerCase();
135
- return locale.startsWith("ko") ? "ko" : "en";
136
- }
137
120
  exports.CONFIG_DIR_PATH = CONFIG_DIR;
138
121
  exports.CONFIG_FILE_PATH = CONFIG_FILE;
package/dist/index.js CHANGED
@@ -124,7 +124,7 @@ async function main() {
124
124
  };
125
125
  process.on("SIGINT", shutdown);
126
126
  process.on("SIGTERM", shutdown);
127
- const server = new index_js_1.Server({ name: "syke", version: "1.4.2" }, { capabilities: { tools: {} } });
127
+ const server = new index_js_1.Server({ name: "syke", version: "1.4.16" }, { capabilities: { tools: {} } });
128
128
  // List tools
129
129
  server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
130
130
  tools: [
@@ -204,7 +204,7 @@ async function main() {
204
204
  },
205
205
  {
206
206
  name: "ai_analyze",
207
- description: "Use AI (Gemini/OpenAI/Claude) to perform semantic analysis on a file. Reads the file's source code and its dependents to explain what might break when modified and how to safely make changes. Returns Korean analysis.",
207
+ description: "Use AI (Gemini/OpenAI/Claude) to perform semantic analysis on a file. Reads the file's source code and its dependents to explain what might break when modified and how to safely make changes.",
208
208
  inputSchema: {
209
209
  type: "object",
210
210
  properties: {
@@ -488,7 +488,7 @@ async function main() {
488
488
  }
489
489
  });
490
490
  // Pre-warm the graph (skip if no project root — e.g. Smithery scan)
491
- console.error(`[syke] Starting SYKE MCP Server v1.4.1`);
491
+ console.error(`[syke] Starting SYKE MCP Server v1.4.16`);
492
492
  console.error(`[syke] License: ${licenseStatus.plan.toUpperCase()} (${licenseStatus.source})`);
493
493
  if (licenseStatus.expiresAt) {
494
494
  console.error(`[syke] Expires: ${licenseStatus.expiresAt}`);
@@ -660,7 +660,7 @@ main().catch((err) => {
660
660
  * See: https://smithery.ai/docs/deploy#sandbox-server
661
661
  */
662
662
  function createSandboxServer() {
663
- const sandboxServer = new index_js_1.Server({ name: "syke", version: "1.4.2" }, { capabilities: { tools: {} } });
663
+ const sandboxServer = new index_js_1.Server({ name: "syke", version: "1.4.16" }, { capabilities: { tools: {} } });
664
664
  sandboxServer.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
665
665
  tools: [
666
666
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syke1/mcp-server",
3
- "version": "1.4.14",
3
+ "version": "1.4.16",
4
4
  "mcpName": "io.github.khalomsky/syke",
5
5
  "description": "AI code impact analysis MCP server — dependency graphs, cascade detection, and a mandatory build gate for AI coding agents",
6
6
  "main": "dist/index.js",