clay-server 2.47.0-beta.2 → 2.47.0-beta.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.
@@ -1,232 +0,0 @@
1
- var z = require("zod");
2
- var datastore = require("./mate-datastore");
3
- var FEATURE_ENABLED = false;
4
-
5
- function attachMateDatastore(ctx) {
6
- var cwd = ctx.cwd;
7
- var isMate = ctx.isMate;
8
- var send = ctx.send;
9
- var sendTo = ctx.sendTo;
10
-
11
- function isFeatureAvailable() {
12
- return FEATURE_ENABLED && datastore.isMateDatastoreAvailable();
13
- }
14
-
15
- function ensureProjectDatastore() {
16
- if (!FEATURE_ENABLED) {
17
- return { ok: false, code: "MATE_DATASTORE_NOT_ALLOWED", message: "Mate datastore is not enabled." };
18
- }
19
- if (!isMate) {
20
- return { ok: false, code: "MATE_DATASTORE_NOT_ALLOWED", message: "Mate datastore is only available in Mate sessions." };
21
- }
22
- try {
23
- return datastore.ensureMateDatastore({ mateDir: cwd });
24
- } catch (e) {
25
- return { ok: false, code: "MATE_DATASTORE_UNAVAILABLE", message: e.message || "Mate datastore is unavailable." };
26
- }
27
- }
28
-
29
- function getDatastoreWarning(handle) {
30
- if (!handle || !handle.warning) return null;
31
- return handle.warning;
32
- }
33
-
34
- function normalizeParams(input) {
35
- if (!input) return [];
36
- if (Array.isArray(input.params)) return input.params;
37
- return [];
38
- }
39
-
40
- function normalizeToolResult(result, requestId) {
41
- var payload = result || { ok: false, code: "MATE_DATASTORE_UNAVAILABLE", message: "Mate datastore is unavailable." };
42
- if (typeof requestId !== "undefined") payload.requestId = requestId;
43
- return payload;
44
- }
45
-
46
- function callToolInternal(toolName, input) {
47
- var handle = ensureProjectDatastore();
48
- if (!handle || handle.ok === false) {
49
- return normalizeToolResult(handle, input && input.requestId);
50
- }
51
-
52
- var warning = getDatastoreWarning(handle);
53
- var params = normalizeParams(input);
54
-
55
- if (toolName === "clay_db_query") {
56
- var queryResult = datastore.runQuery(handle, input.sql, params, { maxRows: 200, maxBytes: 1024 * 1024, includeSizeInfo: true });
57
- if (warning && queryResult.ok && !queryResult.warning) queryResult.warning = warning;
58
- return normalizeToolResult(queryResult, input && input.requestId);
59
- }
60
-
61
- if (toolName === "clay_db_exec") {
62
- var execResult = datastore.runExec(handle, input.sql, params, { maxBytes: 1024 * 1024, includeSizeInfo: true });
63
- if (warning && execResult.ok && !execResult.warning) execResult.warning = warning;
64
- if (execResult.ok) {
65
- broadcastDbChange({ tool: toolName, sql: input.sql, changes: execResult.changes || 0 });
66
- }
67
- return normalizeToolResult(execResult, input && input.requestId);
68
- }
69
-
70
- if (toolName === "clay_db_tables") {
71
- var tablesResult = datastore.listSchemaObjects(handle);
72
- if (warning && tablesResult.ok && !tablesResult.warning) tablesResult.warning = warning;
73
- return normalizeToolResult(tablesResult, input && input.requestId);
74
- }
75
-
76
- if (toolName === "clay_db_describe") {
77
- var describeResult = datastore.describeTable(handle, input.table);
78
- if (warning && describeResult.ok && !describeResult.warning) describeResult.warning = warning;
79
- return normalizeToolResult(describeResult, input && input.requestId);
80
- }
81
-
82
- return normalizeToolResult({ ok: false, code: "MATE_DATASTORE_NOT_ALLOWED", message: "Unknown datastore tool: " + toolName }, input && input.requestId);
83
- }
84
-
85
- function broadcastDbChange(details) {
86
- var payload = {
87
- type: "mate_db_change",
88
- details: details || {},
89
- };
90
- send(payload);
91
- }
92
-
93
- function handleMateDatastoreMessage(ws, msg) {
94
- if (msg.type !== "mate_db_tables" && msg.type !== "mate_db_describe" && msg.type !== "mate_db_query" && msg.type !== "mate_db_exec") {
95
- return false;
96
- }
97
-
98
- if (!FEATURE_ENABLED) {
99
- return false;
100
- }
101
-
102
- if (!isMate) {
103
- sendTo(ws, {
104
- type: "mate_db_error",
105
- requestId: msg.requestId || null,
106
- code: "MATE_DATASTORE_NOT_ALLOWED",
107
- message: "Mate datastore is only available in Mate sessions.",
108
- });
109
- return true;
110
- }
111
-
112
- if (msg.type === "mate_db_tables") {
113
- sendResult(ws, "mate_db_tables_result", callToolInternal("clay_db_tables", msg));
114
- return true;
115
- }
116
-
117
- if (msg.type === "mate_db_describe") {
118
- sendResult(ws, "mate_db_describe_result", callToolInternal("clay_db_describe", msg));
119
- return true;
120
- }
121
-
122
- if (msg.type === "mate_db_query") {
123
- sendResult(ws, "mate_db_query_result", callToolInternal("clay_db_query", msg));
124
- return true;
125
- }
126
-
127
- if (msg.type === "mate_db_exec") {
128
- sendResult(ws, "mate_db_exec_result", callToolInternal("clay_db_exec", msg));
129
- return true;
130
- }
131
-
132
- return true;
133
- }
134
-
135
- function sendResult(ws, type, result) {
136
- var payload = result || { ok: false, code: "MATE_DATASTORE_UNAVAILABLE", message: "Mate datastore is unavailable." };
137
- payload.type = type;
138
- sendTo(ws, payload);
139
- }
140
-
141
- function getToolDefinitions() {
142
- if (!isMate || !isFeatureAvailable()) return [];
143
- return [
144
- {
145
- name: "clay_db_query",
146
- description: "Execute read-only SQL against the current Mate datastore.",
147
- inputSchema: {
148
- sql: z.string().min(1).describe("SQL query"),
149
- params: z.array(z.any()).optional().describe("Positional parameters"),
150
- },
151
- handler: function (input) {
152
- return callToolInternal("clay_db_query", input || {});
153
- },
154
- },
155
- {
156
- name: "clay_db_exec",
157
- description: "Execute schema or write SQL against the current Mate datastore.",
158
- inputSchema: {
159
- sql: z.string().min(1).describe("SQL statement"),
160
- params: z.array(z.any()).optional().describe("Positional parameters"),
161
- },
162
- handler: function (input) {
163
- return callToolInternal("clay_db_exec", input || {});
164
- },
165
- },
166
- {
167
- name: "clay_db_tables",
168
- description: "List schema objects in the current Mate datastore.",
169
- inputSchema: undefined,
170
- handler: function (input) {
171
- return callToolInternal("clay_db_tables", input || {});
172
- },
173
- },
174
- {
175
- name: "clay_db_describe",
176
- description: "Describe a table or view in the current Mate datastore.",
177
- inputSchema: {
178
- table: z.string().min(1).describe("Table name"),
179
- },
180
- handler: function (input) {
181
- return callToolInternal("clay_db_describe", input || {});
182
- },
183
- },
184
- ];
185
- }
186
-
187
- function createMcpServer() {
188
- var defs = getToolDefinitions();
189
- if (!defs.length) return null;
190
- var registered = {};
191
- for (var i = 0; i < defs.length; i++) {
192
- registered[defs[i].name] = {
193
- description: defs[i].description,
194
- inputSchema: defs[i].inputSchema,
195
- handler: defs[i].handler,
196
- };
197
- }
198
- return {
199
- name: "clay-datastore",
200
- version: "1.0.0",
201
- instance: {
202
- _registeredTools: registered,
203
- },
204
- };
205
- }
206
-
207
- function getSessionToolDefinitions() {
208
- if (!isMate || !isFeatureAvailable()) return null;
209
- return getToolDefinitions();
210
- }
211
-
212
- function callMateTool(session, toolName, input) {
213
- return callToolInternal(toolName, input || {});
214
- }
215
-
216
- function closeAllDatastores() {
217
- datastore.closeAllMateDatastores();
218
- }
219
-
220
- return {
221
- isFeatureAvailable: isFeatureAvailable,
222
- handleMateDatastoreMessage: handleMateDatastoreMessage,
223
- getToolDefinitions: getToolDefinitions,
224
- createMcpServer: createMcpServer,
225
- getSessionToolDefinitions: getSessionToolDefinitions,
226
- callMateTool: callMateTool,
227
- ensureProjectDatastore: ensureProjectDatastore,
228
- closeAllDatastores: closeAllDatastores,
229
- };
230
- }
231
-
232
- module.exports = { attachMateDatastore: attachMateDatastore };
@@ -1,280 +0,0 @@
1
- import { escapeHtml } from './utils.js';
2
- import { refreshIcons } from './icons.js';
3
- import { getWs } from './ws-ref.js';
4
-
5
- var wsGetter = null;
6
- var panelEl = null;
7
- var tableListEl = null;
8
- var tableNameEl = null;
9
- var tableSchemaEl = null;
10
- var resultEl = null;
11
- var statusEl = null;
12
- var dataBtnEl = null;
13
- var mainColumnEl = null;
14
- var currentTables = [];
15
- var currentTable = null;
16
- var panelOpen = false;
17
- var routingToScheduler = false;
18
-
19
- function sendWs(msg) {
20
- var ws = wsGetter ? wsGetter() : getWs();
21
- if (ws && ws.readyState === 1) ws.send(JSON.stringify(msg));
22
- }
23
-
24
- function quoteIdentifier(name) {
25
- return '"' + String(name || "").replace(/"/g, '""') + '"';
26
- }
27
-
28
- function ensurePanel() {
29
- if (panelEl) return;
30
- mainColumnEl = document.getElementById("main-column");
31
- if (!mainColumnEl) return;
32
-
33
- panelEl = document.createElement("div");
34
- panelEl.id = "mate-datastore-panel";
35
- panelEl.className = "hidden";
36
-
37
- panelEl.innerHTML =
38
- '<div class="scheduler-top-bar mate-datastore-top-bar">' +
39
- '<span class="scheduler-top-title mate-datastore-top-title"><i data-lucide="database"></i>Data</span>' +
40
- '<div class="mate-datastore-top-actions">' +
41
- '<button id="mate-db-refresh-btn" class="scheduler-close-btn" type="button" title="Refresh tables"><i data-lucide="refresh-cw"></i></button>' +
42
- '<button id="mate-db-back-btn" class="scheduler-close-btn" type="button" title="Close"><i data-lucide="x"></i></button>' +
43
- '</div>' +
44
- '</div>' +
45
- '<div class="mate-db-status" id="mate-db-status"></div>' +
46
- '<div class="mate-db-layout">' +
47
- '<div class="mate-db-table-column">' +
48
- '<div class="mate-db-section-title">Objects</div>' +
49
- '<div id="mate-db-table-list" class="mate-db-table-list"></div>' +
50
- '</div>' +
51
- '<div class="mate-db-detail">' +
52
- '<div class="mate-db-section-title" id="mate-db-table-name">No table selected</div>' +
53
- '<pre id="mate-db-table-schema" class="mate-db-table-schema"></pre>' +
54
- '<div class="mate-db-section-title">Rows</div>' +
55
- '<pre id="mate-db-result" class="mate-db-result"></pre>' +
56
- '</div>' +
57
- '</div>';
58
-
59
- mainColumnEl.appendChild(panelEl);
60
- tableListEl = document.getElementById("mate-db-table-list");
61
- tableNameEl = document.getElementById("mate-db-table-name");
62
- tableSchemaEl = document.getElementById("mate-db-table-schema");
63
- resultEl = document.getElementById("mate-db-result");
64
- statusEl = document.getElementById("mate-db-status");
65
-
66
- var refreshBtn = document.getElementById("mate-db-refresh-btn");
67
- var backBtn = document.getElementById("mate-db-back-btn");
68
-
69
- if (refreshBtn) {
70
- refreshBtn.addEventListener("click", function () {
71
- requestTables();
72
- });
73
- }
74
-
75
- if (backBtn) {
76
- backBtn.addEventListener("click", function () {
77
- setSectionVisibility(false);
78
- });
79
- }
80
-
81
- refreshIcons();
82
- }
83
-
84
- function setSectionVisibility(open) {
85
- ensurePanel();
86
- panelOpen = open;
87
- if (panelEl) panelEl.classList.toggle("hidden", !open);
88
- if (mainColumnEl) mainColumnEl.classList.toggle("mate-datastore-open", open);
89
- if (dataBtnEl) dataBtnEl.classList.toggle("active", open);
90
- refreshIcons();
91
- }
92
-
93
- function requestTables() {
94
- sendWs({ type: "mate_db_tables" });
95
- }
96
-
97
- function renderStatus(text, kind) {
98
- if (!statusEl) return;
99
- statusEl.textContent = text || "";
100
- statusEl.dataset.kind = kind || "";
101
- }
102
-
103
- function renderResult(payload) {
104
- if (!resultEl) return;
105
- resultEl.textContent = JSON.stringify(payload, null, 2);
106
- }
107
-
108
- function formatColumns(columns) {
109
- var list = Array.isArray(columns) ? columns : [];
110
- if (!list.length) return "No column information available.";
111
- var lines = [];
112
- for (var i = 0; i < list.length; i++) {
113
- var col = list[i] || {};
114
- var line = (col.name || "?") + " " + (col.type || "");
115
- if (col.pk) line += " PRIMARY KEY";
116
- if (col.notnull) line += " NOT NULL";
117
- if (typeof col.dflt_value !== "undefined" && col.dflt_value !== null) line += " DEFAULT " + col.dflt_value;
118
- lines.push(line.trim());
119
- }
120
- return lines.join("\n");
121
- }
122
-
123
- function renderTableList(objects) {
124
- currentTables = objects || [];
125
- if (!tableListEl) return;
126
- tableListEl.innerHTML = "";
127
-
128
- if (!currentTables.length) {
129
- var empty = document.createElement("div");
130
- empty.className = "mate-db-empty";
131
- empty.textContent = "No tables or views found.";
132
- tableListEl.appendChild(empty);
133
- return;
134
- }
135
-
136
- for (var i = 0; i < currentTables.length; i++) {
137
- (function (obj) {
138
- var row = document.createElement("button");
139
- row.type = "button";
140
- row.className = "mate-db-table-item" + (currentTable === obj.name ? " active" : "");
141
- var label = obj.type || "object";
142
- row.innerHTML = '<span class="mate-db-table-item-name">' + escapeHtml(obj.name) + '</span>' +
143
- '<span class="mate-db-table-item-type">' + escapeHtml(label) + '</span>';
144
- row.addEventListener("click", function () {
145
- selectTable(obj.name);
146
- });
147
- tableListEl.appendChild(row);
148
- })(currentTables[i]);
149
- }
150
- }
151
-
152
- function findFirstDescribableObject(objects) {
153
- var list = objects || [];
154
- for (var i = 0; i < list.length; i++) {
155
- if (list[i] && (list[i].type === "table" || list[i].type === "view")) return list[i];
156
- }
157
- return null;
158
- }
159
-
160
- function findObjectByName(name) {
161
- for (var i = 0; i < currentTables.length; i++) {
162
- if (currentTables[i] && currentTables[i].name === name) return currentTables[i];
163
- }
164
- return null;
165
- }
166
-
167
- function selectTable(tableName) {
168
- currentTable = tableName;
169
- renderTableList(currentTables);
170
- var obj = findObjectByName(tableName);
171
- if (!obj) return;
172
- if (obj.type !== "table" && obj.type !== "view") {
173
- renderStatus("Selected " + (obj.type || "object") + " " + tableName + ".", "ok");
174
- if (tableNameEl) tableNameEl.textContent = tableName;
175
- if (tableSchemaEl) tableSchemaEl.textContent = (obj.type || "object") + ": " + tableName;
176
- renderResult(obj);
177
- return;
178
- }
179
- renderStatus("Loading " + tableName + "...", "info");
180
- sendWs({ type: "mate_db_describe", table: tableName });
181
- sendWs({ type: "mate_db_query", sql: "SELECT * FROM " + quoteIdentifier(tableName) + " LIMIT 100", params: [] });
182
- }
183
-
184
- export function initMateDatastoreUI(getWsFn) {
185
- wsGetter = getWsFn;
186
- dataBtnEl = document.getElementById("mate-data-btn");
187
- if (!dataBtnEl) return;
188
-
189
- dataBtnEl.addEventListener("click", function () {
190
- if (panelOpen) {
191
- setSectionVisibility(false);
192
- } else {
193
- setSectionVisibility(true);
194
- requestTables();
195
- }
196
- });
197
-
198
- document.addEventListener("click", function (e) {
199
- var btn = e.target && e.target.closest ? e.target.closest("#scheduler-btn, #mate-scheduler-btn") : null;
200
- if (!btn || !panelOpen || routingToScheduler) return;
201
- e.preventDefault();
202
- e.stopPropagation();
203
- if (typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
204
- routingToScheduler = true;
205
- setSectionVisibility(false);
206
- setTimeout(function () {
207
- var schedulerBtn = document.getElementById("scheduler-btn");
208
- if (schedulerBtn) schedulerBtn.click();
209
- routingToScheduler = false;
210
- }, 0);
211
- }, true);
212
-
213
- setSectionVisibility(false);
214
- }
215
-
216
- export function showMateDatastorePanel() {
217
- setSectionVisibility(true);
218
- requestTables();
219
- }
220
-
221
- export function hideMateDatastorePanel() {
222
- setSectionVisibility(false);
223
- }
224
-
225
- export function handleMateDatastoreTablesResult(msg) {
226
- if (msg.ok === false) {
227
- renderStatus(msg.message || "Failed to load datastore tables.", "error");
228
- renderResult(msg);
229
- return;
230
- }
231
- renderStatus(msg.warning || "Datastore tables loaded.", msg.warning ? "warn" : "ok");
232
- renderTableList(msg.objects || []);
233
- if (msg.objects && msg.objects.length > 0) {
234
- var found = false;
235
- for (var i = 0; i < msg.objects.length; i++) {
236
- if (msg.objects[i].name === currentTable) {
237
- found = true;
238
- break;
239
- }
240
- }
241
- if (!found) {
242
- var firstObject = findFirstDescribableObject(msg.objects);
243
- if (firstObject) selectTable(firstObject.name);
244
- }
245
- }
246
- renderResult(msg.objects || []);
247
- }
248
-
249
- export function handleMateDatastoreDescribeResult(msg) {
250
- if (msg.ok === false) {
251
- renderStatus(msg.message || "Failed to describe table.", "error");
252
- renderResult(msg);
253
- return;
254
- }
255
- renderStatus(msg.warning || ("Described " + (msg.table || "table") + "."), msg.warning ? "warn" : "ok");
256
- if (tableNameEl) tableNameEl.textContent = msg.table || "Table";
257
- if (tableSchemaEl) tableSchemaEl.textContent = formatColumns(msg.columns);
258
- }
259
-
260
- export function handleMateDatastoreQueryResult(msg) {
261
- if (msg.ok === false) {
262
- renderStatus(msg.message || "Query failed.", "error");
263
- renderResult(msg);
264
- return;
265
- }
266
- var status = "Showing " + (msg.rows ? msg.rows.length : 0) + " row(s).";
267
- if (msg.truncated) status = status.replace(".", " (truncated).");
268
- renderStatus(msg.warning || status, msg.warning ? "warn" : "ok");
269
- renderResult(msg.rows || []);
270
- }
271
-
272
- export function handleMateDatastoreError(msg) {
273
- renderStatus(msg.message || "Mate datastore error.", "error");
274
- renderResult(msg);
275
- }
276
-
277
- export function handleMateDatastoreChange(msg) {
278
- renderStatus("Datastore changed.", "info");
279
- if (panelOpen) requestTables();
280
- }