forage-mcp 0.1.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/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +146 -0
- package/dist/cli.js.map +1 -0
- package/dist/persistence/log.d.ts +11 -0
- package/dist/persistence/log.d.ts.map +1 -0
- package/dist/persistence/log.js +21 -0
- package/dist/persistence/log.js.map +1 -0
- package/dist/persistence/manifest.d.ts +24 -0
- package/dist/persistence/manifest.d.ts.map +1 -0
- package/dist/persistence/manifest.js +45 -0
- package/dist/persistence/manifest.js.map +1 -0
- package/dist/proxy/manager.d.ts +20 -0
- package/dist/proxy/manager.d.ts.map +1 -0
- package/dist/proxy/manager.js +77 -0
- package/dist/proxy/manager.js.map +1 -0
- package/dist/proxy/wrapper.d.ts +20 -0
- package/dist/proxy/wrapper.d.ts.map +1 -0
- package/dist/proxy/wrapper.js +37 -0
- package/dist/proxy/wrapper.js.map +1 -0
- package/dist/registries/npm.d.ts +10 -0
- package/dist/registries/npm.d.ts.map +1 -0
- package/dist/registries/npm.js +74 -0
- package/dist/registries/npm.js.map +1 -0
- package/dist/registries/official.d.ts +23 -0
- package/dist/registries/official.d.ts.map +1 -0
- package/dist/registries/official.js +57 -0
- package/dist/registries/official.js.map +1 -0
- package/dist/registries/smithery.d.ts +3 -0
- package/dist/registries/smithery.d.ts.map +1 -0
- package/dist/registries/smithery.js +27 -0
- package/dist/registries/smithery.js.map +1 -0
- package/dist/registries/types.d.ts +13 -0
- package/dist/registries/types.d.ts.map +1 -0
- package/dist/registries/types.js +2 -0
- package/dist/registries/types.js.map +1 -0
- package/dist/rules/detector.d.ts +8 -0
- package/dist/rules/detector.d.ts.map +1 -0
- package/dist/rules/detector.js +54 -0
- package/dist/rules/detector.js.map +1 -0
- package/dist/rules/writer.d.ts +8 -0
- package/dist/rules/writer.d.ts.map +1 -0
- package/dist/rules/writer.js +135 -0
- package/dist/rules/writer.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +167 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/evaluate.d.ts +17 -0
- package/dist/tools/evaluate.d.ts.map +1 -0
- package/dist/tools/evaluate.js +31 -0
- package/dist/tools/evaluate.js.map +1 -0
- package/dist/tools/install.d.ts +18 -0
- package/dist/tools/install.d.ts.map +1 -0
- package/dist/tools/install.js +91 -0
- package/dist/tools/install.js.map +1 -0
- package/dist/tools/learn.d.ts +12 -0
- package/dist/tools/learn.d.ts.map +1 -0
- package/dist/tools/learn.js +31 -0
- package/dist/tools/learn.js.map +1 -0
- package/dist/tools/search.d.ts +10 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +50 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/status.d.ts +20 -0
- package/dist/tools/status.d.ts.map +1 -0
- package/dist/tools/status.js +24 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/uninstall.d.ts +11 -0
- package/dist/tools/uninstall.d.ts.map +1 -0
- package/dist/tools/uninstall.js +55 -0
- package/dist/tools/uninstall.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../src/proxy/wrapper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAUjD;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,iBAAiB,EAAE,EAAE,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE;gBAC1D,WAAW,EAAE,QAAQ,UAAU,KAAK,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;gBACnE,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,UAAU;gBACV,YAAY,EAAE,IAAI,CAAC,IAAI;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SearchResult } from "./types.js";
|
|
2
|
+
export declare function searchNpm(query: string): Promise<SearchResult[]>;
|
|
3
|
+
export declare function getPackageDetails(packageName: string): Promise<{
|
|
4
|
+
description: string;
|
|
5
|
+
version: string;
|
|
6
|
+
readme?: string;
|
|
7
|
+
repository?: string;
|
|
8
|
+
weeklyDownloads?: number;
|
|
9
|
+
} | null>;
|
|
10
|
+
//# sourceMappingURL=npm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm.d.ts","sourceRoot":"","sources":["../../src/registries/npm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoB/C,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuCtE;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,IAAI,CAAC,CAwCR"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const BASE_URL = "https://registry.npmjs.org";
|
|
2
|
+
export async function searchNpm(query) {
|
|
3
|
+
try {
|
|
4
|
+
// Search for MCP servers specifically
|
|
5
|
+
const searchQuery = `${query} mcp server`;
|
|
6
|
+
const url = `${BASE_URL}/-/v1/search?text=${encodeURIComponent(searchQuery)}&size=10`;
|
|
7
|
+
const response = await fetch(url, {
|
|
8
|
+
headers: { Accept: "application/json" },
|
|
9
|
+
signal: AbortSignal.timeout(10000),
|
|
10
|
+
});
|
|
11
|
+
if (!response.ok)
|
|
12
|
+
return [];
|
|
13
|
+
const data = (await response.json());
|
|
14
|
+
return data.objects
|
|
15
|
+
.filter((obj) => {
|
|
16
|
+
const name = obj.package.name.toLowerCase();
|
|
17
|
+
const desc = (obj.package.description ?? "").toLowerCase();
|
|
18
|
+
// Filter to packages that are likely MCP servers
|
|
19
|
+
return (name.includes("mcp") ||
|
|
20
|
+
desc.includes("mcp") ||
|
|
21
|
+
desc.includes("model context protocol"));
|
|
22
|
+
})
|
|
23
|
+
.map((obj) => ({
|
|
24
|
+
name: obj.package.name,
|
|
25
|
+
packageName: obj.package.name,
|
|
26
|
+
description: obj.package.description ?? "",
|
|
27
|
+
source: "npm",
|
|
28
|
+
url: obj.package.links?.repository ?? obj.package.links?.npm,
|
|
29
|
+
version: obj.package.version,
|
|
30
|
+
command: "npx",
|
|
31
|
+
args: ["-y", obj.package.name],
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function getPackageDetails(packageName) {
|
|
39
|
+
try {
|
|
40
|
+
const url = `${BASE_URL}/${encodeURIComponent(packageName)}`;
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
headers: { Accept: "application/json" },
|
|
43
|
+
signal: AbortSignal.timeout(10000),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
return null;
|
|
47
|
+
const data = (await response.json());
|
|
48
|
+
// Get weekly downloads from separate API
|
|
49
|
+
let weeklyDownloads;
|
|
50
|
+
try {
|
|
51
|
+
const dlResponse = await fetch(`https://api.npmjs.org/downloads/point/last-week/${encodeURIComponent(packageName)}`, { signal: AbortSignal.timeout(5000) });
|
|
52
|
+
if (dlResponse.ok) {
|
|
53
|
+
const dlData = (await dlResponse.json());
|
|
54
|
+
weeklyDownloads = dlData.downloads;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Ignore download count failures
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
description: data.description ?? "",
|
|
62
|
+
version: data["dist-tags"]?.latest ?? "",
|
|
63
|
+
readme: data.readme,
|
|
64
|
+
repository: typeof data.repository === "object" && data.repository !== null
|
|
65
|
+
? data.repository.url
|
|
66
|
+
: undefined,
|
|
67
|
+
weeklyDownloads,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=npm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../src/registries/npm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SearchResult } from "./types.js";
|
|
2
|
+
interface OfficialServerEntry {
|
|
3
|
+
server: {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
repository?: {
|
|
7
|
+
url?: string;
|
|
8
|
+
};
|
|
9
|
+
version?: string;
|
|
10
|
+
packages?: Array<{
|
|
11
|
+
registryType: string;
|
|
12
|
+
identifier: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
version?: string;
|
|
15
|
+
runtime?: string;
|
|
16
|
+
arguments?: string[];
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function searchOfficial(query: string): Promise<SearchResult[]>;
|
|
21
|
+
export declare function getServerDetails(name: string): Promise<OfficialServerEntry["server"] | null>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=official.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"official.d.ts","sourceRoot":"","sources":["../../src/registries/official.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,UAAU,mBAAmB;IAC3B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,KAAK,CAAC;YACf,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC,CAAC;KACJ,CAAC;CACH;AAMD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,EAAE,CAAC,CAqCzB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAiB/C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const BASE_URL = "https://registry.modelcontextprotocol.io/v0";
|
|
2
|
+
export async function searchOfficial(query) {
|
|
3
|
+
try {
|
|
4
|
+
const url = `${BASE_URL}/servers?search=${encodeURIComponent(query)}&limit=10`;
|
|
5
|
+
const response = await fetch(url, {
|
|
6
|
+
headers: { Accept: "application/json" },
|
|
7
|
+
signal: AbortSignal.timeout(10000),
|
|
8
|
+
});
|
|
9
|
+
if (!response.ok)
|
|
10
|
+
return [];
|
|
11
|
+
const data = (await response.json());
|
|
12
|
+
const results = [];
|
|
13
|
+
for (const entry of data.servers ?? []) {
|
|
14
|
+
const s = entry.server;
|
|
15
|
+
if (!s?.name)
|
|
16
|
+
continue;
|
|
17
|
+
const npmPkg = s.packages?.find((p) => p.registryType === "npm");
|
|
18
|
+
const packageName = npmPkg?.identifier ?? npmPkg?.name ?? s.name;
|
|
19
|
+
results.push({
|
|
20
|
+
name: s.name,
|
|
21
|
+
packageName,
|
|
22
|
+
description: s.description ?? "",
|
|
23
|
+
source: "official-registry",
|
|
24
|
+
url: s.repository?.url,
|
|
25
|
+
version: s.version ?? npmPkg?.version,
|
|
26
|
+
command: npmPkg ? "npx" : undefined,
|
|
27
|
+
args: npmPkg
|
|
28
|
+
? ["-y", packageName, ...(npmPkg.arguments ?? [])]
|
|
29
|
+
: undefined,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function getServerDetails(name) {
|
|
39
|
+
try {
|
|
40
|
+
const url = `${BASE_URL}/servers/${encodeURIComponent(name)}`;
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
headers: { Accept: "application/json" },
|
|
43
|
+
signal: AbortSignal.timeout(10000),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
return null;
|
|
47
|
+
const data = (await response.json());
|
|
48
|
+
// The API might return wrapped or unwrapped
|
|
49
|
+
if ("server" in data)
|
|
50
|
+
return data.server;
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=official.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"official.js","sourceRoot":"","sources":["../../src/registries/official.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAuB/D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,QAAQ,mBAAmB,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC;QAC/E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAE5B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;QAE/D,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,IAAI,CAAC,CAAC,EAAE,IAAI;gBAAE,SAAS;YAEvB,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;YACjE,MAAM,WAAW,GAAG,MAAM,EAAE,UAAU,IAAI,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC;YAEjE,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW;gBACX,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;gBAChC,MAAM,EAAE,mBAAmB;gBAC3B,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,GAAG;gBACtB,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,MAAM,EAAE,OAAO;gBACrC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;gBACnC,IAAI,EAAE,MAAM;oBACV,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;oBAClD,CAAC,CAAC,SAAS;aACd,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY;IAEZ,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,QAAQ,YAAY,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAE9B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwD,CAAC;QAC5F,4CAA4C;QAC5C,IAAI,QAAQ,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smithery.d.ts","sourceRoot":"","sources":["../../src/registries/smithery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiB/C,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,EAAE,CAAC,CAyBzB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const BASE_URL = "https://registry.smithery.ai";
|
|
2
|
+
export async function searchSmithery(query) {
|
|
3
|
+
try {
|
|
4
|
+
const url = `${BASE_URL}/servers?q=${encodeURIComponent(query)}&pageSize=10`;
|
|
5
|
+
const response = await fetch(url, {
|
|
6
|
+
headers: {
|
|
7
|
+
Accept: "application/json",
|
|
8
|
+
},
|
|
9
|
+
signal: AbortSignal.timeout(10000),
|
|
10
|
+
});
|
|
11
|
+
if (!response.ok)
|
|
12
|
+
return [];
|
|
13
|
+
const data = (await response.json());
|
|
14
|
+
return (data.servers ?? []).map((server) => ({
|
|
15
|
+
name: server.displayName ?? server.qualifiedName,
|
|
16
|
+
packageName: server.qualifiedName,
|
|
17
|
+
description: server.description ?? "",
|
|
18
|
+
source: "smithery",
|
|
19
|
+
url: server.homepage ?? `https://smithery.ai/server/${server.qualifiedName}`,
|
|
20
|
+
downloads: server.useCount,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=smithery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smithery.js","sourceRoot":"","sources":["../../src/registries/smithery.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,8BAA8B,CAAC;AAehD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,QAAQ,cAAc,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC;QAC7E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,MAAM,EAAE,kBAAkB;aAC3B;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAE5B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;QAE/D,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3C,IAAI,EAAE,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,aAAa;YAChD,WAAW,EAAE,MAAM,CAAC,aAAa;YACjC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;YACrC,MAAM,EAAE,UAAmB;YAC3B,GAAG,EAAE,MAAM,CAAC,QAAQ,IAAI,8BAA8B,MAAM,CAAC,aAAa,EAAE;YAC5E,SAAS,EAAE,MAAM,CAAC,QAAQ;SAC3B,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SearchResult {
|
|
2
|
+
name: string;
|
|
3
|
+
packageName: string;
|
|
4
|
+
description: string;
|
|
5
|
+
source: "official-registry" | "smithery" | "npm";
|
|
6
|
+
url?: string;
|
|
7
|
+
stars?: number;
|
|
8
|
+
downloads?: number;
|
|
9
|
+
version?: string;
|
|
10
|
+
command?: string;
|
|
11
|
+
args?: string[];
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/registries/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,GAAG,UAAU,GAAG,KAAK,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/registries/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type AgentType = "claude-code" | "cursor" | "codex" | "unknown";
|
|
2
|
+
export interface RulesTarget {
|
|
3
|
+
agent: AgentType;
|
|
4
|
+
filePath: string;
|
|
5
|
+
sectionHeader: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function detectAgent(cwd?: string): Promise<RulesTarget[]>;
|
|
8
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/rules/detector.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAmDtE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
export async function detectAgent(cwd) {
|
|
5
|
+
const projectDir = cwd ?? process.cwd();
|
|
6
|
+
const targets = [];
|
|
7
|
+
// Check for Claude Code (CLAUDE.md in project or home dir)
|
|
8
|
+
const claudeMdProject = path.join(projectDir, "CLAUDE.md");
|
|
9
|
+
const claudeMdHome = path.join(os.homedir(), "CLAUDE.md");
|
|
10
|
+
try {
|
|
11
|
+
await fs.access(claudeMdProject);
|
|
12
|
+
targets.push({
|
|
13
|
+
agent: "claude-code",
|
|
14
|
+
filePath: claudeMdProject,
|
|
15
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Project CLAUDE.md doesn't exist, use home dir
|
|
20
|
+
targets.push({
|
|
21
|
+
agent: "claude-code",
|
|
22
|
+
filePath: claudeMdHome,
|
|
23
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
// Check for Cursor (.cursor/rules/ directory)
|
|
27
|
+
const cursorDir = path.join(projectDir, ".cursor", "rules");
|
|
28
|
+
try {
|
|
29
|
+
await fs.access(cursorDir);
|
|
30
|
+
targets.push({
|
|
31
|
+
agent: "cursor",
|
|
32
|
+
filePath: path.join(cursorDir, "forage.mdc"),
|
|
33
|
+
sectionHeader: "# Forage: Installed Tools",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// No Cursor config
|
|
38
|
+
}
|
|
39
|
+
// Check for Codex/Copilot (AGENTS.md)
|
|
40
|
+
const agentsMd = path.join(projectDir, "AGENTS.md");
|
|
41
|
+
try {
|
|
42
|
+
await fs.access(agentsMd);
|
|
43
|
+
targets.push({
|
|
44
|
+
agent: "codex",
|
|
45
|
+
filePath: agentsMd,
|
|
46
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// No AGENTS.md
|
|
51
|
+
}
|
|
52
|
+
return targets;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/rules/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAUzB,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAY;IAC5C,MAAM,UAAU,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACxC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,2DAA2D;IAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,eAAe;YACzB,aAAa,EAAE,4BAA4B;SAC5C,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;QAChD,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,YAAY;YACtB,aAAa,EAAE,4BAA4B;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,8CAA8C;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;YAC5C,aAAa,EAAE,2BAA2B;SAC3C,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB;IACrB,CAAC;IAED,sCAAsC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,QAAQ;YAClB,aAAa,EAAE,4BAA4B;SAC5C,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface LearnInput {
|
|
2
|
+
toolName: string;
|
|
3
|
+
rules: string;
|
|
4
|
+
target?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function writeRules(input: LearnInput): Promise<string[]>;
|
|
7
|
+
export declare function removeRules(toolName: string, target?: string): Promise<string[]>;
|
|
8
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/rules/writer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmCrE;AAED,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { detectAgent } from "./detector.js";
|
|
4
|
+
export async function writeRules(input) {
|
|
5
|
+
let targets;
|
|
6
|
+
if (input.target) {
|
|
7
|
+
// User specified a specific target file
|
|
8
|
+
targets = [
|
|
9
|
+
{
|
|
10
|
+
agent: "unknown",
|
|
11
|
+
filePath: input.target,
|
|
12
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
targets = await detectAgent();
|
|
18
|
+
// Default to CLAUDE.md in home dir if nothing detected
|
|
19
|
+
if (targets.length === 0) {
|
|
20
|
+
const os = await import("node:os");
|
|
21
|
+
targets = [
|
|
22
|
+
{
|
|
23
|
+
agent: "claude-code",
|
|
24
|
+
filePath: path.join(os.homedir(), "CLAUDE.md"),
|
|
25
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const updatedFiles = [];
|
|
31
|
+
for (const target of targets) {
|
|
32
|
+
await writeToFile(target, input.toolName, input.rules);
|
|
33
|
+
updatedFiles.push(target.filePath);
|
|
34
|
+
}
|
|
35
|
+
return updatedFiles;
|
|
36
|
+
}
|
|
37
|
+
export async function removeRules(toolName, target) {
|
|
38
|
+
let targets;
|
|
39
|
+
if (target) {
|
|
40
|
+
targets = [
|
|
41
|
+
{
|
|
42
|
+
agent: "unknown",
|
|
43
|
+
filePath: target,
|
|
44
|
+
sectionHeader: "## Forage: Installed Tools",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
targets = await detectAgent();
|
|
50
|
+
}
|
|
51
|
+
const updatedFiles = [];
|
|
52
|
+
for (const t of targets) {
|
|
53
|
+
const removed = await removeFromFile(t, toolName);
|
|
54
|
+
if (removed)
|
|
55
|
+
updatedFiles.push(t.filePath);
|
|
56
|
+
}
|
|
57
|
+
return updatedFiles;
|
|
58
|
+
}
|
|
59
|
+
async function writeToFile(target, toolName, rules) {
|
|
60
|
+
let content = "";
|
|
61
|
+
try {
|
|
62
|
+
content = await fs.readFile(target.filePath, "utf-8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// File doesn't exist, we'll create it
|
|
66
|
+
}
|
|
67
|
+
const toolBlock = formatToolBlock(toolName, rules);
|
|
68
|
+
const sectionHeader = target.sectionHeader;
|
|
69
|
+
if (content.includes(sectionHeader)) {
|
|
70
|
+
// Section exists — check if tool already has an entry
|
|
71
|
+
const toolMarkerStart = `<!-- forage:${toolName} -->`;
|
|
72
|
+
const toolMarkerEnd = `<!-- /forage:${toolName} -->`;
|
|
73
|
+
if (content.includes(toolMarkerStart)) {
|
|
74
|
+
// Replace existing entry
|
|
75
|
+
const startIdx = content.indexOf(toolMarkerStart);
|
|
76
|
+
const endIdx = content.indexOf(toolMarkerEnd) + toolMarkerEnd.length;
|
|
77
|
+
content =
|
|
78
|
+
content.slice(0, startIdx) + toolBlock + content.slice(endIdx);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Append to existing section
|
|
82
|
+
const sectionIdx = content.indexOf(sectionHeader) + sectionHeader.length;
|
|
83
|
+
content =
|
|
84
|
+
content.slice(0, sectionIdx) +
|
|
85
|
+
"\n\n" +
|
|
86
|
+
toolBlock +
|
|
87
|
+
content.slice(sectionIdx);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Create new section at end of file
|
|
92
|
+
content =
|
|
93
|
+
content.trimEnd() + "\n\n" + sectionHeader + "\n\n" + toolBlock + "\n";
|
|
94
|
+
}
|
|
95
|
+
await fs.mkdir(path.dirname(target.filePath), { recursive: true });
|
|
96
|
+
await fs.writeFile(target.filePath, content, "utf-8");
|
|
97
|
+
}
|
|
98
|
+
async function removeFromFile(target, toolName) {
|
|
99
|
+
let content;
|
|
100
|
+
try {
|
|
101
|
+
content = await fs.readFile(target.filePath, "utf-8");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const toolMarkerStart = `<!-- forage:${toolName} -->`;
|
|
107
|
+
const toolMarkerEnd = `<!-- /forage:${toolName} -->`;
|
|
108
|
+
if (!content.includes(toolMarkerStart))
|
|
109
|
+
return false;
|
|
110
|
+
const startIdx = content.indexOf(toolMarkerStart);
|
|
111
|
+
const endIdx = content.indexOf(toolMarkerEnd) + toolMarkerEnd.length;
|
|
112
|
+
// Remove the tool block and any surrounding blank lines
|
|
113
|
+
let before = content.slice(0, startIdx).replace(/\n\n$/, "\n");
|
|
114
|
+
let after = content.slice(endIdx).replace(/^\n\n/, "\n");
|
|
115
|
+
content = before + after;
|
|
116
|
+
// If the section is now empty, remove it too
|
|
117
|
+
const sectionHeader = target.sectionHeader;
|
|
118
|
+
if (content.includes(sectionHeader)) {
|
|
119
|
+
const sectionIdx = content.indexOf(sectionHeader);
|
|
120
|
+
const afterSection = content.slice(sectionIdx + sectionHeader.length);
|
|
121
|
+
const nextSection = afterSection.search(/\n##? /);
|
|
122
|
+
const sectionContent = nextSection === -1 ? afterSection : afterSection.slice(0, nextSection);
|
|
123
|
+
if (sectionContent.trim() === "") {
|
|
124
|
+
content =
|
|
125
|
+
content.slice(0, sectionIdx).trimEnd() +
|
|
126
|
+
(nextSection === -1 ? "\n" : afterSection.slice(nextSection));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
await fs.writeFile(target.filePath, content, "utf-8");
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
function formatToolBlock(toolName, rules) {
|
|
133
|
+
return `<!-- forage:${toolName} -->\n### ${toolName}\n\n${rules}\n<!-- /forage:${toolName} -->`;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/rules/writer.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|