@vornrun/mcp 0.8.0-beta.2 → 0.8.0-beta.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.js +187 -25
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import "module";
|
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
|
|
7
7
|
// ../server/src/config-manager.ts
|
|
8
|
-
import
|
|
8
|
+
import fs5 from "fs";
|
|
9
9
|
|
|
10
10
|
// ../shared/src/agent-defaults.ts
|
|
11
11
|
var DEFAULT_AGENT_COMMANDS = {
|
|
@@ -34,9 +34,9 @@ var DEFAULT_AGENT_COMMANDS = {
|
|
|
34
34
|
|
|
35
35
|
// ../server/src/database.ts
|
|
36
36
|
import Database from "libsql";
|
|
37
|
-
import
|
|
37
|
+
import path4 from "path";
|
|
38
38
|
import os from "os";
|
|
39
|
-
import
|
|
39
|
+
import fs4 from "fs";
|
|
40
40
|
import { randomUUID } from "crypto";
|
|
41
41
|
|
|
42
42
|
// ../server/src/logger.ts
|
|
@@ -124,6 +124,65 @@ import path2 from "path";
|
|
|
124
124
|
import crypto2 from "crypto";
|
|
125
125
|
var GATE_VIEW_MAX_BYTES = 5 * 1024 * 1024;
|
|
126
126
|
|
|
127
|
+
// ../server/src/native-core.ts
|
|
128
|
+
import fs3 from "fs";
|
|
129
|
+
import path3 from "path";
|
|
130
|
+
var NATIVE_CORE_FILE = "vorn_core.node";
|
|
131
|
+
function nativeCoreCandidates(dir, override) {
|
|
132
|
+
const candidates = [
|
|
133
|
+
path3.join(dir, "..", "core", NATIVE_CORE_FILE),
|
|
134
|
+
path3.join(dir, "..", "..", "core", NATIVE_CORE_FILE)
|
|
135
|
+
];
|
|
136
|
+
return override ? [path3.resolve(override), ...candidates] : candidates;
|
|
137
|
+
}
|
|
138
|
+
function dlopen(file) {
|
|
139
|
+
const mod = { exports: {} };
|
|
140
|
+
process.dlopen(mod, file);
|
|
141
|
+
return mod.exports;
|
|
142
|
+
}
|
|
143
|
+
function loadNativeCore(candidates, deps = {}) {
|
|
144
|
+
const exists = deps.exists ?? fs3.existsSync;
|
|
145
|
+
const open = deps.open ?? dlopen;
|
|
146
|
+
const file = candidates.find((candidate) => exists(candidate));
|
|
147
|
+
if (!file) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`${NATIVE_CORE_FILE} not found; build it with \`yarn build:core\` (looked in ${candidates.join(", ")})`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const core = open(file);
|
|
153
|
+
if (typeof core.info !== "function" || typeof core.hello !== "function") {
|
|
154
|
+
throw new Error(`${file} is not a vorn core: it exports no info() or hello()`);
|
|
155
|
+
}
|
|
156
|
+
return core;
|
|
157
|
+
}
|
|
158
|
+
function selectCore(options = {}) {
|
|
159
|
+
const env = options.env ?? process.env;
|
|
160
|
+
const dir = options.dir ?? serverDir();
|
|
161
|
+
const load = options.load ?? ((candidates) => loadNativeCore(candidates));
|
|
162
|
+
try {
|
|
163
|
+
const native2 = load(nativeCoreCandidates(dir, env.VORN_CORE_PATH));
|
|
164
|
+
const info = native2.info();
|
|
165
|
+
if (!info || typeof info.version !== "string") {
|
|
166
|
+
throw new Error("vorn core info() returned no version");
|
|
167
|
+
}
|
|
168
|
+
return { native: native2, info };
|
|
169
|
+
} catch (err) {
|
|
170
|
+
return { native: null, error: err instanceof Error ? err.message : String(err) };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function serverDir() {
|
|
174
|
+
return typeof __dirname !== "undefined" ? __dirname : path3.dirname(process.argv[1]);
|
|
175
|
+
}
|
|
176
|
+
var active = null;
|
|
177
|
+
var loadOverride;
|
|
178
|
+
function activeCore() {
|
|
179
|
+
active ??= selectCore({ load: loadOverride });
|
|
180
|
+
return active;
|
|
181
|
+
}
|
|
182
|
+
function nativeCore() {
|
|
183
|
+
return activeCore().native;
|
|
184
|
+
}
|
|
185
|
+
|
|
127
186
|
// ../server/src/default-workflows.ts
|
|
128
187
|
var DEFAULT_TASK_WORKFLOW_ID = "system:default-task-workflow";
|
|
129
188
|
var DEV_SERVER_WORKFLOW_ID = "system:dev-server-on-restore";
|
|
@@ -201,16 +260,21 @@ function buildDevServerWorkflow() {
|
|
|
201
260
|
}
|
|
202
261
|
|
|
203
262
|
// ../server/src/database.ts
|
|
204
|
-
var DEFAULT_DATA_DIR =
|
|
263
|
+
var DEFAULT_DATA_DIR = path4.join(os.homedir(), ".vorn");
|
|
205
264
|
var resolvedDataDir = null;
|
|
206
265
|
function dbPath() {
|
|
207
|
-
return
|
|
266
|
+
return path4.join(getDataDir(), "vorn.db");
|
|
208
267
|
}
|
|
209
268
|
var db = null;
|
|
269
|
+
var native = null;
|
|
270
|
+
var nativeError = null;
|
|
210
271
|
function getDb() {
|
|
211
272
|
if (!db) throw new Error("Database not initialized. Call initDatabase() first.");
|
|
212
273
|
return db;
|
|
213
274
|
}
|
|
275
|
+
function nativeCall(store, call, ...args) {
|
|
276
|
+
return JSON.parse(store.call(call, JSON.stringify(args)));
|
|
277
|
+
}
|
|
214
278
|
function getDataDir() {
|
|
215
279
|
if (!resolvedDataDir) {
|
|
216
280
|
throw new Error("Data directory not resolved. Call initDatabase() first.");
|
|
@@ -219,8 +283,13 @@ function getDataDir() {
|
|
|
219
283
|
}
|
|
220
284
|
function initDatabase(dataDir2) {
|
|
221
285
|
resolvedDataDir = dataDir2 ?? DEFAULT_DATA_DIR;
|
|
222
|
-
if (!
|
|
223
|
-
|
|
286
|
+
if (!fs4.existsSync(getDataDir())) {
|
|
287
|
+
fs4.mkdirSync(getDataDir(), { recursive: true, mode: 448 });
|
|
288
|
+
}
|
|
289
|
+
if (nativeStoreWanted()) {
|
|
290
|
+
openNativeStore((store) => store.open(dbPath(), nativeOptions()));
|
|
291
|
+
requireForcedNativeStore();
|
|
292
|
+
if (native) return;
|
|
224
293
|
}
|
|
225
294
|
try {
|
|
226
295
|
db = new Database(dbPath());
|
|
@@ -241,8 +310,90 @@ function initDatabase(dataDir2) {
|
|
|
241
310
|
throw err;
|
|
242
311
|
}
|
|
243
312
|
}
|
|
313
|
+
if (!nativeStoreClass() && nativeStoreFlag(readDefault("experimental"))) {
|
|
314
|
+
nativeError = NO_NATIVE_STORE;
|
|
315
|
+
logger_default.warn(`[database] Native store is on, but ${nativeError}; using the TypeScript store`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function requireForcedNativeStore() {
|
|
319
|
+
if (process.env.VORN_NATIVE_STORE === "1" && !native)
|
|
320
|
+
throw new Error(`VORN_NATIVE_STORE=1 but the native store did not open: ${nativeError}`);
|
|
321
|
+
}
|
|
322
|
+
var NO_NATIVE_STORE = "the native core is not loaded, or was built without the store";
|
|
323
|
+
function nativeStoreWanted() {
|
|
324
|
+
const forced = process.env.VORN_NATIVE_STORE;
|
|
325
|
+
if (forced === "1") return true;
|
|
326
|
+
if (forced === "0") return false;
|
|
327
|
+
const NativeStoreClass = nativeStoreClass();
|
|
328
|
+
if (!NativeStoreClass) return false;
|
|
329
|
+
try {
|
|
330
|
+
return nativeStoreFlag(NativeStoreClass.readDefault(dbPath(), "experimental"));
|
|
331
|
+
} catch (err) {
|
|
332
|
+
logger_default.warn({ err }, "[database] could not read the Native store switch");
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function nativeStoreFlag(experimental) {
|
|
337
|
+
try {
|
|
338
|
+
const flags = experimental ? JSON.parse(experimental) : null;
|
|
339
|
+
return isPlainObject(flags) && flags.nativeStore === true;
|
|
340
|
+
} catch {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function readDefault(key) {
|
|
345
|
+
try {
|
|
346
|
+
const row = getDb().prepare("SELECT value FROM defaults WHERE key = ?").get(key);
|
|
347
|
+
return row?.value ?? null;
|
|
348
|
+
} catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function openNativeStore(open) {
|
|
353
|
+
const NativeStoreClass = nativeStoreClass();
|
|
354
|
+
if (!NativeStoreClass) {
|
|
355
|
+
nativeError = NO_NATIVE_STORE;
|
|
356
|
+
logger_default.warn(`[database] Native store is on, but ${nativeError}; using the TypeScript store`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
native = open(NativeStoreClass);
|
|
361
|
+
if (native.recovered) {
|
|
362
|
+
logger_default.warn(
|
|
363
|
+
`[database] the native store replaced a corrupt database; backup at ${native.recovered}`
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
nativeError = null;
|
|
367
|
+
logger_default.info("[database] using the native store");
|
|
368
|
+
} catch (err) {
|
|
369
|
+
native = null;
|
|
370
|
+
nativeError = err instanceof Error ? err.message : String(err);
|
|
371
|
+
logger_default.error({ err }, "[database] the native store did not open; using the TypeScript store");
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function nativeStoreClass() {
|
|
375
|
+
const NativeStoreClass = nativeCore()?.NativeStore;
|
|
376
|
+
return typeof NativeStoreClass === "function" ? NativeStoreClass : null;
|
|
377
|
+
}
|
|
378
|
+
function nativeOptions() {
|
|
379
|
+
let ownerName = "owner";
|
|
380
|
+
try {
|
|
381
|
+
ownerName = os.userInfo().username || ownerName;
|
|
382
|
+
} catch {
|
|
383
|
+
}
|
|
384
|
+
return JSON.stringify({
|
|
385
|
+
defaultShell: getDefaultShell(),
|
|
386
|
+
defaultAgentCommands: DEFAULT_AGENT_COMMANDS,
|
|
387
|
+
defaultWorkspace: DEFAULT_WORKSPACE,
|
|
388
|
+
ownerName,
|
|
389
|
+
seedWorkflows: [
|
|
390
|
+
{ flag: "hasSeededDefaultTaskWorkflow", workflow: buildDefaultTaskWorkflow() },
|
|
391
|
+
{ flag: "hasSeededDevServerWorkflow", workflow: buildDevServerWorkflow() }
|
|
392
|
+
]
|
|
393
|
+
});
|
|
244
394
|
}
|
|
245
395
|
function seedSystemDefaults() {
|
|
396
|
+
if (native) return nativeCall(native, "seedSystemDefaults");
|
|
246
397
|
seedWorkflowOnce(
|
|
247
398
|
"hasSeededDefaultTaskWorkflow",
|
|
248
399
|
DEFAULT_TASK_WORKFLOW_ID,
|
|
@@ -294,13 +445,13 @@ function recoverCorruptDatabase() {
|
|
|
294
445
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
295
446
|
const backupPath = `${dbPath()}.corrupt-${timestamp}`;
|
|
296
447
|
try {
|
|
297
|
-
if (
|
|
298
|
-
|
|
448
|
+
if (fs4.existsSync(dbPath())) {
|
|
449
|
+
fs4.copyFileSync(dbPath(), backupPath);
|
|
299
450
|
logger_default.info(`[database] Backed up corrupt database to ${backupPath}`);
|
|
300
451
|
}
|
|
301
452
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
302
453
|
const file = dbPath() + suffix;
|
|
303
|
-
if (
|
|
454
|
+
if (fs4.existsSync(file)) fs4.unlinkSync(file);
|
|
304
455
|
}
|
|
305
456
|
} catch (backupErr) {
|
|
306
457
|
logger_default.error({ backupErr }, "[database] Failed to back up corrupt database:");
|
|
@@ -319,6 +470,10 @@ function recoverCorruptDatabase() {
|
|
|
319
470
|
logger_default.warn(`[database] Database was corrupted and has been reset. Backup saved to: ${backupPath}`);
|
|
320
471
|
}
|
|
321
472
|
function closeDatabase() {
|
|
473
|
+
if (native) {
|
|
474
|
+
native.close();
|
|
475
|
+
native = null;
|
|
476
|
+
}
|
|
322
477
|
if (db) {
|
|
323
478
|
db.close();
|
|
324
479
|
db = null;
|
|
@@ -1379,6 +1534,7 @@ function verifySchema(d) {
|
|
|
1379
1534
|
}
|
|
1380
1535
|
}
|
|
1381
1536
|
function loadConfig() {
|
|
1537
|
+
if (native) return nativeCall(native, "loadConfig");
|
|
1382
1538
|
const d = getDb();
|
|
1383
1539
|
const defaults = loadDefaults(d);
|
|
1384
1540
|
const projects = loadProjects(d);
|
|
@@ -1578,7 +1734,13 @@ function pruneMissing(d, table, keyColumn, keep, baseRevision) {
|
|
|
1578
1734
|
remove.run(key);
|
|
1579
1735
|
}
|
|
1580
1736
|
}
|
|
1737
|
+
function nativeConfig(config) {
|
|
1738
|
+
const deleted = Object.entries(config.defaults).filter(([, value]) => value === void 0).map(([key]) => key);
|
|
1739
|
+
const agentCommands = config.agentCommands && Object.fromEntries(Object.entries(config.agentCommands).map(([key, cmd]) => [key, cmd ?? null]));
|
|
1740
|
+
return [{ ...config, ...agentCommands && { agentCommands } }, deleted];
|
|
1741
|
+
}
|
|
1581
1742
|
function saveConfig(config) {
|
|
1743
|
+
if (native) return nativeCall(native, "saveConfig", ...nativeConfig(config));
|
|
1582
1744
|
const d = getDb();
|
|
1583
1745
|
const run = d.transaction(() => {
|
|
1584
1746
|
const baseRevision = config.revision ?? Number.MAX_SAFE_INTEGER;
|
|
@@ -1970,7 +2132,7 @@ var ConfigManager = class {
|
|
|
1970
2132
|
watchDb() {
|
|
1971
2133
|
if (this.dbWatcher) return;
|
|
1972
2134
|
try {
|
|
1973
|
-
this.dbWatcher =
|
|
2135
|
+
this.dbWatcher = fs5.watch(getDataDir(), (_eventType, filename) => {
|
|
1974
2136
|
if (filename !== ".db-signal") return;
|
|
1975
2137
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
1976
2138
|
this.debounceTimer = setTimeout(() => {
|
|
@@ -2003,7 +2165,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2003
2165
|
|
|
2004
2166
|
// src/tools/tasks.ts
|
|
2005
2167
|
import crypto3 from "crypto";
|
|
2006
|
-
import
|
|
2168
|
+
import path6 from "path";
|
|
2007
2169
|
import { z as z2 } from "zod";
|
|
2008
2170
|
|
|
2009
2171
|
// src/validation.ts
|
|
@@ -2032,8 +2194,8 @@ var V = {
|
|
|
2032
2194
|
};
|
|
2033
2195
|
|
|
2034
2196
|
// ../server/src/rpc-client.ts
|
|
2035
|
-
import
|
|
2036
|
-
import
|
|
2197
|
+
import fs6 from "fs";
|
|
2198
|
+
import path5 from "path";
|
|
2037
2199
|
import os2 from "os";
|
|
2038
2200
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
2039
2201
|
import { WebSocket } from "ws";
|
|
@@ -2042,13 +2204,13 @@ function named(value) {
|
|
|
2042
2204
|
return value?.trim() ? value : void 0;
|
|
2043
2205
|
}
|
|
2044
2206
|
function dataDir() {
|
|
2045
|
-
return dataDirOverride ?? named(process.env.VORN_DATA_DIR) ??
|
|
2207
|
+
return dataDirOverride ?? named(process.env.VORN_DATA_DIR) ?? path5.join(os2.homedir(), ".vorn");
|
|
2046
2208
|
}
|
|
2047
2209
|
function portFile() {
|
|
2048
|
-
return
|
|
2210
|
+
return path5.join(dataDir(), WS_PORT_FILENAME);
|
|
2049
2211
|
}
|
|
2050
2212
|
function localTokenFile() {
|
|
2051
|
-
return
|
|
2213
|
+
return path5.join(dataDir(), LOCAL_TOKEN_FILENAME);
|
|
2052
2214
|
}
|
|
2053
2215
|
function tokenFileMissingMessage() {
|
|
2054
2216
|
return `Vorn local credential not found (${localTokenFile()}).
|
|
@@ -2060,7 +2222,7 @@ MCP included, reaches a server that moved.`;
|
|
|
2060
2222
|
}
|
|
2061
2223
|
function readLocalToken() {
|
|
2062
2224
|
try {
|
|
2063
|
-
const token =
|
|
2225
|
+
const token = fs6.readFileSync(localTokenFile(), "utf-8").trim();
|
|
2064
2226
|
if (!token) throw new Error("empty");
|
|
2065
2227
|
return token;
|
|
2066
2228
|
} catch {
|
|
@@ -2180,8 +2342,8 @@ function discoverAndHeal() {
|
|
|
2180
2342
|
cacheTimestamp = now;
|
|
2181
2343
|
if (discovered) {
|
|
2182
2344
|
try {
|
|
2183
|
-
|
|
2184
|
-
|
|
2345
|
+
fs6.mkdirSync(dataDir(), { recursive: true });
|
|
2346
|
+
fs6.writeFileSync(portFile(), JSON.stringify({ port: discovered }), "utf-8");
|
|
2185
2347
|
} catch {
|
|
2186
2348
|
}
|
|
2187
2349
|
return { port: discovered };
|
|
@@ -2190,7 +2352,7 @@ function discoverAndHeal() {
|
|
|
2190
2352
|
}
|
|
2191
2353
|
function readPort() {
|
|
2192
2354
|
try {
|
|
2193
|
-
const raw =
|
|
2355
|
+
const raw = fs6.readFileSync(portFile(), "utf-8").trim();
|
|
2194
2356
|
if (!raw) return { port: null, reason: "invalid" };
|
|
2195
2357
|
if (raw.startsWith("{")) {
|
|
2196
2358
|
const parsed = JSON.parse(raw);
|
|
@@ -2628,12 +2790,12 @@ function registerTaskTools(server) {
|
|
|
2628
2790
|
};
|
|
2629
2791
|
}
|
|
2630
2792
|
const cwd = args.cwd || process.cwd();
|
|
2631
|
-
const normalizedCwd =
|
|
2793
|
+
const normalizedCwd = path6.resolve(cwd);
|
|
2632
2794
|
const projects = await dbListProjects();
|
|
2633
2795
|
let matchedProject = null;
|
|
2634
2796
|
let matchLen = 0;
|
|
2635
2797
|
for (const p of projects) {
|
|
2636
|
-
const normalizedPath =
|
|
2798
|
+
const normalizedPath = path6.resolve(p.path);
|
|
2637
2799
|
if (normalizedCwd.startsWith(normalizedPath) && normalizedPath.length > matchLen) {
|
|
2638
2800
|
matchedProject = p;
|
|
2639
2801
|
matchLen = normalizedPath.length;
|
|
@@ -2661,7 +2823,7 @@ function registerTaskTools(server) {
|
|
|
2661
2823
|
let matchedTask = null;
|
|
2662
2824
|
for (const t of projectTasks) {
|
|
2663
2825
|
if (t.worktreePath) {
|
|
2664
|
-
const normalizedWorktree =
|
|
2826
|
+
const normalizedWorktree = path6.resolve(t.worktreePath);
|
|
2665
2827
|
if (normalizedCwd.startsWith(normalizedWorktree)) {
|
|
2666
2828
|
matchedTask = t;
|
|
2667
2829
|
break;
|
|
@@ -5980,7 +6142,7 @@ console.warn = (...args) => _origError("[mcp:warn]", ...args);
|
|
|
5980
6142
|
console.error = (...args) => _origError("[mcp:error]", ...args);
|
|
5981
6143
|
async function main() {
|
|
5982
6144
|
configManager.init();
|
|
5983
|
-
const version = true ? "0.8.0-beta.
|
|
6145
|
+
const version = true ? "0.8.0-beta.3" : createRequire(import.meta.url)("../package.json").version;
|
|
5984
6146
|
const server = createMcpServer(version);
|
|
5985
6147
|
const transport = new StdioServerTransport();
|
|
5986
6148
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vornrun/mcp",
|
|
3
|
-
"version": "0.8.0-beta.
|
|
3
|
+
"version": "0.8.0-beta.3",
|
|
4
4
|
"description": "Vorn MCP server — task management, git, and workflow tools for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"zod": "^4.5.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@vornrun/server": "0.8.0-beta.
|
|
42
|
-
"@vornrun/shared": "0.8.0-beta.
|
|
41
|
+
"@vornrun/server": "0.8.0-beta.3",
|
|
42
|
+
"@vornrun/shared": "0.8.0-beta.3",
|
|
43
43
|
"tsup": "^8.5.1",
|
|
44
44
|
"tsx": "^4.23.1",
|
|
45
45
|
"typescript": "^6.0.3"
|