clay-server 2.12.0 → 2.13.0-beta.1
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/daemon.js +14 -0
- package/lib/dm.js +3 -3
- package/lib/mates.js +222 -0
- package/lib/project.js +83 -2
- package/lib/public/app.js +273 -10
- package/lib/public/css/base.css +1 -0
- package/lib/public/css/mates.css +1018 -0
- package/lib/public/index.html +238 -0
- package/lib/public/modules/mate-knowledge.js +222 -0
- package/lib/public/modules/mate-sidebar.js +329 -0
- package/lib/public/modules/mate-wizard.js +265 -0
- package/lib/public/modules/profile.js +207 -0
- package/lib/public/modules/sidebar.js +143 -3
- package/lib/public/style.css +1 -0
- package/lib/sdk-bridge.js +4 -0
- package/lib/server.js +110 -3
- package/lib/sessions.js +27 -0
- package/package.json +1 -1
package/lib/public/index.html
CHANGED
|
@@ -192,7 +192,43 @@
|
|
|
192
192
|
</div>
|
|
193
193
|
<div id="sidebar-resize-handle"></div>
|
|
194
194
|
<div id="sidebar-overlay"></div>
|
|
195
|
+
|
|
196
|
+
<!-- Mate sidebar (separate from project sidebar, shown during mate DM) -->
|
|
197
|
+
<div id="mate-sidebar-column" class="hidden">
|
|
198
|
+
<div class="mate-sidebar-header" id="mate-sidebar-header">
|
|
199
|
+
<img id="mate-sidebar-avatar" class="mate-sidebar-avatar" alt="">
|
|
200
|
+
<span id="mate-sidebar-name" class="mate-sidebar-name"></span>
|
|
201
|
+
<i data-lucide="chevron-down" class="mate-sidebar-chevron"></i>
|
|
202
|
+
</div>
|
|
203
|
+
<div id="mate-sidebar-seed" class="mate-sidebar-seed hidden"></div>
|
|
204
|
+
<div id="mate-sidebar-tools">
|
|
205
|
+
<button id="mate-knowledge-btn"><i data-lucide="book-open"></i> <span>Knowledge</span><span id="mate-knowledge-count" class="sidebar-badge hidden"></span></button>
|
|
206
|
+
<button id="mate-sticky-notes-btn"><i data-lucide="sticky-note"></i> <span>Sticky Notes</span></button>
|
|
207
|
+
<button id="mate-skills-btn"><i data-lucide="puzzle"></i> <span>Skills</span></button>
|
|
208
|
+
</div>
|
|
209
|
+
<div class="mate-sidebar-sessions-header">
|
|
210
|
+
<span>Conversations</span>
|
|
211
|
+
<div class="mate-sidebar-actions">
|
|
212
|
+
<button id="mate-new-session-btn" type="button" title="New session"><i data-lucide="plus"></i></button>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div id="mate-session-list" class="mate-session-list"></div>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
195
218
|
<div id="main-column">
|
|
219
|
+
<div id="mate-knowledge-container" class="hidden">
|
|
220
|
+
<div class="mate-knowledge-header">
|
|
221
|
+
<div class="mate-knowledge-title-wrap">
|
|
222
|
+
<i data-lucide="book-open"></i>
|
|
223
|
+
<h2>Knowledge</h2>
|
|
224
|
+
<span id="mate-knowledge-header-count" class="mate-knowledge-count"></span>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="mate-knowledge-header-actions">
|
|
227
|
+
<button id="mate-knowledge-close-btn" title="Close"><i data-lucide="x"></i></button>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
<div id="mate-knowledge-grid" class="mate-knowledge-grid"></div>
|
|
231
|
+
</div>
|
|
196
232
|
<div class="dm-header-bar" id="dm-header-bar">
|
|
197
233
|
<img id="dm-header-avatar" class="dm-header-avatar" alt="">
|
|
198
234
|
<span id="dm-header-name" class="dm-header-name"></span>
|
|
@@ -1244,6 +1280,208 @@
|
|
|
1244
1280
|
</div>
|
|
1245
1281
|
</div>
|
|
1246
1282
|
|
|
1283
|
+
<!-- Mate Wizard -->
|
|
1284
|
+
<div id="mate-wizard" class="hidden">
|
|
1285
|
+
<div class="mate-wizard-backdrop"></div>
|
|
1286
|
+
<div class="mate-wizard-card">
|
|
1287
|
+
<div class="mate-wizard-header">
|
|
1288
|
+
<span>Create a Mate</span>
|
|
1289
|
+
<button id="mate-wizard-close">×</button>
|
|
1290
|
+
</div>
|
|
1291
|
+
<div class="mate-wizard-progress">
|
|
1292
|
+
<span class="mate-dot active" data-step="1"></span>
|
|
1293
|
+
<span class="mate-dot" data-step="2"></span>
|
|
1294
|
+
<span class="mate-dot" data-step="3"></span>
|
|
1295
|
+
<span class="mate-dot" data-step="4"></span>
|
|
1296
|
+
</div>
|
|
1297
|
+
<div class="mate-wizard-steps">
|
|
1298
|
+
<!-- Step 1: Relationship -->
|
|
1299
|
+
<div class="mate-step active" data-step="1">
|
|
1300
|
+
<h3>What kind of relationship?</h3>
|
|
1301
|
+
<p class="mate-hint">Pick the role that best fits what you need. You can refine this later in the interview.</p>
|
|
1302
|
+
<div class="mate-card-grid">
|
|
1303
|
+
<button class="mate-card" data-value="colleague">
|
|
1304
|
+
<span class="mate-card-emoji">🤝</span>
|
|
1305
|
+
<span class="mate-card-label">Colleague</span>
|
|
1306
|
+
<span class="mate-card-desc">Works alongside you as an equal</span>
|
|
1307
|
+
</button>
|
|
1308
|
+
<button class="mate-card" data-value="friend">
|
|
1309
|
+
<span class="mate-card-emoji">😊</span>
|
|
1310
|
+
<span class="mate-card-label">Friend</span>
|
|
1311
|
+
<span class="mate-card-desc">Casual, honest, easy to talk to</span>
|
|
1312
|
+
</button>
|
|
1313
|
+
<button class="mate-card" data-value="mentor">
|
|
1314
|
+
<span class="mate-card-emoji">🧭</span>
|
|
1315
|
+
<span class="mate-card-label">Mentor</span>
|
|
1316
|
+
<span class="mate-card-desc">Guides your long-term growth</span>
|
|
1317
|
+
</button>
|
|
1318
|
+
<button class="mate-card" data-value="coach">
|
|
1319
|
+
<span class="mate-card-emoji">🎯</span>
|
|
1320
|
+
<span class="mate-card-label">Coach</span>
|
|
1321
|
+
<span class="mate-card-desc">Pushes you toward your goals</span>
|
|
1322
|
+
</button>
|
|
1323
|
+
<button class="mate-card" data-value="teacher">
|
|
1324
|
+
<span class="mate-card-emoji">🎓</span>
|
|
1325
|
+
<span class="mate-card-label">Teacher</span>
|
|
1326
|
+
<span class="mate-card-desc">Explains, teaches, breaks things down</span>
|
|
1327
|
+
</button>
|
|
1328
|
+
<button class="mate-card" data-value="assistant">
|
|
1329
|
+
<span class="mate-card-emoji">📋</span>
|
|
1330
|
+
<span class="mate-card-label">Assistant</span>
|
|
1331
|
+
<span class="mate-card-desc">Handles tasks you hand off</span>
|
|
1332
|
+
</button>
|
|
1333
|
+
<button class="mate-card" data-value="reviewer">
|
|
1334
|
+
<span class="mate-card-emoji">🔍</span>
|
|
1335
|
+
<span class="mate-card-label">Reviewer</span>
|
|
1336
|
+
<span class="mate-card-desc">Checks your work, catches mistakes</span>
|
|
1337
|
+
</button>
|
|
1338
|
+
<button class="mate-card" data-value="companion">
|
|
1339
|
+
<span class="mate-card-emoji">☕</span>
|
|
1340
|
+
<span class="mate-card-label">Companion</span>
|
|
1341
|
+
<span class="mate-card-desc">Just someone to hang out with</span>
|
|
1342
|
+
</button>
|
|
1343
|
+
<button class="mate-card" data-value="supervisor">
|
|
1344
|
+
<span class="mate-card-emoji">💼</span>
|
|
1345
|
+
<span class="mate-card-label">Supervisor</span>
|
|
1346
|
+
<span class="mate-card-desc">Keeps you in check, sets standards</span>
|
|
1347
|
+
</button>
|
|
1348
|
+
<button class="mate-card" data-value="critic">
|
|
1349
|
+
<span class="mate-card-emoji">🥊</span>
|
|
1350
|
+
<span class="mate-card-label">Critic</span>
|
|
1351
|
+
<span class="mate-card-desc">Challenges your ideas, debates back</span>
|
|
1352
|
+
</button>
|
|
1353
|
+
<button class="mate-card" data-value="rubber_duck">
|
|
1354
|
+
<span class="mate-card-emoji">🦆</span>
|
|
1355
|
+
<span class="mate-card-label">Rubber Duck</span>
|
|
1356
|
+
<span class="mate-card-desc">Listens while you think out loud</span>
|
|
1357
|
+
</button>
|
|
1358
|
+
<button class="mate-card" data-value="custom">
|
|
1359
|
+
<span class="mate-card-emoji">✏️</span>
|
|
1360
|
+
<span class="mate-card-label">Custom</span>
|
|
1361
|
+
<span class="mate-card-desc">Define your own role</span>
|
|
1362
|
+
</button>
|
|
1363
|
+
</div>
|
|
1364
|
+
<input type="text" id="mate-relationship-custom" class="mate-custom-input hidden" placeholder="Describe the relationship..." maxlength="60">
|
|
1365
|
+
</div>
|
|
1366
|
+
|
|
1367
|
+
<!-- Step 2: Activity -->
|
|
1368
|
+
<div class="mate-step" data-step="2">
|
|
1369
|
+
<h3>What will you do together?</h3>
|
|
1370
|
+
<p class="mate-hint">Select one or more activities. These help shape the interview.</p>
|
|
1371
|
+
<div class="mate-tag-grid">
|
|
1372
|
+
<button class="mate-tag" data-value="coding">💻 Coding</button>
|
|
1373
|
+
<button class="mate-tag" data-value="writing">✍️ Writing</button>
|
|
1374
|
+
<button class="mate-tag" data-value="studying">📚 Studying</button>
|
|
1375
|
+
<button class="mate-tag" data-value="planning">📋 Planning</button>
|
|
1376
|
+
<button class="mate-tag" data-value="brainstorming">💡 Brainstorming</button>
|
|
1377
|
+
<button class="mate-tag" data-value="organizing">🗂️ Organizing</button>
|
|
1378
|
+
<button class="mate-tag" data-value="chatting">💬 Chatting</button>
|
|
1379
|
+
<button class="mate-tag" data-value="designing">🎨 Designing</button>
|
|
1380
|
+
<button class="mate-tag" data-value="reviewing">🔍 Reviewing</button>
|
|
1381
|
+
<button class="mate-tag" data-value="researching">🧪 Researching</button>
|
|
1382
|
+
<button class="mate-tag" data-value="debugging">🐛 Debugging</button>
|
|
1383
|
+
<button class="mate-tag" data-value="journaling">📓 Journaling</button>
|
|
1384
|
+
<button class="mate-tag" data-value="data_analysis">📊 Data Analysis</button>
|
|
1385
|
+
<button class="mate-tag" data-value="finances">💰 Finances</button>
|
|
1386
|
+
<button class="mate-tag" data-value="career">📈 Career</button>
|
|
1387
|
+
<button class="mate-tag" data-value="health">🏥 Health</button>
|
|
1388
|
+
<button class="mate-tag" data-value="fitness">🏋️ Fitness</button>
|
|
1389
|
+
<button class="mate-tag" data-value="cooking">🍳 Cooking</button>
|
|
1390
|
+
<button class="mate-tag" data-value="language">🗣️ Language</button>
|
|
1391
|
+
<button class="mate-tag" data-value="parenting">👶 Parenting</button>
|
|
1392
|
+
<button class="mate-tag" data-value="music">🎵 Music</button>
|
|
1393
|
+
<button class="mate-tag" data-value="gaming">🎮 Gaming</button>
|
|
1394
|
+
<button class="mate-tag" data-value="reading">📖 Reading</button>
|
|
1395
|
+
<button class="mate-tag" data-value="marketing">📣 Marketing</button>
|
|
1396
|
+
<button class="mate-tag" data-value="teaching">🧑‍🏫 Teaching</button>
|
|
1397
|
+
<button class="mate-tag" data-value="travel">✈️ Travel</button>
|
|
1398
|
+
<button class="mate-tag" data-value="shopping">🛍️ Shopping</button>
|
|
1399
|
+
<button class="mate-tag" data-value="diy">🔨 DIY</button>
|
|
1400
|
+
</div>
|
|
1401
|
+
<input type="text" id="mate-activity-custom" class="mate-custom-input" placeholder="Add a custom activity..." maxlength="40">
|
|
1402
|
+
</div>
|
|
1403
|
+
|
|
1404
|
+
<!-- Step 3: Communication Style -->
|
|
1405
|
+
<div class="mate-step" data-step="3">
|
|
1406
|
+
<h3>How should they communicate?</h3>
|
|
1407
|
+
<p class="mate-hint">Pick the style that feels right. You can combine multiple.</p>
|
|
1408
|
+
<div class="mate-style-grid">
|
|
1409
|
+
<button class="mate-style-card" data-value="direct_concise">
|
|
1410
|
+
<span class="mate-style-label">Direct + Concise</span>
|
|
1411
|
+
<span class="mate-style-example">"No. Do it this way."</span>
|
|
1412
|
+
</button>
|
|
1413
|
+
<button class="mate-style-card" data-value="soft_detailed">
|
|
1414
|
+
<span class="mate-style-label">Soft + Detailed</span>
|
|
1415
|
+
<span class="mate-style-example">"Here's another approach you might like, and here's why..."</span>
|
|
1416
|
+
</button>
|
|
1417
|
+
<button class="mate-style-card" data-value="witty">
|
|
1418
|
+
<span class="mate-style-label">Witty</span>
|
|
1419
|
+
<span class="mate-style-example">"That's... creative. Let me show you what actually works."</span>
|
|
1420
|
+
</button>
|
|
1421
|
+
<button class="mate-style-card" data-value="encouraging">
|
|
1422
|
+
<span class="mate-style-label">Encouraging</span>
|
|
1423
|
+
<span class="mate-style-example">"You're on the right track! Let's push a bit further."</span>
|
|
1424
|
+
</button>
|
|
1425
|
+
<button class="mate-style-card" data-value="formal">
|
|
1426
|
+
<span class="mate-style-label">Formal</span>
|
|
1427
|
+
<span class="mate-style-example">"I would recommend the following adjustments."</span>
|
|
1428
|
+
</button>
|
|
1429
|
+
<button class="mate-style-card" data-value="no_nonsense">
|
|
1430
|
+
<span class="mate-style-label">No-nonsense</span>
|
|
1431
|
+
<span class="mate-style-example">"Three problems. Here are the fixes."</span>
|
|
1432
|
+
</button>
|
|
1433
|
+
</div>
|
|
1434
|
+
</div>
|
|
1435
|
+
|
|
1436
|
+
<!-- Step 4: Autonomy -->
|
|
1437
|
+
<div class="mate-step" data-step="4">
|
|
1438
|
+
<h3>How much should they do on their own?</h3>
|
|
1439
|
+
<p class="mate-hint">This is about how much freedom your mate gets before checking with you.</p>
|
|
1440
|
+
<div class="mate-autonomy-options">
|
|
1441
|
+
<button class="mate-autonomy-btn" data-value="always_ask">
|
|
1442
|
+
<span class="mate-autonomy-title">Ask me everything</span>
|
|
1443
|
+
<span class="mate-autonomy-desc">"Before you do anything, run it by me first."</span>
|
|
1444
|
+
</button>
|
|
1445
|
+
<button class="mate-autonomy-btn active" data-value="minor_stuff_ok">
|
|
1446
|
+
<span class="mate-autonomy-title">Small stuff is fine</span>
|
|
1447
|
+
<span class="mate-autonomy-desc">"Little things, just do it. Anything big, ask me."</span>
|
|
1448
|
+
</button>
|
|
1449
|
+
<button class="mate-autonomy-btn" data-value="mostly_autonomous">
|
|
1450
|
+
<span class="mate-autonomy-title">Mostly free</span>
|
|
1451
|
+
<span class="mate-autonomy-desc">"Do your thing. Only check if it's really important."</span>
|
|
1452
|
+
</button>
|
|
1453
|
+
<button class="mate-autonomy-btn" data-value="fully_autonomous">
|
|
1454
|
+
<span class="mate-autonomy-title">Full freedom</span>
|
|
1455
|
+
<span class="mate-autonomy-desc">"Just get it done and tell me after."</span>
|
|
1456
|
+
</button>
|
|
1457
|
+
</div>
|
|
1458
|
+
</div>
|
|
1459
|
+
</div>
|
|
1460
|
+
<div class="mate-wizard-footer">
|
|
1461
|
+
<button id="mate-wizard-back" class="mate-btn secondary">Back</button>
|
|
1462
|
+
<div>
|
|
1463
|
+
<button id="mate-wizard-next" class="mate-btn primary">Next</button>
|
|
1464
|
+
</div>
|
|
1465
|
+
</div>
|
|
1466
|
+
</div>
|
|
1467
|
+
</div>
|
|
1468
|
+
|
|
1469
|
+
<!-- Knowledge Editor Modal -->
|
|
1470
|
+
<div id="mate-knowledge-editor" class="hidden">
|
|
1471
|
+
<div class="mate-knowledge-editor-backdrop"></div>
|
|
1472
|
+
<div class="mate-knowledge-editor-card">
|
|
1473
|
+
<div class="mate-knowledge-editor-header">
|
|
1474
|
+
<input type="text" id="mate-knowledge-editor-name" placeholder="File name..." maxlength="80" spellcheck="false">
|
|
1475
|
+
<button id="mate-knowledge-editor-close">×</button>
|
|
1476
|
+
</div>
|
|
1477
|
+
<textarea id="mate-knowledge-editor-content" placeholder="Write anything your mate should know..."></textarea>
|
|
1478
|
+
<div class="mate-knowledge-editor-footer">
|
|
1479
|
+
<button id="mate-knowledge-editor-delete" class="mate-btn secondary" style="margin-right:auto">Delete</button>
|
|
1480
|
+
<button id="mate-knowledge-editor-save" class="mate-btn primary">Save</button>
|
|
1481
|
+
</div>
|
|
1482
|
+
</div>
|
|
1483
|
+
</div>
|
|
1484
|
+
|
|
1247
1485
|
<!-- Scheduler panel is dynamically created in #app by scheduler.js -->
|
|
1248
1486
|
|
|
1249
1487
|
<!-- Schedule Edit Modal -->
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { iconHtml, refreshIcons } from './icons.js';
|
|
2
|
+
import { hideNotes } from './sticky-notes.js';
|
|
3
|
+
|
|
4
|
+
var getMateWs = null;
|
|
5
|
+
var containerEl = null;
|
|
6
|
+
var gridEl = null;
|
|
7
|
+
var closeBtn = null;
|
|
8
|
+
var sidebarBtn = null;
|
|
9
|
+
var countBadge = null;
|
|
10
|
+
var visible = false;
|
|
11
|
+
var cachedFiles = [];
|
|
12
|
+
|
|
13
|
+
// Editor elements
|
|
14
|
+
var editorEl = null;
|
|
15
|
+
var editorNameEl = null;
|
|
16
|
+
var editorContentEl = null;
|
|
17
|
+
var editorSaveBtn = null;
|
|
18
|
+
var editorDeleteBtn = null;
|
|
19
|
+
var editorCloseBtn = null;
|
|
20
|
+
var editorBackdrop = null;
|
|
21
|
+
var editingFile = null;
|
|
22
|
+
|
|
23
|
+
export function initMateKnowledge(mateWsGetter) {
|
|
24
|
+
getMateWs = mateWsGetter;
|
|
25
|
+
containerEl = document.getElementById("mate-knowledge-container");
|
|
26
|
+
gridEl = document.getElementById("mate-knowledge-grid");
|
|
27
|
+
closeBtn = document.getElementById("mate-knowledge-close-btn");
|
|
28
|
+
sidebarBtn = document.getElementById("mate-knowledge-btn");
|
|
29
|
+
countBadge = document.getElementById("mate-knowledge-count");
|
|
30
|
+
|
|
31
|
+
editorEl = document.getElementById("mate-knowledge-editor");
|
|
32
|
+
editorNameEl = document.getElementById("mate-knowledge-editor-name");
|
|
33
|
+
editorContentEl = document.getElementById("mate-knowledge-editor-content");
|
|
34
|
+
editorSaveBtn = document.getElementById("mate-knowledge-editor-save");
|
|
35
|
+
editorDeleteBtn = document.getElementById("mate-knowledge-editor-delete");
|
|
36
|
+
editorCloseBtn = document.getElementById("mate-knowledge-editor-close");
|
|
37
|
+
editorBackdrop = editorEl ? editorEl.querySelector(".mate-knowledge-editor-backdrop") : null;
|
|
38
|
+
|
|
39
|
+
if (sidebarBtn) {
|
|
40
|
+
sidebarBtn.addEventListener("click", function () {
|
|
41
|
+
if (visible) {
|
|
42
|
+
hideKnowledge();
|
|
43
|
+
} else {
|
|
44
|
+
showKnowledge();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (closeBtn) {
|
|
50
|
+
closeBtn.addEventListener("click", hideKnowledge);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (editorSaveBtn) {
|
|
54
|
+
editorSaveBtn.addEventListener("click", saveKnowledge);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (editorDeleteBtn) {
|
|
58
|
+
editorDeleteBtn.addEventListener("click", function () {
|
|
59
|
+
if (editingFile) {
|
|
60
|
+
var ws = getMateWs ? getMateWs() : null;
|
|
61
|
+
if (ws && ws.readyState === 1) {
|
|
62
|
+
ws.send(JSON.stringify({ type: "knowledge_delete", name: editingFile }));
|
|
63
|
+
}
|
|
64
|
+
closeEditor();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (editorCloseBtn) {
|
|
70
|
+
editorCloseBtn.addEventListener("click", closeEditor);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (editorBackdrop) {
|
|
74
|
+
editorBackdrop.addEventListener("click", closeEditor);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Stop keyboard events from leaking
|
|
78
|
+
var stopProp = function (e) { e.stopPropagation(); };
|
|
79
|
+
if (editorNameEl) {
|
|
80
|
+
editorNameEl.addEventListener("keydown", stopProp);
|
|
81
|
+
editorNameEl.addEventListener("keyup", stopProp);
|
|
82
|
+
editorNameEl.addEventListener("keypress", stopProp);
|
|
83
|
+
}
|
|
84
|
+
if (editorContentEl) {
|
|
85
|
+
editorContentEl.addEventListener("keydown", stopProp);
|
|
86
|
+
editorContentEl.addEventListener("keyup", stopProp);
|
|
87
|
+
editorContentEl.addEventListener("keypress", stopProp);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function showKnowledge() {
|
|
92
|
+
visible = true;
|
|
93
|
+
hideNotes();
|
|
94
|
+
if (containerEl) containerEl.classList.remove("hidden");
|
|
95
|
+
if (sidebarBtn) sidebarBtn.classList.add("active");
|
|
96
|
+
requestKnowledgeList();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function hideKnowledge() {
|
|
100
|
+
visible = false;
|
|
101
|
+
if (containerEl) containerEl.classList.add("hidden");
|
|
102
|
+
if (sidebarBtn) sidebarBtn.classList.remove("active");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isKnowledgeVisible() {
|
|
106
|
+
return visible;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function requestKnowledgeList() {
|
|
110
|
+
var ws = getMateWs ? getMateWs() : null;
|
|
111
|
+
if (ws && ws.readyState === 1) {
|
|
112
|
+
ws.send(JSON.stringify({ type: "knowledge_list" }));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function renderKnowledgeList(files) {
|
|
117
|
+
cachedFiles = files || [];
|
|
118
|
+
|
|
119
|
+
// Update badges
|
|
120
|
+
if (countBadge) {
|
|
121
|
+
if (cachedFiles.length > 0) {
|
|
122
|
+
countBadge.textContent = String(cachedFiles.length);
|
|
123
|
+
countBadge.classList.remove("hidden");
|
|
124
|
+
} else {
|
|
125
|
+
countBadge.classList.add("hidden");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
var headerCount = document.getElementById("mate-knowledge-header-count");
|
|
129
|
+
if (headerCount) {
|
|
130
|
+
headerCount.textContent = cachedFiles.length > 0 ? cachedFiles.length + " files" : "";
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!gridEl) return;
|
|
134
|
+
gridEl.innerHTML = "";
|
|
135
|
+
|
|
136
|
+
// Add tile (always first)
|
|
137
|
+
var addTile = document.createElement("div");
|
|
138
|
+
addTile.className = "mate-knowledge-tile mate-knowledge-tile-add";
|
|
139
|
+
addTile.innerHTML = '<span class="mate-knowledge-add-icon">' + iconHtml("plus") + '</span><span class="mate-knowledge-add-label">Add Knowledge</span>';
|
|
140
|
+
addTile.addEventListener("click", function () { openEditor(null); });
|
|
141
|
+
gridEl.appendChild(addTile);
|
|
142
|
+
|
|
143
|
+
for (var i = 0; i < cachedFiles.length; i++) {
|
|
144
|
+
gridEl.appendChild(renderTile(cachedFiles[i]));
|
|
145
|
+
}
|
|
146
|
+
refreshIcons();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function renderTile(file) {
|
|
150
|
+
var tile = document.createElement("div");
|
|
151
|
+
tile.className = "mate-knowledge-tile";
|
|
152
|
+
|
|
153
|
+
var title = document.createElement("div");
|
|
154
|
+
title.className = "mate-knowledge-tile-title";
|
|
155
|
+
title.textContent = file.name.replace(/\.md$/, "");
|
|
156
|
+
tile.appendChild(title);
|
|
157
|
+
|
|
158
|
+
var preview = document.createElement("div");
|
|
159
|
+
preview.className = "mate-knowledge-tile-preview";
|
|
160
|
+
// Preview will be populated if we have content cached; for now show size
|
|
161
|
+
var sizeKb = file.size > 1024 ? (file.size / 1024).toFixed(1) + " KB" : file.size + " bytes";
|
|
162
|
+
preview.textContent = sizeKb;
|
|
163
|
+
tile.appendChild(preview);
|
|
164
|
+
|
|
165
|
+
tile.addEventListener("click", (function (name) {
|
|
166
|
+
return function () {
|
|
167
|
+
var ws = getMateWs ? getMateWs() : null;
|
|
168
|
+
if (ws && ws.readyState === 1) {
|
|
169
|
+
ws.send(JSON.stringify({ type: "knowledge_read", name: name }));
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
})(file.name));
|
|
173
|
+
|
|
174
|
+
return tile;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function handleKnowledgeContent(msg) {
|
|
178
|
+
openEditor(msg.name, msg.content || "");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function openEditor(fileName, content) {
|
|
182
|
+
if (!editorEl) return;
|
|
183
|
+
editingFile = fileName || null;
|
|
184
|
+
if (editorNameEl) {
|
|
185
|
+
editorNameEl.value = fileName ? fileName.replace(/\.md$/, "") : "";
|
|
186
|
+
editorNameEl.readOnly = !!fileName;
|
|
187
|
+
}
|
|
188
|
+
if (editorContentEl) {
|
|
189
|
+
editorContentEl.value = content || "";
|
|
190
|
+
}
|
|
191
|
+
if (editorDeleteBtn) {
|
|
192
|
+
editorDeleteBtn.style.display = fileName ? "" : "none";
|
|
193
|
+
}
|
|
194
|
+
editorEl.classList.remove("hidden");
|
|
195
|
+
if (!fileName && editorNameEl) {
|
|
196
|
+
editorNameEl.focus();
|
|
197
|
+
} else if (editorContentEl) {
|
|
198
|
+
editorContentEl.focus();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function closeEditor() {
|
|
203
|
+
if (editorEl) editorEl.classList.add("hidden");
|
|
204
|
+
editingFile = null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function saveKnowledge() {
|
|
208
|
+
if (!editorNameEl || !editorContentEl) return;
|
|
209
|
+
var name = editorNameEl.value.trim();
|
|
210
|
+
var content = editorContentEl.value;
|
|
211
|
+
if (!name) {
|
|
212
|
+
editorNameEl.style.outline = "2px solid var(--error, #ff5555)";
|
|
213
|
+
setTimeout(function () { editorNameEl.style.outline = ""; }, 1500);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (!name.endsWith(".md")) name += ".md";
|
|
217
|
+
var ws = getMateWs ? getMateWs() : null;
|
|
218
|
+
if (ws && ws.readyState === 1) {
|
|
219
|
+
ws.send(JSON.stringify({ type: "knowledge_save", name: name, content: content }));
|
|
220
|
+
}
|
|
221
|
+
closeEditor();
|
|
222
|
+
}
|