@radnine/storybook-addon-claude 0.3.2 → 0.3.3

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.
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.MarkdownContent = MarkdownContent;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _marked = require("marked");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ // Configure marked for compact chat rendering
12
+ const renderer = new _marked.marked.Renderer();
13
+
14
+ // Override link rendering to open in new tabs
15
+ renderer.link = function ({
16
+ href,
17
+ title,
18
+ text
19
+ }) {
20
+ const titleAttr = title ? ` title="${title}"` : '';
21
+ return `<a href="${href}" target="_blank" rel="noopener noreferrer"${titleAttr}>${text}</a>`;
22
+ };
23
+ _marked.marked.setOptions({
24
+ renderer,
25
+ gfm: true,
26
+ breaks: true
27
+ });
28
+
29
+ // Compact markdown styles scoped under .claude-md
30
+ const MARKDOWN_STYLES = `
31
+ .claude-md { line-height: 1.5; word-break: break-word; }
32
+ .claude-md h1 { font-size: 1.1em; font-weight: 600; margin: 8px 0 4px; }
33
+ .claude-md h2 { font-size: 1.05em; font-weight: 600; margin: 8px 0 4px; }
34
+ .claude-md h3 { font-size: 1em; font-weight: 600; margin: 6px 0 3px; }
35
+ .claude-md h4, .claude-md h5, .claude-md h6 { font-size: 1em; font-weight: 600; margin: 4px 0 2px; }
36
+ .claude-md p { margin: 4px 0; }
37
+ .claude-md ul, .claude-md ol { margin: 4px 0; padding-left: 20px; }
38
+ .claude-md li { margin: 2px 0; }
39
+ .claude-md code { background: rgba(0,0,0,0.06); padding: 1px 4px; border-radius: 3px; font-size: 0.9em; }
40
+ .claude-md pre { background: rgba(0,0,0,0.04); padding: 8px; border-radius: 4px; overflow-x: auto; margin: 4px 0; }
41
+ .claude-md pre code { background: none; padding: 0; }
42
+ .claude-md table { border-collapse: collapse; margin: 4px 0; font-size: 0.95em; }
43
+ .claude-md th, .claude-md td { border: 1px solid rgba(0,0,0,0.15); padding: 4px 8px; }
44
+ .claude-md th { background: rgba(0,0,0,0.04); font-weight: 600; }
45
+ .claude-md blockquote { border-left: 3px solid rgba(0,0,0,0.15); margin: 4px 0; padding: 2px 8px; color: #666; }
46
+ .claude-md a { color: #0366d6; text-decoration: none; }
47
+ .claude-md a:hover { text-decoration: underline; }
48
+ .claude-md hr { border: none; border-top: 1px solid rgba(0,0,0,0.1); margin: 8px 0; }
49
+ .claude-md > *:first-child { margin-top: 0; }
50
+ .claude-md > *:last-child { margin-bottom: 0; }
51
+ `;
52
+
53
+ // Inject styles once
54
+ let stylesInjected = false;
55
+ function ensureStyles() {
56
+ if (stylesInjected) return;
57
+ try {
58
+ const style = document.createElement('style');
59
+ style.textContent = MARKDOWN_STYLES;
60
+ document.head.appendChild(style);
61
+ stylesInjected = true;
62
+ } catch (_e) {
63
+ // SSR or test environment — ignore
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Renders markdown text as formatted HTML.
69
+ * Compact styling designed for chat bubbles.
70
+ *
71
+ * @param {{ text: string }} props
72
+ */
73
+ function MarkdownContent({
74
+ text
75
+ }) {
76
+ ensureStyles();
77
+ const html = (0, _react.useMemo)(() => {
78
+ if (!text) return '';
79
+ return _marked.marked.parse(text);
80
+ }, [text]);
81
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
82
+ className: "claude-md",
83
+ dangerouslySetInnerHTML: {
84
+ __html: html
85
+ }
86
+ });
87
+ }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.MessageList = MessageList;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
+ var _MarkdownContent = require("./MarkdownContent");
8
9
  var _jsxRuntime = require("react/jsx-runtime");
9
10
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
11
  /**
@@ -190,7 +191,9 @@ function AssistantMessage({
190
191
  ...styles.assistantBubble,
191
192
  ...(replay ? styles.replay : {})
192
193
  },
193
- children: text || '(empty response)'
194
+ children: text ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_MarkdownContent.MarkdownContent, {
195
+ text: text
196
+ }) : '(empty response)'
194
197
  })
195
198
  });
196
199
  }
@@ -242,18 +245,14 @@ function ResultMessage({
242
245
  data
243
246
  }) {
244
247
  const subtype = data?.subtype || 'unknown';
245
- const resultText = typeof data?.result === 'string' ? data.result : '';
246
248
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
247
249
  style: styles.resultRow,
248
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
250
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
249
251
  style: styles.resultBubble,
250
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
252
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
251
253
  style: styles.resultLabel,
252
254
  children: subtype === 'success' ? 'Completed' : `Result: ${subtype}`
253
- }), resultText && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
254
- style: styles.resultText,
255
- children: resultText.slice(0, 200)
256
- })]
255
+ })
257
256
  })
258
257
  });
259
258
  }
@@ -326,7 +325,9 @@ function GenericOutputMessage({
326
325
  ...styles.assistantBubble,
327
326
  ...(replay ? styles.replay : {})
328
327
  },
329
- children: text
328
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MarkdownContent.MarkdownContent, {
329
+ text: text
330
+ })
330
331
  })
331
332
  });
332
333
  }
@@ -498,7 +499,6 @@ const styles = {
498
499
  color: '#333',
499
500
  fontSize: '13px',
500
501
  lineHeight: '1.4',
501
- whiteSpace: 'pre-wrap',
502
502
  wordBreak: 'break-word'
503
503
  },
504
504
  replay: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radnine/storybook-addon-claude",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Storybook addon panel for chatting with Claude via the standalone daemon",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {
@@ -29,6 +29,9 @@
29
29
  "ai",
30
30
  "design"
31
31
  ],
32
+ "dependencies": {
33
+ "marked": "^15.0.0"
34
+ },
32
35
  "peerDependencies": {
33
36
  "storybook": "^9.0.0",
34
37
  "react": "^18.0.0 || ^19.0.0",