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.
- package/README.md +21 -0
- package/dist/{cache-WGZ2C7BZ.js → cache-RRKF2IZ5.js} +5 -5
- package/dist/{instructions-33TUHLTK.js → chunk-4PFEG4GQ.js} +1 -0
- package/dist/{chunk-7PPC6IG6.js → chunk-JJ367RK5.js} +163 -1
- package/dist/{chunk-SLN5ABF5.js → chunk-MOOVNMIN.js} +1 -160
- package/dist/{chunk-3XR77YJM.js → chunk-N7R4P42P.js} +265 -9
- package/dist/{chunk-HBMF62U4.js → chunk-SBJMHDBM.js} +4 -0
- package/dist/{chunk-TRZ3LD6B.js → chunk-TSIXVZCT.js} +11 -1
- package/dist/chunk-UTVFELXS.js +9 -0
- package/dist/chunk-WMESQUZU.js +25 -0
- package/dist/{chunk-QMH2DT6K.js → chunk-WN4AQFMO.js} +25 -11
- package/dist/cli.js +19 -16
- package/dist/{export-IKPBLZOO.js → export-KALLYKWG.js} +2 -2
- package/dist/{install-agents-AXT6DMYM.js → install-agents-DLSH3FNC.js} +6 -6
- package/dist/instructions-YPXOZZHI.js +6 -0
- package/dist/notifier-4L27HKHI.js +10 -0
- package/dist/{refresh-MSN5YNPS.js → refresh-N4O2QLYS.js} +7 -7
- package/dist/{status-XN6VHO66.js → status-YK2KBG57.js} +1 -1
- package/dist/{tools-KRPOUYNT.js → tools-GN6GM55U.js} +459 -24
- package/package.json +1 -1
|
@@ -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-
|
|
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-
|
|
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
|
|
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 (!
|
|
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
|
-
|
|
362
|
-
|
|
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 (!
|
|
616
|
+
if (!existsSync4(path)) return [];
|
|
368
617
|
try {
|
|
369
|
-
const stat =
|
|
618
|
+
const stat = statSync2(path);
|
|
370
619
|
if (stat.size === 0) return [];
|
|
371
620
|
if (stat.size > 100 * 1024 * 1024) return [];
|
|
372
|
-
return
|
|
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-
|
|
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,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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
29
|
-
const { refreshCommand } = await import("./refresh-
|
|
30
|
-
const { installAgentsCommand } = await import("./install-agents-
|
|
31
|
-
const { exportCommand } = await import("./export-
|
|
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-
|
|
98
|
-
const { getActiveToolDefinitionsForBrain, handleToolCall } = await import("./tools-
|
|
99
|
-
const { KNIT_INSTRUCTIONS } = await import("./instructions-
|
|
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
|
-
{
|
|
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-
|
|
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-
|
|
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-
|
|
4
|
-
import "./chunk-SLN5ABF5.js";
|
|
5
|
-
import "./chunk-M3YZOJNW.js";
|
|
3
|
+
} from "./chunk-WN4AQFMO.js";
|
|
6
4
|
import {
|
|
7
5
|
installAgentsForProject
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
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-
|
|
11
|
+
import "./chunk-SBJMHDBM.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/install-agents.ts
|
|
14
14
|
import { existsSync } from "fs";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
buildKnowledge
|
|
3
|
-
|
|
4
|
-
|
|
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-
|
|
15
|
+
} from "./chunk-SBJMHDBM.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/refresh.ts
|
|
18
18
|
import { readFileSync, readdirSync, writeFileSync, existsSync } from "fs";
|