claude-simple 0.2.12 → 0.2.14
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/package.json +2 -1
- package/public/agent-panel.js +8 -4
- package/public/chat.js +8 -2
- package/public/index.html +3 -2
- package/public/mermaid.js +48 -0
- package/public/state.js +4 -3
- package/public/style.css +7 -0
- package/public/sw.js +4 -3
- package/public/ui.min.css +1 -1
- package/public/vendor/mermaid.min.js +3636 -0
- package/src/agents/sessions.js +13 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-simple",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claude-simple": "server.js",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"jszip": "^3.10.1",
|
|
41
41
|
"mammoth": "^1.8.0",
|
|
42
42
|
"marked": "^9.1.6",
|
|
43
|
+
"mermaid": "^11.17.1",
|
|
43
44
|
"pdfjs-dist": "^3.11.174",
|
|
44
45
|
"ws": "^8.16.0",
|
|
45
46
|
"xlsx": "^0.18.5"
|
package/public/agent-panel.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { esc, $ } from './lib.js';
|
|
6
6
|
import { api, authHeaders, currentMachineId } from './api.js';
|
|
7
7
|
import { hubMode, ctx, currentAgent, currentProject } from './state.js';
|
|
8
|
+
import { renderMermaid } from './mermaid.js';
|
|
8
9
|
|
|
9
10
|
let panelOpen = false;
|
|
10
11
|
let mode = 'chat'; // chat | report | history | config
|
|
@@ -35,10 +36,13 @@ function mdHtml(text) {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
function highlight(root) {
|
|
38
|
-
if (!root
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
if (!root) return;
|
|
40
|
+
if (typeof hljs !== 'undefined') {
|
|
41
|
+
root.querySelectorAll('pre code').forEach((el) => {
|
|
42
|
+
try { hljs.highlightElement(el); } catch {}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
renderMermaid(root);
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
/** Fetch SSE with auth (+ hub machine routing). */
|
package/public/chat.js
CHANGED
|
@@ -6,6 +6,7 @@ import { ctx, isProcessing, currentProject, currentTab, currentModel, currentEff
|
|
|
6
6
|
import { sendWs, api, authHeaders, flushWsQueue, clearWsQueue } from './api.js';
|
|
7
7
|
import { initWakeLock, setWakeLockDesired } from './wake-lock.js';
|
|
8
8
|
import { pushNotification } from './notifications.js';
|
|
9
|
+
import { renderMermaid } from './mermaid.js';
|
|
9
10
|
|
|
10
11
|
function assistantLabel() {
|
|
11
12
|
return AGENT_LABELS[currentAgent.peek()] || 'Assistant';
|
|
@@ -513,7 +514,7 @@ function finalizeAssistantStream() {
|
|
|
513
514
|
liveAsstBody.classList.remove('whitespace-pre-wrap');
|
|
514
515
|
liveAsstBody.classList.add('md');
|
|
515
516
|
liveAsstBody.innerHTML = renderMarkdown(text);
|
|
516
|
-
|
|
517
|
+
enhanceMarkdown(liveAsstEl);
|
|
517
518
|
} else {
|
|
518
519
|
liveAsstEl.remove();
|
|
519
520
|
}
|
|
@@ -1005,7 +1006,7 @@ export function appendMsg(role, _label, text, opts = {}) {
|
|
|
1005
1006
|
if (!msgs) return;
|
|
1006
1007
|
const ts = coerceTs(opts.ts) ?? (role === 'system' ? null : Date.now());
|
|
1007
1008
|
msgs.insertAdjacentHTML('beforeend', bubbleHtml(role, text, ts));
|
|
1008
|
-
|
|
1009
|
+
enhanceMarkdown(msgs.lastElementChild);
|
|
1009
1010
|
stickBottom(msgs, role === 'user');
|
|
1010
1011
|
}
|
|
1011
1012
|
|
|
@@ -1523,6 +1524,11 @@ function highlightCode(root) {
|
|
|
1523
1524
|
});
|
|
1524
1525
|
}
|
|
1525
1526
|
|
|
1527
|
+
function enhanceMarkdown(root) {
|
|
1528
|
+
highlightCode(root);
|
|
1529
|
+
renderMermaid(root);
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1526
1532
|
// ── Init (called after HTML is in DOM) ────────────────────────────────────────
|
|
1527
1533
|
export function initChat() {
|
|
1528
1534
|
applyChatDensity();
|
package/public/index.html
CHANGED
|
@@ -82,7 +82,8 @@
|
|
|
82
82
|
<script src="/vendor/marked.min.js"></script>
|
|
83
83
|
<link id="hljs-theme" rel="stylesheet" href="/vendor/highlight-dark.min.css">
|
|
84
84
|
<script src="/vendor/highlight.min.js"></script>
|
|
85
|
-
<
|
|
85
|
+
<script src="/vendor/mermaid.min.js"></script>
|
|
86
|
+
<link rel="stylesheet" href="style.css?v=ui-14">
|
|
86
87
|
</head>
|
|
87
88
|
<body class="h-dvh overflow-hidden flex flex-col bg-base-100 text-base-content">
|
|
88
89
|
<div id="root" class="flex flex-col flex-1 overflow-hidden"></div>
|
|
@@ -98,6 +99,6 @@
|
|
|
98
99
|
}
|
|
99
100
|
}, 10000);
|
|
100
101
|
</script>
|
|
101
|
-
<script type="module" src="app.js?v=ui-
|
|
102
|
+
<script type="module" src="app.js?v=ui-14"></script>
|
|
102
103
|
</body>
|
|
103
104
|
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Local Mermaid integration. It is loaded from /vendor in index.html so Hub
|
|
2
|
+
// diagrams keep working when public CDNs are unavailable.
|
|
3
|
+
let initialized = false;
|
|
4
|
+
let sequence = 0;
|
|
5
|
+
|
|
6
|
+
function setup() {
|
|
7
|
+
const api = globalThis.mermaid;
|
|
8
|
+
if (!api || initialized) return api;
|
|
9
|
+
api.initialize({
|
|
10
|
+
startOnLoad: false,
|
|
11
|
+
securityLevel: 'strict',
|
|
12
|
+
theme: document.documentElement.dataset.theme === 'dark' ? 'dark' : 'default',
|
|
13
|
+
flowchart: { htmlLabels: false },
|
|
14
|
+
});
|
|
15
|
+
initialized = true;
|
|
16
|
+
return api;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Render fenced ```mermaid blocks below a freshly-rendered Markdown root. */
|
|
20
|
+
export function renderMermaid(root) {
|
|
21
|
+
const api = setup();
|
|
22
|
+
if (!api || !root) return;
|
|
23
|
+
root.querySelectorAll('pre code.language-mermaid, pre code.lang-mermaid').forEach(code => {
|
|
24
|
+
if (code.dataset.mermaidHandled) return;
|
|
25
|
+
const pre = code.closest('pre');
|
|
26
|
+
const source = code.textContent?.trim();
|
|
27
|
+
if (!pre || !source) return;
|
|
28
|
+
code.dataset.mermaidHandled = '1';
|
|
29
|
+
|
|
30
|
+
const host = document.createElement('div');
|
|
31
|
+
host.className = 'mermaid-diagram';
|
|
32
|
+
host.setAttribute('role', 'img');
|
|
33
|
+
host.setAttribute('aria-label', 'Mermaid diagram');
|
|
34
|
+
pre.replaceWith(host);
|
|
35
|
+
const id = `mermaid-diagram-${++sequence}`;
|
|
36
|
+
|
|
37
|
+
Promise.resolve(api.render(id, source)).then(({ svg, bindFunctions }) => {
|
|
38
|
+
host.innerHTML = svg;
|
|
39
|
+
bindFunctions?.(host);
|
|
40
|
+
}).catch(error => {
|
|
41
|
+
// Syntax errors remain inspectable/copyable as the original code block.
|
|
42
|
+
host.replaceWith(pre);
|
|
43
|
+
delete code.dataset.mermaidHandled;
|
|
44
|
+
pre.classList.add('mermaid-error');
|
|
45
|
+
pre.title = `Mermaid render failed: ${error?.message || 'invalid diagram'}`;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
package/public/state.js
CHANGED
|
@@ -384,7 +384,6 @@ function asSessionArray(v) {
|
|
|
384
384
|
|
|
385
385
|
/** Sessions after local filters (agent / time / workspace / text / favorites). */
|
|
386
386
|
export const filteredSessions = computed(() => {
|
|
387
|
-
const filter = sessionFilter.value;
|
|
388
387
|
const search = sessionSearch.value.toLowerCase().trim();
|
|
389
388
|
const sort = sessionSort.value;
|
|
390
389
|
const aFilter = agentFilter.value;
|
|
@@ -398,7 +397,9 @@ export const filteredSessions = computed(() => {
|
|
|
398
397
|
? asSessionArray(hits.results)
|
|
399
398
|
: asSessionArray(sessionsData.value);
|
|
400
399
|
|
|
401
|
-
|
|
400
|
+
// `sessionFilter` is the active Files/Git workspace path. It must not
|
|
401
|
+
// constrain the sidebar: otherwise opening a session (or a session without
|
|
402
|
+
// a recorded cwd) makes every project folder disappear from the project UI.
|
|
402
403
|
// Hub: only show sessions on the currently selected machine
|
|
403
404
|
const mid = selectedMachineId.value;
|
|
404
405
|
if (hubMode.value && mid) {
|
|
@@ -431,7 +432,7 @@ export const filteredSessions = computed(() => {
|
|
|
431
432
|
});
|
|
432
433
|
|
|
433
434
|
// Cap timeline dump when no filter/search
|
|
434
|
-
if (!
|
|
435
|
+
if (!search && !favOnly) return list.slice(0, 120);
|
|
435
436
|
return list;
|
|
436
437
|
});
|
|
437
438
|
|
package/public/style.css
CHANGED
|
@@ -1153,6 +1153,13 @@ html.pwa-standalone .ma-panel {
|
|
|
1153
1153
|
flex: 0 0 auto;
|
|
1154
1154
|
}
|
|
1155
1155
|
.topbar-icon-label { display: inline; }
|
|
1156
|
+
.mermaid-diagram {
|
|
1157
|
+
overflow-x: auto;
|
|
1158
|
+
padding: .75rem .25rem .25rem;
|
|
1159
|
+
text-align: center;
|
|
1160
|
+
}
|
|
1161
|
+
.mermaid-diagram svg { max-width: 100%; height: auto; }
|
|
1162
|
+
.mermaid-error { border-color: color-mix(in oklch, var(--color-error) 55%, var(--color-base-300)); }
|
|
1156
1163
|
@media (max-width: 640px) {
|
|
1157
1164
|
#recent-menu {
|
|
1158
1165
|
min-width: 0;
|
package/public/sw.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/* Agent UI service worker — cache shell assets only.
|
|
2
2
|
* Never intercepts WebSocket or mutates API semantics beyond offline fallback.
|
|
3
3
|
* Bump CACHE when shipping UI that must invalidate old shells. */
|
|
4
|
-
const CACHE = 'agent-ui-shell-
|
|
4
|
+
const CACHE = 'agent-ui-shell-v19';
|
|
5
5
|
const PRECACHE = [
|
|
6
6
|
'/',
|
|
7
7
|
'/index.html',
|
|
8
8
|
'/manifest.webmanifest',
|
|
9
|
-
'/style.css?v=ui-
|
|
9
|
+
'/style.css?v=ui-14',
|
|
10
10
|
'/style.css',
|
|
11
11
|
'/ui.min.css',
|
|
12
12
|
'/vendor/mini-react.min.js',
|
|
13
13
|
'/vendor/marked.min.js',
|
|
14
14
|
'/vendor/highlight.min.js',
|
|
15
15
|
'/vendor/highlight-dark.min.css',
|
|
16
|
-
'/
|
|
16
|
+
'/vendor/mermaid.min.js',
|
|
17
|
+
'/app.js?v=ui-14',
|
|
17
18
|
'/icons/icon-192.png',
|
|
18
19
|
'/icons/icon-512.png',
|
|
19
20
|
'/icons/icon-maskable-512.png',
|