@axiomatic-labs/claudeflow 2.13.67 → 2.13.69
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/panel.js +73 -6
- package/package.json +1 -1
package/lib/panel.js
CHANGED
|
@@ -1031,6 +1031,13 @@ function row(k, v, badge) {
|
|
|
1031
1031
|
return \`<div class="card-row"><span class="k">\${escapeHtml(k)}</span><span class="v">\${b}\${escapeHtml(v)}</span></div>\`;
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
// Same as row() but the value is rendered as raw HTML (caller is responsible
|
|
1035
|
+
// for escaping). Use for values that already contain HTML markup (e.g. <code>).
|
|
1036
|
+
function rowHtml(k, vHtml, badge) {
|
|
1037
|
+
const b = badge ? \`<span class="badge \${badge.kind}">\${escapeHtml(badge.text)}</span>\` : '';
|
|
1038
|
+
return \`<div class="card-row"><span class="k">\${escapeHtml(k)}</span><span class="v">\${b}\${vHtml}</span></div>\`;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1034
1041
|
function escapeHtml(s) {
|
|
1035
1042
|
return String(s == null ? '' : s)
|
|
1036
1043
|
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
@@ -1461,10 +1468,10 @@ function renderObserver() {
|
|
|
1461
1468
|
// Browser section
|
|
1462
1469
|
const browserBlock = o.browser && o.browser.last_snapshot_at
|
|
1463
1470
|
? \`<div class="card" style="padding:10px 14px;font-size:13px;">
|
|
1464
|
-
\${
|
|
1465
|
-
\${
|
|
1466
|
-
\${
|
|
1467
|
-
\${
|
|
1471
|
+
\${rowHtml('Latest URL', o.browser.latest_url ? '<code>' + escapeHtml(o.browser.latest_url) + '</code>' : '<span class="muted">none</span>')}
|
|
1472
|
+
\${rowHtml('Latest route', o.browser.latest_route ? '<code>' + escapeHtml(o.browser.latest_route) + '</code>' : '<span class="muted">none</span>')}
|
|
1473
|
+
\${rowHtml('Snapshots received', String(o.browser.snapshots_received))}
|
|
1474
|
+
\${rowHtml('Last snapshot', escapeHtml(formatRelativeTime(o.browser.last_snapshot_at)))}
|
|
1468
1475
|
</div>\`
|
|
1469
1476
|
: '<p class="muted">No browser snapshots received yet. (The observer collects when the agent navigates with mcp__claude-in-chrome__*.)</p>';
|
|
1470
1477
|
|
|
@@ -1518,6 +1525,33 @@ function renderObserver() {
|
|
|
1518
1525
|
showResolvedPill +
|
|
1519
1526
|
'</div>';
|
|
1520
1527
|
|
|
1528
|
+
// Match file:line patterns in stack traces (most common formats):
|
|
1529
|
+
// http://localhost:3001/src/foo.tsx:51:22
|
|
1530
|
+
// /Users/abs/path.ts:42
|
|
1531
|
+
// at SomeFn (path:line:col)
|
|
1532
|
+
function extractFileLineHints(text) {
|
|
1533
|
+
if (typeof text !== 'string') return [];
|
|
1534
|
+
const hints = new Set();
|
|
1535
|
+
// localhost source URLs (Vite/CRA dev server)
|
|
1536
|
+
const localRe = /https?:\\/\\/localhost(?::\\d+)?\\/([^\\s:]+?\\.(?:tsx?|jsx?|vue|svelte)):(\\d+)(?::(\\d+))?/g;
|
|
1537
|
+
let m;
|
|
1538
|
+
while ((m = localRe.exec(text)) !== null) {
|
|
1539
|
+
hints.add(\`\${m[1]}:\${m[2]}\${m[3] ? ':' + m[3] : ''}\`);
|
|
1540
|
+
if (hints.size >= 6) break;
|
|
1541
|
+
}
|
|
1542
|
+
// Bare absolute paths
|
|
1543
|
+
const absRe = /\\b(\\/[A-Za-z0-9_./-]+?\\.(?:tsx?|jsx?|vue|svelte)):(\\d+)(?::(\\d+))?/g;
|
|
1544
|
+
while ((m = absRe.exec(text)) !== null) {
|
|
1545
|
+
hints.add(\`\${m[1]}:\${m[2]}\${m[3] ? ':' + m[3] : ''}\`);
|
|
1546
|
+
if (hints.size >= 6) break;
|
|
1547
|
+
}
|
|
1548
|
+
return [...hints];
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
// Server-side detail (recent_log + exit info) lookup per surface label.
|
|
1552
|
+
const serverByLabel = {};
|
|
1553
|
+
o.servers.forEach((srv) => { serverByLabel[srv.label] = srv; });
|
|
1554
|
+
|
|
1521
1555
|
// Incidents feed
|
|
1522
1556
|
const incidentsBlock = filteredIncidents.length === 0
|
|
1523
1557
|
? '<p class="muted">No incidents in this filter.</p>'
|
|
@@ -1530,6 +1564,36 @@ function renderObserver() {
|
|
|
1530
1564
|
const surfaceLabel = inc.source === 'server' && inc.metadata && inc.metadata.label
|
|
1531
1565
|
? inc.metadata.label
|
|
1532
1566
|
: inc.surface || inc.source;
|
|
1567
|
+
const fullMsg = inc.message || '';
|
|
1568
|
+
const fileLineHints = extractFileLineHints(fullMsg);
|
|
1569
|
+
// Show first 240 chars by default, collapsible to full message.
|
|
1570
|
+
const PREVIEW_CHARS = 240;
|
|
1571
|
+
const isLong = fullMsg.length > PREVIEW_CHARS;
|
|
1572
|
+
const previewMsg = isLong ? fullMsg.slice(0, PREVIEW_CHARS) + '…' : fullMsg;
|
|
1573
|
+
const fullBlock = isLong
|
|
1574
|
+
? '<details style="margin-top:4px;"><summary style="cursor:pointer;color:var(--muted);font-size:11px;">Show full message + stack (' + fullMsg.length + ' chars)</summary><pre style="font-size:11px;white-space:pre-wrap;background:var(--panel-2);padding:8px;border-radius:4px;margin:4px 0 0 0;overflow:auto;max-height:400px;">' + escapeHtml(fullMsg) + '</pre></details>'
|
|
1575
|
+
: '';
|
|
1576
|
+
const fileLinesHtml = fileLineHints.length > 0
|
|
1577
|
+
? '<div class="muted" style="font-size:11px;margin-top:4px;">📄 ' + fileLineHints.map((f) => '<code>' + escapeHtml(f) + '</code>').join(' • ') + '</div>'
|
|
1578
|
+
: '';
|
|
1579
|
+
const urlLine = inc.metadata && inc.metadata.url
|
|
1580
|
+
? '<div class="muted" style="font-size:11px;margin-top:4px;">🌐 <code>' + escapeHtml(inc.metadata.url) + '</code>' + (inc.metadata.route && inc.metadata.route !== inc.metadata.url ? ' (' + escapeHtml(inc.metadata.route) + ')' : '') + '</div>'
|
|
1581
|
+
: '';
|
|
1582
|
+
// For server incidents, attach recent_log + exit info from the matching server record.
|
|
1583
|
+
let serverDetail = '';
|
|
1584
|
+
if (inc.source === 'server') {
|
|
1585
|
+
const srv = serverByLabel[surfaceLabel];
|
|
1586
|
+
if (srv) {
|
|
1587
|
+
const exitInfo = srv.last_exit_code !== null && srv.last_exit_code !== undefined
|
|
1588
|
+
? \`<div class="muted" style="font-size:11px;margin-top:4px;">🛑 last exit: code \${srv.last_exit_code}\${srv.last_exit_signal ? ' / signal ' + srv.last_exit_signal : ''} at \${escapeHtml(formatRelativeTime(srv.last_exit_at))}</div>\`
|
|
1589
|
+
: '';
|
|
1590
|
+
const logLines = Array.isArray(srv.recent_log) ? srv.recent_log : [];
|
|
1591
|
+
const logBlock = logLines.length > 0
|
|
1592
|
+
? '<details style="margin-top:4px;"><summary style="cursor:pointer;color:var(--muted);font-size:11px;">📋 recent_log (' + logLines.length + ' lines from daemon-supervised stdout/stderr)</summary><pre style="font-size:11px;white-space:pre-wrap;background:var(--panel-2);padding:8px;border-radius:4px;margin:4px 0 0 0;overflow:auto;max-height:300px;">' + logLines.slice(-50).map((l) => escapeHtml(typeof l === 'string' ? l : (l.line || JSON.stringify(l)))).join('\\n') + '</pre></details>'
|
|
1593
|
+
: '<div class="muted" style="font-size:11px;margin-top:4px;">📋 No recent_log captured (server is observed_external — daemon only port-probes it, doesn\\'t pipe stdout/stderr). Run the server under the daemon supervisor to capture log lines, or check the dev server\\'s own terminal output.</div>';
|
|
1594
|
+
serverDetail = exitInfo + logBlock;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1533
1597
|
return \`<div class="incident-row" style="padding:10px 14px;border-top:1px solid var(--border);">
|
|
1534
1598
|
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px;">
|
|
1535
1599
|
<span class="badge \${sevClass}">\${escapeHtml(inc.severity || 'info')}</span>
|
|
@@ -1540,8 +1604,11 @@ function renderObserver() {
|
|
|
1540
1604
|
\${resolvedBadge}
|
|
1541
1605
|
<span class="muted" style="margin-left:auto;font-size:11px;">\${escapeHtml(formatRelativeTime(inc.last_seen_at))}</span>
|
|
1542
1606
|
</div>
|
|
1543
|
-
<div style="font-size:12px;white-space:pre-wrap;">\${escapeHtml(
|
|
1544
|
-
\${
|
|
1607
|
+
<div style="font-size:12px;white-space:pre-wrap;">\${escapeHtml(previewMsg)}</div>
|
|
1608
|
+
\${fullBlock}
|
|
1609
|
+
\${fileLinesHtml}
|
|
1610
|
+
\${urlLine}
|
|
1611
|
+
\${serverDetail}
|
|
1545
1612
|
</div>\`;
|
|
1546
1613
|
}).join('') +
|
|
1547
1614
|
'</div>';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.69",
|
|
4
4
|
"description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeflow": "./bin/cli.js"
|