init project
This commit is contained in:
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { z } from 'zod';
|
||||
import { config } from '../../config.js';
|
||||
import { detectProject } from '../../lib/frameworks/detect.js';
|
||||
import { readPackageJson } from '../../lib/frameworks/packageManager.js';
|
||||
import { readComposerJson } from '../../lib/frameworks/composer.js';
|
||||
import { errorResult, jsonResult, targetSchema, toErrorMessage } from '../shared.js';
|
||||
export function registerGetPackageInfoTool(server) {
|
||||
server.registerTool('get_package_info', {
|
||||
title: 'Get Package Info',
|
||||
description: 'Return installed package metadata from package.json (React/Node projects) or composer.json (PHP projects): version, scripts, and key dependencies.',
|
||||
inputSchema: {
|
||||
target: targetSchema,
|
||||
ecosystem: z
|
||||
.enum(['npm', 'composer', 'auto'])
|
||||
.optional()
|
||||
.default('auto')
|
||||
.describe('Which manifest to read. Auto detects from the resolved project.'),
|
||||
},
|
||||
}, async ({ target, ecosystem }) => {
|
||||
try {
|
||||
const detected = detectProject(config.workspaceRoot);
|
||||
const adapter = target === 'frontend'
|
||||
? detected.frontend
|
||||
: target === 'backend'
|
||||
? detected.backend
|
||||
: (detected.frontend ?? detected.backend ?? detected.primary);
|
||||
if (!adapter)
|
||||
return errorResult('No project detected in WORKSPACE_ROOT.');
|
||||
const resolvedEcosystem = ecosystem === 'auto' ? (adapter.packageManager === 'composer' ? 'composer' : 'npm') : ecosystem;
|
||||
const root = adapter.root;
|
||||
if (resolvedEcosystem === 'composer') {
|
||||
const composerJson = readComposerJson(root);
|
||||
if (!composerJson)
|
||||
return errorResult(`No composer.json found at ${root}`);
|
||||
const lockPath = path.join(root, 'composer.lock');
|
||||
let installed = {};
|
||||
if (fs.existsSync(lockPath)) {
|
||||
try {
|
||||
const lock = JSON.parse(fs.readFileSync(lockPath, 'utf8'));
|
||||
installed = Object.fromEntries((lock.packages ?? []).slice(0, 50).map((p) => [p.name, p.version]));
|
||||
}
|
||||
catch {
|
||||
// ignore lock parse errors
|
||||
}
|
||||
}
|
||||
return jsonResult({
|
||||
ecosystem: 'composer',
|
||||
root,
|
||||
name: composerJson.name ?? null,
|
||||
require: composerJson.require ?? {},
|
||||
requireDev: composerJson['require-dev'] ?? {},
|
||||
scripts: composerJson.scripts ?? {},
|
||||
installedSample: installed,
|
||||
});
|
||||
}
|
||||
const packageJson = readPackageJson(root);
|
||||
if (!packageJson)
|
||||
return errorResult(`No package.json found at ${root}`);
|
||||
return jsonResult({
|
||||
ecosystem: 'npm',
|
||||
root,
|
||||
name: packageJson.name ?? null,
|
||||
scripts: packageJson.scripts ?? {},
|
||||
dependencies: packageJson.dependencies ?? {},
|
||||
devDependencies: packageJson.devDependencies ?? {},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
return errorResult(toErrorMessage(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=getPackageInfo.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"getPackageInfo.js","sourceRoot":"","sources":["../../../src/tools/docs/getPackageInfo.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
import { registerSearchPackageDocsTool } from './searchPackageDocs.js';
|
||||
import { registerSearchMdnTool } from './searchMdn.js';
|
||||
import { registerSearchLaravelDocsTool } from './searchLaravelDocs.js';
|
||||
import { registerSearchCodeIgniterDocsTool } from './searchCodeIgniterDocs.js';
|
||||
import { registerGetPackageInfoTool } from './getPackageInfo.js';
|
||||
export function registerDocsTools(server) {
|
||||
registerSearchPackageDocsTool(server);
|
||||
registerSearchMdnTool(server);
|
||||
registerSearchLaravelDocsTool(server);
|
||||
registerSearchCodeIgniterDocsTool(server);
|
||||
registerGetPackageInfoTool(server);
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/docs/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,iCAAiC,CAAC,MAAM,CAAC,CAAC;IAC1C,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import { z } from 'zod';
|
||||
import { config } from '../../config.js';
|
||||
import { detectProject } from '../../lib/frameworks/detect.js';
|
||||
import { readComposerJson } from '../../lib/frameworks/composer.js';
|
||||
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
|
||||
function extractMajorMinor(versionConstraint) {
|
||||
if (!versionConstraint)
|
||||
return '4';
|
||||
const match = versionConstraint.match(/(\d+)\.(\d+)/);
|
||||
if (!match)
|
||||
return '4';
|
||||
const [, major] = match;
|
||||
return `${major}`;
|
||||
}
|
||||
export function registerSearchCodeIgniterDocsTool(server) {
|
||||
server.registerTool('search_codeigniter_docs', {
|
||||
title: 'Search CodeIgniter Docs',
|
||||
description: 'Return a deep link to the CodeIgniter 4 user guide for a topic, version-matched to the codeigniter4/framework constraint in composer.json.',
|
||||
inputSchema: {
|
||||
topic: z.string().min(1).describe('Documentation topic, e.g. "models" or "database".'),
|
||||
version: z.string().optional().describe('Override the major version, e.g. "4". Auto-detected by default.'),
|
||||
},
|
||||
}, async ({ topic, version }) => {
|
||||
try {
|
||||
const detected = detectProject(config.workspaceRoot);
|
||||
const ciRoot = detected.backend?.kind === 'codeigniter' ? detected.backend.root : config.workspaceRoot;
|
||||
const composerJson = readComposerJson(ciRoot);
|
||||
const constraint = composerJson?.require?.['codeigniter4/framework'];
|
||||
const docsVersion = version ?? extractMajorMinor(constraint);
|
||||
const slug = topic.toLowerCase().replace(/\s+/g, '_');
|
||||
const url = `https://codeigniter4.github.io/userguide/${docsVersion}/${slug}.html`;
|
||||
return jsonResult({
|
||||
topic,
|
||||
version: docsVersion,
|
||||
composerConstraint: constraint ?? null,
|
||||
url,
|
||||
note: 'This is a best-effort documentation link. If the topic page does not exist, the user guide index may help.',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
return errorResult(toErrorMessage(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=searchCodeIgniterDocs.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"searchCodeIgniterDocs.js","sourceRoot":"","sources":["../../../src/tools/docs/searchCodeIgniterDocs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvE,SAAS,iBAAiB,CAAC,iBAAqC;IAC9D,IAAI,CAAC,iBAAiB;QAAE,OAAO,GAAG,CAAC;IACnC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,GAAG,CAAC;IACvB,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;IACxB,OAAO,GAAG,KAAK,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,4IAA4I;QAC9I,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mDAAmD,CAAC;YACtF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC;SAC3G;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;YACvG,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,wBAAwB,CAAC,CAAC;YACrE,MAAM,WAAW,GAAG,OAAO,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACtD,MAAM,GAAG,GAAG,4CAA4C,WAAW,IAAI,IAAI,OAAO,CAAC;YACnF,OAAO,UAAU,CAAC;gBAChB,KAAK;gBACL,OAAO,EAAE,WAAW;gBACpB,kBAAkB,EAAE,UAAU,IAAI,IAAI;gBACtC,GAAG;gBACH,IAAI,EAAE,4GAA4G;aACnH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
import { z } from 'zod';
|
||||
import { config } from '../../config.js';
|
||||
import { detectProject } from '../../lib/frameworks/detect.js';
|
||||
import { readComposerJson } from '../../lib/frameworks/composer.js';
|
||||
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
|
||||
function extractMajorMinor(versionConstraint) {
|
||||
if (!versionConstraint)
|
||||
return '11.x';
|
||||
const match = versionConstraint.match(/(\d+)\.(\d+)/);
|
||||
if (!match)
|
||||
return '11.x';
|
||||
const [, major, minor] = match;
|
||||
return `${major}.${minor}`;
|
||||
}
|
||||
export function registerSearchLaravelDocsTool(server) {
|
||||
server.registerTool('search_laravel_docs', {
|
||||
title: 'Search Laravel Docs',
|
||||
description: 'Return a deep link to the Laravel documentation for a topic, version-matched to the laravel/framework constraint in composer.json.',
|
||||
inputSchema: {
|
||||
topic: z.string().min(1).describe('Documentation topic, e.g. "eloquent" or "validation".'),
|
||||
version: z.string().optional().describe('Override the version segment, e.g. "11.x". Auto-detected by default.'),
|
||||
},
|
||||
}, async ({ topic, version }) => {
|
||||
try {
|
||||
const detected = detectProject(config.workspaceRoot);
|
||||
const laravelRoot = detected.backend?.kind === 'laravel' ? detected.backend.root : config.workspaceRoot;
|
||||
const composerJson = readComposerJson(laravelRoot);
|
||||
const constraint = composerJson?.require?.['laravel/framework'];
|
||||
const docsVersion = version ?? extractMajorMinor(constraint) + '.x';
|
||||
const slug = topic.toLowerCase().replace(/\s+/g, '-');
|
||||
const url = `https://laravel.com/docs/${docsVersion}/${slug}`;
|
||||
return jsonResult({
|
||||
topic,
|
||||
version: docsVersion,
|
||||
composerConstraint: constraint ?? null,
|
||||
url,
|
||||
note: 'This is a best-effort documentation link. If the topic page does not exist, MDN/search engines may help refine the query.',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
return errorResult(toErrorMessage(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=searchLaravelDocs.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"searchLaravelDocs.js","sourceRoot":"","sources":["../../../src/tools/docs/searchLaravelDocs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvE,SAAS,iBAAiB,CAAC,iBAAqC;IAC9D,IAAI,CAAC,iBAAiB;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;IAC/B,OAAO,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,oIAAoI;QACtI,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uDAAuD,CAAC;YAC1F,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sEAAsE,CAAC;SAChH;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;YACxG,MAAM,YAAY,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,mBAAmB,CAAC,CAAC;YAChE,MAAM,WAAW,GAAG,OAAO,IAAI,iBAAiB,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACtD,MAAM,GAAG,GAAG,4BAA4B,WAAW,IAAI,IAAI,EAAE,CAAC;YAC9D,OAAO,UAAU,CAAC;gBAChB,KAAK;gBACL,OAAO,EAAE,WAAW;gBACpB,kBAAkB,EAAE,UAAU,IAAI,IAAI;gBACtC,GAAG;gBACH,IAAI,EAAE,2HAA2H;aAClI,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
import { z } from 'zod';
|
||||
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
|
||||
export function registerSearchMdnTool(server) {
|
||||
server.registerTool('search_mdn', {
|
||||
title: 'Search MDN',
|
||||
description: 'Search MDN for a web platform API, CSS property, or HTML element and return the top results.',
|
||||
inputSchema: {
|
||||
query: z.string().min(1).describe('Search query, e.g. "Array.prototype.map" or "fetch API".'),
|
||||
limit: z.number().int().positive().optional().default(5).describe('Maximum number of results to return.'),
|
||||
},
|
||||
}, async ({ query, limit }) => {
|
||||
try {
|
||||
const url = `https://developer.mozilla.org/api/v1/search?q=${encodeURIComponent(query)}&locale=en-US`;
|
||||
const response = await fetch(url, { headers: { Accept: 'application/json' } });
|
||||
if (!response.ok) {
|
||||
throw new Error(`MDN search returned HTTP ${response.status}`);
|
||||
}
|
||||
const data = (await response.json());
|
||||
const results = data.documents?.slice(0, limit).map((doc) => ({
|
||||
title: doc.title,
|
||||
url: `https://developer.mozilla.org${doc.mdn_url}`,
|
||||
summary: doc.summary,
|
||||
})) ?? [];
|
||||
return jsonResult({ query, results });
|
||||
}
|
||||
catch (error) {
|
||||
return errorResult(toErrorMessage(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=searchMdn.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"searchMdn.js","sourceRoot":"","sources":["../../../src/tools/docs/searchMdn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAWvE,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,8FAA8F;QAC3G,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0DAA0D,CAAC;YAC7F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;SAC1G;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,iDAAiD,kBAAkB,CAAC,KAAK,CAAC,eAAe,CAAC;YACtG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAC/E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAoB,CAAC;YACxD,MAAM,OAAO,GACX,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC5C,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,GAAG,EAAE,gCAAgC,GAAG,CAAC,OAAO,EAAE;gBAClD,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
||||
Vendored
+87
@@ -0,0 +1,87 @@
|
||||
import { z } from 'zod';
|
||||
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
|
||||
async function fetchJson(url) {
|
||||
const response = await fetch(url, { headers: { Accept: 'application/json' } });
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status} from ${url}`);
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
async function fetchText(url) {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status} from ${url}`);
|
||||
}
|
||||
return response.text();
|
||||
}
|
||||
async function fetchNpmDocs(name, version) {
|
||||
const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(name)}`;
|
||||
const info = (await fetchJson(registryUrl));
|
||||
const resolvedVersion = version ?? info['dist-tags'].latest;
|
||||
const versionData = info.versions[resolvedVersion];
|
||||
let readme = null;
|
||||
try {
|
||||
readme = await fetchText(`https://unpkg.com/${name}@${resolvedVersion}/README.md`);
|
||||
}
|
||||
catch {
|
||||
try {
|
||||
readme = await fetchText(`https://unpkg.com/${name}@${resolvedVersion}/readme.md`);
|
||||
}
|
||||
catch {
|
||||
readme = info.readme ?? null;
|
||||
}
|
||||
}
|
||||
return {
|
||||
ecosystem: 'npm',
|
||||
package: name,
|
||||
version: resolvedVersion,
|
||||
description: versionData?.description ?? null,
|
||||
homepage: versionData?.homepage ?? null,
|
||||
repository: versionData?.repository?.url ?? null,
|
||||
readme,
|
||||
readmeSource: readme ? `https://unpkg.com/${name}@${resolvedVersion}/README.md` : null,
|
||||
};
|
||||
}
|
||||
async function fetchPackagistDocs(name, version) {
|
||||
const url = `https://packagist.org/packages/${encodeURIComponent(name)}.json`;
|
||||
const info = (await fetchJson(url));
|
||||
const pkg = info.package;
|
||||
const versions = Object.keys(pkg.versions ?? {}).sort();
|
||||
const resolvedVersion = version ?? versions[versions.length - 1];
|
||||
return {
|
||||
ecosystem: 'composer',
|
||||
package: pkg.name,
|
||||
version: resolvedVersion,
|
||||
description: pkg.description ?? null,
|
||||
repository: pkg.repository ?? null,
|
||||
versions: versions.slice(-20),
|
||||
note: 'README fetching for Packagist packages is not yet implemented; use the repository URL to read the README.',
|
||||
};
|
||||
}
|
||||
export function registerSearchPackageDocsTool(server) {
|
||||
server.registerTool('search_package_docs', {
|
||||
title: 'Search Package Docs',
|
||||
description: 'Fetch README/docs for an npm or Composer/Packagist package. For npm packages, resolves the version and fetches the README from unpkg. For Composer packages, returns Packagist metadata including the repository URL.',
|
||||
inputSchema: {
|
||||
name: z.string().min(1).describe('Package name, e.g. "axios" or "laravel/framework".'),
|
||||
ecosystem: z
|
||||
.enum(['npm', 'composer', 'auto'])
|
||||
.optional()
|
||||
.default('auto')
|
||||
.describe('Which package ecosystem to search. Auto detects from the name ("laravel/framework" → composer).'),
|
||||
version: z.string().optional().describe('Specific version to look up. Defaults to latest.'),
|
||||
},
|
||||
}, async ({ name, ecosystem, version }) => {
|
||||
try {
|
||||
const resolvedEcosystem = ecosystem === 'auto' ? (name.includes('/') ? 'composer' : 'npm') : ecosystem;
|
||||
if (resolvedEcosystem === 'composer') {
|
||||
return jsonResult(await fetchPackagistDocs(name, version));
|
||||
}
|
||||
return jsonResult(await fetchNpmDocs(name, version));
|
||||
}
|
||||
catch (error) {
|
||||
return errorResult(toErrorMessage(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=searchPackageDocs.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"searchPackageDocs.js","sourceRoot":"","sources":["../../../src/tools/docs/searchPackageDocs.ts"],"names":[],"mappings":"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"}
|
||||
Reference in New Issue
Block a user