@sheetpane/mcp 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +33 -2
- package/dist/ERRORS.md +811 -0
- package/dist/api.d.ts +7 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +67 -0
- package/dist/api.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +34 -0
- package/dist/bin.js.map +1 -0
- package/dist/custom-elements.json +1246 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins.json +50 -0
- package/dist/protocol.d.ts +29 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +52 -0
- package/dist/protocol.js.map +1 -0
- package/dist/tools.d.ts +36 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +413 -0
- package/dist/tools.js.map +1 -0
- package/package.json +40 -3
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Looks one name up across the elements and the plugins.
|
|
3
|
+
* @param raw - An element tag, attribute, property, method, event (with or without `on`), `--sp-*` token, slot, part or plugin.
|
|
4
|
+
* @returns Every match with its kind, element, manifest entry and record link; near names when nothing matches.
|
|
5
|
+
*/
|
|
6
|
+
export declare function describeApi(raw: string): Record<string, unknown>;
|
|
7
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8BhE"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// describe_api (W-39 DoD 3): a name of the public API → its custom-elements manifest entry (W-37),
|
|
2
|
+
// which carries the TSDoc (W-36), and the record that specifies it. Plugins come from a table the
|
|
3
|
+
// build writes from each plugin's package.json.
|
|
4
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const REPO = 'https://github.com/arpitarya/sheetpane/blob/main/';
|
|
9
|
+
const RECORD = { 'sheetpane-excel': 'records/0105_GRID.md', 'sheetpane-errors': 'records/0106_ERRORS.md' };
|
|
10
|
+
/** Reads the first of `dist/<file>` and the workspace copy. */
|
|
11
|
+
function data(file, workspace) {
|
|
12
|
+
for (const p of [join(here, file), join(here, workspace)])
|
|
13
|
+
if (existsSync(p))
|
|
14
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
let cached;
|
|
18
|
+
function load() {
|
|
19
|
+
if (cached)
|
|
20
|
+
return cached;
|
|
21
|
+
const m = data('custom-elements.json', '../../grid/custom-elements.json');
|
|
22
|
+
const plugins = data('plugins.json', '../dist/plugins.json') ?? [];
|
|
23
|
+
cached = { elements: (m?.modules ?? []).flatMap((mod) => mod.declarations ?? []).filter((d) => d.customElement && d.tagName), plugins };
|
|
24
|
+
return cached;
|
|
25
|
+
}
|
|
26
|
+
const KINDS = [['attributes', 'attribute'], ['members', 'member'], ['events', 'event'], ['cssProperties', 'css-property'], ['slots', 'slot'], ['cssParts', 'css-part']];
|
|
27
|
+
/**
|
|
28
|
+
* Looks one name up across the elements and the plugins.
|
|
29
|
+
* @param raw - An element tag, attribute, property, method, event (with or without `on`), `--sp-*` token, slot, part or plugin.
|
|
30
|
+
* @returns Every match with its kind, element, manifest entry and record link; near names when nothing matches.
|
|
31
|
+
*/
|
|
32
|
+
export function describeApi(raw) {
|
|
33
|
+
const { elements, plugins } = load();
|
|
34
|
+
const name = raw.trim().replace(/^<|\/?>$/g, '').replace(/^on(?=sheetpane-)/, '');
|
|
35
|
+
const lower = name.toLowerCase();
|
|
36
|
+
const matches = [];
|
|
37
|
+
for (const d of elements) {
|
|
38
|
+
const record = REPO + (RECORD[d.tagName] ?? 'records/0105_GRID.md');
|
|
39
|
+
if (d.tagName === lower || d.name === name) {
|
|
40
|
+
matches.push({ kind: 'element', element: d.tagName, class: d.name, summary: d.summary, description: d.description, attributes: d.attributes?.map((a) => a.name), events: d.events?.map((e) => e.name), record });
|
|
41
|
+
}
|
|
42
|
+
for (const [list, kind] of KINDS) {
|
|
43
|
+
for (const e of d[list] ?? []) {
|
|
44
|
+
const hit = e.name === name || (kind === 'attribute' && e.name === lower) || (kind === 'member' && e.attribute === lower);
|
|
45
|
+
if (hit) {
|
|
46
|
+
const { kind: memberKind, ...rest } = e;
|
|
47
|
+
matches.push({ kind, ...(memberKind ? { memberKind } : {}), element: d.tagName, ...rest, record });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const pid = lower.replace(/^@sheetpane\//, '');
|
|
53
|
+
for (const p of plugins)
|
|
54
|
+
if (p.id === pid)
|
|
55
|
+
matches.push({ kind: 'plugin', ...p, use: `<sheetpane-excel plugins="${p.id}"> after import '${p.package}'`, record: REPO + p.record });
|
|
56
|
+
// an element first: `sheetpane-errors` is a tag and an event
|
|
57
|
+
matches.sort((a, b) => Number(b.kind === 'element') - Number(a.kind === 'element'));
|
|
58
|
+
if (matches.length)
|
|
59
|
+
return { matches };
|
|
60
|
+
if (!elements.length)
|
|
61
|
+
return { matches: [], error: 'The custom-elements manifest is missing from this install — reinstall @sheetpane/mcp.' };
|
|
62
|
+
const all = new Set([...elements.flatMap((d) => [d.tagName, ...KINDS.flatMap(([l]) => (d[l] ?? []).map((e) => e.name))]), ...plugins.map((p) => p.package)]);
|
|
63
|
+
// near: a name holding what was asked, or a name (four letters or more, prefix aside) the ask holds
|
|
64
|
+
const near = [...all].filter((n) => { const k = n.toLowerCase(), bare = k.replace(/^--sp-|^sheetpane-|^@sheetpane\//, ''); return (lower.length >= 3 && k.includes(lower)) || (bare.length >= 4 && lower.includes(bare)); }).sort().slice(0, 10);
|
|
65
|
+
return { matches: [], error: `sheetpane has no public name “${raw}”.`, ...(near.length ? { near } : {}) };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// sheetpane-mcp: the MCP server over stdio — one JSON-RPC message per line in, one per line out.
|
|
3
|
+
// stdout carries protocol messages only; anything else goes to stderr.
|
|
4
|
+
import { createInterface } from 'node:readline';
|
|
5
|
+
import { handle } from './protocol.js';
|
|
6
|
+
const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
7
|
+
let queue = Promise.resolve();
|
|
8
|
+
rl.on('line', (line) => {
|
|
9
|
+
if (!line.trim())
|
|
10
|
+
return;
|
|
11
|
+
// answer in arrival order, one at a time: the tools are quick and the order stays predictable
|
|
12
|
+
queue = queue.then(async () => {
|
|
13
|
+
let msg;
|
|
14
|
+
try {
|
|
15
|
+
msg = JSON.parse(line);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } }) + '\n');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// JSON-RPC batches left MCP in 2025-06-18: an array is an invalid request (handle says so)
|
|
22
|
+
try {
|
|
23
|
+
const res = await handle(msg);
|
|
24
|
+
if (res)
|
|
25
|
+
process.stdout.write(JSON.stringify(res) + '\n');
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
const id = msg?.id ?? null;
|
|
29
|
+
process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, error: { code: -32603, message: `Internal error: ${e.message}` } }) + '\n');
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
rl.on('close', () => { void queue.then(() => process.exit(0)); });
|
|
34
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,iGAAiG;AACjG,uEAAuE;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1E,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AAC9B,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO;IACzB,8FAA8F;IAC9F,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QAC5B,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3H,OAAO;QACT,CAAC;QACD,2FAA2F;QAC3F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,GAAG;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,EAAE,GAAI,GAA+B,EAAE,EAAE,IAAI,IAAI,CAAC;YACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,mBAAoB,CAAW,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACnJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
|