@virsanghavi/axis-server 1.0.4 → 1.0.6
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/mcp-server.mjs +72 -45
- package/package.json +1 -1
package/dist/mcp-server.mjs
CHANGED
|
@@ -110,17 +110,18 @@ var ContextManager = class {
|
|
|
110
110
|
return `Updated ${filename}`;
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
async searchContext(query) {
|
|
113
|
+
async searchContext(query, projectName = "default") {
|
|
114
114
|
if (!this.apiUrl) {
|
|
115
115
|
throw new Error("SHARED_CONTEXT_API_URL not configured.");
|
|
116
116
|
}
|
|
117
|
-
const
|
|
117
|
+
const endpoint = this.apiUrl.endsWith("/v1") ? `${this.apiUrl}/search` : `${this.apiUrl}/v1/search`;
|
|
118
|
+
const response = await fetch(endpoint, {
|
|
118
119
|
method: "POST",
|
|
119
120
|
headers: {
|
|
120
121
|
"Content-Type": "application/json",
|
|
121
122
|
"Authorization": `Bearer ${this.apiSecret || ""}`
|
|
122
123
|
},
|
|
123
|
-
body: JSON.stringify({ query })
|
|
124
|
+
body: JSON.stringify({ query, projectName })
|
|
124
125
|
});
|
|
125
126
|
if (!response.ok) {
|
|
126
127
|
const text = await response.text();
|
|
@@ -134,18 +135,19 @@ var ContextManager = class {
|
|
|
134
135
|
}
|
|
135
136
|
throw new Error("No results format recognized.");
|
|
136
137
|
}
|
|
137
|
-
async embedContent(items) {
|
|
138
|
+
async embedContent(items, projectName = "default") {
|
|
138
139
|
if (!this.apiUrl) {
|
|
139
140
|
console.warn("Skipping RAG embedding: SHARED_CONTEXT_API_URL not configured.");
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
142
|
-
const
|
|
143
|
+
const endpoint = this.apiUrl.endsWith("/v1") ? `${this.apiUrl}/embed` : `${this.apiUrl}/v1/embed`;
|
|
144
|
+
const response = await fetch(endpoint, {
|
|
143
145
|
method: "POST",
|
|
144
146
|
headers: {
|
|
145
147
|
"Content-Type": "application/json",
|
|
146
148
|
"Authorization": `Bearer ${this.apiSecret || ""}`
|
|
147
149
|
},
|
|
148
|
-
body: JSON.stringify({ items })
|
|
150
|
+
body: JSON.stringify({ items, projectName })
|
|
149
151
|
});
|
|
150
152
|
if (!response.ok) {
|
|
151
153
|
const text = await response.text();
|
|
@@ -238,6 +240,9 @@ var NerveCenter = class {
|
|
|
238
240
|
get projectId() {
|
|
239
241
|
return this._projectId;
|
|
240
242
|
}
|
|
243
|
+
get currentProjectName() {
|
|
244
|
+
return this.projectName;
|
|
245
|
+
}
|
|
241
246
|
async init() {
|
|
242
247
|
await this.loadState();
|
|
243
248
|
await this.detectProjectName();
|
|
@@ -758,43 +763,49 @@ var nerveCenter = new NerveCenter(manager, {
|
|
|
758
763
|
supabaseServiceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY,
|
|
759
764
|
projectName: process.env.PROJECT_NAME || "default"
|
|
760
765
|
});
|
|
761
|
-
var ragEngine
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
);
|
|
766
|
+
var ragEngine;
|
|
767
|
+
if (process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.SUPABASE_SERVICE_ROLE_KEY) {
|
|
768
|
+
ragEngine = new RagEngine(
|
|
769
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL,
|
|
770
|
+
process.env.SUPABASE_SERVICE_ROLE_KEY,
|
|
771
|
+
process.env.OPENAI_API_KEY || ""
|
|
772
|
+
);
|
|
773
|
+
}
|
|
768
774
|
async function ensureFileSystem() {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
const axisInstructions = path3.join(axisDir, "instructions");
|
|
778
|
-
const legacyInstructions = path3.join(cwd, "agent-instructions");
|
|
779
|
-
if (fsSync.existsSync(legacyInstructions) && !fsSync.existsSync(axisDir)) {
|
|
780
|
-
logger.info("Using legacy agent-instructions directory");
|
|
781
|
-
} else {
|
|
782
|
-
await fs3.mkdir(axisInstructions, { recursive: true }).catch(() => {
|
|
775
|
+
try {
|
|
776
|
+
const fs3 = await import("fs/promises");
|
|
777
|
+
const path3 = await import("path");
|
|
778
|
+
const fsSync = await import("fs");
|
|
779
|
+
const cwd = process.cwd();
|
|
780
|
+
logger.info(`Server CWD: ${cwd}`);
|
|
781
|
+
const historyDir = path3.join(cwd, "history");
|
|
782
|
+
await fs3.mkdir(historyDir, { recursive: true }).catch(() => {
|
|
783
783
|
});
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
784
|
+
const axisDir = path3.join(cwd, ".axis");
|
|
785
|
+
const axisInstructions = path3.join(axisDir, "instructions");
|
|
786
|
+
const legacyInstructions = path3.join(cwd, "agent-instructions");
|
|
787
|
+
if (fsSync.existsSync(legacyInstructions) && !fsSync.existsSync(axisDir)) {
|
|
788
|
+
logger.info("Using legacy agent-instructions directory");
|
|
789
|
+
} else {
|
|
790
|
+
await fs3.mkdir(axisInstructions, { recursive: true }).catch(() => {
|
|
791
|
+
});
|
|
792
|
+
const defaults = [
|
|
793
|
+
["context.md", "# Project Context\n\n"],
|
|
794
|
+
["conventions.md", "# Coding Conventions\n\n"],
|
|
795
|
+
["activity.md", "# Activity Log\n\n"]
|
|
796
|
+
];
|
|
797
|
+
for (const [file, content] of defaults) {
|
|
798
|
+
const p = path3.join(axisInstructions, file);
|
|
799
|
+
try {
|
|
800
|
+
await fs3.access(p);
|
|
801
|
+
} catch {
|
|
802
|
+
await fs3.writeFile(p, content);
|
|
803
|
+
logger.info(`Created default context file: ${file}`);
|
|
804
|
+
}
|
|
796
805
|
}
|
|
797
806
|
}
|
|
807
|
+
} catch (error) {
|
|
808
|
+
logger.warn("Could not initialize local file system. Persistence features (context.md) may be disabled.", { error: String(error) });
|
|
798
809
|
}
|
|
799
810
|
}
|
|
800
811
|
var server = new Server(
|
|
@@ -1084,13 +1095,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1084
1095
|
if (name === "index_file") {
|
|
1085
1096
|
const filePath = String(args?.filePath);
|
|
1086
1097
|
const content = String(args?.content);
|
|
1087
|
-
|
|
1088
|
-
|
|
1098
|
+
try {
|
|
1099
|
+
await manager.embedContent([{ content, metadata: { filePath } }], nerveCenter.currentProjectName);
|
|
1100
|
+
return { content: [{ type: "text", text: "Indexed via Remote API." }] };
|
|
1101
|
+
} catch (e) {
|
|
1102
|
+
if (ragEngine) {
|
|
1103
|
+
const success = await ragEngine.indexContent(filePath, content);
|
|
1104
|
+
return { content: [{ type: "text", text: success ? "Indexed locally." : "Local index failed." }] };
|
|
1105
|
+
}
|
|
1106
|
+
return { content: [{ type: "text", text: `Indexing failed: ${e}` }], isError: true };
|
|
1107
|
+
}
|
|
1089
1108
|
}
|
|
1090
1109
|
if (name === SEARCH_CONTEXT_TOOL) {
|
|
1091
1110
|
const query = String(args?.query);
|
|
1092
|
-
|
|
1093
|
-
|
|
1111
|
+
try {
|
|
1112
|
+
const results = await manager.searchContext(query, nerveCenter.currentProjectName);
|
|
1113
|
+
return { content: [{ type: "text", text: results }] };
|
|
1114
|
+
} catch (e) {
|
|
1115
|
+
if (ragEngine) {
|
|
1116
|
+
const results = await ragEngine.search(query);
|
|
1117
|
+
return { content: [{ type: "text", text: results.join("\n---\n") }] };
|
|
1118
|
+
}
|
|
1119
|
+
return { content: [{ type: "text", text: `Search failed: ${e}` }], isError: true };
|
|
1120
|
+
}
|
|
1094
1121
|
}
|
|
1095
1122
|
if (name === "get_subscription_status") {
|
|
1096
1123
|
const email = String(args?.email);
|
|
@@ -1162,9 +1189,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1162
1189
|
async function main() {
|
|
1163
1190
|
await ensureFileSystem();
|
|
1164
1191
|
await nerveCenter.init();
|
|
1165
|
-
if (nerveCenter.projectId) {
|
|
1192
|
+
if (nerveCenter.projectId && ragEngine) {
|
|
1166
1193
|
ragEngine.setProjectId(nerveCenter.projectId);
|
|
1167
|
-
logger.info(`RAG Engine linked to Project ID: ${nerveCenter.projectId}`);
|
|
1194
|
+
logger.info(`Local RAG Engine linked to Project ID: ${nerveCenter.projectId}`);
|
|
1168
1195
|
}
|
|
1169
1196
|
const transport = new StdioServerTransport();
|
|
1170
1197
|
await server.connect(transport);
|