@context-engine-bridge/context-engine-mcp-bridge 0.0.27 → 0.0.28
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/src/mcpServer.js +5 -36
- package/src/uploader.js +64 -17
package/package.json
CHANGED
package/src/mcpServer.js
CHANGED
|
@@ -72,40 +72,6 @@ async function listMemoryTools(client) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function withTimeout(promise, ms, label) {
|
|
76
|
-
return new Promise((resolve, reject) => {
|
|
77
|
-
let settled = false;
|
|
78
|
-
const timer = setTimeout(() => {
|
|
79
|
-
if (settled) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
settled = true;
|
|
83
|
-
const errorMessage =
|
|
84
|
-
label != null
|
|
85
|
-
? `[ctxce] Timeout after ${ms}ms in ${label}`
|
|
86
|
-
: `[ctxce] Timeout after ${ms}ms`;
|
|
87
|
-
reject(new Error(errorMessage));
|
|
88
|
-
}, ms);
|
|
89
|
-
promise
|
|
90
|
-
.then((value) => {
|
|
91
|
-
if (settled) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
settled = true;
|
|
95
|
-
clearTimeout(timer);
|
|
96
|
-
resolve(value);
|
|
97
|
-
})
|
|
98
|
-
.catch((err) => {
|
|
99
|
-
if (settled) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
settled = true;
|
|
103
|
-
clearTimeout(timer);
|
|
104
|
-
reject(err);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
75
|
function getBridgeToolTimeoutMs() {
|
|
110
76
|
try {
|
|
111
77
|
const raw = process.env.CTXCE_TOOL_TIMEOUT_MSEC;
|
|
@@ -705,7 +671,7 @@ async function createBridgeServer(options) {
|
|
|
705
671
|
|
|
706
672
|
let nextIndexerClient = null;
|
|
707
673
|
try {
|
|
708
|
-
const indexerTransport = new StreamableHTTPClientTransport(indexerUrl, transportOpts);
|
|
674
|
+
const indexerTransport = new StreamableHTTPClientTransport(new URL(indexerUrl), transportOpts);
|
|
709
675
|
const client = new Client(
|
|
710
676
|
{
|
|
711
677
|
name: "ctx-context-engine-bridge-http-client",
|
|
@@ -729,7 +695,7 @@ async function createBridgeServer(options) {
|
|
|
729
695
|
let nextMemoryClient = null;
|
|
730
696
|
if (memoryUrl) {
|
|
731
697
|
try {
|
|
732
|
-
const memoryTransport = new StreamableHTTPClientTransport(memoryUrl, transportOpts);
|
|
698
|
+
const memoryTransport = new StreamableHTTPClientTransport(new URL(memoryUrl), transportOpts);
|
|
733
699
|
const client = new Client(
|
|
734
700
|
{
|
|
735
701
|
name: "ctx-context-engine-bridge-memory-client",
|
|
@@ -860,6 +826,9 @@ async function createBridgeServer(options) {
|
|
|
860
826
|
args = maybeRemapToolArgs(name, args, workspace);
|
|
861
827
|
|
|
862
828
|
if (name === "set_session_defaults") {
|
|
829
|
+
if (!indexerClient) {
|
|
830
|
+
throw new Error("Indexer client not connected");
|
|
831
|
+
}
|
|
863
832
|
const indexerResult = await indexerClient.callTool({ name, arguments: args });
|
|
864
833
|
if (memoryClient) {
|
|
865
834
|
try {
|
package/src/uploader.js
CHANGED
|
@@ -129,33 +129,76 @@ export async function createBundle(workspacePath, options = {}) {
|
|
|
129
129
|
log(`[uploader] Found ${files.length} code files`);
|
|
130
130
|
|
|
131
131
|
const bundleId = createHash("sha256").update(Date.now().toString() + Math.random().toString()).digest("hex").slice(0, 16);
|
|
132
|
+
const createdAt = new Date().toISOString();
|
|
133
|
+
|
|
134
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "ctxce-"));
|
|
135
|
+
const bundleDir = path.join(tmpDir, bundleId);
|
|
136
|
+
const metadataDir = path.join(bundleDir, ".metadata");
|
|
137
|
+
const filesDir = path.join(bundleDir, "files");
|
|
138
|
+
|
|
139
|
+
fs.mkdirSync(metadataDir, { recursive: true });
|
|
140
|
+
fs.mkdirSync(filesDir, { recursive: true });
|
|
141
|
+
|
|
142
|
+
const operations = [];
|
|
143
|
+
const fileHashes = {};
|
|
144
|
+
let totalSize = 0;
|
|
145
|
+
|
|
146
|
+
for (const file of files) {
|
|
147
|
+
const destPath = path.join(filesDir, file.path);
|
|
148
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
149
|
+
fs.copyFileSync(file.fullPath, destPath);
|
|
150
|
+
|
|
151
|
+
const hash = computeFileHash(file.fullPath);
|
|
152
|
+
fileHashes[file.path] = hash;
|
|
153
|
+
totalSize += file.size;
|
|
154
|
+
|
|
155
|
+
operations.push({
|
|
156
|
+
op: "upsert",
|
|
157
|
+
path: file.path,
|
|
158
|
+
size: file.size,
|
|
159
|
+
hash,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
132
162
|
|
|
133
163
|
const manifest = {
|
|
164
|
+
version: "1.0",
|
|
134
165
|
bundle_id: bundleId,
|
|
135
166
|
workspace_path: workspacePath,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
167
|
+
collection_name: computeLogicalRepoId(workspacePath),
|
|
168
|
+
created_at: createdAt,
|
|
169
|
+
sequence_number: null,
|
|
170
|
+
parent_sequence: null,
|
|
171
|
+
operations: {
|
|
172
|
+
created: files.length,
|
|
173
|
+
updated: 0,
|
|
174
|
+
deleted: 0,
|
|
175
|
+
moved: 0,
|
|
176
|
+
},
|
|
177
|
+
total_files: files.length,
|
|
178
|
+
total_size_bytes: totalSize,
|
|
179
|
+
compression: "gzip",
|
|
180
|
+
encoding: "utf-8",
|
|
145
181
|
};
|
|
146
182
|
|
|
147
|
-
|
|
148
|
-
|
|
183
|
+
fs.writeFileSync(path.join(bundleDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
184
|
+
fs.writeFileSync(path.join(metadataDir, "operations.json"), JSON.stringify({ operations }, null, 2));
|
|
185
|
+
fs.writeFileSync(path.join(metadataDir, "hashes.json"), JSON.stringify({
|
|
186
|
+
workspace_path: workspacePath,
|
|
187
|
+
updated_at: createdAt,
|
|
188
|
+
file_hashes: fileHashes,
|
|
189
|
+
}, null, 2));
|
|
190
|
+
|
|
191
|
+
const bundlePath = path.join(tmpDir, `${bundleId}.tar.gz`);
|
|
149
192
|
|
|
150
193
|
try {
|
|
151
194
|
await tarCreate(
|
|
152
195
|
{
|
|
153
196
|
gzip: true,
|
|
154
197
|
file: bundlePath,
|
|
155
|
-
cwd:
|
|
198
|
+
cwd: tmpDir,
|
|
156
199
|
portable: true,
|
|
157
200
|
},
|
|
158
|
-
|
|
201
|
+
[bundleId]
|
|
159
202
|
);
|
|
160
203
|
|
|
161
204
|
const bundleSize = fs.statSync(bundlePath).size;
|
|
@@ -194,13 +237,13 @@ export async function uploadBundle(bundlePath, manifest, uploadEndpoint, session
|
|
|
194
237
|
parts.push(bundleData);
|
|
195
238
|
parts.push(`\r\n`);
|
|
196
239
|
|
|
240
|
+
const logicalRepoId = computeLogicalRepoId(manifest.workspace_path);
|
|
197
241
|
const fields = {
|
|
198
242
|
workspace_path: manifest.workspace_path,
|
|
199
|
-
collection_name: manifest.
|
|
200
|
-
sequence_number: String(manifest.sequence_number),
|
|
243
|
+
collection_name: manifest.collection_name || logicalRepoId,
|
|
201
244
|
force: "true",
|
|
202
245
|
source_path: manifest.workspace_path,
|
|
203
|
-
logical_repo_id:
|
|
246
|
+
logical_repo_id: logicalRepoId,
|
|
204
247
|
session: sessionId,
|
|
205
248
|
};
|
|
206
249
|
|
|
@@ -242,7 +285,11 @@ export async function uploadBundle(bundlePath, manifest, uploadEndpoint, session
|
|
|
242
285
|
}
|
|
243
286
|
|
|
244
287
|
if (!resp.ok || !result.success) {
|
|
245
|
-
|
|
288
|
+
let errorMsg = result.error?.message || result.detail || result.error;
|
|
289
|
+
if (typeof errorMsg === "object") {
|
|
290
|
+
errorMsg = JSON.stringify(errorMsg);
|
|
291
|
+
}
|
|
292
|
+
errorMsg = errorMsg || `HTTP ${resp.status}`;
|
|
246
293
|
log(`[uploader] Upload failed: ${errorMsg}`);
|
|
247
294
|
return { success: false, error: errorMsg };
|
|
248
295
|
}
|