@elaraai/east-plugin 0.0.0-stage → 1.0.85
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/LICENSE.md +682 -0
- package/README.md +104 -2
- package/dist/daemon/east-py-lsp.d.ts +2 -0
- package/dist/daemon/east-py-lsp.d.ts.map +1 -0
- package/dist/daemon/east-py-lsp.js +9 -0
- package/dist/daemon/east-py-lsp.js.map +1 -0
- package/dist/daemon/lsp.d.ts +2 -0
- package/dist/daemon/lsp.d.ts.map +1 -0
- package/dist/daemon/lsp.js +7 -0
- package/dist/daemon/lsp.js.map +1 -0
- package/dist/daemon/server.d.ts +2 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +71 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/hooks/diagnose-bash.d.ts +2 -0
- package/dist/hooks/diagnose-bash.d.ts.map +1 -0
- package/dist/hooks/diagnose-bash.js +28 -0
- package/dist/hooks/diagnose-bash.js.map +1 -0
- package/dist/hooks/diagnose.d.ts +2 -0
- package/dist/hooks/diagnose.d.ts.map +1 -0
- package/dist/hooks/diagnose.js +33 -0
- package/dist/hooks/diagnose.js.map +1 -0
- package/dist/hooks/pre-read.d.ts +2 -0
- package/dist/hooks/pre-read.d.ts.map +1 -0
- package/dist/hooks/pre-read.js +11 -0
- package/dist/hooks/pre-read.js.map +1 -0
- package/dist/hooks/pre-write.d.ts +2 -0
- package/dist/hooks/pre-write.d.ts.map +1 -0
- package/dist/hooks/pre-write.js +11 -0
- package/dist/hooks/pre-write.js.map +1 -0
- package/dist/hooks/session-start.d.ts +2 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +34 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/hooks/subagent-start.d.ts +2 -0
- package/dist/hooks/subagent-start.d.ts.map +1 -0
- package/dist/hooks/subagent-start.js +29 -0
- package/dist/hooks/subagent-start.js.map +1 -0
- package/dist/lib/bash-writes.d.ts +11 -0
- package/dist/lib/bash-writes.d.ts.map +1 -0
- package/dist/lib/bash-writes.js +74 -0
- package/dist/lib/bash-writes.js.map +1 -0
- package/dist/lib/codex-hook.d.ts +62 -0
- package/dist/lib/codex-hook.d.ts.map +1 -0
- package/dist/lib/codex-hook.js +93 -0
- package/dist/lib/codex-hook.js.map +1 -0
- package/dist/lib/codex-skills.d.ts +38 -0
- package/dist/lib/codex-skills.d.ts.map +1 -0
- package/dist/lib/codex-skills.js +80 -0
- package/dist/lib/codex-skills.js.map +1 -0
- package/dist/lib/codex-tools.d.ts +11 -0
- package/dist/lib/codex-tools.d.ts.map +1 -0
- package/dist/lib/codex-tools.js +41 -0
- package/dist/lib/codex-tools.js.map +1 -0
- package/dist/lib/diagnostics-client.d.ts +9 -0
- package/dist/lib/diagnostics-client.d.ts.map +1 -0
- package/dist/lib/diagnostics-client.js +123 -0
- package/dist/lib/diagnostics-client.js.map +1 -0
- package/dist/lib/east-index.d.ts +3 -0
- package/dist/lib/east-index.d.ts.map +1 -0
- package/dist/lib/east-index.js +9 -0
- package/dist/lib/east-index.js.map +1 -0
- package/dist/lib/east-project.d.ts +49 -0
- package/dist/lib/east-project.d.ts.map +1 -0
- package/dist/lib/east-project.js +121 -0
- package/dist/lib/east-project.js.map +1 -0
- package/dist/lib/east-py-lint.d.ts +7 -0
- package/dist/lib/east-py-lint.d.ts.map +1 -0
- package/dist/lib/east-py-lint.js +22 -0
- package/dist/lib/east-py-lint.js.map +1 -0
- package/dist/lib/east-rules-context.d.ts +7 -0
- package/dist/lib/east-rules-context.d.ts.map +1 -0
- package/dist/lib/east-rules-context.js +91 -0
- package/dist/lib/east-rules-context.js.map +1 -0
- package/dist/lib/hook-io.d.ts +30 -0
- package/dist/lib/hook-io.d.ts.map +1 -0
- package/dist/lib/hook-io.js +29 -0
- package/dist/lib/hook-io.js.map +1 -0
- package/dist/lib/host.d.ts +3 -0
- package/dist/lib/host.d.ts.map +1 -0
- package/dist/lib/host.js +9 -0
- package/dist/lib/host.js.map +1 -0
- package/dist/lib/lsp-client.d.ts +34 -0
- package/dist/lib/lsp-client.d.ts.map +1 -0
- package/dist/lib/lsp-client.js +200 -0
- package/dist/lib/lsp-client.js.map +1 -0
- package/dist/lib/plugin-status.d.ts +9 -0
- package/dist/lib/plugin-status.d.ts.map +1 -0
- package/dist/lib/plugin-status.js +164 -0
- package/dist/lib/plugin-status.js.map +1 -0
- package/dist/lib/review.d.ts +16 -0
- package/dist/lib/review.d.ts.map +1 -0
- package/dist/lib/review.js +74 -0
- package/dist/lib/review.js.map +1 -0
- package/dist/lib/search-guidance.d.ts +44 -0
- package/dist/lib/search-guidance.d.ts.map +1 -0
- package/dist/lib/search-guidance.js +73 -0
- package/dist/lib/search-guidance.js.map +1 -0
- package/dist/lib/search-hooks.d.ts +75 -0
- package/dist/lib/search-hooks.d.ts.map +1 -0
- package/dist/lib/search-hooks.js +117 -0
- package/dist/lib/search-hooks.js.map +1 -0
- package/dist/lib/search.d.ts +108 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +167 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/transcript.d.ts +29 -0
- package/dist/lib/transcript.d.ts.map +1 -0
- package/dist/lib/transcript.js +109 -0
- package/dist/lib/transcript.js.map +1 -0
- package/dist/mcp/example-tools.d.ts +26 -0
- package/dist/mcp/example-tools.d.ts.map +1 -0
- package/dist/mcp/example-tools.js +94 -0
- package/dist/mcp/example-tools.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +51 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/scripts/examples-file.d.ts +38 -0
- package/dist/scripts/examples-file.d.ts.map +1 -0
- package/dist/scripts/examples-file.js +224 -0
- package/dist/scripts/examples-file.js.map +1 -0
- package/dist/scripts/generate-index.d.ts +127 -0
- package/dist/scripts/generate-index.d.ts.map +1 -0
- package/dist/scripts/generate-index.js +315 -0
- package/dist/scripts/generate-index.js.map +1 -0
- package/dist/status/report.d.ts +2 -0
- package/dist/status/report.d.ts.map +1 -0
- package/dist/status/report.js +9 -0
- package/dist/status/report.js.map +1 -0
- package/index.json +44929 -0
- package/package.json +66 -4
- package/scripts/render-python.py +67 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import MiniSearch from "minisearch";
|
|
2
|
+
export declare const MIN_SCORE = 5;
|
|
3
|
+
export type Language = "typescript" | "python";
|
|
4
|
+
export type Format = "summary" | "full";
|
|
5
|
+
export interface IndexEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
skill: string;
|
|
8
|
+
package: string;
|
|
9
|
+
file: string;
|
|
10
|
+
suite: string;
|
|
11
|
+
test: string;
|
|
12
|
+
keywords: string[];
|
|
13
|
+
imports: string[];
|
|
14
|
+
/** `["typescript", "python"]` (a program, printed from IR), `["tsx"]` (JSX-authored UI), `["typescript"]` (authored, not a program). */
|
|
15
|
+
languages: Array<"typescript" | "python" | "tsx">;
|
|
16
|
+
/** Authored TypeScript (UI and static entries). */
|
|
17
|
+
source?: string;
|
|
18
|
+
/** The example's IR as JSON (program entries). */
|
|
19
|
+
ir?: string;
|
|
20
|
+
/** The TypeScript printed from the IR (program entries). */
|
|
21
|
+
ts?: string;
|
|
22
|
+
/** The python printed from the IR, or null when the index was built without python (program entries). */
|
|
23
|
+
python?: string | null;
|
|
24
|
+
signature?: {
|
|
25
|
+
inputs: string[];
|
|
26
|
+
output: string;
|
|
27
|
+
async: boolean;
|
|
28
|
+
};
|
|
29
|
+
inputs?: string | null;
|
|
30
|
+
returns?: string | null;
|
|
31
|
+
builtins?: string[];
|
|
32
|
+
}
|
|
33
|
+
/** The fields MiniSearch scores — derived text, not stored twice. */
|
|
34
|
+
interface SearchDocument extends IndexEntry {
|
|
35
|
+
keywordsText: string;
|
|
36
|
+
builtinsText: string;
|
|
37
|
+
typesText: string;
|
|
38
|
+
code: string;
|
|
39
|
+
}
|
|
40
|
+
export type ExampleIndex = MiniSearch<SearchDocument>;
|
|
41
|
+
/** The loaded index: the search over it and the package names it holds. */
|
|
42
|
+
export interface LoadedIndex {
|
|
43
|
+
search: ExampleIndex;
|
|
44
|
+
/** Every indexed package name, sorted — the values the `package` filter accepts. */
|
|
45
|
+
packages: string[];
|
|
46
|
+
}
|
|
47
|
+
/** The searchable index over `indexPath` (loaded once per process). */
|
|
48
|
+
export declare function buildSearchIndex(indexPath: string): Promise<ExampleIndex>;
|
|
49
|
+
/** The index over `indexPath`, with its package names. */
|
|
50
|
+
export declare function loadIndex(indexPath: string): Promise<LoadedIndex>;
|
|
51
|
+
/**
|
|
52
|
+
* One search over several index files: a plugin that builds on East's serves
|
|
53
|
+
* East's corpus and its own together, the package filter knowing both. An id
|
|
54
|
+
* is the example's package, file and export, so two corpora never share one;
|
|
55
|
+
* an id found in two files is refused, naming both, rather than one shadowing
|
|
56
|
+
* the other.
|
|
57
|
+
*
|
|
58
|
+
* @param indexPaths - The `index.json` files, East's (`EAST_INDEX_PATH`) among them to answer its corpus too
|
|
59
|
+
* @returns The index over every file's entries, with their package names
|
|
60
|
+
*/
|
|
61
|
+
export declare function loadIndexes(indexPaths: readonly string[]): Promise<LoadedIndex>;
|
|
62
|
+
/** A package filter as the index names packages: `@elaraai/east-node-io` and `east-node-io` are the same package. */
|
|
63
|
+
export declare function normalizePackage(filter: string): string;
|
|
64
|
+
export interface SearchRequest {
|
|
65
|
+
query: string;
|
|
66
|
+
limit: number;
|
|
67
|
+
/** A package or skill name; the `@elaraai/` scope is accepted and ignored. */
|
|
68
|
+
package?: string | undefined;
|
|
69
|
+
}
|
|
70
|
+
export interface SearchResult {
|
|
71
|
+
entries: IndexEntry[];
|
|
72
|
+
/** Set when the package filter names no indexed package — the caller should say so, with `known`. */
|
|
73
|
+
unknownPackage?: string;
|
|
74
|
+
known: string[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The search the tool runs: scored hits above `MIN_SCORE`, the package
|
|
78
|
+
* filter applied INSIDE the search so `limit` counts filtered hits (a filter
|
|
79
|
+
* applied after a capped result list starves), and an unknown package
|
|
80
|
+
* reported rather than returned as an empty list.
|
|
81
|
+
*/
|
|
82
|
+
export declare function searchExamples(index: LoadedIndex, request: SearchRequest): SearchResult;
|
|
83
|
+
/** Whether an entry has something to show for a requested language: `typescript` covers authored TSX too. */
|
|
84
|
+
export declare function speaks(entry: IndexEntry, language: Language): boolean;
|
|
85
|
+
/** The code of an entry in `language` and the fence it takes, or null when the entry has none in it. */
|
|
86
|
+
export declare function codeOf(entry: IndexEntry, language: Language): {
|
|
87
|
+
code: string;
|
|
88
|
+
fence: string;
|
|
89
|
+
} | null;
|
|
90
|
+
/** What the tools' words call the corpus and its fetch tool. */
|
|
91
|
+
export interface CorpusNames {
|
|
92
|
+
/** The corpus, as in "East example(s)". */
|
|
93
|
+
corpus: string;
|
|
94
|
+
/** The tool that fetches one example in full. */
|
|
95
|
+
getTool: string;
|
|
96
|
+
}
|
|
97
|
+
/** East's names. */
|
|
98
|
+
export declare const EAST_CORPUS: CorpusNames;
|
|
99
|
+
/** One line per hit: id, description, signature, keywords, the example's inputs and result. */
|
|
100
|
+
export declare function formatSummary(entries: IndexEntry[], language: Language, names?: CorpusNames): string;
|
|
101
|
+
/** An entry in full: its description, signature, code in `language`, and the example inputs and result. */
|
|
102
|
+
export declare function formatFull(entries: IndexEntry[], language: Language): string;
|
|
103
|
+
/** Search results as the tool renders them. */
|
|
104
|
+
export declare function formatResults(entries: IndexEntry[], language: Language, format: Format, names?: CorpusNames): string;
|
|
105
|
+
/** The index entry with `id`, or null. */
|
|
106
|
+
export declare function getEntry(index: ExampleIndex, id: string): IndexEntry | null;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../lib/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import MiniSearch from "minisearch";
|
|
3
|
+
// The example index (#654): every East program example stored as its IR with
|
|
4
|
+
// the TypeScript and python printed from it, UI and hand-written examples as
|
|
5
|
+
// their authored TypeScript. Searched by what an example IS — its keywords,
|
|
6
|
+
// description, the builtins it calls, its types — and rendered in the
|
|
7
|
+
// language the caller asks for, as a summary or in full.
|
|
8
|
+
export const MIN_SCORE = 5;
|
|
9
|
+
/** The searchable index over `indexPath` (loaded once per process). */
|
|
10
|
+
export async function buildSearchIndex(indexPath) {
|
|
11
|
+
return (await loadIndex(indexPath)).search;
|
|
12
|
+
}
|
|
13
|
+
/** The index over `indexPath`, with its package names. */
|
|
14
|
+
export async function loadIndex(indexPath) {
|
|
15
|
+
return loadIndexes([indexPath]);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One search over several index files: a plugin that builds on East's serves
|
|
19
|
+
* East's corpus and its own together, the package filter knowing both. An id
|
|
20
|
+
* is the example's package, file and export, so two corpora never share one;
|
|
21
|
+
* an id found in two files is refused, naming both, rather than one shadowing
|
|
22
|
+
* the other.
|
|
23
|
+
*
|
|
24
|
+
* @param indexPaths - The `index.json` files, East's (`EAST_INDEX_PATH`) among them to answer its corpus too
|
|
25
|
+
* @returns The index over every file's entries, with their package names
|
|
26
|
+
*/
|
|
27
|
+
export async function loadIndexes(indexPaths) {
|
|
28
|
+
const entries = [];
|
|
29
|
+
const fileOf = new Map();
|
|
30
|
+
for (const indexPath of indexPaths) {
|
|
31
|
+
const data = JSON.parse(await readFile(indexPath, "utf-8"));
|
|
32
|
+
for (const entry of data.entries) {
|
|
33
|
+
const first = fileOf.get(entry.id);
|
|
34
|
+
if (first !== undefined)
|
|
35
|
+
throw new Error(`example id "${entry.id}" is in both ${first} and ${indexPath}`);
|
|
36
|
+
fileOf.set(entry.id, indexPath);
|
|
37
|
+
entries.push(entry);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const data = { entries };
|
|
41
|
+
const miniSearch = new MiniSearch({
|
|
42
|
+
idField: "id",
|
|
43
|
+
fields: ["keywordsText", "test", "builtinsText", "suite", "typesText", "code"],
|
|
44
|
+
storeFields: ["id", "skill", "package", "suite", "test", "keywords", "imports", "languages", "source", "ts", "python", "signature", "inputs", "returns", "builtins"],
|
|
45
|
+
searchOptions: {
|
|
46
|
+
boost: { keywordsText: 3, test: 2, builtinsText: 2, suite: 1.5, typesText: 1, code: 1 },
|
|
47
|
+
fuzzy: 0.2,
|
|
48
|
+
prefix: true,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const documents = data.entries.map((entry) => ({
|
|
52
|
+
...entry,
|
|
53
|
+
keywordsText: entry.keywords.join(" "),
|
|
54
|
+
builtinsText: (entry.builtins ?? []).join(" "),
|
|
55
|
+
typesText: entry.signature ? [...entry.signature.inputs, entry.signature.output].join(" ") : "",
|
|
56
|
+
code: entry.source ?? entry.ts ?? "",
|
|
57
|
+
}));
|
|
58
|
+
miniSearch.addAll(documents);
|
|
59
|
+
return { search: miniSearch, packages: [...new Set(data.entries.map((e) => e.package))].sort() };
|
|
60
|
+
}
|
|
61
|
+
/** A package filter as the index names packages: `@elaraai/east-node-io` and `east-node-io` are the same package. */
|
|
62
|
+
export function normalizePackage(filter) {
|
|
63
|
+
return filter.trim().toLowerCase().replace(/^@elaraai\//, "");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The search the tool runs: scored hits above `MIN_SCORE`, the package
|
|
67
|
+
* filter applied INSIDE the search so `limit` counts filtered hits (a filter
|
|
68
|
+
* applied after a capped result list starves), and an unknown package
|
|
69
|
+
* reported rather than returned as an empty list.
|
|
70
|
+
*/
|
|
71
|
+
export function searchExamples(index, request) {
|
|
72
|
+
const known = index.packages;
|
|
73
|
+
const filter = request.package;
|
|
74
|
+
const pkg = typeof filter === "string" && filter.trim() !== "" ? normalizePackage(filter) : undefined;
|
|
75
|
+
if (pkg !== undefined && typeof filter === "string" && !known.includes(pkg)) {
|
|
76
|
+
return { entries: [], unknownPackage: filter, known };
|
|
77
|
+
}
|
|
78
|
+
const options = {
|
|
79
|
+
limit: request.limit,
|
|
80
|
+
...(pkg === undefined ? {} : { filter: (r) => r.package === pkg || r.skill === pkg }),
|
|
81
|
+
};
|
|
82
|
+
const hits = index.search.search(request.query, options);
|
|
83
|
+
return { entries: hits.filter((r) => r.score >= MIN_SCORE).slice(0, request.limit), known };
|
|
84
|
+
}
|
|
85
|
+
/** `(inputs) -> output`, or the kind of a non-program entry. */
|
|
86
|
+
function signatureOf(entry) {
|
|
87
|
+
if (entry.signature === undefined)
|
|
88
|
+
return entry.languages.includes("tsx") ? "tsx (a UI component, authored as JSX)" : "typescript (authored)";
|
|
89
|
+
const arrow = entry.signature.async ? "~>" : "->";
|
|
90
|
+
return `(${entry.signature.inputs.join(", ")}) ${arrow} ${entry.signature.output}`;
|
|
91
|
+
}
|
|
92
|
+
function clip(text, max) {
|
|
93
|
+
return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
|
|
94
|
+
}
|
|
95
|
+
/** Whether an entry has something to show for a requested language: `typescript` covers authored TSX too. */
|
|
96
|
+
export function speaks(entry, language) {
|
|
97
|
+
return language === "python" ? entry.languages.includes("python") : entry.languages.some((l) => l === "typescript" || l === "tsx");
|
|
98
|
+
}
|
|
99
|
+
/** The code of an entry in `language` and the fence it takes, or null when the entry has none in it. */
|
|
100
|
+
export function codeOf(entry, language) {
|
|
101
|
+
if (language === "python")
|
|
102
|
+
return entry.python ? { code: entry.python, fence: "python" } : null;
|
|
103
|
+
if (entry.ts !== undefined)
|
|
104
|
+
return { code: entry.ts, fence: "typescript" };
|
|
105
|
+
if (entry.source !== undefined) {
|
|
106
|
+
return { code: [...entry.imports, "", entry.source].join("\n"), fence: entry.languages.includes("tsx") ? "tsx" : "typescript" };
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/** East's names. */
|
|
111
|
+
export const EAST_CORPUS = { corpus: "East", getTool: "get_east_example" };
|
|
112
|
+
/** One line per hit: id, description, signature, keywords, the example's inputs and result. */
|
|
113
|
+
export function formatSummary(entries, language, names = EAST_CORPUS) {
|
|
114
|
+
const lines = entries.map((e) => {
|
|
115
|
+
const parts = [`- \`${e.id}\` — ${e.test}`, ` ${signatureOf(e)}`];
|
|
116
|
+
if (e.keywords.length > 0)
|
|
117
|
+
parts.push(` keywords: ${clip(e.keywords.join(", "), 160)}`);
|
|
118
|
+
if (e.inputs !== undefined && e.inputs !== null)
|
|
119
|
+
parts.push(` e.g. ${clip(e.inputs, 100)} → ${e.returns === null || e.returns === undefined ? "(see the example)" : clip(e.returns, 100)}`);
|
|
120
|
+
if (language === "python" && !speaks(e, "python"))
|
|
121
|
+
parts.push(` (${e.languages.join("/")} only)`);
|
|
122
|
+
else if (language === "python" && !e.python)
|
|
123
|
+
parts.push(" (no python rendering in this index build)");
|
|
124
|
+
return parts.join("\n");
|
|
125
|
+
});
|
|
126
|
+
return [
|
|
127
|
+
"<east-examples>",
|
|
128
|
+
`## ${entries.length} ${names.corpus} example(s) — fetch one in full with ${names.getTool}(id, language: "${language}")`,
|
|
129
|
+
"",
|
|
130
|
+
...lines,
|
|
131
|
+
"</east-examples>",
|
|
132
|
+
].join("\n");
|
|
133
|
+
}
|
|
134
|
+
/** An entry in full: its description, signature, code in `language`, and the example inputs and result. */
|
|
135
|
+
export function formatFull(entries, language) {
|
|
136
|
+
const sections = entries.map((e) => {
|
|
137
|
+
const code = codeOf(e, language);
|
|
138
|
+
const body = code === null
|
|
139
|
+
? (!speaks(e, language)
|
|
140
|
+
? `_${e.languages.join("/")} only: request language: "typescript"._`
|
|
141
|
+
: "_No python rendering in this index build._")
|
|
142
|
+
: ["```" + code.fence, code.code, "```"].join("\n");
|
|
143
|
+
const io = e.inputs !== undefined && e.inputs !== null
|
|
144
|
+
? `Inputs: \`${clip(e.inputs, 300)}\`${e.returns === null || e.returns === undefined ? "" : ` → returns \`${clip(e.returns, 300)}\``}`
|
|
145
|
+
: "";
|
|
146
|
+
return [
|
|
147
|
+
`### \`${e.id}\``,
|
|
148
|
+
`${e.test} · Suite: ${e.suite} · Package: ${e.package}`,
|
|
149
|
+
`Signature: ${signatureOf(e)}`,
|
|
150
|
+
e.keywords.length > 0 ? `Keywords: ${e.keywords.join(", ")}` : "",
|
|
151
|
+
"",
|
|
152
|
+
body,
|
|
153
|
+
io,
|
|
154
|
+
].filter((l) => l !== "").join("\n");
|
|
155
|
+
});
|
|
156
|
+
return ["<east-examples>", ...sections, "</east-examples>"].join("\n\n");
|
|
157
|
+
}
|
|
158
|
+
/** Search results as the tool renders them. */
|
|
159
|
+
export function formatResults(entries, language, format, names = EAST_CORPUS) {
|
|
160
|
+
return format === "full" ? formatFull(entries, language) : formatSummary(entries, language, names);
|
|
161
|
+
}
|
|
162
|
+
/** The index entry with `id`, or null. */
|
|
163
|
+
export function getEntry(index, id) {
|
|
164
|
+
const stored = index.getStoredFields(id);
|
|
165
|
+
return stored === undefined ? null : stored;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../lib/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The example-search tools, as the transcript records their use. */
|
|
2
|
+
export declare const SEARCH_TOOLS: string[];
|
|
3
|
+
/**
|
|
4
|
+
* Whether the session's transcript records a call of an example-search tool
|
|
5
|
+
* (the whole file, once).
|
|
6
|
+
*
|
|
7
|
+
* @param transcriptPath - The session's transcript
|
|
8
|
+
* @param tools - The tools whose call counts as a search (default East's)
|
|
9
|
+
* @returns Whether one of them was called
|
|
10
|
+
*/
|
|
11
|
+
export declare function searchedInTranscript(transcriptPath: string, tools?: readonly string[]): Promise<boolean>;
|
|
12
|
+
interface ContentBlock {
|
|
13
|
+
type: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
thinking?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
input?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
interface TranscriptEntry {
|
|
20
|
+
type: string;
|
|
21
|
+
message?: {
|
|
22
|
+
content?: ContentBlock[] | string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare function readRecentEntries(transcriptPath: string, maxEntries?: number): Promise<TranscriptEntry[]>;
|
|
26
|
+
export declare function extractRecentContext(entries: TranscriptEntry[]): string;
|
|
27
|
+
export declare function extractRecentFiles(entries: TranscriptEntry[], maxFiles?: number): string[];
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=transcript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../lib/transcript.ts"],"names":[],"mappings":"AAIA,qEAAqE;AACrE,eAAO,MAAM,YAAY,UAA+J,CAAC;AAEzL;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,MAAM,EAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ5H;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;KACnC,CAAC;CACH;AAED,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA2B3G;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAmCvE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,QAAQ,SAAK,GAAG,MAAM,EAAE,CAqBtF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
const MAX_READ_BYTES = 200_000;
|
|
3
|
+
/** The example-search tools, as the transcript records their use. */
|
|
4
|
+
export const SEARCH_TOOLS = ["mcp__plugin_east_east__search_east_examples", "mcp__plugin_east_east__get_east_example", "mcp__east__search_east_examples", "mcp__east__get_east_example"];
|
|
5
|
+
/**
|
|
6
|
+
* Whether the session's transcript records a call of an example-search tool
|
|
7
|
+
* (the whole file, once).
|
|
8
|
+
*
|
|
9
|
+
* @param transcriptPath - The session's transcript
|
|
10
|
+
* @param tools - The tools whose call counts as a search (default East's)
|
|
11
|
+
* @returns Whether one of them was called
|
|
12
|
+
*/
|
|
13
|
+
export async function searchedInTranscript(transcriptPath, tools = SEARCH_TOOLS) {
|
|
14
|
+
let raw;
|
|
15
|
+
try {
|
|
16
|
+
raw = await readFile(transcriptPath, "utf-8");
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return tools.some((tool) => raw.includes(`"name":"${tool}"`) || raw.includes(`"name": "${tool}"`));
|
|
22
|
+
}
|
|
23
|
+
export async function readRecentEntries(transcriptPath, maxEntries = 30) {
|
|
24
|
+
let raw;
|
|
25
|
+
try {
|
|
26
|
+
const buf = await readFile(transcriptPath);
|
|
27
|
+
const slice = buf.length > MAX_READ_BYTES
|
|
28
|
+
? buf.subarray(buf.length - MAX_READ_BYTES)
|
|
29
|
+
: buf;
|
|
30
|
+
raw = slice.toString("utf-8");
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const lines = raw.trimEnd().split("\n");
|
|
36
|
+
const entries = [];
|
|
37
|
+
for (let i = lines.length - 1; i >= 0 && entries.length < maxEntries; i--) {
|
|
38
|
+
try {
|
|
39
|
+
const entry = JSON.parse(lines[i]);
|
|
40
|
+
if (entry.type === "assistant" || entry.type === "user") {
|
|
41
|
+
entries.push(entry);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// skip malformed lines (including partial first line from slice)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return entries;
|
|
49
|
+
}
|
|
50
|
+
export function extractRecentContext(entries) {
|
|
51
|
+
const texts = [];
|
|
52
|
+
const files = [];
|
|
53
|
+
let textCount = 0;
|
|
54
|
+
for (const entry of entries) {
|
|
55
|
+
if (entry.type !== "assistant")
|
|
56
|
+
continue;
|
|
57
|
+
const content = entry.message?.content;
|
|
58
|
+
if (!Array.isArray(content))
|
|
59
|
+
continue;
|
|
60
|
+
for (const block of content) {
|
|
61
|
+
if (block.type === "text" && block.text) {
|
|
62
|
+
texts.push(block.text);
|
|
63
|
+
textCount++;
|
|
64
|
+
}
|
|
65
|
+
else if (block.type === "thinking" && block.thinking) {
|
|
66
|
+
texts.push(block.thinking);
|
|
67
|
+
textCount++;
|
|
68
|
+
}
|
|
69
|
+
else if (block.type === "tool_use") {
|
|
70
|
+
const filePath = block.input?.file_path;
|
|
71
|
+
if (typeof filePath === "string" && !files.includes(filePath)) {
|
|
72
|
+
files.push(filePath);
|
|
73
|
+
}
|
|
74
|
+
if (block.name === "Grep" && typeof block.input?.pattern === "string") {
|
|
75
|
+
texts.push(block.input.pattern);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (textCount >= 5)
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
const fileContext = files.slice(0, 5).map((f) => f.split("/").pop()).join(" ");
|
|
83
|
+
const reasoning = texts.join("\n").slice(0, 2000);
|
|
84
|
+
return [reasoning, fileContext].filter(Boolean).join("\n");
|
|
85
|
+
}
|
|
86
|
+
export function extractRecentFiles(entries, maxFiles = 10) {
|
|
87
|
+
const files = [];
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
if (entry.type !== "assistant")
|
|
90
|
+
continue;
|
|
91
|
+
const content = entry.message?.content;
|
|
92
|
+
if (!Array.isArray(content))
|
|
93
|
+
continue;
|
|
94
|
+
for (const block of content) {
|
|
95
|
+
if (block.type !== "tool_use")
|
|
96
|
+
continue;
|
|
97
|
+
if (!["Read", "Edit", "Write"].includes(block.name ?? ""))
|
|
98
|
+
continue;
|
|
99
|
+
const filePath = block.input?.file_path;
|
|
100
|
+
if (typeof filePath === "string" && !files.includes(filePath)) {
|
|
101
|
+
files.push(filePath);
|
|
102
|
+
if (files.length >= maxFiles)
|
|
103
|
+
return files;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return files;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../lib/transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type LoadedIndex } from "../lib/search.js";
|
|
3
|
+
/** East's indexed packages, as the search tool's package filter names them. */
|
|
4
|
+
export declare const EAST_PACKAGES: readonly string[];
|
|
5
|
+
/** What the search and fetch tools answer from, and the names they go by. */
|
|
6
|
+
export interface ExampleToolsOptions {
|
|
7
|
+
/** The `index.json` files the tools answer from, read once — East's (`EAST_INDEX_PATH`) among them to answer its corpus too — or an index already loaded. */
|
|
8
|
+
index: readonly string[] | Promise<LoadedIndex>;
|
|
9
|
+
/** The search tool's name (default `search_east_examples`). */
|
|
10
|
+
searchTool?: string;
|
|
11
|
+
/** The fetch tool's name (default `get_east_example`). */
|
|
12
|
+
getTool?: string;
|
|
13
|
+
/** What the tools call the corpus and its code (default `East`). */
|
|
14
|
+
corpus?: string;
|
|
15
|
+
/** The package names the package filter's description lists (default East's). */
|
|
16
|
+
packages?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Registers the example search and fetch tools on `server`.
|
|
20
|
+
*
|
|
21
|
+
* @param server - The MCP server the tools join
|
|
22
|
+
* @param options - The index they answer from and the names they go by
|
|
23
|
+
* @returns The index, once loaded
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerExampleTools(server: McpServer, options: ExampleToolsOptions): Promise<LoadedIndex>;
|
|
26
|
+
//# sourceMappingURL=example-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-tools.d.ts","sourceRoot":"","sources":["../../mcp/example-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAiF,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOnI,+EAA+E;AAC/E,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAyH,CAAC;AAErK,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IAClC,6JAA6J;IAC7J,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CA2F1G"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { EAST_CORPUS, formatFull, formatResults, getEntry, loadIndexes, searchExamples } from "../lib/search.js";
|
|
3
|
+
// The example search's two MCP tools (#654), for any server: East's own
|
|
4
|
+
// registers them with East's names over East's index, and a plugin that builds
|
|
5
|
+
// on East's registers them with its own names over its index — beside East's
|
|
6
|
+
// to answer both corpora from one server, or alone beside the East plugin.
|
|
7
|
+
/** East's indexed packages, as the search tool's package filter names them. */
|
|
8
|
+
export const EAST_PACKAGES = ["east", "east-node-std", "east-node-io", "east-py-datascience", "east-ui", "e3-ui", "e3", "e3-ui-cli", "e3-create"];
|
|
9
|
+
function isLoaded(index) {
|
|
10
|
+
return typeof index.then === "function";
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Registers the example search and fetch tools on `server`.
|
|
14
|
+
*
|
|
15
|
+
* @param server - The MCP server the tools join
|
|
16
|
+
* @param options - The index they answer from and the names they go by
|
|
17
|
+
* @returns The index, once loaded
|
|
18
|
+
*/
|
|
19
|
+
export function registerExampleTools(server, options) {
|
|
20
|
+
const searchTool = options.searchTool ?? "search_east_examples";
|
|
21
|
+
const getTool = options.getTool ?? EAST_CORPUS.getTool;
|
|
22
|
+
const corpus = options.corpus ?? EAST_CORPUS.corpus;
|
|
23
|
+
const packages = options.packages ?? EAST_PACKAGES;
|
|
24
|
+
const names = { corpus, getTool };
|
|
25
|
+
const indexPromise = isLoaded(options.index) ? options.index : loadIndexes(options.index);
|
|
26
|
+
const languageArg = z
|
|
27
|
+
.enum(["typescript", "python"])
|
|
28
|
+
.default("typescript")
|
|
29
|
+
.describe('The language to render examples in: "typescript" (the East DSL) or "python" (east-py). Every core example is stored as IR and printed in either; UI examples are TypeScript only.');
|
|
30
|
+
server.tool(searchTool, `The mandatory first step before writing or changing ${corpus} code: search the tested example index for the capability you are about to use. Every ${corpus} API has an example here, stored as IR and rendered in TypeScript or python. Returns summaries by default (id, description, signature, keywords, the example inputs and result — a few hundred bytes each); pass format: "full" for the code, or fetch one with ${getTool}. Do not read node_modules/@elaraai or *.examples.ts files instead — this is the same corpus, exact and far cheaper.`, {
|
|
31
|
+
query: z.string().describe("What you need, in words: the operation, the types involved, the method name if you know it (e.g. \"group by key and sum\", \"dict merge\", \"parse csv blob\")"),
|
|
32
|
+
language: languageArg,
|
|
33
|
+
format: z
|
|
34
|
+
.enum(["summary", "full"])
|
|
35
|
+
.default("summary")
|
|
36
|
+
.describe('"summary" (default) lists the hits in one line each; "full" includes each hit\'s code in the requested language'),
|
|
37
|
+
limit: z
|
|
38
|
+
.number()
|
|
39
|
+
.int()
|
|
40
|
+
.min(1)
|
|
41
|
+
.max(20)
|
|
42
|
+
.default(5)
|
|
43
|
+
.describe("Maximum number of results to return (default 5, max 20)"),
|
|
44
|
+
package: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe(`Filter results to one package by its bare name — ${packages.join(", ")} — the \`@elaraai/\` scope is accepted and ignored; an unknown name is reported with the indexed names`),
|
|
48
|
+
}, async ({ query, language, format, limit, package: packageFilter }) => {
|
|
49
|
+
const index = await indexPromise;
|
|
50
|
+
const { entries, unknownPackage, known } = searchExamples(index, { query, limit, package: packageFilter });
|
|
51
|
+
if (unknownPackage !== undefined) {
|
|
52
|
+
return {
|
|
53
|
+
content: [
|
|
54
|
+
{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: `Package "${unknownPackage}" is not an indexed package name. Indexed packages: ${known.join(", ")} (bare names; \`@elaraai/east-node-io\` and \`east-node-io\` are the same). Retry with one of them, or without a package filter.`,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (entries.length === 0) {
|
|
62
|
+
const scope = packageFilter ? ` in package "${packageFilter}"` : "";
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `No ${corpus} examples found for query: "${query}"${scope} — try the operation's plain-English name, the East method name, or the types involved${packageFilter ? ", or drop the package filter" : ""}.`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: formatResults(entries, language, format, names),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
server.tool(getTool, `One ${corpus} example in full, by the id a search returned: its code printed in the requested language from the example's IR (TypeScript or python), its signature, and the example inputs and expected result. The second step after ${searchTool}.`, {
|
|
82
|
+
id: z.string().describe("The example id from a search result, e.g. \"east:array.examples.ts:arrayMap\""),
|
|
83
|
+
language: languageArg,
|
|
84
|
+
}, async ({ id, language }) => {
|
|
85
|
+
const index = await indexPromise;
|
|
86
|
+
const entry = getEntry(index.search, id);
|
|
87
|
+
if (entry === null) {
|
|
88
|
+
return { content: [{ type: "text", text: `No ${corpus} example with id "${id}" — ids come from ${searchTool} results.` }] };
|
|
89
|
+
}
|
|
90
|
+
return { content: [{ type: "text", text: formatFull([entry], language) }] };
|
|
91
|
+
});
|
|
92
|
+
return indexPromise;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=example-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-tools.js","sourceRoot":"","sources":["../../mcp/example-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../mcp/server.ts"],"names":[],"mappings":""}
|