claude-simple 0.2.13 → 0.2.15
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 +64 -0
- 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 +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-simple",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
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-15">
|
|
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-15"></script>
|
|
102
103
|
</body>
|
|
103
104
|
</html>
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
function normalizeSource(raw) {
|
|
20
|
+
let source = String(raw || '').replace(/\r\n?/g, '\n').trim();
|
|
21
|
+
// Some agents include the Markdown fence or language name inside an already
|
|
22
|
+
// fenced Mermaid block. Mermaid treats both as grammar tokens and renders
|
|
23
|
+
// its own error SVG, so remove that transport wrapper defensively.
|
|
24
|
+
source = source.replace(/^```(?:mermaid)?\s*/i, '').replace(/\s*```$/, '').trim();
|
|
25
|
+
source = source.replace(/^mermaid\s*\n/i, '');
|
|
26
|
+
// `graph` remains an alias, but normalising it avoids version-specific
|
|
27
|
+
// parser behaviour in Mermaid 11 and keeps generated diagrams consistent.
|
|
28
|
+
source = source.replace(/^graph\s+(TD|TB|BT|RL|LR)\b/i, 'flowchart $1');
|
|
29
|
+
return source;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Render fenced ```mermaid blocks below a freshly-rendered Markdown root. */
|
|
33
|
+
export function renderMermaid(root) {
|
|
34
|
+
const api = setup();
|
|
35
|
+
if (!api || !root) return;
|
|
36
|
+
root.querySelectorAll('pre code.language-mermaid, pre code.lang-mermaid').forEach(code => {
|
|
37
|
+
if (code.dataset.mermaidHandled) return;
|
|
38
|
+
const pre = code.closest('pre');
|
|
39
|
+
const source = normalizeSource(code.textContent);
|
|
40
|
+
if (!pre || !source) return;
|
|
41
|
+
code.dataset.mermaidHandled = '1';
|
|
42
|
+
|
|
43
|
+
const host = document.createElement('div');
|
|
44
|
+
host.className = 'mermaid-diagram';
|
|
45
|
+
host.setAttribute('role', 'img');
|
|
46
|
+
host.setAttribute('aria-label', 'Mermaid diagram');
|
|
47
|
+
pre.replaceWith(host);
|
|
48
|
+
const id = `mermaid-diagram-${++sequence}`;
|
|
49
|
+
|
|
50
|
+
// Mermaid.render may resolve with an error SVG for invalid syntax rather
|
|
51
|
+
// than reject. Parse first so invalid generated content always takes the
|
|
52
|
+
// clean code-block fallback below.
|
|
53
|
+
Promise.resolve(api.parse(source)).then(() => api.render(id, source)).then(({ svg, bindFunctions }) => {
|
|
54
|
+
host.innerHTML = svg;
|
|
55
|
+
bindFunctions?.(host);
|
|
56
|
+
}).catch(error => {
|
|
57
|
+
// Syntax errors remain inspectable/copyable as the original code block.
|
|
58
|
+
host.replaceWith(pre);
|
|
59
|
+
delete code.dataset.mermaidHandled;
|
|
60
|
+
pre.classList.add('mermaid-error');
|
|
61
|
+
pre.title = `Mermaid render failed: ${error?.message || 'invalid diagram'}`;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
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-v20';
|
|
5
5
|
const PRECACHE = [
|
|
6
6
|
'/',
|
|
7
7
|
'/index.html',
|
|
8
8
|
'/manifest.webmanifest',
|
|
9
|
-
'/style.css?v=ui-
|
|
9
|
+
'/style.css?v=ui-15',
|
|
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-15',
|
|
17
18
|
'/icons/icon-192.png',
|
|
18
19
|
'/icons/icon-512.png',
|
|
19
20
|
'/icons/icon-maskable-512.png',
|