@spooky-sync/cli 0.0.1-canary.290 → 0.0.1-canary.291
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/devtools-mcp/index.js +78 -46
- package/package.json +6 -6
package/devtools-mcp/index.js
CHANGED
|
@@ -9166,7 +9166,8 @@ const BRIDGE_METHODS = {
|
|
|
9166
9166
|
GET_QUERY_ROWS: "getQueryRows",
|
|
9167
9167
|
UPDATE_TABLE_ROW: "updateTableRow",
|
|
9168
9168
|
DELETE_TABLE_ROW: "deleteTableRow",
|
|
9169
|
-
|
|
9169
|
+
/** `{ method: 'mutationOp' | 'logOp', op, args }`: the Mutations / Logs dispatchers. */
|
|
9170
|
+
PAGE_OP: "pageOp"
|
|
9170
9171
|
};
|
|
9171
9172
|
const BRIDGE_PORT = 9315;
|
|
9172
9173
|
function isBridgeResponse(msg) {
|
|
@@ -12962,6 +12963,7 @@ var ZodFirstPartyTypeKind;
|
|
|
12962
12963
|
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
|
12963
12964
|
const stringType = ZodString.create;
|
|
12964
12965
|
const numberType = ZodNumber.create;
|
|
12966
|
+
const booleanType = ZodBoolean.create;
|
|
12965
12967
|
const unknownType = ZodUnknown.create;
|
|
12966
12968
|
ZodNever.create;
|
|
12967
12969
|
ZodArray.create;
|
|
@@ -23593,6 +23595,22 @@ const EMPTY_COMPLETION_RESULT = {
|
|
|
23593
23595
|
function json(data) {
|
|
23594
23596
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
23595
23597
|
}
|
|
23598
|
+
const LOG_LEVELS = { trace: 10, debug: 20, info: 30, warn: 40, error: 50, fatal: 60 };
|
|
23599
|
+
const LEVEL_NAMES = Object.keys(LOG_LEVELS);
|
|
23600
|
+
const levelName = (level) => Object.entries(LOG_LEVELS).reduce(
|
|
23601
|
+
(name, [n, v]) => level >= v ? n : name,
|
|
23602
|
+
"trace"
|
|
23603
|
+
);
|
|
23604
|
+
function readableLog(e) {
|
|
23605
|
+
let data;
|
|
23606
|
+
try {
|
|
23607
|
+
const { time: _time, level: _level, msg: _msg, ...rest } = JSON.parse(e.line);
|
|
23608
|
+
data = Object.keys(rest).length ? rest : void 0;
|
|
23609
|
+
} catch {
|
|
23610
|
+
data = { truncated: e.line };
|
|
23611
|
+
}
|
|
23612
|
+
return { seq: e.seq, time: new Date(e.time).toISOString(), level: levelName(e.level), msg: e.msg, data };
|
|
23613
|
+
}
|
|
23596
23614
|
function createServer(bridge, surreal) {
|
|
23597
23615
|
const server = new McpServer({
|
|
23598
23616
|
name: "sp00ky-devtools",
|
|
@@ -23608,7 +23626,7 @@ function createServer(bridge, surreal) {
|
|
|
23608
23626
|
);
|
|
23609
23627
|
server.tool(
|
|
23610
23628
|
"get_state",
|
|
23611
|
-
"Get the full Sp00ky DevTools state (
|
|
23629
|
+
"Get the full Sp00ky DevTools state (queries, mutations, auth, database, versions)",
|
|
23612
23630
|
{ tabId: numberType().optional().describe("Browser tab ID (uses first connected tab if omitted)") },
|
|
23613
23631
|
async ({ tabId }) => {
|
|
23614
23632
|
if (!bridge.isConnected) {
|
|
@@ -23787,32 +23805,70 @@ function createServer(bridge, surreal) {
|
|
|
23787
23805
|
}
|
|
23788
23806
|
);
|
|
23789
23807
|
server.tool(
|
|
23790
|
-
"
|
|
23791
|
-
|
|
23808
|
+
"get_mutations",
|
|
23809
|
+
`The client's writes: the outbox (pending / retrying with attempt counts), what left it since DevTools attached (synced with the server latency, or rolled back with the server error), debounced updates, the tab role and connection (a follower tab never drains), and the rows of the persistent failed-writes tray with their payload and before image. Answers "did my write reach the server?" and "why was it rolled back?".`,
|
|
23792
23810
|
{
|
|
23793
|
-
|
|
23794
|
-
|
|
23811
|
+
status: enumType(["pending", "retrying", "synced", "rolled-back", "dropped"]).optional().describe("Only entries with this status"),
|
|
23812
|
+
includeTray: booleanType().optional().default(true).describe("Also read the failed-writes tray rows"),
|
|
23795
23813
|
tabId: numberType().optional().describe("Browser tab ID")
|
|
23796
23814
|
},
|
|
23797
|
-
async ({
|
|
23798
|
-
if (bridge.isConnected) {
|
|
23799
|
-
|
|
23800
|
-
let events = state?.eventsHistory ?? [];
|
|
23801
|
-
if (eventType) {
|
|
23802
|
-
events = events.filter((e) => e.eventType === eventType);
|
|
23803
|
-
}
|
|
23804
|
-
if (limit2) {
|
|
23805
|
-
events = events.slice(-limit2);
|
|
23806
|
-
}
|
|
23807
|
-
return json(events);
|
|
23815
|
+
async ({ status, includeTray, tabId }) => {
|
|
23816
|
+
if (!bridge.isConnected) {
|
|
23817
|
+
throw new Error("No extension connected. get_mutations requires the Sp00ky DevTools browser extension.");
|
|
23808
23818
|
}
|
|
23809
|
-
|
|
23810
|
-
|
|
23811
|
-
|
|
23819
|
+
const state = await bridge.request(BRIDGE_METHODS.GET_STATE, {}, tabId);
|
|
23820
|
+
const mutations = state?.mutations;
|
|
23821
|
+
if (!mutations) {
|
|
23822
|
+
throw new Error("This client does not report its mutations; update @spooky-sync/core.");
|
|
23823
|
+
}
|
|
23824
|
+
const entries = status ? (mutations.entries ?? []).filter((e) => e.status === status) : mutations.entries;
|
|
23825
|
+
const failed = includeTray ? (await bridge.request(
|
|
23826
|
+
BRIDGE_METHODS.PAGE_OP,
|
|
23827
|
+
{ method: "mutationOp", op: "listFailed", args: {} },
|
|
23828
|
+
tabId
|
|
23829
|
+
))?.failed : void 0;
|
|
23830
|
+
return json({ ...mutations, entries, failed });
|
|
23831
|
+
}
|
|
23832
|
+
);
|
|
23833
|
+
server.tool(
|
|
23834
|
+
"get_logs",
|
|
23835
|
+
"Recent lines from the client's own logger (the page keeps its last 500), oldest first, each with its structured fields. Pass `after` = a previous call's `head` to read only what is new. `captureLevel` changes what the page records (e.g. 'debug') without printing more to the console; it holds for the tab's session, so a reload records its boot at that level.",
|
|
23836
|
+
{
|
|
23837
|
+
minLevel: enumType(LEVEL_NAMES).optional().describe("Only lines at or above this level"),
|
|
23838
|
+
contains: stringType().optional().describe("Only lines whose JSON contains this text (case-insensitive)"),
|
|
23839
|
+
after: numberType().optional().describe("Only lines after this seq (a previous `head`)"),
|
|
23840
|
+
limit: numberType().optional().default(100).describe("Max lines, newest kept"),
|
|
23841
|
+
captureLevel: enumType(LEVEL_NAMES).optional().describe("Set what the page records from now on"),
|
|
23842
|
+
tabId: numberType().optional().describe("Browser tab ID")
|
|
23843
|
+
},
|
|
23844
|
+
async ({ minLevel, contains: contains2, after, limit: limit2, captureLevel, tabId }) => {
|
|
23845
|
+
if (!bridge.isConnected) {
|
|
23846
|
+
throw new Error("No extension connected. get_logs requires the Sp00ky DevTools browser extension.");
|
|
23847
|
+
}
|
|
23848
|
+
if (captureLevel) {
|
|
23849
|
+
await bridge.request(
|
|
23850
|
+
BRIDGE_METHODS.PAGE_OP,
|
|
23851
|
+
{ method: "logOp", op: "setCaptureLevel", args: { level: captureLevel } },
|
|
23852
|
+
tabId
|
|
23812
23853
|
);
|
|
23813
|
-
return json(result);
|
|
23814
23854
|
}
|
|
23815
|
-
|
|
23855
|
+
const read = await bridge.request(
|
|
23856
|
+
BRIDGE_METHODS.PAGE_OP,
|
|
23857
|
+
{ method: "logOp", op: "read", args: { after: after ?? 0 } },
|
|
23858
|
+
tabId
|
|
23859
|
+
);
|
|
23860
|
+
const floor = minLevel ? LOG_LEVELS[minLevel] : 0;
|
|
23861
|
+
const term = contains2?.toLowerCase();
|
|
23862
|
+
const entries = (read?.entries ?? []).filter(
|
|
23863
|
+
(e) => e.level >= floor && (!term || String(e.line).toLowerCase().includes(term))
|
|
23864
|
+
);
|
|
23865
|
+
return json({
|
|
23866
|
+
head: read?.head,
|
|
23867
|
+
dropped: read?.dropped,
|
|
23868
|
+
consoleLevel: read?.consoleLevel,
|
|
23869
|
+
captureLevel: read?.captureLevel,
|
|
23870
|
+
entries: entries.slice(Math.max(0, entries.length - (limit2 ?? 100))).map(readableLog)
|
|
23871
|
+
});
|
|
23816
23872
|
}
|
|
23817
23873
|
);
|
|
23818
23874
|
server.tool(
|
|
@@ -23827,18 +23883,6 @@ function createServer(bridge, surreal) {
|
|
|
23827
23883
|
return json(state?.auth ?? null);
|
|
23828
23884
|
}
|
|
23829
23885
|
);
|
|
23830
|
-
server.tool(
|
|
23831
|
-
"clear_history",
|
|
23832
|
-
"Clear the event history",
|
|
23833
|
-
{ tabId: numberType().optional().describe("Browser tab ID") },
|
|
23834
|
-
async ({ tabId }) => {
|
|
23835
|
-
if (!bridge.isConnected) {
|
|
23836
|
-
throw new Error("No extension connected. clear_history requires the Sp00ky DevTools browser extension.");
|
|
23837
|
-
}
|
|
23838
|
-
await bridge.request(BRIDGE_METHODS.CLEAR_HISTORY, {}, tabId);
|
|
23839
|
-
return { content: [{ type: "text", text: "History cleared." }] };
|
|
23840
|
-
}
|
|
23841
|
-
);
|
|
23842
23886
|
server.tool(
|
|
23843
23887
|
"describe_schema",
|
|
23844
23888
|
"Describe all tables with columns, types, and sp00ky annotations (@crdt, @parent). Stitches INFO FOR DB with parsed schema metadata. With the browser extension this returns @crdt/@parent semantics; direct-DB mode returns raw column info only.",
|
|
@@ -23983,18 +24027,6 @@ function createServer(bridge, surreal) {
|
|
|
23983
24027
|
}
|
|
23984
24028
|
throw new Error("No extension connected and no direct database configured.");
|
|
23985
24029
|
});
|
|
23986
|
-
server.resource("events", "sp00ky://events", { description: "Event history" }, async (uri2) => {
|
|
23987
|
-
if (bridge.isConnected) {
|
|
23988
|
-
const state = await bridge.request(BRIDGE_METHODS.GET_STATE);
|
|
23989
|
-
const events = state?.eventsHistory ?? [];
|
|
23990
|
-
return { contents: [{ uri: uri2.href, mimeType: "application/json", text: JSON.stringify(events, null, 2) }] };
|
|
23991
|
-
}
|
|
23992
|
-
if (surreal) {
|
|
23993
|
-
const result = await surreal.query("SELECT * FROM _00_events ORDER BY timestamp DESC LIMIT 50;");
|
|
23994
|
-
return { contents: [{ uri: uri2.href, mimeType: "application/json", text: JSON.stringify(result, null, 2) }] };
|
|
23995
|
-
}
|
|
23996
|
-
throw new Error("No extension connected and no direct database configured.");
|
|
23997
|
-
});
|
|
23998
24030
|
return server;
|
|
23999
24031
|
}
|
|
24000
24032
|
async function main() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spooky-sync/cli",
|
|
3
|
-
"version": "0.0.1-canary.
|
|
3
|
+
"version": "0.0.1-canary.291",
|
|
4
4
|
"description": "Generate TypeScript/Dart types from SurrealDB schema files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/syncgen.cjs",
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"vitest": "^1.0.0"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@spooky-sync/cli-darwin-arm64": "0.0.1-canary.
|
|
66
|
-
"@spooky-sync/cli-darwin-x64": "0.0.1-canary.
|
|
67
|
-
"@spooky-sync/cli-linux-arm64": "0.0.1-canary.
|
|
68
|
-
"@spooky-sync/cli-linux-x64": "0.0.1-canary.
|
|
69
|
-
"@spooky-sync/cli-win32-x64": "0.0.1-canary.
|
|
65
|
+
"@spooky-sync/cli-darwin-arm64": "0.0.1-canary.291",
|
|
66
|
+
"@spooky-sync/cli-darwin-x64": "0.0.1-canary.291",
|
|
67
|
+
"@spooky-sync/cli-linux-arm64": "0.0.1-canary.291",
|
|
68
|
+
"@spooky-sync/cli-linux-x64": "0.0.1-canary.291",
|
|
69
|
+
"@spooky-sync/cli-win32-x64": "0.0.1-canary.291"
|
|
70
70
|
}
|
|
71
71
|
}
|