knit-mcp 0.7.0 → 0.8.0

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.
@@ -1,17 +1,23 @@
1
1
  import {
2
+ KNIT_MARKER_END,
3
+ KNIT_MARKER_START,
4
+ LEGACY_ENGRAM_MARKER_END,
5
+ LEGACY_ENGRAM_MARKER_START,
2
6
  VOLTAGENT_PINNED_SHA,
3
7
  VOLTAGENT_REF,
4
8
  categoryOf,
5
9
  isBundledCore,
6
10
  knownAgents,
7
11
  rawAgentUrl
8
- } from "./chunk-7PPC6IG6.js";
12
+ } from "./chunk-JJ367RK5.js";
9
13
  import {
10
14
  agentsCacheFile,
15
+ integrationsConfigPath,
11
16
  projectAgentFile,
12
17
  projectAgentsDir,
18
+ projectDataDir,
13
19
  sessionsJsonlPath
14
- } from "./chunk-HBMF62U4.js";
20
+ } from "./chunk-SBJMHDBM.js";
15
21
 
16
22
  // src/engine/install-agents.ts
17
23
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
@@ -285,8 +291,242 @@ function agentsNeededByProject(config) {
285
291
  return Array.from(names);
286
292
  }
287
293
 
294
+ // src/mcp/update-check.ts
295
+ var REGISTRY_DIST_TAGS_URL = "https://registry.npmjs.org/-/package/knit-mcp/dist-tags";
296
+ var FETCH_TIMEOUT_MS = 2e3;
297
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
298
+ var cachedLatest = null;
299
+ var lastCheckedAt = 0;
300
+ var inFlight = null;
301
+ function getCachedLatestVersion() {
302
+ if (Date.now() - lastCheckedAt > CACHE_TTL_MS) {
303
+ prewarmLatestVersion();
304
+ }
305
+ return cachedLatest;
306
+ }
307
+ function prewarmLatestVersion() {
308
+ if (inFlight) return;
309
+ if (Date.now() - lastCheckedAt < CACHE_TTL_MS && cachedLatest !== null) return;
310
+ inFlight = doFetch().finally(() => {
311
+ inFlight = null;
312
+ });
313
+ }
314
+ async function doFetch() {
315
+ const controller = new AbortController();
316
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
317
+ try {
318
+ const res = await fetch(REGISTRY_DIST_TAGS_URL, { signal: controller.signal });
319
+ if (!res.ok) return;
320
+ const data = await res.json();
321
+ if (typeof data.latest === "string" && data.latest.length > 0) {
322
+ cachedLatest = data.latest;
323
+ lastCheckedAt = Date.now();
324
+ }
325
+ } catch {
326
+ } finally {
327
+ clearTimeout(timeout);
328
+ }
329
+ }
330
+ function isNewerVersion(latest, current) {
331
+ const parse = (v) => {
332
+ const stripped = v.replace(/[-+].*$/, "");
333
+ const parts = stripped.split(".").map((n) => parseInt(n, 10) || 0);
334
+ return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
335
+ };
336
+ const [a1, a2, a3] = parse(latest);
337
+ const [b1, b2, b3] = parse(current);
338
+ if (a1 !== b1) return a1 > b1;
339
+ if (a2 !== b2) return a2 > b2;
340
+ return a3 > b3;
341
+ }
342
+
343
+ // src/engine/integration-scanner.ts
344
+ import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync, statSync, writeFileSync as writeFileSync3, renameSync, unlinkSync } from "fs";
345
+ import { homedir as osHomedir } from "os";
346
+ import { join as join2 } from "path";
347
+ var homedir = () => osHomedir();
348
+ function scanIntegrations(rootPath, opts) {
349
+ const home = homedir();
350
+ void projectDataDir;
351
+ const ruflo = detectRuflo(rootPath, home);
352
+ const gstack = detectGstack(rootPath, home);
353
+ const codetour = detectCodeTour(rootPath);
354
+ const conductor = detectConductor(home);
355
+ const otherMcp = detectOtherMcpServers(home);
356
+ const customWorkflowSections = detectCustomWorkflowSections(rootPath);
357
+ const summary = buildSummary({ ruflo, gstack, codetour, conductor, otherMcp, customWorkflowSections });
358
+ return {
359
+ scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
360
+ knitVersion: opts?.knitVersion,
361
+ detected: {
362
+ ruflo,
363
+ gstack,
364
+ codetour,
365
+ conductor,
366
+ other_mcp_servers: otherMcp,
367
+ custom_workflow_sections: customWorkflowSections
368
+ },
369
+ summary
370
+ };
371
+ }
372
+ function persistScanResult(rootPath, result) {
373
+ const path = integrationsConfigPath(rootPath);
374
+ const tmpPath = `${path}.tmp-${process.pid}-${Date.now()}`;
375
+ try {
376
+ writeFileSync3(tmpPath, JSON.stringify(result, null, 2), "utf-8");
377
+ renameSync(tmpPath, path);
378
+ } catch (err) {
379
+ try {
380
+ unlinkSync(tmpPath);
381
+ } catch {
382
+ }
383
+ throw err;
384
+ }
385
+ }
386
+ function loadScanResult(rootPath) {
387
+ const path = integrationsConfigPath(rootPath);
388
+ if (!existsSync3(path)) return null;
389
+ try {
390
+ const data = JSON.parse(readFileSync3(path, "utf-8"));
391
+ if (typeof data?.scannedAt !== "string" || !data?.detected) return null;
392
+ return data;
393
+ } catch {
394
+ return null;
395
+ }
396
+ }
397
+ function safeExists(p) {
398
+ try {
399
+ return existsSync3(p);
400
+ } catch {
401
+ return false;
402
+ }
403
+ }
404
+ function safeIsDir(p) {
405
+ try {
406
+ return statSync(p).isDirectory();
407
+ } catch {
408
+ return false;
409
+ }
410
+ }
411
+ function readClaudeConfigSafely(home) {
412
+ const claudeJson = join2(home, ".claude.json");
413
+ if (!safeExists(claudeJson)) return null;
414
+ try {
415
+ return JSON.parse(readFileSync3(claudeJson, "utf-8"));
416
+ } catch {
417
+ return null;
418
+ }
419
+ }
420
+ function detectRuflo(rootPath, home) {
421
+ const via = [];
422
+ if (safeExists(join2(home, ".ruflo")) && safeIsDir(join2(home, ".ruflo"))) via.push("home-dir");
423
+ if (safeExists(join2(home, ".claude-flow")) && safeIsDir(join2(home, ".claude-flow"))) via.push("claude-flow-dir");
424
+ if (safeExists(join2(rootPath, ".claude-flow")) && safeIsDir(join2(rootPath, ".claude-flow"))) via.push("project-claude-flow-dir");
425
+ const claudeConfig = readClaudeConfigSafely(home);
426
+ const mcpServers = claudeConfig?.mcpServers ?? {};
427
+ if ("ruflo" in mcpServers || "claude-flow" in mcpServers) via.push("mcp-server");
428
+ try {
429
+ const pkgPath = join2(rootPath, "package.json");
430
+ if (safeExists(pkgPath)) {
431
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
432
+ const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
433
+ if (deps.ruflo || deps["claude-flow"]) via.push("npm-dep");
434
+ }
435
+ } catch {
436
+ }
437
+ return { present: via.length > 0, via };
438
+ }
439
+ function detectGstack(rootPath, home) {
440
+ const via = [];
441
+ if (safeExists(join2(home, ".gstack")) && safeIsDir(join2(home, ".gstack"))) via.push("home-dir");
442
+ const skillsDir = join2(home, ".claude", "skills");
443
+ if (safeExists(skillsDir) && safeIsDir(skillsDir)) {
444
+ try {
445
+ const skills = readdirSync(skillsDir);
446
+ if (skills.some((s) => s === "gstack" || s.startsWith("gstack-"))) {
447
+ via.push("skills-dir");
448
+ }
449
+ } catch {
450
+ }
451
+ }
452
+ if (safeExists(join2(rootPath, ".gstack")) && safeIsDir(join2(rootPath, ".gstack"))) via.push("project-dir");
453
+ return { present: via.length > 0, via };
454
+ }
455
+ function detectCodeTour(rootPath) {
456
+ const via = [];
457
+ const files = [];
458
+ const toursDir = join2(rootPath, ".tours");
459
+ if (safeExists(toursDir) && safeIsDir(toursDir)) {
460
+ via.push("dot-tours-dir");
461
+ try {
462
+ for (const f of readdirSync(toursDir)) {
463
+ if (f.endsWith(".tour")) files.push(`.tours/${f}`);
464
+ }
465
+ } catch {
466
+ }
467
+ }
468
+ return { present: via.length > 0, via, ...files.length > 0 ? { files } : {} };
469
+ }
470
+ function detectConductor(home) {
471
+ const via = [];
472
+ if (safeExists(join2(home, ".conductor")) && safeIsDir(join2(home, ".conductor"))) via.push("home-dir");
473
+ return { present: via.length > 0, via };
474
+ }
475
+ function detectOtherMcpServers(home) {
476
+ const config = readClaudeConfigSafely(home);
477
+ const mcpServers = config?.mcpServers ?? {};
478
+ const names = Object.keys(mcpServers).filter((n) => n !== "knit-brain" && n !== "engram-brain");
479
+ return names.sort();
480
+ }
481
+ function detectCustomWorkflowSections(rootPath) {
482
+ const claudeMd = join2(rootPath, "CLAUDE.md");
483
+ if (!safeExists(claudeMd)) return [];
484
+ let content;
485
+ try {
486
+ content = readFileSync3(claudeMd, "utf-8");
487
+ } catch {
488
+ return [];
489
+ }
490
+ for (const [startMarker, endMarker] of [
491
+ [KNIT_MARKER_START, KNIT_MARKER_END],
492
+ [LEGACY_ENGRAM_MARKER_START, LEGACY_ENGRAM_MARKER_END]
493
+ ]) {
494
+ const startIdx = content.indexOf(startMarker);
495
+ const endIdx = content.indexOf(endMarker);
496
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
497
+ content = content.slice(0, startIdx) + content.slice(endIdx + endMarker.length);
498
+ }
499
+ }
500
+ const patterns = [
501
+ /^##\s+(?:Engineering|Development|Dev)\s+Workflow\b/im,
502
+ /^##\s+Workflow\s*$/im,
503
+ /^##\s+Process\b/im,
504
+ /^##\s+Methodology\b/im,
505
+ /^##\s+How\s+we\s+ship\b/im
506
+ ];
507
+ const found = [];
508
+ for (const re of patterns) {
509
+ const match = content.match(re);
510
+ if (match) found.push(match[0].replace(/^##\s+/, "").trim());
511
+ }
512
+ return found;
513
+ }
514
+ function buildSummary(parts) {
515
+ const labels = [];
516
+ if (parts.ruflo.present) labels.push(`Ruflo (${parts.ruflo.via.join(", ")})`);
517
+ if (parts.gstack.present) labels.push(`gstack (${parts.gstack.via.join(", ")})`);
518
+ if (parts.codetour.present) labels.push(`CodeTour (${parts.codetour.via.join(", ")})`);
519
+ if (parts.conductor.present) labels.push(`Conductor (${parts.conductor.via.join(", ")})`);
520
+ if (parts.otherMcp.length > 0) labels.push(`other MCP servers: ${parts.otherMcp.join(", ")}`);
521
+ if (parts.customWorkflowSections.length > 0) labels.push(`custom workflow sections in CLAUDE.md (${parts.customWorkflowSections.join("; ")})`);
522
+ if (labels.length === 0) {
523
+ return "No existing workflow frameworks detected. Knit operates in full-protocol mode.";
524
+ }
525
+ return `Detected: ${labels.join("; ")}. v0.7.2 surfaces this for awareness; v0.8 will tailor Knit's server instructions to defer routing decisions to these where they overlap (memory + classification stay Knit's domain).`;
526
+ }
527
+
288
528
  // src/engine/sessions.ts
289
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, appendFileSync, readFileSync as readFileSync3, statSync, writeFileSync as writeFileSync3, renameSync } from "fs";
529
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, appendFileSync, readFileSync as readFileSync4, statSync as statSync2, writeFileSync as writeFileSync4, renameSync as renameSync2 } from "fs";
290
530
  import { dirname as dirname2 } from "path";
291
531
  function appendSession(rootPath, entry) {
292
532
  const path = sessionsJsonlPath(rootPath);
@@ -327,9 +567,18 @@ function getRecentSessions(rootPath, n = 3) {
327
567
  function sessionCount(rootPath) {
328
568
  return readAllLines(rootPath).length;
329
569
  }
570
+ function loadAllSessions(rootPath) {
571
+ const lines = readAllLines(rootPath);
572
+ const out = [];
573
+ for (const line of lines) {
574
+ const entry = parseLine(line);
575
+ if (entry) out.push(entry);
576
+ }
577
+ return out;
578
+ }
330
579
  function pruneSessionsByAge(rootPath, maxAgeDays) {
331
580
  const path = sessionsJsonlPath(rootPath);
332
- if (!existsSync3(path)) return { kept: 0, pruned: 0 };
581
+ if (!existsSync4(path)) return { kept: 0, pruned: 0 };
333
582
  const lines = readAllLines(rootPath);
334
583
  if (lines.length === 0) return { kept: 0, pruned: 0 };
335
584
  const cutoffMs = Date.now() - maxAgeDays * 864e5;
@@ -358,18 +607,18 @@ function pruneSessionsByAge(rootPath, maxAgeDays) {
358
607
  const tmpPath = `${path}.tmp-${process.pid}-${Date.now()}`;
359
608
  const body = keptLines.length === 0 ? "" : keptLines.join("\n") + "\n";
360
609
  mkdirSync3(dirname2(path), { recursive: true });
361
- writeFileSync3(tmpPath, body, "utf-8");
362
- renameSync(tmpPath, path);
610
+ writeFileSync4(tmpPath, body, "utf-8");
611
+ renameSync2(tmpPath, path);
363
612
  return { kept: keptLines.length, pruned };
364
613
  }
365
614
  function readAllLines(rootPath) {
366
615
  const path = sessionsJsonlPath(rootPath);
367
- if (!existsSync3(path)) return [];
616
+ if (!existsSync4(path)) return [];
368
617
  try {
369
- const stat = statSync(path);
618
+ const stat = statSync2(path);
370
619
  if (stat.size === 0) return [];
371
620
  if (stat.size > 100 * 1024 * 1024) return [];
372
- return readFileSync3(path, "utf-8").split("\n").filter(Boolean);
621
+ return readFileSync4(path, "utf-8").split("\n").filter(Boolean);
373
622
  } catch {
374
623
  return [];
375
624
  }
@@ -400,9 +649,16 @@ function parseLine(line) {
400
649
 
401
650
  export {
402
651
  installAgentsForProject,
652
+ getCachedLatestVersion,
653
+ prewarmLatestVersion,
654
+ isNewerVersion,
655
+ scanIntegrations,
656
+ persistScanResult,
657
+ loadScanResult,
403
658
  appendSession,
404
659
  searchSessions,
405
660
  getRecentSessions,
406
661
  sessionCount,
662
+ loadAllSessions,
407
663
  pruneSessionsByAge
408
664
  };
@@ -90,6 +90,9 @@ function sessionMarkerPath(rootPath) {
90
90
  function featuresConfigPath(rootPath) {
91
91
  return join2(projectDataDir(rootPath), "features.json");
92
92
  }
93
+ function integrationsConfigPath(rootPath) {
94
+ return join2(projectDataDir(rootPath), "integrations.json");
95
+ }
93
96
  function learningsDir(rootPath) {
94
97
  return join2(projectDataDir(rootPath), "learnings");
95
98
  }
@@ -137,6 +140,7 @@ export {
137
140
  classificationMarkerPath,
138
141
  sessionMarkerPath,
139
142
  featuresConfigPath,
143
+ integrationsConfigPath,
140
144
  learningsDir,
141
145
  learningsFilePath,
142
146
  sessionsLogPath,
@@ -2,7 +2,7 @@ import {
2
2
  canonicalRepoRoot,
3
3
  globalLearningsPath,
4
4
  projectId
5
- } from "./chunk-HBMF62U4.js";
5
+ } from "./chunk-SBJMHDBM.js";
6
6
 
7
7
  // src/engine/global-learnings.ts
8
8
  import { existsSync, mkdirSync, appendFileSync, readFileSync, statSync } from "fs";
@@ -44,6 +44,15 @@ function getRecentGlobalLearnings(n = 5) {
44
44
  }
45
45
  return out;
46
46
  }
47
+ function loadAllGlobalLearnings() {
48
+ const lines = readAllLines();
49
+ const out = [];
50
+ for (const line of lines) {
51
+ const entry = parseLine(line);
52
+ if (entry) out.push(entry);
53
+ }
54
+ return out;
55
+ }
47
56
  function buildGlobalLearning(sourceProjectRoot, payload) {
48
57
  return {
49
58
  id: payload.id ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
@@ -83,5 +92,6 @@ export {
83
92
  appendGlobalLearning,
84
93
  searchGlobalLearnings,
85
94
  getRecentGlobalLearnings,
95
+ loadAllGlobalLearnings,
86
96
  buildGlobalLearning
87
97
  };
@@ -0,0 +1,9 @@
1
+ // src/version.ts
2
+ import { createRequire } from "module";
3
+ var require2 = createRequire(import.meta.url);
4
+ var pkg = require2("../package.json");
5
+ var VERSION = pkg.version;
6
+
7
+ export {
8
+ VERSION
9
+ };
@@ -0,0 +1,25 @@
1
+ // src/mcp/notifier.ts
2
+ var notifierImpl = null;
3
+ function registerToolsListChangedNotifier(fn) {
4
+ notifierImpl = fn;
5
+ }
6
+ function notifyToolsListChanged() {
7
+ if (!notifierImpl) return;
8
+ try {
9
+ const result = notifierImpl();
10
+ if (result && typeof result.then === "function") {
11
+ result.catch(() => {
12
+ });
13
+ }
14
+ } catch {
15
+ }
16
+ }
17
+ function __resetNotifierForTests() {
18
+ notifierImpl = null;
19
+ }
20
+
21
+ export {
22
+ registerToolsListChangedNotifier,
23
+ notifyToolsListChanged,
24
+ __resetNotifierForTests
25
+ };
@@ -1,20 +1,23 @@
1
1
  import {
2
- KNIT_MARKER_START,
2
+ installAgentsForProject,
3
+ persistScanResult,
4
+ prewarmLatestVersion,
5
+ pruneSessionsByAge,
6
+ scanIntegrations
7
+ } from "./chunk-N7R4P42P.js";
8
+ import {
3
9
  buildKnowledge,
4
- buildReverseDependencies,
10
+ buildReverseDependencies
11
+ } from "./chunk-MOOVNMIN.js";
12
+ import {
13
+ KNIT_MARKER_START,
5
14
  generateClaudeMd,
15
+ scanProject,
6
16
  spliceKnitBlock
7
- } from "./chunk-SLN5ABF5.js";
17
+ } from "./chunk-JJ367RK5.js";
8
18
  import {
9
19
  readLearnings
10
20
  } from "./chunk-M3YZOJNW.js";
11
- import {
12
- installAgentsForProject,
13
- pruneSessionsByAge
14
- } from "./chunk-3XR77YJM.js";
15
- import {
16
- scanProject
17
- } from "./chunk-7PPC6IG6.js";
18
21
  import {
19
22
  importFromMarkdown,
20
23
  loadKnowledgeBase,
@@ -38,7 +41,7 @@ import {
38
41
  sessionsJsonlPath,
39
42
  sessionsLogPath,
40
43
  teamsPath
41
- } from "./chunk-HBMF62U4.js";
44
+ } from "./chunk-SBJMHDBM.js";
42
45
 
43
46
  // src/mcp/cache.ts
44
47
  import { execSync } from "child_process";
@@ -497,6 +500,7 @@ function getBrain(rootPath) {
497
500
  if (cache && cache.rootPath === rootPath) {
498
501
  return cache;
499
502
  }
503
+ void prewarmLatestVersion();
500
504
  let autoInitialized = false;
501
505
  const haveCentralized = existsSync(knowledgePath(rootPath));
502
506
  const haveLegacy = existsSync(legacyKnowledgePath(rootPath));
@@ -563,6 +567,16 @@ function autoInitialize(rootPath) {
563
567
  } catch (e) {
564
568
  const msg = e instanceof Error ? e.message : String(e);
565
569
  process.stderr.write(`[knit] session prune background error: ${msg}
570
+ `);
571
+ }
572
+ });
573
+ Promise.resolve().then(() => {
574
+ try {
575
+ const result = scanIntegrations(rootPath);
576
+ persistScanResult(rootPath, result);
577
+ } catch (e) {
578
+ const msg = e instanceof Error ? e.message : String(e);
579
+ process.stderr.write(`[knit] integration scan background error: ${msg}
566
580
  `);
567
581
  }
568
582
  });
package/dist/cli.js CHANGED
@@ -1,15 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ VERSION
4
+ } from "./chunk-UTVFELXS.js";
2
5
 
3
6
  // src/cli.ts
4
7
  import { Command } from "commander";
5
-
6
- // src/version.ts
7
- import { createRequire } from "module";
8
- var require2 = createRequire(import.meta.url);
9
- var pkg = require2("../package.json");
10
- var VERSION = pkg.version;
11
-
12
- // src/cli.ts
13
8
  var args = process.argv.slice(2);
14
9
  var hasSubcommand = args.length > 0 && ["setup", "status", "refresh", "install-agents", "export", "--help", "-h", "--version", "-V"].includes(args[0]);
15
10
  var isTTY = process.stdin.isTTY;
@@ -25,10 +20,10 @@ async function runCLI() {
25
20
  const gradient = (await import("gradient-string")).default;
26
21
  const chalk = (await import("chalk")).default;
27
22
  const { setupCommand } = await import("./setup-5TUUWLIJ.js");
28
- const { statusCommand } = await import("./status-XN6VHO66.js");
29
- const { refreshCommand } = await import("./refresh-MSN5YNPS.js");
30
- const { installAgentsCommand } = await import("./install-agents-AXT6DMYM.js");
31
- const { exportCommand } = await import("./export-IKPBLZOO.js");
23
+ const { statusCommand } = await import("./status-YK2KBG57.js");
24
+ const { refreshCommand } = await import("./refresh-N4O2QLYS.js");
25
+ const { installAgentsCommand } = await import("./install-agents-DLSH3FNC.js");
26
+ const { exportCommand } = await import("./export-KALLYKWG.js");
32
27
  const ENGRAM_GRADIENT = gradient(["#7c3aed", "#2563eb", "#06b6d4"]);
33
28
  const banner = `
34
29
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
@@ -94,14 +89,22 @@ async function runMCP() {
94
89
  const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
95
90
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
96
91
  const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
97
- const { getBrain, detectProjectRoot, refreshBrain } = await import("./cache-WGZ2C7BZ.js");
98
- const { getActiveToolDefinitionsForBrain, handleToolCall } = await import("./tools-KRPOUYNT.js");
99
- const { KNIT_INSTRUCTIONS } = await import("./instructions-33TUHLTK.js");
92
+ const { getBrain, detectProjectRoot, refreshBrain } = await import("./cache-RRKF2IZ5.js");
93
+ const { getActiveToolDefinitionsForBrain, handleToolCall } = await import("./tools-GN6GM55U.js");
94
+ const { KNIT_INSTRUCTIONS } = await import("./instructions-YPXOZZHI.js");
95
+ const { registerToolsListChangedNotifier } = await import("./notifier-4L27HKHI.js");
100
96
  const ROOT_PATH = detectProjectRoot();
101
97
  const server = new Server(
102
98
  { name: "knit-brain", version: VERSION },
103
- { capabilities: { tools: {} }, instructions: KNIT_INSTRUCTIONS }
99
+ {
100
+ capabilities: { tools: { listChanged: true } },
101
+ instructions: KNIT_INSTRUCTIONS
102
+ }
104
103
  );
104
+ registerToolsListChangedNotifier(() => {
105
+ void server.sendToolListChanged().catch(() => {
106
+ });
107
+ });
105
108
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
106
109
  tools: getActiveToolDefinitionsForBrain(getBrain(ROOT_PATH))
107
110
  }));
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getRecentGlobalLearnings
3
- } from "./chunk-TRZ3LD6B.js";
3
+ } from "./chunk-TSIXVZCT.js";
4
4
  import {
5
5
  loadKnowledgeBase
6
6
  } from "./chunk-BAUQEFYY.js";
7
7
  import {
8
8
  globalLearningsPath,
9
9
  knitRoot
10
- } from "./chunk-HBMF62U4.js";
10
+ } from "./chunk-SBJMHDBM.js";
11
11
 
12
12
  // src/commands/export.ts
13
13
  import { existsSync, mkdirSync, readdirSync, writeFileSync, statSync } from "fs";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  getBrain
3
- } from "./chunk-QMH2DT6K.js";
4
- import "./chunk-SLN5ABF5.js";
5
- import "./chunk-M3YZOJNW.js";
3
+ } from "./chunk-WN4AQFMO.js";
6
4
  import {
7
5
  installAgentsForProject
8
- } from "./chunk-3XR77YJM.js";
9
- import "./chunk-7PPC6IG6.js";
6
+ } from "./chunk-N7R4P42P.js";
7
+ import "./chunk-MOOVNMIN.js";
8
+ import "./chunk-JJ367RK5.js";
9
+ import "./chunk-M3YZOJNW.js";
10
10
  import "./chunk-BAUQEFYY.js";
11
- import "./chunk-HBMF62U4.js";
11
+ import "./chunk-SBJMHDBM.js";
12
12
 
13
13
  // src/commands/install-agents.ts
14
14
  import { existsSync } from "fs";
@@ -0,0 +1,6 @@
1
+ import {
2
+ KNIT_INSTRUCTIONS
3
+ } from "./chunk-4PFEG4GQ.js";
4
+ export {
5
+ KNIT_INSTRUCTIONS
6
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ __resetNotifierForTests,
3
+ notifyToolsListChanged,
4
+ registerToolsListChangedNotifier
5
+ } from "./chunk-WMESQUZU.js";
6
+ export {
7
+ __resetNotifierForTests,
8
+ notifyToolsListChanged,
9
+ registerToolsListChangedNotifier
10
+ };
@@ -1,18 +1,18 @@
1
1
  import {
2
- buildKnowledge,
3
- generateClaudeMd
4
- } from "./chunk-SLN5ABF5.js";
2
+ buildKnowledge
3
+ } from "./chunk-MOOVNMIN.js";
4
+ import {
5
+ generateClaudeMd,
6
+ scanProject
7
+ } from "./chunk-JJ367RK5.js";
5
8
  import {
6
9
  findFalsePositives
7
10
  } from "./chunk-M3YZOJNW.js";
8
- import {
9
- scanProject
10
- } from "./chunk-7PPC6IG6.js";
11
11
  import {
12
12
  knowledgePath,
13
13
  learningsDir,
14
14
  projectDataDir
15
- } from "./chunk-HBMF62U4.js";
15
+ } from "./chunk-SBJMHDBM.js";
16
16
 
17
17
  // src/commands/refresh.ts
18
18
  import { readFileSync, readdirSync, writeFileSync, existsSync } from "fs";
@@ -11,7 +11,7 @@ import {
11
11
  knowledgePath,
12
12
  knowledgebasePath,
13
13
  learningsDir
14
- } from "./chunk-HBMF62U4.js";
14
+ } from "./chunk-SBJMHDBM.js";
15
15
 
16
16
  // src/commands/status.ts
17
17
  import { existsSync, readFileSync, readdirSync } from "fs";