@mrmtsu/mcms-cli 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,435 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { spawn } from "node:child_process";
3
+ import { createRequire } from "node:module";
4
+ import { dirname, extname, resolve } from "node:path";
5
+ import { CliError } from "../errors.js";
6
+ import { EXIT_CODE } from "../exit-codes.js";
7
+ const MCP_COMMAND_OVERRIDE = process.env.MICROCMS_DOC_MCP_COMMAND;
8
+ const MCP_STARTUP_TIMEOUT_MS = 2_000;
9
+ const MCP_REQUEST_TIMEOUT_MS = 5_000;
10
+ export function createMcpDocsProvider() {
11
+ const client = createMcpClient(resolveMcpRuntime());
12
+ return {
13
+ async healthcheck() {
14
+ await callTool(client, "fetch_general");
15
+ },
16
+ async listDocuments(params) {
17
+ const args = params.category ? { category: params.category } : undefined;
18
+ const raw = await callTool(client, "list_documents", args);
19
+ const payload = parseListDocumentsPayload(raw);
20
+ const categoryRows = payload.categories ?? [];
21
+ const docs = categoryRows
22
+ .flatMap((row) => {
23
+ const category = typeof row.category === "string" ? row.category : undefined;
24
+ const files = Array.isArray(row.files) ? row.files : [];
25
+ if (!category) {
26
+ return [];
27
+ }
28
+ return files
29
+ .filter((file) => typeof file === "string")
30
+ .map((filename) => ({ category, filename }));
31
+ })
32
+ .slice(0, params.limit);
33
+ const counts = new Map();
34
+ for (const doc of docs) {
35
+ counts.set(doc.category, (counts.get(doc.category) ?? 0) + 1);
36
+ }
37
+ return {
38
+ categories: [...counts.entries()].map(([category, count]) => ({ category, count })),
39
+ docs,
40
+ total: docs.length
41
+ };
42
+ },
43
+ async getDocument(params) {
44
+ const raw = await callTool(client, "search_document", {
45
+ category: params.category,
46
+ filename: params.filename
47
+ });
48
+ return {
49
+ category: params.category,
50
+ filename: params.filename,
51
+ markdown: normalizeSearchDocumentOutput(raw)
52
+ };
53
+ },
54
+ async dispose() {
55
+ await client.close();
56
+ }
57
+ };
58
+ }
59
+ function createMcpClient(runtime) {
60
+ let nextId = 1;
61
+ const pending = new Map();
62
+ const stderrChunks = [];
63
+ let processRef = null;
64
+ let initialized = false;
65
+ let startupPromise = null;
66
+ let startupTimer = null;
67
+ let startupResolve = null;
68
+ let startupReject = null;
69
+ let buffer = Buffer.alloc(0);
70
+ function ensureStarted() {
71
+ if (processRef) {
72
+ return processRef;
73
+ }
74
+ const child = spawn(runtime.command, runtime.args, {
75
+ stdio: "pipe",
76
+ env: buildMcpEnv()
77
+ });
78
+ processRef = child;
79
+ startupPromise = new Promise((resolve, reject) => {
80
+ startupResolve = resolve;
81
+ startupReject = reject;
82
+ startupTimer = setTimeout(() => {
83
+ reject(new Error(`MCP server startup timed out after ${MCP_STARTUP_TIMEOUT_MS}ms`));
84
+ }, MCP_STARTUP_TIMEOUT_MS);
85
+ });
86
+ child.once("spawn", () => {
87
+ clearStartupTimer();
88
+ startupResolve?.();
89
+ });
90
+ child.on("error", (error) => {
91
+ const wrapped = new Error(`Failed to launch MCP server command "${runtime.command}": ${error.message}`);
92
+ clearStartupTimer();
93
+ startupReject?.(wrapped);
94
+ throwFromPending(wrapped);
95
+ });
96
+ child.on("exit", (code, signal) => {
97
+ const suffix = stderrChunks.length > 0 ? ` (${stderrChunks.join("").trim()})` : "";
98
+ const wrapped = new Error(`MCP server exited (code=${code ?? "null"}, signal=${signal ?? "null"})${suffix}`);
99
+ clearStartupTimer();
100
+ startupReject?.(wrapped);
101
+ throwFromPending(wrapped);
102
+ });
103
+ child.stderr.on("data", (chunk) => {
104
+ stderrChunks.push(Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk));
105
+ });
106
+ child.stdout.on("data", (chunk) => {
107
+ const part = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
108
+ buffer = Buffer.concat([buffer, part]);
109
+ try {
110
+ for (const message of readTransportMessages(() => buffer, (next) => {
111
+ buffer = next;
112
+ })) {
113
+ onMessage(message);
114
+ }
115
+ }
116
+ catch (error) {
117
+ const wrapped = new Error(`Failed to parse MCP response: ${error instanceof Error ? error.message : "unknown error"}`);
118
+ throwFromPending(wrapped);
119
+ }
120
+ });
121
+ return child;
122
+ }
123
+ async function request(method, params) {
124
+ const child = ensureStarted();
125
+ await startupPromise;
126
+ if (!initialized) {
127
+ await initialize(child);
128
+ initialized = true;
129
+ }
130
+ return requestRaw(child, method, params);
131
+ }
132
+ async function initialize(child) {
133
+ await requestRaw(child, "initialize", {
134
+ protocolVersion: "2025-06-18",
135
+ capabilities: {},
136
+ clientInfo: {
137
+ name: "mcms-cli",
138
+ version: "0.1.0"
139
+ }
140
+ });
141
+ const initializedNotification = serializeTransportMessage({
142
+ jsonrpc: "2.0",
143
+ method: "notifications/initialized",
144
+ params: {}
145
+ });
146
+ child.stdin.write(initializedNotification, (error) => {
147
+ if (error) {
148
+ throwFromPending(new Error(`Failed to send MCP initialized notification: ${error.message}`));
149
+ }
150
+ });
151
+ }
152
+ async function requestRaw(child, method, params) {
153
+ const id = nextId++;
154
+ const payload = {
155
+ jsonrpc: "2.0",
156
+ id,
157
+ method,
158
+ params
159
+ };
160
+ const serialized = serializeTransportMessage(payload);
161
+ return await new Promise((resolve, reject) => {
162
+ const timer = setTimeout(() => {
163
+ pending.delete(id);
164
+ reject(new Error(`MCP request timed out: ${method}`));
165
+ }, MCP_REQUEST_TIMEOUT_MS);
166
+ pending.set(id, {
167
+ resolve,
168
+ reject,
169
+ timer
170
+ });
171
+ child.stdin.write(serialized, (error) => {
172
+ if (!error) {
173
+ return;
174
+ }
175
+ const entry = pending.get(id);
176
+ if (!entry) {
177
+ return;
178
+ }
179
+ clearTimeout(entry.timer);
180
+ pending.delete(id);
181
+ reject(new Error(`Failed to write MCP request (${method}): ${error.message}`));
182
+ });
183
+ });
184
+ }
185
+ function onMessage(message) {
186
+ if (typeof message !== "object" || message === null) {
187
+ return;
188
+ }
189
+ const response = message;
190
+ if (typeof response.id !== "number") {
191
+ return;
192
+ }
193
+ const entry = pending.get(response.id);
194
+ if (!entry) {
195
+ return;
196
+ }
197
+ clearTimeout(entry.timer);
198
+ pending.delete(response.id);
199
+ if (response.error) {
200
+ const details = response.error.data === undefined ? "" : ` (${JSON.stringify(response.error.data)})`;
201
+ entry.reject(new Error(`${response.error.message ?? "MCP request failed"}${details}`));
202
+ return;
203
+ }
204
+ entry.resolve(response.result);
205
+ }
206
+ async function close() {
207
+ if (!processRef) {
208
+ return;
209
+ }
210
+ const child = processRef;
211
+ processRef = null;
212
+ initialized = false;
213
+ throwFromPending(new Error("MCP client closed"));
214
+ if (!child.killed) {
215
+ child.kill();
216
+ }
217
+ }
218
+ function throwFromPending(error) {
219
+ for (const [id, entry] of pending.entries()) {
220
+ clearTimeout(entry.timer);
221
+ entry.reject(error);
222
+ pending.delete(id);
223
+ }
224
+ }
225
+ function clearStartupTimer() {
226
+ if (startupTimer) {
227
+ clearTimeout(startupTimer);
228
+ startupTimer = null;
229
+ }
230
+ }
231
+ return {
232
+ request,
233
+ close
234
+ };
235
+ }
236
+ function resolveMcpRuntime() {
237
+ const overridden = MCP_COMMAND_OVERRIDE?.trim();
238
+ if (overridden && overridden.length > 0) {
239
+ const extension = extname(overridden).toLowerCase();
240
+ if (extension === ".js" || extension === ".mjs" || extension === ".cjs") {
241
+ return {
242
+ command: process.execPath,
243
+ args: [overridden]
244
+ };
245
+ }
246
+ return {
247
+ command: overridden,
248
+ args: []
249
+ };
250
+ }
251
+ try {
252
+ const require = createRequire(import.meta.url);
253
+ const packageJsonPath = require.resolve("microcms-document-mcp-server/package.json");
254
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
255
+ const binRelative = typeof packageJson.bin === "string"
256
+ ? packageJson.bin
257
+ : packageJson.bin?.["microcms-document-mcp-server"] ?? (packageJson.bin ? Object.values(packageJson.bin)[0] : undefined);
258
+ if (!binRelative) {
259
+ throw new Error("bin field is missing");
260
+ }
261
+ return {
262
+ command: process.execPath,
263
+ args: [resolve(dirname(packageJsonPath), binRelative)]
264
+ };
265
+ }
266
+ catch {
267
+ return {
268
+ command: "microcms-document-mcp-server",
269
+ args: []
270
+ };
271
+ }
272
+ }
273
+ function buildMcpEnv() {
274
+ const keys = ["PATH", "HOME", "USERPROFILE", "TMPDIR", "TMP", "TEMP", "SYSTEMROOT", "COMSPEC", "WINDIR", "LANG", "LC_ALL"];
275
+ const env = {};
276
+ for (const key of keys) {
277
+ const value = process.env[key];
278
+ if (value !== undefined) {
279
+ env[key] = value;
280
+ }
281
+ }
282
+ return env;
283
+ }
284
+ async function callTool(client, name, args) {
285
+ try {
286
+ const result = await client.request("tools/call", {
287
+ name,
288
+ arguments: args ?? {}
289
+ });
290
+ const text = extractToolText(result);
291
+ if (text === null) {
292
+ throw new Error(`MCP tool "${name}" returned unsupported response payload`);
293
+ }
294
+ return text;
295
+ }
296
+ catch (error) {
297
+ throw new CliError({
298
+ code: "INVALID_INPUT",
299
+ message: `MCP tool call failed (${name}): ${error instanceof Error ? error.message : "unknown error"}`,
300
+ exitCode: EXIT_CODE.INVALID_INPUT
301
+ });
302
+ }
303
+ }
304
+ function extractToolText(result) {
305
+ if (typeof result === "string") {
306
+ return result;
307
+ }
308
+ if (typeof result !== "object" || result === null) {
309
+ return null;
310
+ }
311
+ const maybeContent = result.content;
312
+ if (!Array.isArray(maybeContent)) {
313
+ return null;
314
+ }
315
+ const texts = maybeContent
316
+ .map((entry) => {
317
+ if (typeof entry !== "object" || entry === null) {
318
+ return null;
319
+ }
320
+ const item = entry;
321
+ if (item.type !== "text" || typeof item.text !== "string") {
322
+ return null;
323
+ }
324
+ return item.text;
325
+ })
326
+ .filter((text) => text !== null);
327
+ if (texts.length === 0) {
328
+ return null;
329
+ }
330
+ return texts.join("\n");
331
+ }
332
+ function parseListDocumentsPayload(raw) {
333
+ let parsed;
334
+ try {
335
+ parsed = JSON.parse(raw);
336
+ }
337
+ catch {
338
+ throw new CliError({
339
+ code: "INVALID_INPUT",
340
+ message: "MCP list_documents returned non-JSON payload",
341
+ exitCode: EXIT_CODE.INVALID_INPUT
342
+ });
343
+ }
344
+ if (typeof parsed !== "object" || parsed === null) {
345
+ throw new CliError({
346
+ code: "INVALID_INPUT",
347
+ message: "MCP list_documents returned invalid payload",
348
+ exitCode: EXIT_CODE.INVALID_INPUT
349
+ });
350
+ }
351
+ return parsed;
352
+ }
353
+ function normalizeSearchDocumentOutput(raw) {
354
+ const normalized = raw.replace(/\r\n/g, "\n").trim();
355
+ const marker = "\n---\n";
356
+ if (!normalized.startsWith("カテゴリー:") || !normalized.includes(marker)) {
357
+ return normalized;
358
+ }
359
+ const start = normalized.indexOf(marker);
360
+ return normalized.slice(start + 1).trim();
361
+ }
362
+ function serializeTransportMessage(payload) {
363
+ return Buffer.from(`${JSON.stringify(payload)}\n`, "utf8");
364
+ }
365
+ function* readTransportMessages(readBuffer, setBuffer) {
366
+ while (true) {
367
+ const current = readBuffer();
368
+ if (current.length === 0) {
369
+ return;
370
+ }
371
+ if (startsWithContentLengthHeader(current)) {
372
+ const separatorIndex = current.indexOf("\r\n\r\n");
373
+ if (separatorIndex < 0) {
374
+ return;
375
+ }
376
+ const headerText = current.slice(0, separatorIndex).toString("utf8");
377
+ const length = parseContentLength(headerText);
378
+ if (length === null) {
379
+ throw new Error("MCP framing error: missing Content-Length");
380
+ }
381
+ const bodyStart = separatorIndex + 4;
382
+ const bodyEnd = bodyStart + length;
383
+ if (current.length < bodyEnd) {
384
+ return;
385
+ }
386
+ const body = current.slice(bodyStart, bodyEnd).toString("utf8");
387
+ setBuffer(current.slice(bodyEnd));
388
+ yield parseJsonMessage(body);
389
+ continue;
390
+ }
391
+ const lineBreakIndex = current.indexOf(0x0a);
392
+ if (lineBreakIndex < 0) {
393
+ return;
394
+ }
395
+ const line = current.slice(0, lineBreakIndex).toString("utf8").replace(/\r$/, "").trim();
396
+ setBuffer(current.slice(lineBreakIndex + 1));
397
+ if (line.length === 0) {
398
+ continue;
399
+ }
400
+ yield parseJsonMessage(line);
401
+ }
402
+ }
403
+ function parseJsonMessage(raw) {
404
+ try {
405
+ return JSON.parse(raw);
406
+ }
407
+ catch (error) {
408
+ throw new Error(`MCP transport error: invalid JSON payload (${error instanceof Error ? error.message : "unknown"})`);
409
+ }
410
+ }
411
+ function startsWithContentLengthHeader(buffer) {
412
+ const probe = buffer.subarray(0, 32).toString("utf8").toLowerCase();
413
+ return probe.startsWith("content-length:");
414
+ }
415
+ function parseContentLength(headerText) {
416
+ const lines = headerText.split(/\r\n/);
417
+ for (const line of lines) {
418
+ const separator = line.indexOf(":");
419
+ if (separator < 0) {
420
+ continue;
421
+ }
422
+ const key = line.slice(0, separator).trim().toLowerCase();
423
+ if (key !== "content-length") {
424
+ continue;
425
+ }
426
+ const raw = line.slice(separator + 1).trim();
427
+ const parsed = Number.parseInt(raw, 10);
428
+ if (!Number.isFinite(parsed) || parsed < 0) {
429
+ return null;
430
+ }
431
+ return parsed;
432
+ }
433
+ return null;
434
+ }
435
+ //# sourceMappingURL=mcp-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-provider.js","sourceRoot":"","sources":["../../../src/core/docs/mcp-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export type DocsSourceMode = "auto" | "mcp" | "local";
2
+ export type DocsSourceResolved = "mcp" | "local";
3
+ export type DocsDocument = {
4
+ category: string;
5
+ filename: string;
6
+ };
7
+ export type DocsListResult = {
8
+ categories: Array<{
9
+ category: string;
10
+ count: number;
11
+ }>;
12
+ docs: DocsDocument[];
13
+ total: number;
14
+ };
15
+ export type DocsGetResult = {
16
+ category: string;
17
+ filename: string;
18
+ markdown: string;
19
+ };
20
+ export type DocsProvider = {
21
+ listDocuments(params: {
22
+ category?: string;
23
+ limit: number;
24
+ }): Promise<DocsListResult>;
25
+ getDocument(params: {
26
+ category: string;
27
+ filename: string;
28
+ }): Promise<DocsGetResult>;
29
+ dispose?(): Promise<void>;
30
+ };
31
+ export type ResolvedDocsProvider = {
32
+ provider: DocsProvider;
33
+ sourceResolved: DocsSourceResolved;
34
+ warnings: string[];
35
+ };
36
+ export declare function resolveDocsProvider(source: DocsSourceMode): Promise<ResolvedDocsProvider>;
37
+ export declare function parseDocsSourceOption(value: string | undefined): DocsSourceMode;
38
+ export declare function truncateMarkdown(markdown: string, maxChars: number | undefined): {
39
+ markdown: string;
40
+ truncated: boolean;
41
+ originalLength: number;
42
+ };
@@ -0,0 +1,76 @@
1
+ import { CliError } from "../errors.js";
2
+ import { EXIT_CODE } from "../exit-codes.js";
3
+ import { createLocalDocsProvider } from "./local-provider.js";
4
+ import { createMcpDocsProvider } from "./mcp-provider.js";
5
+ export async function resolveDocsProvider(source) {
6
+ if (source === "local") {
7
+ return {
8
+ provider: createLocalDocsProvider(),
9
+ sourceResolved: "local",
10
+ warnings: []
11
+ };
12
+ }
13
+ if (source === "mcp") {
14
+ const provider = createMcpDocsProvider();
15
+ await provider.healthcheck();
16
+ return {
17
+ provider,
18
+ sourceResolved: "mcp",
19
+ warnings: []
20
+ };
21
+ }
22
+ const mcpProvider = createMcpDocsProvider();
23
+ try {
24
+ await mcpProvider.healthcheck();
25
+ return {
26
+ provider: mcpProvider,
27
+ sourceResolved: "mcp",
28
+ warnings: []
29
+ };
30
+ }
31
+ catch (error) {
32
+ await mcpProvider.dispose?.();
33
+ const reason = toWarningMessage(error);
34
+ return {
35
+ provider: createLocalDocsProvider(),
36
+ sourceResolved: "local",
37
+ warnings: [`MCP source is unavailable, fell back to local source: ${reason}`]
38
+ };
39
+ }
40
+ }
41
+ export function parseDocsSourceOption(value) {
42
+ const normalized = value?.trim().toLowerCase() ?? "auto";
43
+ if (normalized === "auto" || normalized === "mcp" || normalized === "local") {
44
+ return normalized;
45
+ }
46
+ throw new CliError({
47
+ code: "INVALID_INPUT",
48
+ message: `Invalid source: ${value}. Expected auto, mcp, or local.`,
49
+ exitCode: EXIT_CODE.INVALID_INPUT
50
+ });
51
+ }
52
+ export function truncateMarkdown(markdown, maxChars) {
53
+ const originalLength = markdown.length;
54
+ if (!maxChars || originalLength <= maxChars) {
55
+ return {
56
+ markdown,
57
+ truncated: false,
58
+ originalLength
59
+ };
60
+ }
61
+ return {
62
+ markdown: `${markdown.slice(0, maxChars)}\n\n<!-- truncated -->`,
63
+ truncated: true,
64
+ originalLength
65
+ };
66
+ }
67
+ function toWarningMessage(error) {
68
+ if (error instanceof CliError) {
69
+ return error.message;
70
+ }
71
+ if (error instanceof Error) {
72
+ return error.message;
73
+ }
74
+ return "unknown error";
75
+ }
76
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/core/docs/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAkC1D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAsB;IAC9D,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO;YACL,QAAQ,EAAE,uBAAuB,EAAE;YACnC,cAAc,EAAE,OAAO;YACvB,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;QACzC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO;YACL,QAAQ;YACR,cAAc,EAAE,KAAK;YACrB,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,WAAW,EAAE,CAAC;QAChC,OAAO;YACL,QAAQ,EAAE,WAAW;YACrB,cAAc,EAAE,KAAK;YACrB,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACvC,OAAO;YACL,QAAQ,EAAE,uBAAuB,EAAE;YACnC,cAAc,EAAE,OAAO;YACvB,QAAQ,EAAE,CAAC,yDAAyD,MAAM,EAAE,CAAC;SAC9E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC;IACzD,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC5E,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,IAAI,QAAQ,CAAC;QACjB,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,mBAAmB,KAAK,iCAAiC;QAClE,QAAQ,EAAE,SAAS,CAAC,aAAa;KAClC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,QAA4B;IAK7E,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC;IACvC,IAAI,CAAC,QAAQ,IAAI,cAAc,IAAI,QAAQ,EAAE,CAAC;QAC5C,OAAO;YACL,QAAQ;YACR,SAAS,EAAE,KAAK;YAChB,cAAc;SACf,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,wBAAwB;QAChE,SAAS,EAAE,IAAI;QACf,cAAc;KACf,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export type SearchHit = {
2
+ kind: "command" | "doc";
3
+ title: string;
4
+ ref: string;
5
+ snippet: string;
6
+ score: number;
7
+ source: "local" | "mcp";
8
+ category?: string;
9
+ filename?: string;
10
+ };
11
+ export declare function rankSearchHits(query: string, hits: SearchHit[], limit: number): SearchHit[];
@@ -0,0 +1,48 @@
1
+ export function rankSearchHits(query, hits, limit) {
2
+ const normalizedQuery = normalize(query);
3
+ const tokens = tokenize(normalizedQuery);
4
+ const scored = hits
5
+ .map((hit) => ({
6
+ hit,
7
+ score: computeScore(tokens, normalizedQuery, `${hit.title}\n${hit.ref}\n${hit.snippet}`)
8
+ }))
9
+ .filter((item) => item.score > 0)
10
+ .sort((a, b) => {
11
+ if (b.score !== a.score) {
12
+ return b.score - a.score;
13
+ }
14
+ return a.hit.title.localeCompare(b.hit.title);
15
+ })
16
+ .slice(0, limit)
17
+ .map((item) => ({
18
+ ...item.hit,
19
+ score: item.score
20
+ }));
21
+ return scored;
22
+ }
23
+ function computeScore(tokens, normalizedQuery, haystackRaw) {
24
+ const haystack = normalize(haystackRaw);
25
+ let score = 0;
26
+ if (normalizedQuery.length > 0 && haystack.includes(normalizedQuery)) {
27
+ score += 5;
28
+ }
29
+ for (const token of tokens) {
30
+ if (token.length < 2) {
31
+ continue;
32
+ }
33
+ if (haystack.includes(token)) {
34
+ score += 2;
35
+ }
36
+ }
37
+ return score;
38
+ }
39
+ function normalize(value) {
40
+ return value.toLowerCase().normalize("NFKC");
41
+ }
42
+ function tokenize(value) {
43
+ return value
44
+ .split(/[^\p{L}\p{N}_-]+/u)
45
+ .map((token) => token.trim())
46
+ .filter((token) => token.length > 0);
47
+ }
48
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,IAAiB,EAAE,KAAa;IAC5E,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI;SAChB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACb,GAAG;QACH,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;KACzF,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;SAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAC3B,CAAC;QAED,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,GAAG;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC,CAAC;IAEN,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB,EAAE,eAAuB,EAAE,WAAmB;IAClF,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAExC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACrE,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,KAAK;SACT,KAAK,CAAC,mBAAmB,CAAC;SAC1B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,20 @@
1
+ export type GlobalOptionSpec = {
2
+ name: string;
3
+ description: string;
4
+ };
5
+ export type CommandSpec = {
6
+ path: string;
7
+ description: string;
8
+ args: string[];
9
+ options: string[];
10
+ readOnly: boolean;
11
+ };
12
+ export type CliSpec = {
13
+ name: string;
14
+ version: string;
15
+ jsonContractVersion: string;
16
+ globalOptions: GlobalOptionSpec[];
17
+ exitCodes: Record<string, number>;
18
+ commands: CommandSpec[];
19
+ };
20
+ export declare function getCliSpec(): CliSpec;