clay-server 2.34.0-beta.2 → 2.34.0-beta.3
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/lib/mate-datastore.js +27 -5
- package/lib/project-mate-datastore.js +16 -2
- package/lib/public/css/mates.css +68 -41
- package/lib/public/index.html +0 -28
- package/lib/public/modules/app-messages.js +1 -5
- package/lib/public/modules/app-rendering.js +0 -2
- package/lib/public/modules/mate-datastore-ui.js +108 -98
- package/lib/public/modules/tools.js +1 -1
- package/lib/sdk-bridge.js +3 -1
- package/lib/yoke/index.js +36 -10
- package/lib/yoke/instructions.js +0 -1
- package/package.json +1 -2
- package/lib/yoke/adapters/gemini.js +0 -709
package/lib/mate-datastore.js
CHANGED
|
@@ -3,10 +3,12 @@ var path = require("path");
|
|
|
3
3
|
var config = require("./config");
|
|
4
4
|
|
|
5
5
|
var sqlite;
|
|
6
|
+
var _availabilityError = null;
|
|
6
7
|
try {
|
|
7
8
|
sqlite = require("node:sqlite");
|
|
8
9
|
} catch (e) {
|
|
9
|
-
|
|
10
|
+
sqlite = null;
|
|
11
|
+
_availabilityError = "Mate datastores require Node 22.13.0 or newer with node:sqlite available.";
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
function parseNodeVersion(version) {
|
|
@@ -24,10 +26,13 @@ function assertNodeVersion() {
|
|
|
24
26
|
throw new Error("Mate datastores require Node 22.13.0 or newer.");
|
|
25
27
|
}
|
|
26
28
|
}
|
|
29
|
+
try {
|
|
30
|
+
assertNodeVersion();
|
|
31
|
+
} catch (e) {
|
|
32
|
+
if (!_availabilityError) _availabilityError = e.message;
|
|
33
|
+
}
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var DatabaseSync = sqlite.DatabaseSync;
|
|
35
|
+
var DatabaseSync = sqlite ? sqlite.DatabaseSync : null;
|
|
31
36
|
|
|
32
37
|
var MAX_ROWS = 200;
|
|
33
38
|
var MAX_RESULT_BYTES = 1024 * 1024;
|
|
@@ -37,6 +42,20 @@ var CLAY_META_VERSION = "1";
|
|
|
37
42
|
|
|
38
43
|
var _dbCache = {};
|
|
39
44
|
|
|
45
|
+
function isMateDatastoreAvailable() {
|
|
46
|
+
return !!DatabaseSync && !_availabilityError;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getMateDatastoreAvailabilityError() {
|
|
50
|
+
return _availabilityError || null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function assertAvailable() {
|
|
54
|
+
if (!isMateDatastoreAvailable()) {
|
|
55
|
+
throw new Error(getMateDatastoreAvailabilityError() || "Mate datastore is unavailable.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
40
59
|
function getMateDbPath(opts) {
|
|
41
60
|
if (opts && opts.dbPath) return String(opts.dbPath);
|
|
42
61
|
if (opts && opts.mateDir) return path.join(String(opts.mateDir), "store.db");
|
|
@@ -77,6 +96,7 @@ function initClayMeta(db) {
|
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
function ensureMateDatastore(opts) {
|
|
99
|
+
assertAvailable();
|
|
80
100
|
var dbPath = getMateDbPath(opts);
|
|
81
101
|
if (_dbCache[dbPath] && _dbCache[dbPath].db) return _dbCache[dbPath];
|
|
82
102
|
ensureParentDir(dbPath);
|
|
@@ -257,7 +277,7 @@ function listSchemaObjects(handle) {
|
|
|
257
277
|
}
|
|
258
278
|
try {
|
|
259
279
|
var rows = wrapper.db.prepare(
|
|
260
|
-
"SELECT name, type, sql FROM sqlite_master WHERE type IN ('table', 'view', 'index') AND name NOT LIKE 'sqlite_%' ORDER BY type, name"
|
|
280
|
+
"SELECT name, type, sql FROM sqlite_master WHERE type IN ('table', 'view', 'index') AND name NOT LIKE 'sqlite_%' AND name NOT LIKE 'clay_%' ORDER BY type, name"
|
|
261
281
|
).all();
|
|
262
282
|
return { ok: true, objects: rows };
|
|
263
283
|
} catch (e) {
|
|
@@ -325,6 +345,8 @@ function normalizeSqliteError(err, fallbackCode, fallbackMessage) {
|
|
|
325
345
|
}
|
|
326
346
|
|
|
327
347
|
module.exports = {
|
|
348
|
+
isMateDatastoreAvailable: isMateDatastoreAvailable,
|
|
349
|
+
getMateDatastoreAvailabilityError: getMateDatastoreAvailabilityError,
|
|
328
350
|
openMateDatastore: openMateDatastore,
|
|
329
351
|
ensureMateDatastore: ensureMateDatastore,
|
|
330
352
|
listSchemaObjects: listSchemaObjects,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var z = require("zod");
|
|
2
2
|
var datastore = require("./mate-datastore");
|
|
3
|
+
var FEATURE_ENABLED = false;
|
|
3
4
|
|
|
4
5
|
function attachMateDatastore(ctx) {
|
|
5
6
|
var cwd = ctx.cwd;
|
|
@@ -7,7 +8,14 @@ function attachMateDatastore(ctx) {
|
|
|
7
8
|
var send = ctx.send;
|
|
8
9
|
var sendTo = ctx.sendTo;
|
|
9
10
|
|
|
11
|
+
function isFeatureAvailable() {
|
|
12
|
+
return FEATURE_ENABLED && datastore.isMateDatastoreAvailable();
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
function ensureProjectDatastore() {
|
|
16
|
+
if (!FEATURE_ENABLED) {
|
|
17
|
+
return { ok: false, code: "MATE_DATASTORE_NOT_ALLOWED", message: "Mate datastore is not enabled." };
|
|
18
|
+
}
|
|
11
19
|
if (!isMate) {
|
|
12
20
|
return { ok: false, code: "MATE_DATASTORE_NOT_ALLOWED", message: "Mate datastore is only available in Mate sessions." };
|
|
13
21
|
}
|
|
@@ -87,6 +95,10 @@ function attachMateDatastore(ctx) {
|
|
|
87
95
|
return false;
|
|
88
96
|
}
|
|
89
97
|
|
|
98
|
+
if (!FEATURE_ENABLED) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
if (!isMate) {
|
|
91
103
|
sendTo(ws, {
|
|
92
104
|
type: "mate_db_error",
|
|
@@ -127,7 +139,7 @@ function attachMateDatastore(ctx) {
|
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
function getToolDefinitions() {
|
|
130
|
-
if (!isMate) return [];
|
|
142
|
+
if (!isMate || !isFeatureAvailable()) return [];
|
|
131
143
|
return [
|
|
132
144
|
{
|
|
133
145
|
name: "clay_db_query",
|
|
@@ -174,6 +186,7 @@ function attachMateDatastore(ctx) {
|
|
|
174
186
|
|
|
175
187
|
function createMcpServer() {
|
|
176
188
|
var defs = getToolDefinitions();
|
|
189
|
+
if (!defs.length) return null;
|
|
177
190
|
var registered = {};
|
|
178
191
|
for (var i = 0; i < defs.length; i++) {
|
|
179
192
|
registered[defs[i].name] = {
|
|
@@ -192,7 +205,7 @@ function attachMateDatastore(ctx) {
|
|
|
192
205
|
}
|
|
193
206
|
|
|
194
207
|
function getSessionToolDefinitions() {
|
|
195
|
-
if (!isMate) return null;
|
|
208
|
+
if (!isMate || !isFeatureAvailable()) return null;
|
|
196
209
|
return getToolDefinitions();
|
|
197
210
|
}
|
|
198
211
|
|
|
@@ -205,6 +218,7 @@ function attachMateDatastore(ctx) {
|
|
|
205
218
|
}
|
|
206
219
|
|
|
207
220
|
return {
|
|
221
|
+
isFeatureAvailable: isFeatureAvailable,
|
|
208
222
|
handleMateDatastoreMessage: handleMateDatastoreMessage,
|
|
209
223
|
getToolDefinitions: getToolDefinitions,
|
|
210
224
|
createMcpServer: createMcpServer,
|
package/lib/public/css/mates.css
CHANGED
|
@@ -1997,19 +1997,60 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
1997
1997
|
}
|
|
1998
1998
|
|
|
1999
1999
|
/* Mate datastore inspector */
|
|
2000
|
-
#mate-
|
|
2000
|
+
#mate-datastore-panel {
|
|
2001
|
+
position: absolute;
|
|
2002
|
+
inset: 0;
|
|
2003
|
+
z-index: 40;
|
|
2004
|
+
background: var(--bg);
|
|
2001
2005
|
display: flex;
|
|
2002
2006
|
flex-direction: column;
|
|
2003
|
-
|
|
2004
|
-
|
|
2007
|
+
overflow: hidden;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
#mate-datastore-panel.hidden {
|
|
2011
|
+
display: none !important;
|
|
2005
2012
|
}
|
|
2006
2013
|
|
|
2007
|
-
#mate-
|
|
2014
|
+
#main-column.mate-datastore-open > .title-bar-content,
|
|
2015
|
+
#main-column.mate-datastore-open > .dm-header-bar,
|
|
2016
|
+
#main-column.mate-datastore-open > #main-panels {
|
|
2008
2017
|
display: none !important;
|
|
2009
2018
|
}
|
|
2010
2019
|
|
|
2020
|
+
.mate-datastore-top-bar {
|
|
2021
|
+
display: flex;
|
|
2022
|
+
align-items: center;
|
|
2023
|
+
justify-content: space-between;
|
|
2024
|
+
height: 48px;
|
|
2025
|
+
padding: 0 16px;
|
|
2026
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
2027
|
+
flex-shrink: 0;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
.mate-datastore-top-title {
|
|
2031
|
+
display: flex;
|
|
2032
|
+
align-items: center;
|
|
2033
|
+
gap: 6px;
|
|
2034
|
+
font-weight: 700;
|
|
2035
|
+
font-size: 15px;
|
|
2036
|
+
color: var(--text);
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
.mate-datastore-top-title .lucide {
|
|
2040
|
+
width: 14px;
|
|
2041
|
+
height: 14px;
|
|
2042
|
+
color: var(--accent);
|
|
2043
|
+
opacity: 0.85;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
.mate-datastore-top-actions {
|
|
2047
|
+
display: flex;
|
|
2048
|
+
align-items: center;
|
|
2049
|
+
gap: 8px;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2011
2052
|
.mate-db-status {
|
|
2012
|
-
padding:
|
|
2053
|
+
padding: 10px 14px 0;
|
|
2013
2054
|
font-size: 12px;
|
|
2014
2055
|
color: var(--text-secondary, #8e8e8e);
|
|
2015
2056
|
}
|
|
@@ -2028,9 +2069,9 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
2028
2069
|
|
|
2029
2070
|
.mate-db-layout {
|
|
2030
2071
|
display: grid;
|
|
2031
|
-
grid-template-columns:
|
|
2072
|
+
grid-template-columns: 220px minmax(0, 1fr);
|
|
2032
2073
|
gap: 10px;
|
|
2033
|
-
padding:
|
|
2074
|
+
padding: 12px 10px 10px;
|
|
2034
2075
|
min-height: 0;
|
|
2035
2076
|
flex: 1;
|
|
2036
2077
|
}
|
|
@@ -2044,10 +2085,10 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
2044
2085
|
|
|
2045
2086
|
.mate-db-table-list {
|
|
2046
2087
|
overflow-y: auto;
|
|
2047
|
-
border: 1px solid var(--border-subtle, rgba(255,255,255,0.
|
|
2048
|
-
border-radius:
|
|
2049
|
-
background: var(--bg
|
|
2050
|
-
padding:
|
|
2088
|
+
border: 1px solid var(--border-subtle, rgba(255,255,255,0.06));
|
|
2089
|
+
border-radius: 12px;
|
|
2090
|
+
background: var(--sidebar-bg, rgba(255,255,255,0.03));
|
|
2091
|
+
padding: 6px;
|
|
2051
2092
|
flex: 1;
|
|
2052
2093
|
}
|
|
2053
2094
|
|
|
@@ -2123,46 +2164,32 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
2123
2164
|
}
|
|
2124
2165
|
|
|
2125
2166
|
.mate-db-table-schema {
|
|
2126
|
-
max-height:
|
|
2167
|
+
max-height: 180px;
|
|
2127
2168
|
}
|
|
2128
2169
|
|
|
2129
|
-
|
|
2130
|
-
.mate-db-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
padding: 10px;
|
|
2134
|
-
border-radius: 10px;
|
|
2135
|
-
border: 1px solid var(--border-subtle, rgba(255,255,255,0.1));
|
|
2136
|
-
background: var(--bg-secondary, rgba(255,255,255,0.04));
|
|
2137
|
-
color: var(--text, #fff);
|
|
2138
|
-
font-family: var(--mono-font, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
2139
|
-
font-size: 11px;
|
|
2140
|
-
resize: vertical;
|
|
2170
|
+
@media (max-width: 900px) {
|
|
2171
|
+
.mate-db-layout {
|
|
2172
|
+
grid-template-columns: 1fr;
|
|
2173
|
+
}
|
|
2141
2174
|
}
|
|
2142
2175
|
|
|
2143
|
-
.mate-
|
|
2144
|
-
|
|
2176
|
+
body.mate-dm-active .mate-datastore-top-bar {
|
|
2177
|
+
background: var(--mate-color);
|
|
2178
|
+
color: #fff;
|
|
2145
2179
|
}
|
|
2146
2180
|
|
|
2147
|
-
.mate-
|
|
2148
|
-
|
|
2149
|
-
|
|
2181
|
+
body.mate-dm-active .mate-datastore-top-title,
|
|
2182
|
+
body.mate-dm-active .mate-datastore-top-title .lucide {
|
|
2183
|
+
color: #fff;
|
|
2150
2184
|
}
|
|
2151
2185
|
|
|
2152
|
-
.mate-
|
|
2153
|
-
|
|
2154
|
-
height: 30px;
|
|
2155
|
-
border: none;
|
|
2156
|
-
border-radius: 8px;
|
|
2157
|
-
background: var(--sidebar-active, rgba(255,255,255,0.08));
|
|
2158
|
-
color: var(--text, #fff);
|
|
2159
|
-
font-size: 12px;
|
|
2160
|
-
font-weight: 600;
|
|
2161
|
-
cursor: pointer;
|
|
2186
|
+
body.mate-dm-active .mate-datastore-top-bar .scheduler-close-btn {
|
|
2187
|
+
color: rgba(255, 255, 255, 0.85);
|
|
2162
2188
|
}
|
|
2163
2189
|
|
|
2164
|
-
.mate-
|
|
2165
|
-
|
|
2190
|
+
body.mate-dm-active .mate-datastore-top-bar .scheduler-close-btn:hover {
|
|
2191
|
+
color: #fff;
|
|
2192
|
+
background: rgba(255, 255, 255, 0.15);
|
|
2166
2193
|
}
|
|
2167
2194
|
|
|
2168
2195
|
.mate-session-item.search-match {
|
package/lib/public/index.html
CHANGED
|
@@ -270,7 +270,6 @@
|
|
|
270
270
|
<div class="mate-sidebar-sessions-header">
|
|
271
271
|
<span>Conversations</span>
|
|
272
272
|
<div class="mate-sidebar-actions">
|
|
273
|
-
<button id="mate-data-btn" type="button" title="Data inspector"><i data-lucide="database"></i></button>
|
|
274
273
|
<button id="mate-search-session-btn" type="button" title="Search sessions"><i data-lucide="search"></i></button>
|
|
275
274
|
<button id="mate-new-session-btn" type="button" title="New session"><i data-lucide="plus"></i></button>
|
|
276
275
|
</div>
|
|
@@ -281,33 +280,6 @@
|
|
|
281
280
|
</div>
|
|
282
281
|
<div id="mate-session-list" class="mate-session-list"></div>
|
|
283
282
|
</div>
|
|
284
|
-
<div id="mate-sidebar-datastore" class="hidden">
|
|
285
|
-
<div class="mate-sidebar-sessions-header">
|
|
286
|
-
<span>Data</span>
|
|
287
|
-
<div class="mate-sidebar-actions">
|
|
288
|
-
<button id="mate-db-refresh-btn" type="button" title="Refresh tables"><i data-lucide="refresh-cw"></i></button>
|
|
289
|
-
<button id="mate-db-back-btn" type="button" title="Back to conversations"><i data-lucide="x"></i></button>
|
|
290
|
-
</div>
|
|
291
|
-
</div>
|
|
292
|
-
<div class="mate-db-status" id="mate-db-status"></div>
|
|
293
|
-
<div class="mate-db-layout">
|
|
294
|
-
<div class="mate-db-table-column">
|
|
295
|
-
<div class="mate-db-section-title">Objects</div>
|
|
296
|
-
<div id="mate-db-table-list" class="mate-db-table-list"></div>
|
|
297
|
-
</div>
|
|
298
|
-
<div class="mate-db-detail">
|
|
299
|
-
<div class="mate-db-section-title" id="mate-db-table-name">No table selected</div>
|
|
300
|
-
<pre id="mate-db-table-schema" class="mate-db-table-schema"></pre>
|
|
301
|
-
<textarea id="mate-db-query" class="mate-db-query" spellcheck="false" placeholder="SELECT * FROM table LIMIT 50;"></textarea>
|
|
302
|
-
<textarea id="mate-db-params" class="mate-db-params" spellcheck="false" placeholder='[]'></textarea>
|
|
303
|
-
<div class="mate-db-actions">
|
|
304
|
-
<button id="mate-db-query-btn" type="button">Query</button>
|
|
305
|
-
<button id="mate-db-exec-btn" type="button">Exec</button>
|
|
306
|
-
</div>
|
|
307
|
-
<pre id="mate-db-result" class="mate-db-result"></pre>
|
|
308
|
-
</div>
|
|
309
|
-
</div>
|
|
310
|
-
</div>
|
|
311
283
|
<div id="mate-sidebar-memory" class="hidden"></div>
|
|
312
284
|
<div id="mate-sidebar-knowledge" class="hidden">
|
|
313
285
|
<div class="mate-sidebar-sessions-header">
|
|
@@ -14,7 +14,7 @@ import { renderSessionList, updateSessionPresence, populateCliSessionList, handl
|
|
|
14
14
|
import { updateDmBadge, renderSidebarPresence, setMentionActive, renderUserStrip } from './sidebar-mates.js';
|
|
15
15
|
import { refreshMobileChatSheet } from './sidebar-mobile.js';
|
|
16
16
|
import { renderMateSessionList, handleMateSearchResults, updateMateSidebarProfile } from './mate-sidebar.js';
|
|
17
|
-
import { handleMateDatastoreTablesResult, handleMateDatastoreDescribeResult, handleMateDatastoreQueryResult,
|
|
17
|
+
import { handleMateDatastoreTablesResult, handleMateDatastoreDescribeResult, handleMateDatastoreQueryResult, handleMateDatastoreError, handleMateDatastoreChange } from './mate-datastore-ui.js';
|
|
18
18
|
import { renderKnowledgeList, handleKnowledgeContent } from './mate-knowledge.js';
|
|
19
19
|
import { renderMemoryList } from './mate-memory.js';
|
|
20
20
|
import { handlePaletteSessionSwitch, setPaletteVersion } from './command-palette.js';
|
|
@@ -288,10 +288,6 @@ export function processMessage(msg) {
|
|
|
288
288
|
handleMateDatastoreQueryResult(msg);
|
|
289
289
|
break;
|
|
290
290
|
|
|
291
|
-
case "mate_db_exec_result":
|
|
292
|
-
handleMateDatastoreExecResult(msg);
|
|
293
|
-
break;
|
|
294
|
-
|
|
295
291
|
case "mate_db_error":
|
|
296
292
|
handleMateDatastoreError(msg);
|
|
297
293
|
break;
|
|
@@ -17,12 +17,10 @@ import { getScheduledMsgEl } from './app-rate-limit.js';
|
|
|
17
17
|
export var VENDOR_AVATARS = {
|
|
18
18
|
claude: "/claude-code-avatar.png",
|
|
19
19
|
codex: "/codex-avatar.png",
|
|
20
|
-
gemini: "/claude-code-avatar.png",
|
|
21
20
|
};
|
|
22
21
|
export var VENDOR_NAMES = {
|
|
23
22
|
claude: "Claude Code",
|
|
24
23
|
codex: "Codex",
|
|
25
|
-
gemini: "Gemini",
|
|
26
24
|
};
|
|
27
25
|
var NEW_MSG_BTN_DEFAULT = "\u2193 Latest";
|
|
28
26
|
var NEW_MSG_BTN_ACTIVITY = "\u2193 New activity";
|
|
@@ -7,29 +7,85 @@ var panelEl = null;
|
|
|
7
7
|
var tableListEl = null;
|
|
8
8
|
var tableNameEl = null;
|
|
9
9
|
var tableSchemaEl = null;
|
|
10
|
-
var queryInputEl = null;
|
|
11
|
-
var paramsInputEl = null;
|
|
12
10
|
var resultEl = null;
|
|
13
11
|
var statusEl = null;
|
|
14
12
|
var dataBtnEl = null;
|
|
15
|
-
var
|
|
16
|
-
var memoryEl = null;
|
|
17
|
-
var knowledgeEl = null;
|
|
13
|
+
var mainColumnEl = null;
|
|
18
14
|
var currentTables = [];
|
|
19
15
|
var currentTable = null;
|
|
20
16
|
var panelOpen = false;
|
|
17
|
+
var routingToScheduler = false;
|
|
21
18
|
|
|
22
19
|
function sendWs(msg) {
|
|
23
20
|
var ws = wsGetter ? wsGetter() : getWs();
|
|
24
21
|
if (ws && ws.readyState === 1) ws.send(JSON.stringify(msg));
|
|
25
22
|
}
|
|
26
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
|
+
|
|
27
84
|
function setSectionVisibility(open) {
|
|
85
|
+
ensurePanel();
|
|
28
86
|
panelOpen = open;
|
|
29
87
|
if (panelEl) panelEl.classList.toggle("hidden", !open);
|
|
30
|
-
if (
|
|
31
|
-
if (memoryEl) memoryEl.classList.toggle("hidden", true);
|
|
32
|
-
if (knowledgeEl) knowledgeEl.classList.toggle("hidden", true);
|
|
88
|
+
if (mainColumnEl) mainColumnEl.classList.toggle("mate-datastore-open", open);
|
|
33
89
|
if (dataBtnEl) dataBtnEl.classList.toggle("active", open);
|
|
34
90
|
refreshIcons();
|
|
35
91
|
}
|
|
@@ -49,6 +105,21 @@ function renderResult(payload) {
|
|
|
49
105
|
resultEl.textContent = JSON.stringify(payload, null, 2);
|
|
50
106
|
}
|
|
51
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
|
+
|
|
52
123
|
function renderTableList(objects) {
|
|
53
124
|
currentTables = objects || [];
|
|
54
125
|
if (!tableListEl) return;
|
|
@@ -101,94 +172,43 @@ function selectTable(tableName) {
|
|
|
101
172
|
if (obj.type !== "table" && obj.type !== "view") {
|
|
102
173
|
renderStatus("Selected " + (obj.type || "object") + " " + tableName + ".", "ok");
|
|
103
174
|
if (tableNameEl) tableNameEl.textContent = tableName;
|
|
104
|
-
if (tableSchemaEl) tableSchemaEl.textContent = obj.
|
|
175
|
+
if (tableSchemaEl) tableSchemaEl.textContent = (obj.type || "object") + ": " + tableName;
|
|
105
176
|
renderResult(obj);
|
|
106
177
|
return;
|
|
107
178
|
}
|
|
108
179
|
renderStatus("Loading " + tableName + "...", "info");
|
|
109
180
|
sendWs({ type: "mate_db_describe", table: tableName });
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function parseParams() {
|
|
114
|
-
if (!paramsInputEl) return [];
|
|
115
|
-
var text = paramsInputEl.value.trim();
|
|
116
|
-
if (!text) return [];
|
|
117
|
-
try {
|
|
118
|
-
var parsed = JSON.parse(text);
|
|
119
|
-
if (Array.isArray(parsed)) return parsed;
|
|
120
|
-
renderStatus("Parameters must be a JSON array.", "error");
|
|
121
|
-
} catch (e) {
|
|
122
|
-
renderStatus("Parameters must be valid JSON.", "error");
|
|
123
|
-
}
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function sendQueryMessage(type) {
|
|
128
|
-
var sql = queryInputEl ? queryInputEl.value : "";
|
|
129
|
-
var params = parseParams();
|
|
130
|
-
if (params === null) return;
|
|
131
|
-
if (!sql || !sql.trim()) {
|
|
132
|
-
renderStatus("Enter SQL before running it.", "error");
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
sendWs({ type: type, sql: sql, params: params });
|
|
181
|
+
sendWs({ type: "mate_db_query", sql: "SELECT * FROM " + quoteIdentifier(tableName) + " LIMIT 100", params: [] });
|
|
136
182
|
}
|
|
137
183
|
|
|
138
184
|
export function initMateDatastoreUI(getWsFn) {
|
|
139
185
|
wsGetter = getWsFn;
|
|
140
|
-
panelEl = document.getElementById("mate-sidebar-datastore");
|
|
141
|
-
tableListEl = document.getElementById("mate-db-table-list");
|
|
142
|
-
tableNameEl = document.getElementById("mate-db-table-name");
|
|
143
|
-
tableSchemaEl = document.getElementById("mate-db-table-schema");
|
|
144
|
-
queryInputEl = document.getElementById("mate-db-query");
|
|
145
|
-
paramsInputEl = document.getElementById("mate-db-params");
|
|
146
|
-
resultEl = document.getElementById("mate-db-result");
|
|
147
|
-
statusEl = document.getElementById("mate-db-status");
|
|
148
186
|
dataBtnEl = document.getElementById("mate-data-btn");
|
|
149
|
-
|
|
150
|
-
memoryEl = document.getElementById("mate-sidebar-memory");
|
|
151
|
-
knowledgeEl = document.getElementById("mate-sidebar-knowledge");
|
|
152
|
-
|
|
153
|
-
var refreshBtn = document.getElementById("mate-db-refresh-btn");
|
|
154
|
-
var queryBtn = document.getElementById("mate-db-query-btn");
|
|
155
|
-
var execBtn = document.getElementById("mate-db-exec-btn");
|
|
156
|
-
var backBtn = document.getElementById("mate-db-back-btn");
|
|
157
|
-
|
|
158
|
-
if (dataBtnEl) {
|
|
159
|
-
dataBtnEl.addEventListener("click", function () {
|
|
160
|
-
if (panelOpen) {
|
|
161
|
-
setSectionVisibility(false);
|
|
162
|
-
} else {
|
|
163
|
-
setSectionVisibility(true);
|
|
164
|
-
requestTables();
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}
|
|
187
|
+
if (!dataBtnEl) return;
|
|
168
188
|
|
|
169
|
-
|
|
170
|
-
|
|
189
|
+
dataBtnEl.addEventListener("click", function () {
|
|
190
|
+
if (panelOpen) {
|
|
191
|
+
setSectionVisibility(false);
|
|
192
|
+
} else {
|
|
193
|
+
setSectionVisibility(true);
|
|
171
194
|
requestTables();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (queryBtn) {
|
|
176
|
-
queryBtn.addEventListener("click", function () {
|
|
177
|
-
sendQueryMessage("mate_db_query");
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (execBtn) {
|
|
182
|
-
execBtn.addEventListener("click", function () {
|
|
183
|
-
sendQueryMessage("mate_db_exec");
|
|
184
|
-
});
|
|
185
|
-
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
186
197
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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);
|
|
192
212
|
|
|
193
213
|
setSectionVisibility(false);
|
|
194
214
|
}
|
|
@@ -234,8 +254,7 @@ export function handleMateDatastoreDescribeResult(msg) {
|
|
|
234
254
|
}
|
|
235
255
|
renderStatus(msg.warning || ("Described " + (msg.table || "table") + "."), msg.warning ? "warn" : "ok");
|
|
236
256
|
if (tableNameEl) tableNameEl.textContent = msg.table || "Table";
|
|
237
|
-
if (tableSchemaEl) tableSchemaEl.textContent = msg.
|
|
238
|
-
renderResult(msg);
|
|
257
|
+
if (tableSchemaEl) tableSchemaEl.textContent = formatColumns(msg.columns);
|
|
239
258
|
}
|
|
240
259
|
|
|
241
260
|
export function handleMateDatastoreQueryResult(msg) {
|
|
@@ -244,19 +263,10 @@ export function handleMateDatastoreQueryResult(msg) {
|
|
|
244
263
|
renderResult(msg);
|
|
245
264
|
return;
|
|
246
265
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
export function handleMateDatastoreExecResult(msg) {
|
|
252
|
-
if (msg.ok === false) {
|
|
253
|
-
renderStatus(msg.message || "Execution failed.", "error");
|
|
254
|
-
renderResult(msg);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
renderStatus(msg.warning || ("Applied " + (msg.changes || 0) + " change(s)."), msg.warning ? "warn" : "ok");
|
|
258
|
-
renderResult(msg);
|
|
259
|
-
requestTables();
|
|
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 || []);
|
|
260
270
|
}
|
|
261
271
|
|
|
262
272
|
export function handleMateDatastoreError(msg) {
|
|
@@ -799,7 +799,7 @@ function resolvePermissionIdentity(mateId, vendor) {
|
|
|
799
799
|
}
|
|
800
800
|
}
|
|
801
801
|
// Project chat: use vendor name and avatar
|
|
802
|
-
var vendorAvatars = { claude: "/claude-code-avatar.png", codex: "/codex-avatar.png"
|
|
802
|
+
var vendorAvatars = { claude: "/claude-code-avatar.png", codex: "/codex-avatar.png" };
|
|
803
803
|
var vendorName = (vendor && VENDOR_NAMES[vendor]) || VENDOR_NAMES.claude;
|
|
804
804
|
return {
|
|
805
805
|
name: vendorName,
|
package/lib/sdk-bridge.js
CHANGED
|
@@ -1183,11 +1183,13 @@ function createSDKBridge(opts) {
|
|
|
1183
1183
|
else if (session.acceptEditsAfterStart) effectiveDefault = "acceptEdits";
|
|
1184
1184
|
else effectiveDefault = globalMode;
|
|
1185
1185
|
var modeToApply = session._loopPermissionMode || effectiveDefault;
|
|
1186
|
-
if (session.acceptEditsAfterStart) delete session.acceptEditsAfterStart;
|
|
1187
1186
|
if (modeToApply && modeToApply !== "default") {
|
|
1188
1187
|
claudeOpts.permissionMode = modeToApply;
|
|
1189
1188
|
}
|
|
1190
1189
|
}
|
|
1190
|
+
// Clear one-shot acceptEditsAfterStart regardless of which branch ran above,
|
|
1191
|
+
// so the flag does not linger into subsequent turns.
|
|
1192
|
+
if (session.acceptEditsAfterStart) delete session.acceptEditsAfterStart;
|
|
1191
1193
|
if (session.cliSessionId && session.lastRewindUuid) {
|
|
1192
1194
|
claudeOpts.resumeSessionAt = session.lastRewindUuid;
|
|
1193
1195
|
delete session.lastRewindUuid;
|