seekstone 0.19.0 → 0.20.1
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/README.md +1 -0
- package/dist/index.js +74 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,6 +163,7 @@ Every write tool (`append_note`, `patch_note`, `patch_frontmatter`, `replace_in_
|
|
|
163
163
|
| `SEEKSTONE_MODEL_PATH` | no | Directory holding the Model2Vec embedding model (default: where `fetch-model` puts the selected model). |
|
|
164
164
|
| `SEEKSTONE_CACHE_DIR` | no | Cache root for the model and per-vault embedding caches (default `~/.cache/seekstone`). |
|
|
165
165
|
| `SEEKSTONE_BUNDLED_MODEL_DIR` | no | Set by the `seekstone-semantic.mcpb` bundle's manifest — sharded model files shipped inside the extension, reassembled into the model directory at boot (disk-only, hash-verified). Not usually set by hand. |
|
|
166
|
+
| `SEEKSTONE_INSTRUCTIONS` | no | Path to a file whose contents become the MCP server's `instructions` string (surfaced to clients alongside the tool list). A relative path resolves against the vault root. Read once at boot, trimmed, capped at 16 KB (truncated with a warning past that). Missing, unreadable, or empty after trim means no instructions — never a boot failure. |
|
|
166
167
|
|
|
167
168
|
---
|
|
168
169
|
|
package/dist/index.js
CHANGED
|
@@ -192,7 +192,7 @@ var init_fetch_model = __esm({
|
|
|
192
192
|
|
|
193
193
|
// src/index.ts
|
|
194
194
|
import { homedir } from "os";
|
|
195
|
-
import { resolve as
|
|
195
|
+
import { resolve as resolve3 } from "path";
|
|
196
196
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
197
197
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
198
198
|
import {
|
|
@@ -439,6 +439,8 @@ Optional environment:
|
|
|
439
439
|
SEEKSTONE_SEMANTIC_MODEL potion-base-8M (default) | potion-retrieval-32M (bigger, more accurate)
|
|
440
440
|
SEEKSTONE_MODEL_PATH Override the embedding-model directory
|
|
441
441
|
SEEKSTONE_CACHE_DIR Override the cache root (default ~/.cache/seekstone)
|
|
442
|
+
SEEKSTONE_INSTRUCTIONS Path to a file whose contents become the MCP
|
|
443
|
+
"instructions" (relative paths resolve against the vault)
|
|
442
444
|
|
|
443
445
|
Add to Claude Code:
|
|
444
446
|
claude mcp add seekstone --env SEEKSTONE_VAULT=/path/to/vault -- npx -y seekstone
|
|
@@ -3790,6 +3792,47 @@ async function runInit(opts, deps) {
|
|
|
3790
3792
|
return { ok: true, exitCode: 0, output: out, wrotePath: configPath, backupPath };
|
|
3791
3793
|
}
|
|
3792
3794
|
|
|
3795
|
+
// src/instructions.ts
|
|
3796
|
+
import { readFileSync } from "fs";
|
|
3797
|
+
import { isAbsolute, resolve as resolve2 } from "path";
|
|
3798
|
+
var MAX_BYTES = 16 * 1024;
|
|
3799
|
+
function truncateUtf8(text, maxBytes) {
|
|
3800
|
+
let bytes = 0;
|
|
3801
|
+
let out = "";
|
|
3802
|
+
for (const ch of text) {
|
|
3803
|
+
const chBytes = Buffer.byteLength(ch, "utf8");
|
|
3804
|
+
if (bytes + chBytes > maxBytes) break;
|
|
3805
|
+
out += ch;
|
|
3806
|
+
bytes += chBytes;
|
|
3807
|
+
}
|
|
3808
|
+
return out;
|
|
3809
|
+
}
|
|
3810
|
+
function resolveInstructions(env, vaultRoot2, log2) {
|
|
3811
|
+
const raw = (env.SEEKSTONE_INSTRUCTIONS ?? "").trim();
|
|
3812
|
+
if (raw === "") return void 0;
|
|
3813
|
+
const path2 = isAbsolute(raw) ? raw : resolve2(vaultRoot2, raw);
|
|
3814
|
+
let content;
|
|
3815
|
+
try {
|
|
3816
|
+
content = readFileSync(path2, "utf8");
|
|
3817
|
+
} catch (err) {
|
|
3818
|
+
log2.warn("cannot read SEEKSTONE_INSTRUCTIONS file; starting without instructions", {
|
|
3819
|
+
path: path2,
|
|
3820
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3821
|
+
});
|
|
3822
|
+
return void 0;
|
|
3823
|
+
}
|
|
3824
|
+
let trimmed = content.trim();
|
|
3825
|
+
if (trimmed === "") return void 0;
|
|
3826
|
+
const bytes = Buffer.byteLength(trimmed, "utf8");
|
|
3827
|
+
if (bytes > MAX_BYTES) {
|
|
3828
|
+
log2.warn("SEEKSTONE_INSTRUCTIONS file exceeds 16 KB; truncated", { path: path2, bytes });
|
|
3829
|
+
trimmed = truncateUtf8(trimmed, MAX_BYTES).trim();
|
|
3830
|
+
if (trimmed === "") return void 0;
|
|
3831
|
+
}
|
|
3832
|
+
log2.info("instructions attached", { bytes: Buffer.byteLength(trimmed, "utf8") });
|
|
3833
|
+
return trimmed;
|
|
3834
|
+
}
|
|
3835
|
+
|
|
3793
3836
|
// src/process-guards.ts
|
|
3794
3837
|
function installProcessGuards(log2) {
|
|
3795
3838
|
const onUnhandledRejection = (reason) => {
|
|
@@ -4894,6 +4937,7 @@ var ALL_TOOLS = [
|
|
|
4894
4937
|
description: "eq/ne compare scalars; contains matches array membership or substring; exists/missing test key presence; gt/gte/lt/lte compare numbers or strings (ISO dates sort correctly)."
|
|
4895
4938
|
},
|
|
4896
4939
|
value: {
|
|
4940
|
+
type: ["string", "number", "boolean"],
|
|
4897
4941
|
description: "Comparison value. Required for every op except exists/missing."
|
|
4898
4942
|
}
|
|
4899
4943
|
},
|
|
@@ -5200,8 +5244,26 @@ var ALL_TOOLS = [
|
|
|
5200
5244
|
properties: {
|
|
5201
5245
|
path: { type: "string", description: "Vault-relative path to the note." },
|
|
5202
5246
|
target: {
|
|
5203
|
-
|
|
5204
|
-
|
|
5247
|
+
description: 'Exactly one of: { heading: "Section Title" } or { block: "block-id" } (without the ^ prefix).',
|
|
5248
|
+
anyOf: [
|
|
5249
|
+
{
|
|
5250
|
+
type: "object",
|
|
5251
|
+
properties: {
|
|
5252
|
+
heading: { type: "string", description: "Heading text (without # markers)." }
|
|
5253
|
+
},
|
|
5254
|
+
required: ["heading"]
|
|
5255
|
+
},
|
|
5256
|
+
{
|
|
5257
|
+
type: "object",
|
|
5258
|
+
properties: {
|
|
5259
|
+
block: {
|
|
5260
|
+
type: "string",
|
|
5261
|
+
description: "Block reference ID (without the ^ prefix)."
|
|
5262
|
+
}
|
|
5263
|
+
},
|
|
5264
|
+
required: ["block"]
|
|
5265
|
+
}
|
|
5266
|
+
]
|
|
5205
5267
|
},
|
|
5206
5268
|
operation: {
|
|
5207
5269
|
type: "string",
|
|
@@ -5468,9 +5530,9 @@ function startWatcher(ctx2, log2, opts) {
|
|
|
5468
5530
|
opts?.onRawEvent?.("unlink", abs, relPath);
|
|
5469
5531
|
if (relPath.endsWith(".md")) remove(relPath);
|
|
5470
5532
|
});
|
|
5471
|
-
const ready = new Promise((
|
|
5533
|
+
const ready = new Promise((resolve4) => {
|
|
5472
5534
|
watcher2.once("ready", () => {
|
|
5473
|
-
|
|
5535
|
+
resolve4();
|
|
5474
5536
|
});
|
|
5475
5537
|
});
|
|
5476
5538
|
return {
|
|
@@ -5480,7 +5542,7 @@ function startWatcher(ctx2, log2, opts) {
|
|
|
5480
5542
|
}
|
|
5481
5543
|
|
|
5482
5544
|
// src/index.ts
|
|
5483
|
-
var VERSION = true ? "0.
|
|
5545
|
+
var VERSION = true ? "0.20.1" : "0.0.0-dev";
|
|
5484
5546
|
var intent = parseCliIntent(process.argv.slice(2));
|
|
5485
5547
|
if (intent === "version") {
|
|
5486
5548
|
process.stdout.write(`${VERSION}
|
|
@@ -5527,7 +5589,7 @@ if (!rawVaultRoot) {
|
|
|
5527
5589
|
log.error("SEEKSTONE_VAULT env var is required");
|
|
5528
5590
|
process.exit(1);
|
|
5529
5591
|
}
|
|
5530
|
-
var vaultRoot =
|
|
5592
|
+
var vaultRoot = resolve3(rawVaultRoot);
|
|
5531
5593
|
var policy = parseWritePolicy(process.env);
|
|
5532
5594
|
if (policy.readOnly) log.info("read-only mode", { env: "SEEKSTONE_READ_ONLY" });
|
|
5533
5595
|
if (policy.writeGlobs) log.info("write paths scoped", { globs: policy.writeGlobs });
|
|
@@ -5579,7 +5641,11 @@ if (semanticCfg) {
|
|
|
5579
5641
|
}
|
|
5580
5642
|
var watcher = startWatcher(ctx, log);
|
|
5581
5643
|
process.on("exit", () => void watcher.stop());
|
|
5582
|
-
var
|
|
5644
|
+
var instructions = resolveInstructions(process.env, vaultRoot, log);
|
|
5645
|
+
var server = new Server(
|
|
5646
|
+
{ name: "seekstone", version: VERSION },
|
|
5647
|
+
{ capabilities: { tools: {} }, instructions }
|
|
5648
|
+
);
|
|
5583
5649
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
5584
5650
|
tools: visibleTools(ctx.policy)
|
|
5585
5651
|
}));
|