threadnote 1.4.1 → 1.4.2
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.cjs +111 -14
- package/dist/threadnote.cjs +15 -17
- package/package.json +1 -1
package/dist/mcp_server.cjs
CHANGED
|
@@ -35715,6 +35715,57 @@ async function sleep(ms) {
|
|
|
35715
35715
|
setTimeout(resolvePromise, ms);
|
|
35716
35716
|
});
|
|
35717
35717
|
}
|
|
35718
|
+
function compareVersions(a, b) {
|
|
35719
|
+
const left = parseVersion(a);
|
|
35720
|
+
const right = parseVersion(b);
|
|
35721
|
+
for (let index = 0; index < 3; index += 1) {
|
|
35722
|
+
const difference = left.numbers[index] - right.numbers[index];
|
|
35723
|
+
if (difference !== 0) {
|
|
35724
|
+
return difference;
|
|
35725
|
+
}
|
|
35726
|
+
}
|
|
35727
|
+
const rankDelta = suffixRank(left.suffix) - suffixRank(right.suffix);
|
|
35728
|
+
if (rankDelta !== 0) {
|
|
35729
|
+
return rankDelta;
|
|
35730
|
+
}
|
|
35731
|
+
if (left.suffix === right.suffix) {
|
|
35732
|
+
return 0;
|
|
35733
|
+
}
|
|
35734
|
+
return (left.suffix ?? "").localeCompare(right.suffix ?? "");
|
|
35735
|
+
}
|
|
35736
|
+
function suffixRank(suffix) {
|
|
35737
|
+
if (suffix === void 0) {
|
|
35738
|
+
return 0;
|
|
35739
|
+
}
|
|
35740
|
+
return /^post/i.test(suffix) ? 1 : -1;
|
|
35741
|
+
}
|
|
35742
|
+
function parseVersion(version2) {
|
|
35743
|
+
const normalized = version2.trim().replace(/^v/, "").split("+", 1)[0];
|
|
35744
|
+
const core = normalized.match(/^\d+(?:\.\d+){0,2}/)?.[0] ?? "";
|
|
35745
|
+
const rawSuffix = normalized.slice(core.length).replace(/^[-_.]/, "");
|
|
35746
|
+
const suffix = core.length > 0 && rawSuffix.length > 0 ? rawSuffix : void 0;
|
|
35747
|
+
const parts = core.split(".");
|
|
35748
|
+
return {
|
|
35749
|
+
numbers: [
|
|
35750
|
+
safeVersionNumber(Number.parseInt(parts[0] ?? "", 10)),
|
|
35751
|
+
safeVersionNumber(Number.parseInt(parts[1] ?? "", 10)),
|
|
35752
|
+
safeVersionNumber(Number.parseInt(parts[2] ?? "", 10))
|
|
35753
|
+
],
|
|
35754
|
+
suffix
|
|
35755
|
+
};
|
|
35756
|
+
}
|
|
35757
|
+
function safeVersionNumber(value) {
|
|
35758
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : 0;
|
|
35759
|
+
}
|
|
35760
|
+
function formatStaleVersionNotice(runningVersion, diskVersion) {
|
|
35761
|
+
if (runningVersion === void 0 || diskVersion === void 0) {
|
|
35762
|
+
return void 0;
|
|
35763
|
+
}
|
|
35764
|
+
if (compareVersions(diskVersion, runningVersion) <= 0) {
|
|
35765
|
+
return void 0;
|
|
35766
|
+
}
|
|
35767
|
+
return `threadnote ${diskVersion} is installed but this MCP server is still running ${runningVersion}. Reconnect the threadnote MCP server (e.g. /mcp) to load the update.`;
|
|
35768
|
+
}
|
|
35718
35769
|
async function ensureDirectory(path, dryRun) {
|
|
35719
35770
|
if (dryRun) {
|
|
35720
35771
|
console.log(`Would create directory: ${path}`);
|
|
@@ -36218,6 +36269,20 @@ function shellQuote(value) {
|
|
|
36218
36269
|
}
|
|
36219
36270
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
36220
36271
|
}
|
|
36272
|
+
function toolRoot() {
|
|
36273
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(__dirname, "package.json"))) {
|
|
36274
|
+
return __dirname;
|
|
36275
|
+
}
|
|
36276
|
+
return (0, import_node_path.resolve)(__dirname, "..");
|
|
36277
|
+
}
|
|
36278
|
+
async function currentPackageVersion() {
|
|
36279
|
+
const rawPackage = await (0, import_promises.readFile)((0, import_node_path.join)(toolRoot(), "package.json"), "utf8");
|
|
36280
|
+
const parsed = JSON.parse(rawPackage);
|
|
36281
|
+
if (!isJsonObject(parsed) || typeof parsed.version !== "string") {
|
|
36282
|
+
throw new Error("Could not read current threadnote package version.");
|
|
36283
|
+
}
|
|
36284
|
+
return parsed.version;
|
|
36285
|
+
}
|
|
36221
36286
|
function errorMessage(err) {
|
|
36222
36287
|
return err instanceof Error ? err.message : String(err);
|
|
36223
36288
|
}
|
|
@@ -39267,8 +39332,36 @@ function formatPlanSection(title, lines) {
|
|
|
39267
39332
|
}
|
|
39268
39333
|
|
|
39269
39334
|
// src/mcp_server.ts
|
|
39335
|
+
var mcpStartupVersion;
|
|
39336
|
+
var staleNoticeCache;
|
|
39337
|
+
var STALE_NOTICE_TTL_MS = 6e4;
|
|
39338
|
+
async function staleVersionNotice() {
|
|
39339
|
+
if (mcpStartupVersion === void 0) {
|
|
39340
|
+
return void 0;
|
|
39341
|
+
}
|
|
39342
|
+
const nowMs = Date.now();
|
|
39343
|
+
if (staleNoticeCache && nowMs - staleNoticeCache.checkedAtMs < STALE_NOTICE_TTL_MS) {
|
|
39344
|
+
return staleNoticeCache.notice;
|
|
39345
|
+
}
|
|
39346
|
+
let notice;
|
|
39347
|
+
try {
|
|
39348
|
+
notice = formatStaleVersionNotice(mcpStartupVersion, await currentPackageVersion());
|
|
39349
|
+
} catch {
|
|
39350
|
+
notice = void 0;
|
|
39351
|
+
}
|
|
39352
|
+
staleNoticeCache = { checkedAtMs: nowMs, notice };
|
|
39353
|
+
return notice;
|
|
39354
|
+
}
|
|
39355
|
+
async function withStaleVersionNotice(result) {
|
|
39356
|
+
const notice = await staleVersionNotice();
|
|
39357
|
+
if (notice === void 0) {
|
|
39358
|
+
return result;
|
|
39359
|
+
}
|
|
39360
|
+
return { ...result, content: [...result.content ?? [], { type: "text", text: `\u26A0 ${notice}` }] };
|
|
39361
|
+
}
|
|
39270
39362
|
async function main() {
|
|
39271
39363
|
const config2 = getRuntimeConfig();
|
|
39364
|
+
mcpStartupVersion = await currentPackageVersion().catch(() => void 0);
|
|
39272
39365
|
const server = new McpServer(
|
|
39273
39366
|
{ name: "threadnote-local-adapter", version: "0.2.0" },
|
|
39274
39367
|
{
|
|
@@ -39466,7 +39559,7 @@ function registerTools(server, config2) {
|
|
|
39466
39559
|
description: "Check OpenViking server health through the CLI.",
|
|
39467
39560
|
inputSchema: {}
|
|
39468
39561
|
},
|
|
39469
|
-
async () => runOpenVikingMcpTool(config2, "health", {})
|
|
39562
|
+
async () => withStaleVersionNotice(await runOpenVikingMcpTool(config2, "health", {}))
|
|
39470
39563
|
);
|
|
39471
39564
|
registerOpenVikingParityTools(server, config2);
|
|
39472
39565
|
server.registerTool(
|
|
@@ -39959,14 +40052,16 @@ function registerSearchTool(server, config2, name, description) {
|
|
|
39959
40052
|
if (!checkedUri.ok) {
|
|
39960
40053
|
return checkedUri.error;
|
|
39961
40054
|
}
|
|
39962
|
-
return
|
|
39963
|
-
|
|
39964
|
-
|
|
39965
|
-
|
|
39966
|
-
|
|
39967
|
-
|
|
39968
|
-
|
|
39969
|
-
|
|
40055
|
+
return withStaleVersionNotice(
|
|
40056
|
+
await runRecallTool(config2, {
|
|
40057
|
+
callerCwd,
|
|
40058
|
+
query: checkedQuery.value,
|
|
40059
|
+
pinnedUri: checkedUri.value,
|
|
40060
|
+
nodeLimit,
|
|
40061
|
+
includeArchived: includeArchived === true,
|
|
40062
|
+
threshold: threshold === void 0 ? void 0 : String(threshold)
|
|
40063
|
+
})
|
|
40064
|
+
);
|
|
39970
40065
|
}
|
|
39971
40066
|
);
|
|
39972
40067
|
}
|
|
@@ -40194,11 +40289,13 @@ function registerStoreTool(server, config2, name, description) {
|
|
|
40194
40289
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40195
40290
|
topic: normalizeOptionalMetadata2(topic)
|
|
40196
40291
|
};
|
|
40197
|
-
return
|
|
40198
|
-
|
|
40199
|
-
|
|
40200
|
-
|
|
40201
|
-
|
|
40292
|
+
return withStaleVersionNotice(
|
|
40293
|
+
await writeDurableMemory(config2, {
|
|
40294
|
+
bodyText: checkedText.value,
|
|
40295
|
+
metadata,
|
|
40296
|
+
replaceUri: checkedReplaceUri.value
|
|
40297
|
+
})
|
|
40298
|
+
);
|
|
40202
40299
|
}
|
|
40203
40300
|
);
|
|
40204
40301
|
}
|
package/dist/threadnote.cjs
CHANGED
|
@@ -4583,6 +4583,14 @@ function toolRoot() {
|
|
|
4583
4583
|
}
|
|
4584
4584
|
return (0, import_node_path2.resolve)(__dirname, "..");
|
|
4585
4585
|
}
|
|
4586
|
+
async function currentPackageVersion() {
|
|
4587
|
+
const rawPackage = await (0, import_promises.readFile)((0, import_node_path2.join)(toolRoot(), "package.json"), "utf8");
|
|
4588
|
+
const parsed = JSON.parse(rawPackage);
|
|
4589
|
+
if (!isJsonObject(parsed) || typeof parsed.version !== "string") {
|
|
4590
|
+
throw new Error("Could not read current threadnote package version.");
|
|
4591
|
+
}
|
|
4592
|
+
return parsed.version;
|
|
4593
|
+
}
|
|
4586
4594
|
function errorMessage(err) {
|
|
4587
4595
|
return err instanceof Error ? err.message : String(err);
|
|
4588
4596
|
}
|
|
@@ -13430,14 +13438,6 @@ async function getUpdateInfo(config, options) {
|
|
|
13430
13438
|
registry: options.registry
|
|
13431
13439
|
};
|
|
13432
13440
|
}
|
|
13433
|
-
async function currentPackageVersion() {
|
|
13434
|
-
const rawPackage = await (0, import_promises10.readFile)((0, import_node_path13.join)(toolRoot(), "package.json"), "utf8");
|
|
13435
|
-
const parsed = JSON.parse(rawPackage);
|
|
13436
|
-
if (!isJsonObject(parsed) || typeof parsed.version !== "string") {
|
|
13437
|
-
throw new Error("Could not read current threadnote package version.");
|
|
13438
|
-
}
|
|
13439
|
-
return parsed.version;
|
|
13440
|
-
}
|
|
13441
13441
|
async function fetchLatestVersion2(registry) {
|
|
13442
13442
|
const url = new URL(`${NPM_PACKAGE_NAME}/latest`, normalizeRegistry(registry));
|
|
13443
13443
|
const controller = new AbortController();
|
|
@@ -14263,22 +14263,20 @@ async function recallShapeCheck(config) {
|
|
|
14263
14263
|
if (result.exitCode !== 0) {
|
|
14264
14264
|
return { name: "recall shape", status: "warn", detail: "search failed; run threadnote repair" };
|
|
14265
14265
|
}
|
|
14266
|
-
|
|
14266
|
+
const start = result.stdout.search(/^\{/m);
|
|
14267
|
+
let envelope;
|
|
14267
14268
|
try {
|
|
14268
|
-
parsed = JSON.parse(result.stdout.
|
|
14269
|
+
const parsed = start >= 0 ? JSON.parse(result.stdout.slice(start)) : void 0;
|
|
14270
|
+
envelope = isJsonObject(parsed) ? parsed.result : void 0;
|
|
14269
14271
|
} catch {
|
|
14270
|
-
|
|
14271
|
-
name: "recall shape",
|
|
14272
|
-
status: "warn",
|
|
14273
|
-
detail: "search output is not JSON; recall may silently return nothing"
|
|
14274
|
-
};
|
|
14272
|
+
envelope = void 0;
|
|
14275
14273
|
}
|
|
14276
14274
|
const buckets = ["memories", "resources", "skills"];
|
|
14277
|
-
if (!isJsonObject(
|
|
14275
|
+
if (!isJsonObject(envelope) || !buckets.some((key) => Array.isArray(envelope[key]))) {
|
|
14278
14276
|
return {
|
|
14279
14277
|
name: "recall shape",
|
|
14280
14278
|
status: "warn",
|
|
14281
|
-
detail: `search JSON missing ${buckets.join("
|
|
14279
|
+
detail: `search JSON missing the result.{${buckets.join(",")}} buckets recall parsing depends on`
|
|
14282
14280
|
};
|
|
14283
14281
|
}
|
|
14284
14282
|
return { name: "recall shape", status: "ok", detail: "memories/resources/skills buckets present" };
|