@drawpro/mcp 0.6.1 → 0.6.4
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/dist/server.js +81 -17
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1411,7 +1411,7 @@ function api() {
|
|
|
1411
1411
|
return clientInstance;
|
|
1412
1412
|
}
|
|
1413
1413
|
var SESSION_ID = Math.random().toString(36).slice(2, 10);
|
|
1414
|
-
var VERSION = "0.6.
|
|
1414
|
+
var VERSION = "0.6.4";
|
|
1415
1415
|
var inFlight = [];
|
|
1416
1416
|
var cachedUser = null;
|
|
1417
1417
|
async function currentUser() {
|
|
@@ -1622,11 +1622,11 @@ tool(
|
|
|
1622
1622
|
);
|
|
1623
1623
|
function buildOrExplain(spec) {
|
|
1624
1624
|
const { scene, issues } = buildDiagram(spec);
|
|
1625
|
-
const
|
|
1626
|
-
if (
|
|
1625
|
+
const errors2 = issues.filter((i) => i.level === "error");
|
|
1626
|
+
if (errors2.length > 0) {
|
|
1627
1627
|
return {
|
|
1628
1628
|
ok: false,
|
|
1629
|
-
error: "The diagram was not created. Fix the spec and try again:\n" +
|
|
1629
|
+
error: "The diagram was not created. Fix the spec and try again:\n" + errors2.map((i) => ` error: ${i.message}`).join("\n")
|
|
1630
1630
|
};
|
|
1631
1631
|
}
|
|
1632
1632
|
const warnings = issues.filter((i) => i.level === "warning");
|
|
@@ -1726,7 +1726,9 @@ tool(
|
|
|
1726
1726
|
sheet_id: import_zod.z.string(),
|
|
1727
1727
|
edits: import_zod.z.array(
|
|
1728
1728
|
import_zod.z.object({
|
|
1729
|
-
find: import_zod.z.string().describe(
|
|
1729
|
+
find: import_zod.z.string().describe(
|
|
1730
|
+
"The element's current text, as read_sheet reports it. Whitespace is matched loosely, so the flattened single-line form read_sheet prints works even when the element itself contains line breaks."
|
|
1731
|
+
),
|
|
1730
1732
|
replace: import_zod.z.string()
|
|
1731
1733
|
})
|
|
1732
1734
|
).describe("Applied all-or-nothing: if any find has no match, nothing is written.")
|
|
@@ -1736,18 +1738,19 @@ tool(
|
|
|
1736
1738
|
if ("error" in unlocked) return text(unlocked.error);
|
|
1737
1739
|
const scene = await api().readSheet(workspace_id, sheet_id, unlocked.key);
|
|
1738
1740
|
const elements = scene.elements;
|
|
1741
|
+
const collapse = (t) => t.replace(/\s+/g, " ").trim();
|
|
1739
1742
|
const counts = /* @__PURE__ */ new Map();
|
|
1740
1743
|
const changedTextIds = /* @__PURE__ */ new Set();
|
|
1741
1744
|
for (const el of elements) {
|
|
1742
1745
|
if (el.type !== "text") continue;
|
|
1743
1746
|
const current = (el.originalText ?? el.text)?.trim();
|
|
1744
1747
|
if (current === void 0) continue;
|
|
1745
|
-
const edit = edits.find((e) => e.find.trim() === current);
|
|
1748
|
+
const edit = edits.find((e) => e.find.trim() === current) ?? edits.find((e) => collapse(e.find) === collapse(current));
|
|
1746
1749
|
if (!edit) continue;
|
|
1747
1750
|
el.text = edit.replace;
|
|
1748
1751
|
el.originalText = edit.replace;
|
|
1749
1752
|
const fontSize = el.fontSize ?? 20;
|
|
1750
|
-
const wrapWidth =
|
|
1753
|
+
const wrapWidth = Math.max(el.width || 0, 80);
|
|
1751
1754
|
const metrics = measureText(edit.replace, fontSize, wrapWidth);
|
|
1752
1755
|
el.width = metrics.width;
|
|
1753
1756
|
el.height = metrics.height;
|
|
@@ -1761,7 +1764,7 @@ tool(
|
|
|
1761
1764
|
const missed = edits.filter((e) => !counts.has(e.find));
|
|
1762
1765
|
if (missed.length > 0) {
|
|
1763
1766
|
return text(
|
|
1764
|
-
"Nothing was written. These strings matched no text element:\n" + missed.map((e) => ` ${JSON.stringify(e.find)}`).join("\n") + "\n\nRun read_sheet and copy the text
|
|
1767
|
+
"Nothing was written. These strings matched no text element:\n" + missed.map((e) => ` ${JSON.stringify(e.find)}`).join("\n") + "\n\nRun read_sheet and copy the text as it appears there. Line breaks and repeated spaces do not need to match \u2014 only the words do."
|
|
1765
1768
|
);
|
|
1766
1769
|
}
|
|
1767
1770
|
const user = await currentUser();
|
|
@@ -1861,6 +1864,44 @@ function summariseLog(file) {
|
|
|
1861
1864
|
}))
|
|
1862
1865
|
};
|
|
1863
1866
|
}
|
|
1867
|
+
function errors(file) {
|
|
1868
|
+
let rows;
|
|
1869
|
+
try {
|
|
1870
|
+
rows = (0, import_node_fs3.readFileSync)(file, "utf8").split("\n").filter(Boolean).flatMap((line) => {
|
|
1871
|
+
try {
|
|
1872
|
+
return [JSON.parse(line)];
|
|
1873
|
+
} catch {
|
|
1874
|
+
return [];
|
|
1875
|
+
}
|
|
1876
|
+
});
|
|
1877
|
+
} catch {
|
|
1878
|
+
console.error(`Could not read ${file}`);
|
|
1879
|
+
process.exit(2);
|
|
1880
|
+
}
|
|
1881
|
+
const failures = rows.filter((r) => r.ok === false || r.refused);
|
|
1882
|
+
if (failures.length === 0) {
|
|
1883
|
+
console.log("No failures or refusals recorded.");
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1887
|
+
for (const r of failures) {
|
|
1888
|
+
const reason = String(r.error ?? "refused (the tool declined, see its message)").slice(0, 120);
|
|
1889
|
+
const acc = grouped.get(reason) ?? { n: 0, tools: /* @__PURE__ */ new Set(), last: "" };
|
|
1890
|
+
acc.n++;
|
|
1891
|
+
acc.tools.add(String(r.tool));
|
|
1892
|
+
acc.last = String(r.ts);
|
|
1893
|
+
grouped.set(reason, acc);
|
|
1894
|
+
}
|
|
1895
|
+
console.log(`${failures.length} of ${rows.length} calls failed or were refused
|
|
1896
|
+
`);
|
|
1897
|
+
for (const [reason, a] of [...grouped.entries()].sort((x, y) => y[1].n - x[1].n)) {
|
|
1898
|
+
console.log(` ${a.n}x ${[...a.tools].join(", ")}`);
|
|
1899
|
+
console.log(` ${reason}`);
|
|
1900
|
+
console.log(` last seen ${a.last}
|
|
1901
|
+
`);
|
|
1902
|
+
}
|
|
1903
|
+
console.log(" This reads your local log and sends nothing.");
|
|
1904
|
+
}
|
|
1864
1905
|
function stats(path, asJson) {
|
|
1865
1906
|
const file = path ?? logPath();
|
|
1866
1907
|
if (!file) {
|
|
@@ -1892,7 +1933,7 @@ function stats(path, asJson) {
|
|
|
1892
1933
|
console.log(
|
|
1893
1934
|
"\n No ids, account details, or diagram content above \u2014 safe to paste into a bug report."
|
|
1894
1935
|
);
|
|
1895
|
-
console.log(" Add --json for a machine-readable copy.");
|
|
1936
|
+
console.log(" Add --json for a machine-readable copy, or --errors to see why calls failed.");
|
|
1896
1937
|
}
|
|
1897
1938
|
function buildReport() {
|
|
1898
1939
|
const file = logPath();
|
|
@@ -1929,15 +1970,29 @@ async function telemetry(action) {
|
|
|
1929
1970
|
if (action === "on") {
|
|
1930
1971
|
writeConfig({ telemetry: "on" });
|
|
1931
1972
|
console.log(`Telemetry on. Usage is recorded to ${logPath()}`);
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1973
|
+
const built = buildReport();
|
|
1974
|
+
if (!built) {
|
|
1975
|
+
console.log("\nNothing recorded yet. The first report goes out once you have used the tools.");
|
|
1976
|
+
console.log("Turn it off any time with: drawpro-mcp telemetry off");
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
console.log("\nSending this now, and roughly once a day after:\n");
|
|
1980
|
+
console.log(JSON.stringify(built, null, 2));
|
|
1981
|
+
const { ok, detail } = await sendReport(built);
|
|
1982
|
+
if (ok) {
|
|
1983
|
+
writeConfig({ lastReportAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1984
|
+
console.log("\nSent.");
|
|
1985
|
+
} else {
|
|
1986
|
+
console.log(`
|
|
1987
|
+
Could not send it (${detail}). Telemetry is still on and it will retry.`);
|
|
1988
|
+
}
|
|
1989
|
+
console.log("Turn it off any time with: drawpro-mcp telemetry off");
|
|
1937
1990
|
return;
|
|
1938
1991
|
}
|
|
1939
|
-
|
|
1940
|
-
`);
|
|
1992
|
+
const last = readConfig().lastReportAt;
|
|
1993
|
+
console.log(`Telemetry is ${telemetryEnabled() ? "ON" : "OFF"}.`);
|
|
1994
|
+
console.log(last ? `Last report sent ${last}.
|
|
1995
|
+
` : "No report has been sent yet.\n");
|
|
1941
1996
|
console.log("If enabled, this is the entire payload \u2014 tool counts and timings,");
|
|
1942
1997
|
console.log("no account, no token, no workspace or sheet ids, nothing drawn:\n");
|
|
1943
1998
|
console.log(
|
|
@@ -2101,7 +2156,16 @@ async function main() {
|
|
|
2101
2156
|
}
|
|
2102
2157
|
if (command === "stats") {
|
|
2103
2158
|
const rest = process.argv.slice(3);
|
|
2104
|
-
|
|
2159
|
+
const file = rest.find((a) => !a.startsWith("--")) ?? logPath();
|
|
2160
|
+
if (rest.includes("--errors")) {
|
|
2161
|
+
if (!file) {
|
|
2162
|
+
console.error("No usage is being recorded, so there is nothing to explain.");
|
|
2163
|
+
process.exit(2);
|
|
2164
|
+
}
|
|
2165
|
+
errors(file);
|
|
2166
|
+
return;
|
|
2167
|
+
}
|
|
2168
|
+
stats(file, rest.includes("--json"));
|
|
2105
2169
|
return;
|
|
2106
2170
|
}
|
|
2107
2171
|
if (command && command !== "serve") {
|