@vheins/local-memory-mcp 0.8.48 → 0.9.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.
@@ -3,8 +3,8 @@ import { fileURLToPath } from "url";
3
3
  import path from "path";
4
4
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
5
5
  var pkgVersion = "0.1.0";
6
- if ("0.8.48") {
7
- pkgVersion = "0.8.48";
6
+ if ("0.9.1") {
7
+ pkgVersion = "0.9.1";
8
8
  } else {
9
9
  let searchDir = __dirname;
10
10
  for (let i = 0; i < 5; i++) {
@@ -309,6 +309,7 @@ var MigrationManager = class {
309
309
  id TEXT PRIMARY KEY,
310
310
  title TEXT NOT NULL,
311
311
  content TEXT NOT NULL,
312
+ parent_id TEXT,
312
313
  context TEXT,
313
314
  version TEXT,
314
315
  language TEXT,
@@ -319,13 +320,25 @@ var MigrationManager = class {
319
320
  metadata TEXT,
320
321
  created_at TEXT NOT NULL,
321
322
  updated_at TEXT NOT NULL,
323
+ hit_count INTEGER NOT NULL DEFAULT 0,
324
+ last_used_at TEXT,
322
325
  agent TEXT NOT NULL DEFAULT 'unknown',
323
- model TEXT NOT NULL DEFAULT 'unknown'
326
+ model TEXT NOT NULL DEFAULT 'unknown',
327
+ FOREIGN KEY (parent_id) REFERENCES coding_standards(id) ON DELETE SET NULL
324
328
  );
325
329
 
326
330
  CREATE INDEX IF NOT EXISTS idx_coding_standards_repo ON coding_standards(repo);
327
331
  CREATE INDEX IF NOT EXISTS idx_coding_standards_is_global ON coding_standards(is_global);
328
332
  CREATE INDEX IF NOT EXISTS idx_coding_standards_language ON coding_standards(language);
333
+ CREATE INDEX IF NOT EXISTS idx_coding_standards_hit_count ON coding_standards(hit_count);
334
+
335
+ CREATE TABLE IF NOT EXISTS standard_vectors (
336
+ standard_id TEXT PRIMARY KEY,
337
+ vector TEXT NOT NULL,
338
+ updated_at TEXT NOT NULL,
339
+ vector_version INTEGER NOT NULL DEFAULT 1,
340
+ FOREIGN KEY (standard_id) REFERENCES coding_standards(id) ON DELETE CASCADE
341
+ );
329
342
 
330
343
  CREATE TABLE IF NOT EXISTS memories_archive (
331
344
  id TEXT PRIMARY KEY,
@@ -434,6 +447,21 @@ var MigrationManager = class {
434
447
  table: "memory_vectors",
435
448
  definition: "ALTER TABLE memory_vectors ADD COLUMN vector_version INTEGER NOT NULL DEFAULT 1"
436
449
  },
450
+ {
451
+ name: "parent_id",
452
+ table: "coding_standards",
453
+ definition: "ALTER TABLE coding_standards ADD COLUMN parent_id TEXT"
454
+ },
455
+ {
456
+ name: "hit_count",
457
+ table: "coding_standards",
458
+ definition: "ALTER TABLE coding_standards ADD COLUMN hit_count INTEGER NOT NULL DEFAULT 0"
459
+ },
460
+ {
461
+ name: "last_used_at",
462
+ table: "coding_standards",
463
+ definition: "ALTER TABLE coding_standards ADD COLUMN last_used_at TEXT"
464
+ },
437
465
  { name: "depends_on", table: "tasks", definition: "ALTER TABLE tasks ADD COLUMN depends_on TEXT" },
438
466
  {
439
467
  name: "est_tokens",
@@ -2087,13 +2115,14 @@ var StandardEntity = class extends BaseEntity {
2087
2115
  insert(entry) {
2088
2116
  this.run(
2089
2117
  `INSERT INTO coding_standards (
2090
- id, title, content, context, version, language, stack,
2091
- is_global, repo, tags, metadata, created_at, updated_at, agent, model
2092
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2118
+ id, title, content, parent_id, context, version, language, stack,
2119
+ is_global, repo, tags, metadata, created_at, updated_at, hit_count, last_used_at, agent, model
2120
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2093
2121
  [
2094
2122
  entry.id,
2095
2123
  entry.title,
2096
2124
  entry.content,
2125
+ entry.parent_id,
2097
2126
  entry.context,
2098
2127
  entry.version,
2099
2128
  entry.language ?? null,
@@ -2104,6 +2133,8 @@ var StandardEntity = class extends BaseEntity {
2104
2133
  Object.keys(entry.metadata).length > 0 ? JSON.stringify(entry.metadata) : null,
2105
2134
  entry.created_at,
2106
2135
  entry.updated_at,
2136
+ entry.hit_count,
2137
+ entry.last_used_at,
2107
2138
  entry.agent,
2108
2139
  entry.model
2109
2140
  ]
@@ -2114,7 +2145,7 @@ var StandardEntity = class extends BaseEntity {
2114
2145
  return row ? this.rowToEntry(row) : null;
2115
2146
  }
2116
2147
  search(options) {
2117
- const { query, context, language, stack, repo, is_global, limit = 20, offset = 0 } = options;
2148
+ const { query, context, version, language, stack, tag, repo, is_global, limit = 20, offset = 0 } = options;
2118
2149
  const where = [];
2119
2150
  const params = [];
2120
2151
  if (query) {
@@ -2125,6 +2156,10 @@ var StandardEntity = class extends BaseEntity {
2125
2156
  where.push("context = ?");
2126
2157
  params.push(context);
2127
2158
  }
2159
+ if (version) {
2160
+ where.push("version = ?");
2161
+ params.push(version);
2162
+ }
2128
2163
  if (language) {
2129
2164
  where.push("language = ?");
2130
2165
  params.push(language);
@@ -2133,6 +2168,10 @@ var StandardEntity = class extends BaseEntity {
2133
2168
  where.push("stack LIKE ?");
2134
2169
  params.push(`%${stack}%`);
2135
2170
  }
2171
+ if (tag) {
2172
+ where.push("tags LIKE ?");
2173
+ params.push(`%${tag}%`);
2174
+ }
2136
2175
  if (repo !== void 0) {
2137
2176
  where.push("(repo = ? OR is_global = 1)");
2138
2177
  params.push(repo);
@@ -2147,6 +2186,43 @@ var StandardEntity = class extends BaseEntity {
2147
2186
  const rows = this.all(sql, params);
2148
2187
  return rows.map((r) => this.rowToEntry(r));
2149
2188
  }
2189
+ searchBySimilarity(query, options) {
2190
+ const candidates = this.search({
2191
+ context: options.context,
2192
+ version: options.version,
2193
+ language: options.language,
2194
+ stack: options.stack?.[0],
2195
+ tag: options.tags?.[0],
2196
+ repo: options.repo,
2197
+ is_global: options.is_global,
2198
+ limit: options.limit ?? 60,
2199
+ offset: options.offset ?? 0
2200
+ });
2201
+ const queryVector = this.computeVector(query);
2202
+ return candidates.map((standard) => {
2203
+ const haystack = [
2204
+ standard.title,
2205
+ standard.content,
2206
+ standard.context,
2207
+ standard.language ?? "",
2208
+ standard.version,
2209
+ ...standard.stack,
2210
+ ...standard.tags,
2211
+ JSON.stringify(standard.metadata)
2212
+ ].filter(Boolean).join(" ");
2213
+ const similarity = this.cosineSimilarity(queryVector, this.computeVector(haystack));
2214
+ return { ...standard, similarity };
2215
+ }).sort((a, b) => b.similarity - a.similarity);
2216
+ }
2217
+ getByIds(ids) {
2218
+ if (ids.length === 0) return [];
2219
+ const placeholders = ids.map(() => "?").join(",");
2220
+ const rows = this.all(
2221
+ `SELECT * FROM coding_standards WHERE id IN (${placeholders})`,
2222
+ ids
2223
+ );
2224
+ return rows.map((row) => this.rowToEntry(row));
2225
+ }
2150
2226
  update(id, updates) {
2151
2227
  const fields = [];
2152
2228
  const values = [];
@@ -2178,11 +2254,45 @@ var StandardEntity = class extends BaseEntity {
2178
2254
  delete(id) {
2179
2255
  this.run("DELETE FROM coding_standards WHERE id = ?", [id]);
2180
2256
  }
2257
+ incrementHitCounts(ids) {
2258
+ if (ids.length === 0) return;
2259
+ const placeholders = ids.map(() => "?").join(",");
2260
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2261
+ this.run(
2262
+ `UPDATE coding_standards
2263
+ SET hit_count = hit_count + 1,
2264
+ last_used_at = ?
2265
+ WHERE id IN (${placeholders})`,
2266
+ [now, ...ids]
2267
+ );
2268
+ }
2269
+ getVectorCandidates(repo, limit = 100) {
2270
+ let sql = `SELECT sv.standard_id, sv.vector
2271
+ FROM standard_vectors sv
2272
+ JOIN coding_standards cs ON cs.id = sv.standard_id`;
2273
+ const params = [];
2274
+ if (repo) {
2275
+ sql += " WHERE (cs.repo = ? OR cs.is_global = 1)";
2276
+ params.push(repo);
2277
+ }
2278
+ sql += " ORDER BY cs.updated_at DESC LIMIT ?";
2279
+ params.push(limit);
2280
+ return this.all(sql, params);
2281
+ }
2282
+ upsertVectorEmbedding(standardId, vector) {
2283
+ this.run(
2284
+ `INSERT INTO standard_vectors (standard_id, vector, updated_at)
2285
+ VALUES (?, ?, ?)
2286
+ ON CONFLICT(standard_id) DO UPDATE SET vector = excluded.vector, updated_at = excluded.updated_at`,
2287
+ [standardId, JSON.stringify(vector), (/* @__PURE__ */ new Date()).toISOString()]
2288
+ );
2289
+ }
2181
2290
  rowToEntry(row) {
2182
2291
  return {
2183
2292
  id: row.id,
2184
2293
  title: row.title,
2185
2294
  content: row.content,
2295
+ parent_id: row.parent_id ?? null,
2186
2296
  context: row.context,
2187
2297
  version: row.version,
2188
2298
  language: row.language ?? null,
@@ -2193,6 +2303,8 @@ var StandardEntity = class extends BaseEntity {
2193
2303
  metadata: this.safeJSONParse(row.metadata, {}),
2194
2304
  created_at: row.created_at,
2195
2305
  updated_at: row.updated_at,
2306
+ hit_count: row.hit_count ?? 0,
2307
+ last_used_at: row.last_used_at ?? null,
2196
2308
  agent: row.agent,
2197
2309
  model: row.model
2198
2310
  };
@@ -2577,6 +2689,82 @@ var SQLiteStore = class _SQLiteStore {
2577
2689
  }
2578
2690
  };
2579
2691
 
2692
+ // src/mcp/storage/vectors.ts
2693
+ import { pipeline, env } from "@xenova/transformers";
2694
+ if (process.env.MCP_SERVER === "true") {
2695
+ env.backends.onnx.logLevel = "error";
2696
+ }
2697
+ var RealVectorStore = class {
2698
+ db;
2699
+ extractor = null;
2700
+ modelName = "Xenova/all-MiniLM-L6-v2";
2701
+ constructor(db) {
2702
+ this.db = db;
2703
+ }
2704
+ /**
2705
+ * Triggers background loading of the vector model.
2706
+ * Useful for avoiding timeouts on the first search/upsert request.
2707
+ */
2708
+ async initialize() {
2709
+ await this.getExtractor();
2710
+ }
2711
+ async getExtractor() {
2712
+ if (!this.extractor) {
2713
+ this.extractor = await pipeline("feature-extraction", this.modelName);
2714
+ }
2715
+ return this.extractor;
2716
+ }
2717
+ cosineSimilarity(v1, v2) {
2718
+ let dotProduct = 0;
2719
+ let mag1 = 0;
2720
+ let mag2 = 0;
2721
+ for (let i = 0; i < v1.length; i++) {
2722
+ dotProduct += v1[i] * v2[i];
2723
+ mag1 += v1[i] * v1[i];
2724
+ mag2 += v2[i] * v2[i];
2725
+ }
2726
+ const mag = Math.sqrt(mag1) * Math.sqrt(mag2);
2727
+ return mag === 0 ? 0 : dotProduct / mag;
2728
+ }
2729
+ async upsert(id, text, kind = "memory") {
2730
+ try {
2731
+ const extractor = await this.getExtractor();
2732
+ const output = await extractor(text, { pooling: "mean", normalize: true });
2733
+ const vector = Array.from(output.data);
2734
+ if (kind === "standard") {
2735
+ this.db.standards.upsertVectorEmbedding(id, vector);
2736
+ } else {
2737
+ this.db.memories.upsertVectorEmbedding(id, vector);
2738
+ }
2739
+ } catch (error) {
2740
+ logger.error("[Vectors] Error during upsert", { id, kind, error: String(error) });
2741
+ throw error;
2742
+ }
2743
+ }
2744
+ async remove(id, _kind = "memory") {
2745
+ if (!id) return;
2746
+ }
2747
+ async search(query, limit, repo, kind = "memory") {
2748
+ try {
2749
+ const extractor = await this.getExtractor();
2750
+ const output = await extractor(query, { pooling: "mean", normalize: true });
2751
+ const queryVector = Array.from(output.data);
2752
+ const rows = kind === "standard" ? this.db.standards.getVectorCandidates(repo, 100).map((row) => ({ id: row.standard_id, vector: row.vector })) : this.db.memories.getVectorCandidates(repo, 100).map((row) => ({ id: row.memory_id, vector: row.vector }));
2753
+ const results = rows.map((row) => {
2754
+ const memoryVector = JSON.parse(row.vector);
2755
+ return {
2756
+ id: row.id,
2757
+ score: this.cosineSimilarity(queryVector, memoryVector)
2758
+ };
2759
+ });
2760
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
2761
+ } catch (error) {
2762
+ logger.error("[Vectors] Error during search", { kind, error: String(error) });
2763
+ return [];
2764
+ }
2765
+ }
2766
+ };
2767
+
2580
2768
  // src/mcp/session.ts
2581
2769
  import path4 from "path";
2582
2770
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -2889,6 +3077,18 @@ var MemoryDetailSchema = z.object({
2889
3077
  }).refine((data) => data.id !== void 0 || data.code !== void 0, {
2890
3078
  message: "Either id or code must be provided"
2891
3079
  });
3080
+ var StandardDetailSchema = z.object({
3081
+ id: z.string().uuid(),
3082
+ structured: z.boolean().default(false)
3083
+ });
3084
+ var StandardDeleteSchema = z.object({
3085
+ repo: z.string().min(1).transform(normalizeRepo).optional(),
3086
+ id: z.string().uuid().optional(),
3087
+ ids: z.array(z.string().uuid()).min(1).optional(),
3088
+ structured: z.boolean().default(false)
3089
+ }).refine((data) => data.id !== void 0 || data.ids !== void 0, {
3090
+ message: "Either 'id' or 'ids' must be provided for deletion"
3091
+ });
2892
3092
  var TaskGetSchema = z.object({
2893
3093
  repo: z.string().min(1).transform(normalizeRepo),
2894
3094
  id: z.string().uuid().optional(),
@@ -2943,24 +3143,53 @@ var TaskClaimSchema = z.object({
2943
3143
  var StandardStoreSchema = z.object({
2944
3144
  name: z.string().min(3).max(255),
2945
3145
  content: z.string().min(10),
3146
+ parent_id: z.string().uuid().optional(),
2946
3147
  context: z.string().optional(),
2947
3148
  version: z.string().optional(),
2948
3149
  language: z.string().optional(),
2949
3150
  stack: z.array(z.string()).optional(),
2950
- repo: z.string().optional(),
3151
+ repo: z.string().transform(normalizeRepo).optional(),
2951
3152
  is_global: z.boolean().optional(),
2952
- tags: z.array(z.string()).optional(),
2953
- metadata: z.record(z.string(), z.any()).optional(),
3153
+ tags: z.array(z.string().min(1)).min(1),
3154
+ metadata: z.record(z.string(), z.any()).refine((value) => Object.keys(value).length > 0, {
3155
+ message: "metadata must contain at least one key"
3156
+ }),
2954
3157
  agent: z.string().optional(),
2955
3158
  model: z.string().optional(),
2956
3159
  structured: z.boolean().default(false)
3160
+ }).refine((data) => data.is_global !== false || !!data.repo, {
3161
+ message: "repo is required for repo-specific standards"
3162
+ });
3163
+ var StandardUpdateSchema = z.object({
3164
+ id: z.string().uuid(),
3165
+ name: z.string().min(3).max(255).optional(),
3166
+ content: z.string().min(10).optional(),
3167
+ parent_id: z.string().uuid().nullable().optional(),
3168
+ context: z.string().optional(),
3169
+ version: z.string().optional(),
3170
+ language: z.string().optional(),
3171
+ stack: z.array(z.string().min(1)).min(1).optional(),
3172
+ repo: z.string().transform(normalizeRepo).optional(),
3173
+ is_global: z.boolean().optional(),
3174
+ tags: z.array(z.string().min(1)).min(1).optional(),
3175
+ metadata: z.record(z.string(), z.any()).refine((value) => Object.keys(value).length > 0, { message: "metadata must contain at least one key" }).optional(),
3176
+ agent: z.string().optional(),
3177
+ model: z.string().optional(),
3178
+ structured: z.boolean().default(false)
3179
+ }).refine(
3180
+ (data) => data.name !== void 0 || data.content !== void 0 || data.parent_id !== void 0 || data.context !== void 0 || data.version !== void 0 || data.language !== void 0 || data.stack !== void 0 || data.repo !== void 0 || data.is_global !== void 0 || data.tags !== void 0 || data.metadata !== void 0 || data.agent !== void 0 || data.model !== void 0,
3181
+ { message: "At least one field must be provided for update" }
3182
+ ).refine((data) => data.is_global !== false || !!data.repo, {
3183
+ message: "repo is required for repo-specific standards"
2957
3184
  });
2958
3185
  var StandardSearchSchema = z.object({
2959
3186
  query: z.string().optional(),
2960
3187
  stack: z.array(z.string()).optional(),
3188
+ tags: z.array(z.string()).optional(),
2961
3189
  language: z.string().optional(),
3190
+ context: z.string().optional(),
2962
3191
  version: z.string().optional(),
2963
- repo: z.string().optional(),
3192
+ repo: z.string().transform(normalizeRepo).optional(),
2964
3193
  is_global: z.boolean().optional(),
2965
3194
  limit: z.number().min(1).max(100).default(20),
2966
3195
  offset: z.number().min(0).default(0),
@@ -3070,6 +3299,19 @@ var TOOL_DEFINITIONS = [
3070
3299
  }
3071
3300
  }
3072
3301
  },
3302
+ {
3303
+ name: "standard-detail",
3304
+ title: "Standard Detail",
3305
+ description: "Fetch full details of a specific coding standard by ID. Use after standard-search when a result is relevant and full guidance is needed.",
3306
+ inputSchema: {
3307
+ type: "object",
3308
+ properties: {
3309
+ id: { type: "string", format: "uuid", description: "Coding standard ID." },
3310
+ structured: { type: "boolean", default: false, description: "If true, returns structured JSON details." }
3311
+ },
3312
+ required: ["id"]
3313
+ }
3314
+ },
3073
3315
  {
3074
3316
  name: "task-detail",
3075
3317
  title: "Task Detail",
@@ -3423,6 +3665,42 @@ var TOOL_DEFINITIONS = [
3423
3665
  required: ["success"]
3424
3666
  }
3425
3667
  },
3668
+ {
3669
+ name: "standard-delete",
3670
+ title: "Standard Delete",
3671
+ description: "Delete one or more coding standards. Supports single 'id' or bulk 'ids'.",
3672
+ annotations: {
3673
+ readOnlyHint: false,
3674
+ idempotentHint: false,
3675
+ destructiveHint: true,
3676
+ openWorldHint: false
3677
+ },
3678
+ inputSchema: {
3679
+ type: "object",
3680
+ properties: {
3681
+ repo: { type: "string", description: "Repository name (optional for single id)" },
3682
+ id: { type: "string", format: "uuid", description: "Coding standard ID to delete" },
3683
+ ids: {
3684
+ type: "array",
3685
+ items: { type: "string", format: "uuid" },
3686
+ minItems: 1,
3687
+ description: "Array of coding standard IDs to delete"
3688
+ },
3689
+ structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
3690
+ }
3691
+ },
3692
+ outputSchema: {
3693
+ type: "object",
3694
+ properties: {
3695
+ success: { type: "boolean" },
3696
+ id: { type: "string" },
3697
+ ids: { type: "array", items: { type: "string" } },
3698
+ repo: { type: "string" },
3699
+ deletedCount: { type: "number" }
3700
+ },
3701
+ required: ["success"]
3702
+ }
3703
+ },
3426
3704
  {
3427
3705
  name: "memory-recap",
3428
3706
  title: "Memory Recap",
@@ -3931,6 +4209,7 @@ var TOOL_DEFINITIONS = [
3931
4209
  properties: {
3932
4210
  name: { type: "string", minLength: 3, maxLength: 255, description: "Human-readable standard name" },
3933
4211
  content: { type: "string", minLength: 10, description: "One atomic, actionable standard written as concise Markdown" },
4212
+ parent_id: { type: "string", format: "uuid", description: "Optional parent standard ID when this rule is a child/specialization." },
3934
4213
  context: { type: "string", description: "Context or category (e.g., 'error-handling', 'security')" },
3935
4214
  version: { type: "string", description: "Version of the standard (e.g., '1.0.0')" },
3936
4215
  language: { type: "string", description: "Programming language (e.g., 'typescript', 'python')" },
@@ -3954,7 +4233,7 @@ var TOOL_DEFINITIONS = [
3954
4233
  model: { type: "string", description: "AI model used" },
3955
4234
  structured: { type: "boolean", default: false }
3956
4235
  },
3957
- required: ["name", "content"]
4236
+ required: ["name", "content", "tags", "metadata"]
3958
4237
  },
3959
4238
  outputSchema: {
3960
4239
  type: "object",
@@ -3966,6 +4245,7 @@ var TOOL_DEFINITIONS = [
3966
4245
  id: { type: "string" },
3967
4246
  title: { type: "string" },
3968
4247
  content: { type: "string" },
4248
+ parent_id: { type: "string", nullable: true },
3969
4249
  context: { type: "string" },
3970
4250
  version: { type: "string" },
3971
4251
  language: { type: "string", nullable: true },
@@ -3983,6 +4263,7 @@ var TOOL_DEFINITIONS = [
3983
4263
  "id",
3984
4264
  "title",
3985
4265
  "content",
4266
+ "parent_id",
3986
4267
  "context",
3987
4268
  "version",
3988
4269
  "stack",
@@ -4000,10 +4281,51 @@ var TOOL_DEFINITIONS = [
4000
4281
  required: ["success", "standard", "message"]
4001
4282
  }
4002
4283
  },
4284
+ {
4285
+ name: "standard-update",
4286
+ title: "Standard Update",
4287
+ description: "Update an existing coding standard. Use this when the rule changes, expands scope, or metadata/tags need correction.",
4288
+ annotations: {
4289
+ readOnlyHint: false,
4290
+ idempotentHint: false,
4291
+ destructiveHint: false,
4292
+ openWorldHint: false
4293
+ },
4294
+ inputSchema: {
4295
+ type: "object",
4296
+ properties: {
4297
+ id: { type: "string", description: "Standard ID to update" },
4298
+ name: { type: "string", minLength: 3, maxLength: 255 },
4299
+ content: { type: "string", minLength: 10 },
4300
+ parent_id: { type: "string", format: "uuid", nullable: true },
4301
+ context: { type: "string" },
4302
+ version: { type: "string" },
4303
+ language: { type: "string" },
4304
+ stack: { type: "array", items: { type: "string" } },
4305
+ repo: { type: "string" },
4306
+ is_global: { type: "boolean" },
4307
+ tags: { type: "array", items: { type: "string" } },
4308
+ metadata: { type: "object" },
4309
+ agent: { type: "string" },
4310
+ model: { type: "string" },
4311
+ structured: { type: "boolean", default: false }
4312
+ },
4313
+ required: ["id"]
4314
+ },
4315
+ outputSchema: {
4316
+ type: "object",
4317
+ properties: {
4318
+ success: { type: "boolean" },
4319
+ id: { type: "string" },
4320
+ updatedFields: { type: "array", items: { type: "string" } }
4321
+ },
4322
+ required: ["success", "id", "updatedFields"]
4323
+ }
4324
+ },
4003
4325
  {
4004
4326
  name: "standard-search",
4005
4327
  title: "Standard Search",
4006
- description: "Navigation and lookup layer for coding standards. Query by text, stack, language, version, repo, and global scope before applying or creating standards.",
4328
+ description: "NAVIGATION LAYER: Returns a compact pointer table of matching coding standards. Use `standard-detail` to fetch full content for a selected result.",
4007
4329
  annotations: {
4008
4330
  readOnlyHint: true,
4009
4331
  idempotentHint: true,
@@ -4018,7 +4340,13 @@ var TOOL_DEFINITIONS = [
4018
4340
  items: { type: "string" },
4019
4341
  description: "Technology stack to filter by (e.g., ['react', 'nextjs'])"
4020
4342
  },
4343
+ tags: {
4344
+ type: "array",
4345
+ items: { type: "string" },
4346
+ description: "Tag filter"
4347
+ },
4021
4348
  language: { type: "string", description: "Programming language filter" },
4349
+ context: { type: "string", description: "Context/category filter" },
4022
4350
  version: { type: "string", description: "Version filter" },
4023
4351
  repo: { type: "string", description: "Repository filter (optional)" },
4024
4352
  is_global: { type: "boolean", description: "Filter by global/repo-specific" },
@@ -4031,35 +4359,29 @@ var TOOL_DEFINITIONS = [
4031
4359
  outputSchema: {
4032
4360
  type: "object",
4033
4361
  properties: {
4034
- success: { type: "boolean" },
4035
- standards: {
4036
- type: "array",
4037
- items: {
4038
- type: "object",
4039
- properties: {
4040
- id: { type: "string" },
4041
- title: { type: "string" },
4042
- content: { type: "string" },
4043
- context: { type: "string" },
4044
- version: { type: "string" },
4045
- language: { type: "string", nullable: true },
4046
- stack: { type: "array", items: { type: "string" } },
4047
- is_global: { type: "boolean" },
4048
- repo: { type: "string", nullable: true },
4049
- tags: { type: "array", items: { type: "string" } },
4050
- metadata: { type: "object" },
4051
- created_at: { type: "string" },
4052
- updated_at: { type: "string" },
4053
- agent: { type: "string" },
4054
- model: { type: "string" }
4362
+ schema: { type: "string", enum: ["standard-search"] },
4363
+ query: { type: "string" },
4364
+ count: { type: "number", description: "Number of rows returned" },
4365
+ total: { type: "number", description: "Total number of matches before pagination" },
4366
+ offset: { type: "number" },
4367
+ limit: { type: "number" },
4368
+ results: {
4369
+ type: "object",
4370
+ properties: {
4371
+ columns: {
4372
+ type: "array",
4373
+ items: { type: "string" }
4374
+ },
4375
+ rows: {
4376
+ type: "array",
4377
+ items: { type: "array" },
4378
+ description: "Each row includes standard id and pointer metadata. Fetch full content via standard-detail."
4055
4379
  }
4056
4380
  },
4057
- description: "Matching coding standards"
4058
- },
4059
- count: { type: "number", description: "Number of results returned" },
4060
- message: { type: "string" }
4381
+ required: ["columns", "rows"]
4382
+ }
4061
4383
  },
4062
- required: ["success", "standards", "count", "message"]
4384
+ required: ["schema", "query", "count", "total", "offset", "limit", "results"]
4063
4385
  }
4064
4386
  }
4065
4387
  ];
@@ -4630,6 +4952,20 @@ async function completePromptArgument(name, argName, value, contextArguments, da
4630
4952
  return [];
4631
4953
  }
4632
4954
 
4955
+ // src/mcp/tools/standard.shared.ts
4956
+ function buildStandardVectorText(standard) {
4957
+ return [
4958
+ standard.title,
4959
+ standard.content,
4960
+ standard.context,
4961
+ standard.version,
4962
+ standard.language ?? "",
4963
+ ...standard.stack,
4964
+ ...standard.tags,
4965
+ JSON.stringify(standard.metadata)
4966
+ ].filter(Boolean).join("\n");
4967
+ }
4968
+
4633
4969
  export {
4634
4970
  MCP_PROTOCOL_VERSION,
4635
4971
  CAPABILITIES,
@@ -4641,6 +4977,7 @@ export {
4641
4977
  createFileSink,
4642
4978
  normalizeRepo,
4643
4979
  SQLiteStore,
4980
+ RealVectorStore,
4644
4981
  MemoryStoreSchema,
4645
4982
  MemoryUpdateSchema,
4646
4983
  MemorySearchSchema,
@@ -4655,12 +4992,15 @@ export {
4655
4992
  TaskListSchema,
4656
4993
  TaskDeleteSchema,
4657
4994
  MemoryDetailSchema,
4995
+ StandardDetailSchema,
4996
+ StandardDeleteSchema,
4658
4997
  TaskGetSchema,
4659
4998
  HandoffCreateSchema,
4660
4999
  HandoffUpdateSchema,
4661
5000
  HandoffListSchema,
4662
5001
  TaskClaimSchema,
4663
5002
  StandardStoreSchema,
5003
+ StandardUpdateSchema,
4664
5004
  StandardSearchSchema,
4665
5005
  TOOL_DEFINITIONS,
4666
5006
  encodeCursor,
@@ -4680,5 +5020,6 @@ export {
4680
5020
  PROMPTS,
4681
5021
  listPrompts,
4682
5022
  getPrompt,
4683
- completePromptArgument
5023
+ completePromptArgument,
5024
+ buildStandardVectorText
4684
5025
  };