clay-server 2.34.0-beta.1 → 2.34.0-beta.10
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/ask-user-mcp-server.js +120 -0
- package/lib/daemon.js +97 -38
- package/lib/mate-datastore.js +27 -5
- package/lib/mates.js +2 -2
- package/lib/os-users.js +13 -0
- package/lib/project-connection.js +16 -9
- package/lib/project-mate-datastore.js +16 -2
- package/lib/project-sessions.js +110 -7
- package/lib/project-user-message.js +4 -3
- package/lib/project.js +97 -10
- package/lib/public/css/mates.css +94 -52
- package/lib/public/css/mobile-nav.css +0 -14
- package/lib/public/css/notifications-center.css +23 -19
- package/lib/public/css/sidebar.css +326 -101
- package/lib/public/index.html +24 -57
- package/lib/public/modules/app-dm.js +0 -2
- package/lib/public/modules/app-messages.js +3 -5
- package/lib/public/modules/app-rendering.js +0 -2
- package/lib/public/modules/diff.js +21 -7
- package/lib/public/modules/mate-datastore-ui.js +108 -98
- package/lib/public/modules/mate-sidebar.js +0 -9
- package/lib/public/modules/mate-wizard.js +15 -15
- package/lib/public/modules/sidebar-mobile.js +10 -20
- package/lib/public/modules/sidebar-sessions.js +490 -113
- package/lib/public/modules/sidebar.js +8 -6
- package/lib/public/modules/tools.js +58 -13
- package/lib/public/sw.js +1 -1
- package/lib/sdk-bridge.js +36 -28
- package/lib/sdk-message-processor.js +14 -3
- package/lib/server.js +28 -72
- package/lib/sessions.js +157 -20
- package/lib/ws-schema.js +2 -0
- package/lib/yoke/adapters/claude-worker.js +114 -2
- package/lib/yoke/adapters/claude.js +56 -5
- package/lib/yoke/adapters/codex.js +349 -58
- package/lib/yoke/index.js +73 -35
- package/lib/yoke/instructions.js +0 -1
- package/lib/yoke/mcp-bridge-server.js +14 -6
- package/package.json +1 -2
- package/lib/yoke/adapters/gemini.js +0 -709
package/lib/public/index.html
CHANGED
|
@@ -197,17 +197,14 @@
|
|
|
197
197
|
</div>
|
|
198
198
|
<div id="sidebar-sessions-header">
|
|
199
199
|
<div id="sessions-header-content">
|
|
200
|
-
<div class="
|
|
201
|
-
<span>Sessions</span>
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
<
|
|
205
|
-
<button id="search-
|
|
200
|
+
<div class="sidebar-sessions-header-row">
|
|
201
|
+
<span class="sidebar-section-label">Sessions</span>
|
|
202
|
+
<span id="session-filter-count" class="session-filter-count hidden"></span>
|
|
203
|
+
<div id="session-header-search-inline" class="sidebar-sessions-search-inline hidden">
|
|
204
|
+
<input id="session-header-search-input" type="text" placeholder="Search sessions..." autocomplete="off" spellcheck="false" />
|
|
205
|
+
<button id="session-header-search-clear" type="button" aria-label="Clear search"><i data-lucide="x"></i></button>
|
|
206
206
|
</div>
|
|
207
|
-
|
|
208
|
-
<div id="session-search" class="hidden">
|
|
209
|
-
<input id="session-search-input" type="text" placeholder="Search sessions..." autocomplete="off" spellcheck="false" />
|
|
210
|
-
<button id="session-search-clear" type="button" aria-label="Clear search"><i data-lucide="x"></i></button>
|
|
207
|
+
<button id="session-header-search-btn" type="button" aria-label="Search sessions" title="Search sessions"><i data-lucide="search"></i></button>
|
|
211
208
|
</div>
|
|
212
209
|
</div>
|
|
213
210
|
<div id="files-header-content" class="hidden"></div>
|
|
@@ -270,7 +267,6 @@
|
|
|
270
267
|
<div class="mate-sidebar-sessions-header">
|
|
271
268
|
<span>Conversations</span>
|
|
272
269
|
<div class="mate-sidebar-actions">
|
|
273
|
-
<button id="mate-data-btn" type="button" title="Data inspector"><i data-lucide="database"></i></button>
|
|
274
270
|
<button id="mate-search-session-btn" type="button" title="Search sessions"><i data-lucide="search"></i></button>
|
|
275
271
|
<button id="mate-new-session-btn" type="button" title="New session"><i data-lucide="plus"></i></button>
|
|
276
272
|
</div>
|
|
@@ -281,33 +277,6 @@
|
|
|
281
277
|
</div>
|
|
282
278
|
<div id="mate-session-list" class="mate-session-list"></div>
|
|
283
279
|
</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
280
|
<div id="mate-sidebar-memory" class="hidden"></div>
|
|
312
281
|
<div id="mate-sidebar-knowledge" class="hidden">
|
|
313
282
|
<div class="mate-sidebar-sessions-header">
|
|
@@ -1883,7 +1852,7 @@
|
|
|
1883
1852
|
<div class="mate-intro-step"><span class="mate-intro-step-num">2</span> Have a short interview where your Mate gets to know you</div>
|
|
1884
1853
|
<div class="mate-intro-step"><span class="mate-intro-step-num">3</span> Start talking</div>
|
|
1885
1854
|
</div>
|
|
1886
|
-
<p class="mate-intro-privacy">Mates run on Claude Code. No separate API keys or external services needed. Your conversations stay on your Clay server and are never stored elsewhere.</p>
|
|
1855
|
+
<p class="mate-intro-privacy">Mates run on Claude Code or ChatGPT Codex, your choice. No separate API keys or external services needed. Your conversations stay on your Clay server and are never stored elsewhere.</p>
|
|
1887
1856
|
</div>
|
|
1888
1857
|
</div>
|
|
1889
1858
|
<!-- Step 1: Relationship -->
|
|
@@ -2024,26 +1993,24 @@
|
|
|
2024
1993
|
</div>
|
|
2025
1994
|
</div>
|
|
2026
1995
|
|
|
2027
|
-
<!-- Step 4:
|
|
1996
|
+
<!-- Step 4: Vendor -->
|
|
2028
1997
|
<div class="mate-step" data-step="4">
|
|
2029
|
-
<h3>
|
|
2030
|
-
<p class="mate-hint">
|
|
2031
|
-
<div class="mate-
|
|
2032
|
-
<button class="mate-
|
|
2033
|
-
<
|
|
2034
|
-
<
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
<span class="mate-autonomy-desc">"Little things, just do it. Anything big, ask me."</span>
|
|
2039
|
-
</button>
|
|
2040
|
-
<button class="mate-autonomy-btn" data-value="mostly_autonomous">
|
|
2041
|
-
<span class="mate-autonomy-title">Mostly free</span>
|
|
2042
|
-
<span class="mate-autonomy-desc">"Do your thing. Only check if it's really important."</span>
|
|
1998
|
+
<h3>Which model should power them?</h3>
|
|
1999
|
+
<p class="mate-hint">You can switch this anytime from the mate's settings.</p>
|
|
2000
|
+
<div class="mate-vendor-option-list">
|
|
2001
|
+
<button class="mate-vendor-option-btn active" data-value="claude">
|
|
2002
|
+
<img src="/claude-code-avatar.png" class="mate-vendor-option-icon" alt="Claude Code">
|
|
2003
|
+
<div class="mate-vendor-option-text">
|
|
2004
|
+
<span class="mate-vendor-option-title">Claude Code</span>
|
|
2005
|
+
<span class="mate-vendor-option-desc">Anthropic's Claude. Thoughtful, conversational, strong at nuanced reasoning and long-form writing. A good default for most mates.</span>
|
|
2006
|
+
</div>
|
|
2043
2007
|
</button>
|
|
2044
|
-
<button class="mate-
|
|
2045
|
-
<
|
|
2046
|
-
<
|
|
2008
|
+
<button class="mate-vendor-option-btn" data-value="codex">
|
|
2009
|
+
<img src="/codex-avatar.png" class="mate-vendor-option-icon" alt="ChatGPT Codex">
|
|
2010
|
+
<div class="mate-vendor-option-text">
|
|
2011
|
+
<span class="mate-vendor-option-title">ChatGPT Codex</span>
|
|
2012
|
+
<span class="mate-vendor-option-desc">OpenAI's GPT coding agent. Fast and direct, strong at code generation and tight execution loops. Good for builder-type mates.</span>
|
|
2013
|
+
</div>
|
|
2047
2014
|
</button>
|
|
2048
2015
|
</div>
|
|
2049
2016
|
</div>
|
|
@@ -474,8 +474,6 @@ export function buildMateInterviewPrompt(mate) {
|
|
|
474
474
|
var styles = sd.communicationStyle.map(function (s) { return styleLabels[s] || s.replace(/_/g, " "); });
|
|
475
475
|
parts.push("Communication: " + styles.join(", "));
|
|
476
476
|
}
|
|
477
|
-
if (sd.autonomy) parts.push("Autonomy: " + sd.autonomy.replace(/_/g, " "));
|
|
478
|
-
|
|
479
477
|
return "Use the /clay-mate-interview skill to start the interview.\n\n" +
|
|
480
478
|
"Mate ID: " + mate.id + "\n" +
|
|
481
479
|
"Mate Directory: .claude/mates/" + mate.id + "\n\n" +
|
|
@@ -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;
|
|
@@ -736,6 +732,8 @@ export function processMessage(msg) {
|
|
|
736
732
|
getTools()[msg.id] = { el: null, name: msg.name, input: null, done: true, hidden: true };
|
|
737
733
|
} else if (msg.name === "propose_debate" || (msg.name && msg.name.indexOf("propose_debate") !== -1)) {
|
|
738
734
|
getTools()[msg.id] = { el: null, name: msg.name, input: null, done: true, hidden: true };
|
|
735
|
+
} else if (msg.name === "ask_user_questions") {
|
|
736
|
+
getTools()[msg.id] = { el: null, name: msg.name, input: null, done: true, hidden: true };
|
|
739
737
|
} else if (getTodoTools()[msg.name]) {
|
|
740
738
|
getTools()[msg.id] = { el: null, name: msg.name, input: null, done: true, hidden: true };
|
|
741
739
|
} else {
|
|
@@ -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";
|
|
@@ -238,25 +238,39 @@ export function renderSplitDiff(oldStr, newStr, lang) {
|
|
|
238
238
|
* Parses hunk headers for line numbers. Optional lang for syntax highlighting.
|
|
239
239
|
* Returns a DOM element.
|
|
240
240
|
*/
|
|
241
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Reconstruct old and new source text from a unified patch string.
|
|
243
|
+
* Skips file headers, "diff --git" lines, index lines, and hunk headers.
|
|
244
|
+
* Returns { oldStr, newStr }.
|
|
245
|
+
*/
|
|
246
|
+
export function reconstructPatchSources(text) {
|
|
242
247
|
var lines = text.split("\n");
|
|
243
|
-
|
|
244
|
-
// Reconstruct old and new source for highlighting
|
|
245
248
|
var oldSrc = [];
|
|
246
249
|
var newSrc = [];
|
|
247
250
|
for (var p = 0; p < lines.length; p++) {
|
|
248
251
|
var pl = lines[p];
|
|
249
|
-
if (pl.startsWith("
|
|
252
|
+
if (pl.startsWith("---") || pl.startsWith("+++")) continue;
|
|
253
|
+
if (pl.startsWith("diff ") || pl.startsWith("index ")) continue;
|
|
254
|
+
if (pl.startsWith("@@")) continue;
|
|
255
|
+
if (pl.startsWith("-")) {
|
|
250
256
|
oldSrc.push(pl.substring(1));
|
|
251
|
-
} else if (pl.startsWith("+")
|
|
257
|
+
} else if (pl.startsWith("+")) {
|
|
252
258
|
newSrc.push(pl.substring(1));
|
|
253
259
|
} else if (pl.startsWith(" ")) {
|
|
254
260
|
oldSrc.push(pl.substring(1));
|
|
255
261
|
newSrc.push(pl.substring(1));
|
|
256
262
|
}
|
|
257
263
|
}
|
|
258
|
-
|
|
259
|
-
|
|
264
|
+
return { oldStr: oldSrc.join("\n"), newStr: newSrc.join("\n") };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function renderPatchDiff(text, lang) {
|
|
268
|
+
var lines = text.split("\n");
|
|
269
|
+
|
|
270
|
+
// Reconstruct old and new source for highlighting
|
|
271
|
+
var sources = reconstructPatchSources(text);
|
|
272
|
+
var oldHL = highlightLines(sources.oldStr, lang);
|
|
273
|
+
var newHL = highlightLines(sources.newStr, lang);
|
|
260
274
|
var oldHLIdx = 0;
|
|
261
275
|
var newHLIdx = 0;
|
|
262
276
|
|
|
@@ -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) {
|
|
@@ -225,15 +225,6 @@ export function showMateSidebar(mateId, mateData) {
|
|
|
225
225
|
if (sd.communicationStyle && sd.communicationStyle.length > 0) {
|
|
226
226
|
seedTooltip.appendChild(makeSeedTags("Style", sd.communicationStyle.map(function (s) { return s.replace(/_/g, " "); })));
|
|
227
227
|
}
|
|
228
|
-
if (sd.autonomy) {
|
|
229
|
-
var autonomyLabels = {
|
|
230
|
-
always_ask: "Ask me everything",
|
|
231
|
-
minor_stuff_ok: "Small stuff is fine",
|
|
232
|
-
mostly_autonomous: "Mostly free",
|
|
233
|
-
fully_autonomous: "Full freedom",
|
|
234
|
-
};
|
|
235
|
-
seedTooltip.appendChild(makeSeedRow("Autonomy", autonomyLabels[sd.autonomy] || sd.autonomy.replace(/_/g, " ")));
|
|
236
|
-
}
|
|
237
228
|
}
|
|
238
229
|
|
|
239
230
|
// Clear session list
|
|
@@ -6,7 +6,7 @@ var mateWizardData = {
|
|
|
6
6
|
relationship: null,
|
|
7
7
|
activity: [],
|
|
8
8
|
communicationStyle: [],
|
|
9
|
-
|
|
9
|
+
vendor: "claude",
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
var _sendWs = null;
|
|
@@ -85,19 +85,19 @@ export function initMateWizard(sendWs, onMateCreated) {
|
|
|
85
85
|
})(styleCards[i]);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
// Step 4:
|
|
89
|
-
var
|
|
90
|
-
for (var i = 0; i <
|
|
88
|
+
// Step 4: Vendor button clicks
|
|
89
|
+
var vendorBtns = document.querySelectorAll("#mate-wizard .mate-vendor-option-btn");
|
|
90
|
+
for (var i = 0; i < vendorBtns.length; i++) {
|
|
91
91
|
(function (btn) {
|
|
92
92
|
btn.addEventListener("click", function () {
|
|
93
|
-
var allBtns = document.querySelectorAll("#mate-wizard .mate-
|
|
93
|
+
var allBtns = document.querySelectorAll("#mate-wizard .mate-vendor-option-btn");
|
|
94
94
|
for (var j = 0; j < allBtns.length; j++) {
|
|
95
95
|
allBtns[j].classList.remove("active");
|
|
96
96
|
}
|
|
97
97
|
btn.classList.add("active");
|
|
98
|
-
mateWizardData.
|
|
98
|
+
mateWizardData.vendor = btn.dataset.value;
|
|
99
99
|
});
|
|
100
|
-
})(
|
|
100
|
+
})(vendorBtns[i]);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -107,7 +107,7 @@ export function openMateWizard() {
|
|
|
107
107
|
relationship: null,
|
|
108
108
|
activity: [],
|
|
109
109
|
communicationStyle: [],
|
|
110
|
-
|
|
110
|
+
vendor: "claude",
|
|
111
111
|
};
|
|
112
112
|
|
|
113
113
|
// Reset UI
|
|
@@ -136,12 +136,12 @@ export function openMateWizard() {
|
|
|
136
136
|
styleCards[i].classList.remove("selected");
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
// Reset
|
|
140
|
-
var
|
|
141
|
-
for (var i = 0; i <
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
|
|
139
|
+
// Reset vendor
|
|
140
|
+
var vendorBtns = el.querySelectorAll(".mate-vendor-option-btn");
|
|
141
|
+
for (var i = 0; i < vendorBtns.length; i++) {
|
|
142
|
+
vendorBtns[i].classList.remove("active");
|
|
143
|
+
if (vendorBtns[i].dataset.value === "claude") {
|
|
144
|
+
vendorBtns[i].classList.add("active");
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -220,7 +220,7 @@ function collectMateWizardData() {
|
|
|
220
220
|
mateWizardData.communicationStyle.push(selectedStyles[i].dataset.value);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
//
|
|
223
|
+
// Vendor (already set via button clicks)
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
function mateWizardNext() {
|
|
@@ -11,7 +11,8 @@ import { getMateSessions } from './mate-sidebar.js';
|
|
|
11
11
|
import { openProjectSettings } from './project-settings.js';
|
|
12
12
|
import {
|
|
13
13
|
getCachedSessions,
|
|
14
|
-
getDateGroup
|
|
14
|
+
getDateGroup,
|
|
15
|
+
openResumePicker
|
|
15
16
|
} from './sidebar-sessions.js';
|
|
16
17
|
import {
|
|
17
18
|
getCachedProjectList,
|
|
@@ -389,12 +390,6 @@ function createMobileSessionItem(s) {
|
|
|
389
390
|
|
|
390
391
|
var titleSpan = document.createElement("span");
|
|
391
392
|
titleSpan.className = "mobile-session-title";
|
|
392
|
-
if (s.bookmarked) {
|
|
393
|
-
var bookmarkIcon = document.createElement("span");
|
|
394
|
-
bookmarkIcon.className = "mobile-session-bookmark";
|
|
395
|
-
bookmarkIcon.innerHTML = iconHtml("star");
|
|
396
|
-
titleSpan.appendChild(bookmarkIcon);
|
|
397
|
-
}
|
|
398
393
|
titleSpan.appendChild(document.createTextNode(s.title || "New Session"));
|
|
399
394
|
el.appendChild(titleSpan);
|
|
400
395
|
|
|
@@ -720,8 +715,7 @@ function renderMobileSessionsInto(container) {
|
|
|
720
715
|
importBtn.innerHTML = '<i data-lucide="import" style="width:16px;height:16px"></i> Import session';
|
|
721
716
|
importBtn.addEventListener("click", function () {
|
|
722
717
|
closeMobileSheet();
|
|
723
|
-
|
|
724
|
-
if (targetBtn) setTimeout(function () { targetBtn.click(); }, 250);
|
|
718
|
+
setTimeout(function () { openResumePicker(); }, 250);
|
|
725
719
|
});
|
|
726
720
|
container.appendChild(importBtn);
|
|
727
721
|
|
|
@@ -784,7 +778,7 @@ function renderMobileSessionsInto(container) {
|
|
|
784
778
|
if (bookmarkedItems.length > 0) {
|
|
785
779
|
var bookmarkedHeader = document.createElement("div");
|
|
786
780
|
bookmarkedHeader.className = "mobile-sheet-group";
|
|
787
|
-
bookmarkedHeader.textContent = "
|
|
781
|
+
bookmarkedHeader.textContent = "Favorites";
|
|
788
782
|
container.appendChild(bookmarkedHeader);
|
|
789
783
|
|
|
790
784
|
for (var bi = 0; bi < bookmarkedItems.length; bi++) {
|
|
@@ -798,10 +792,12 @@ function renderMobileSessionsInto(container) {
|
|
|
798
792
|
var group = getDateGroup(item.lastActivity || 0);
|
|
799
793
|
if (group !== currentGroup) {
|
|
800
794
|
currentGroup = group;
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
795
|
+
if (group !== "Today") {
|
|
796
|
+
var header = document.createElement("div");
|
|
797
|
+
header.className = "mobile-sheet-group";
|
|
798
|
+
header.textContent = group;
|
|
799
|
+
container.appendChild(header);
|
|
800
|
+
}
|
|
805
801
|
}
|
|
806
802
|
if (item.type === "loop") {
|
|
807
803
|
container.appendChild(createMobileLoopGroup(item.loopId, item.children, item.groupKey));
|
|
@@ -977,12 +973,6 @@ function renderSearchResults(container, query) {
|
|
|
977
973
|
|
|
978
974
|
var titleSpan = document.createElement("span");
|
|
979
975
|
titleSpan.className = "mobile-session-title";
|
|
980
|
-
if (s.bookmarked) {
|
|
981
|
-
var bookmarkIcon = document.createElement("span");
|
|
982
|
-
bookmarkIcon.className = "mobile-session-bookmark";
|
|
983
|
-
bookmarkIcon.innerHTML = iconHtml("star");
|
|
984
|
-
titleSpan.appendChild(bookmarkIcon);
|
|
985
|
-
}
|
|
986
976
|
titleSpan.appendChild(document.createTextNode(title));
|
|
987
977
|
el.appendChild(titleSpan);
|
|
988
978
|
|