@mangostudio/cli-darwin-arm64 0.1.0-canary.ea530eb → 0.1.0-canary.eb3254e

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.
@@ -1,43 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Node sidecar for Cursor SDK local agent runs.
4
- * Line 1 on stdin is the JSON request; subsequent lines are tool_response RPC messages.
5
- * Writes NDJSON events (and tool_request RPC) to stdout.
4
+ * The first stdout line is the `ready` handshake; line 1 on stdin is the JSON
5
+ * request; subsequent stdin lines are tool_response RPC messages. Writes
6
+ * NDJSON events (and tool_request RPC) to stdout.
6
7
  */
7
8
 
8
- import { createInterface } from 'node:readline';
9
9
  import { Agent, Cursor } from '@cursor/sdk';
10
+ import {
11
+ createStdinMultiplexer,
12
+ isRecord,
13
+ serializeError,
14
+ writeEvent,
15
+ } from './sidecar-runtime.mjs';
10
16
 
11
- function writeEvent(event) {
12
- process.stdout.write(`${JSON.stringify(event)}\n`);
13
- }
14
-
15
- function isRecord(value) {
16
- return typeof value === 'object' && value !== null && !Array.isArray(value);
17
- }
18
-
19
- function errorStatus(error) {
20
- if (!isRecord(error)) return undefined;
21
- const status = error.status ?? error.statusCode;
22
- return typeof status === 'number' ? status : undefined;
23
- }
24
-
25
- function errorRetryable(error) {
26
- if (!isRecord(error)) return undefined;
27
- return typeof error.isRetryable === 'boolean' ? error.isRetryable : undefined;
28
- }
29
-
30
- function serializeError(error, fallback) {
31
- const message = error instanceof Error && error.message ? error.message : fallback;
32
- const status = errorStatus(error);
33
- const isRetryable = errorRetryable(error);
34
- return {
35
- message,
36
- content: message,
37
- ...(status === undefined ? {} : { status }),
38
- ...(isRetryable === undefined ? {} : { isRetryable, retryable: isRetryable }),
39
- };
40
- }
17
+ /**
18
+ * NDJSON protocol version announced in the `ready` handshake. Must stay in
19
+ * lockstep with CURSOR_SIDECAR_PROTOCOL_VERSION in ../sidecar-process.ts
20
+ * (this script cannot import it — both ship inside the same artifact).
21
+ */
22
+ const PROTOCOL_VERSION = 1;
41
23
 
42
24
  function normalizeCustomTools(value) {
43
25
  if (!Array.isArray(value)) return undefined;
@@ -66,71 +48,6 @@ function normalizeSettingSources(value) {
66
48
  return sources.length > 0 ? sources : ['project'];
67
49
  }
68
50
 
69
- function createStdinMultiplexer() {
70
- const rl = createInterface({ input: process.stdin });
71
- const toolWaiters = new Map();
72
- let toolRpcTimeoutMs;
73
- let requestResolve;
74
- let gotRequest = false;
75
-
76
- const requestPromise = new Promise((resolve) => {
77
- requestResolve = resolve;
78
- });
79
-
80
- rl.on('line', (line) => {
81
- if (!line.trim()) return;
82
-
83
- let parsed;
84
- try {
85
- parsed = JSON.parse(line);
86
- } catch {
87
- return;
88
- }
89
-
90
- if (!gotRequest) {
91
- gotRequest = true;
92
- requestResolve(parsed);
93
- return;
94
- }
95
-
96
- if (parsed?.type === 'tool_response' && typeof parsed.id === 'string') {
97
- const waiter = toolWaiters.get(parsed.id);
98
- if (waiter) {
99
- toolWaiters.delete(parsed.id);
100
- if (waiter.timeout) clearTimeout(waiter.timeout);
101
- waiter.resolve(parsed);
102
- }
103
- }
104
- });
105
-
106
- return {
107
- readRequest: () => requestPromise,
108
- setToolRpcTimeoutMs(value) {
109
- toolRpcTimeoutMs = normalizeToolRpcTimeoutMs(value);
110
- },
111
- waitForToolResponse(id) {
112
- return new Promise((resolve, reject) => {
113
- const timeout =
114
- toolRpcTimeoutMs === undefined
115
- ? undefined
116
- : setTimeout(() => {
117
- toolWaiters.delete(id);
118
- reject(new Error(`Tool RPC timed out after ${toolRpcTimeoutMs}ms.`));
119
- }, toolRpcTimeoutMs);
120
- timeout?.unref?.();
121
- toolWaiters.set(id, { resolve, reject, timeout });
122
- });
123
- },
124
- close: () => rl.close(),
125
- };
126
- }
127
-
128
- function normalizeToolRpcTimeoutMs(value) {
129
- if (typeof value !== 'number' || !Number.isFinite(value)) return undefined;
130
- const rounded = Math.trunc(value);
131
- return rounded > 0 ? rounded : undefined;
132
- }
133
-
134
51
  let nextToolRequestId = 0;
135
52
 
136
53
  function createRpcBackedCustomTools(toolDefs, stdinMux) {
@@ -160,15 +77,16 @@ async function executeViaApi(name, args, stdinMux) {
160
77
  : typeof response.result === 'string'
161
78
  ? response.result
162
79
  : 'Tool execution failed.';
80
+ writeEvent({ type: 'tool_result', id, name, result: message, isError: true });
163
81
  return {
164
82
  content: [{ type: 'text', text: message }],
165
83
  isError: true,
166
84
  };
167
85
  }
168
86
 
169
- if (typeof response.result === 'string') return response.result;
170
- if (response.result !== undefined) return response.result;
171
- return '';
87
+ const result = response.result === undefined ? '' : response.result;
88
+ writeEvent({ type: 'tool_result', id, name, result, isError: false });
89
+ return result;
172
90
  }
173
91
 
174
92
  function extractAssistantText(event) {
@@ -209,6 +127,26 @@ async function disposeAgent(agent) {
209
127
  }
210
128
  }
211
129
 
130
+ /**
131
+ * The agent currently running, tracked so the SIGTERM handler can dispose it
132
+ * (releasing Cursor's native child process) before exiting. Disposal is
133
+ * idempotent: SIGTERM and runAgent's finally may both reach it.
134
+ */
135
+ let activeAgent;
136
+ let activeAgentDisposed = false;
137
+
138
+ async function disposeActiveAgent() {
139
+ if (!activeAgent || activeAgentDisposed) return;
140
+ activeAgentDisposed = true;
141
+ await disposeAgent(activeAgent);
142
+ }
143
+
144
+ process.on('SIGTERM', () => {
145
+ disposeActiveAgent()
146
+ .catch(() => {})
147
+ .finally(() => process.exit(143));
148
+ });
149
+
212
150
  function readApiKey(request) {
213
151
  const apiKey = typeof request.apiKey === 'string' ? request.apiKey.trim() : '';
214
152
  if (!apiKey) throw new Error('Sidecar request missing apiKey.');
@@ -251,9 +189,8 @@ async function runAgent(request, stdinMux) {
251
189
  const customTools = toolDefs ? createRpcBackedCustomTools(toolDefs, stdinMux) : undefined;
252
190
  const settingSources = normalizeSettingSources(request.settingSources);
253
191
 
254
- let agent;
255
192
  try {
256
- agent = await Agent.create({
193
+ activeAgent = await Agent.create({
257
194
  apiKey,
258
195
  model: { id: model, ...(modelParams ? { params: modelParams } : {}) },
259
196
  local: {
@@ -262,6 +199,7 @@ async function runAgent(request, stdinMux) {
262
199
  ...(customTools ? { customTools } : {}),
263
200
  },
264
201
  });
202
+ const agent = activeAgent;
265
203
 
266
204
  const run = await agent.send(prompt);
267
205
  const emittedToolCalls = new Set();
@@ -303,12 +241,14 @@ async function runAgent(request, stdinMux) {
303
241
 
304
242
  writeEvent({ type: 'done', done: true });
305
243
  } finally {
306
- await disposeAgent(agent);
244
+ await disposeActiveAgent();
307
245
  }
308
246
  }
309
247
 
310
248
  async function main() {
311
- const stdinMux = createStdinMultiplexer();
249
+ writeEvent({ type: 'ready', protocolVersion: PROTOCOL_VERSION });
250
+
251
+ const stdinMux = createStdinMultiplexer({ sidecarLabel: 'Cursor' });
312
252
  const request = await stdinMux.readRequest();
313
253
  if (!isRecord(request)) throw new Error('Sidecar request must be a JSON object.');
314
254
 
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Shared Node-side helpers for MangoStudio SDK sidecars.
3
+ *
4
+ * This file is plain ESM because it ships beside sidecar entrypoints and
5
+ * cannot import workspace TypeScript.
6
+ */
7
+
8
+ import { createInterface } from 'node:readline';
9
+
10
+ /** Tool RPC wait applied when the parent does not pass toolRpcTimeoutMs. */
11
+ export const DEFAULT_TOOL_RPC_TIMEOUT_MS = 300_000;
12
+
13
+ // If the parent dies mid-run, stdout writes raise EPIPE; swallow so cleanup
14
+ // paths (agent disposal, exit handlers) still run instead of crashing.
15
+ process.stdout.on('error', () => {});
16
+
17
+ export function writeEvent(event) {
18
+ try {
19
+ process.stdout.write(`${JSON.stringify(event)}\n`);
20
+ } catch {
21
+ // Parent may be gone (EPIPE); nothing useful to do.
22
+ }
23
+ }
24
+
25
+ export function isRecord(value) {
26
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
27
+ }
28
+
29
+ function errorStatus(error) {
30
+ if (!isRecord(error)) return undefined;
31
+ const status = error.status ?? error.statusCode;
32
+ return typeof status === 'number' ? status : undefined;
33
+ }
34
+
35
+ function errorRetryable(error) {
36
+ if (!isRecord(error)) return undefined;
37
+ return typeof error.isRetryable === 'boolean' ? error.isRetryable : undefined;
38
+ }
39
+
40
+ export function serializeError(error, fallback) {
41
+ const message = error instanceof Error && error.message ? error.message : fallback;
42
+ const status = errorStatus(error);
43
+ const isRetryable = errorRetryable(error);
44
+ return {
45
+ message,
46
+ content: message,
47
+ ...(status === undefined ? {} : { status }),
48
+ ...(isRetryable === undefined ? {} : { isRetryable, retryable: isRetryable }),
49
+ };
50
+ }
51
+
52
+ export function createStdinMultiplexer(options = {}) {
53
+ const sidecarLabel = typeof options.sidecarLabel === 'string' ? options.sidecarLabel : 'Node';
54
+ const rl = createInterface({ input: process.stdin });
55
+ const toolWaiters = new Map();
56
+ let toolRpcTimeoutMs = DEFAULT_TOOL_RPC_TIMEOUT_MS;
57
+ let requestResolve;
58
+ let gotRequest = false;
59
+ let closedByUs = false;
60
+
61
+ const requestPromise = new Promise((resolve) => {
62
+ requestResolve = resolve;
63
+ });
64
+
65
+ rl.on('line', (line) => {
66
+ if (!line.trim()) return;
67
+
68
+ let parsed;
69
+ try {
70
+ parsed = JSON.parse(line);
71
+ } catch {
72
+ return;
73
+ }
74
+
75
+ if (!gotRequest) {
76
+ gotRequest = true;
77
+ requestResolve(parsed);
78
+ return;
79
+ }
80
+
81
+ if (parsed?.type === 'tool_response' && typeof parsed.id === 'string') {
82
+ const waiter = toolWaiters.get(parsed.id);
83
+ if (waiter) {
84
+ toolWaiters.delete(parsed.id);
85
+ if (waiter.timeout) clearTimeout(waiter.timeout);
86
+ waiter.resolve(parsed);
87
+ }
88
+ }
89
+ });
90
+
91
+ rl.on('close', () => {
92
+ if (closedByUs) return;
93
+
94
+ // Parent died before sending a request: exit instead of idling forever.
95
+ if (!gotRequest) {
96
+ writeEvent({
97
+ type: 'error',
98
+ content: `${sidecarLabel} sidecar stdin closed before a request was received.`,
99
+ done: true,
100
+ });
101
+ process.exit(1);
102
+ }
103
+
104
+ // Mid-run stdin close: no tool_response can ever arrive; unblock callers.
105
+ rejectPendingToolWaiters(
106
+ toolWaiters,
107
+ new Error(`${sidecarLabel} sidecar stdin closed while a tool call was pending.`)
108
+ );
109
+ });
110
+
111
+ return {
112
+ readRequest: () => requestPromise,
113
+ setToolRpcTimeoutMs(value) {
114
+ toolRpcTimeoutMs = normalizeToolRpcTimeoutMs(value);
115
+ },
116
+ waitForToolResponse(id) {
117
+ return new Promise((resolve, reject) => {
118
+ const timeout = setTimeout(() => {
119
+ toolWaiters.delete(id);
120
+ reject(new Error(`Tool RPC timed out after ${toolRpcTimeoutMs}ms.`));
121
+ }, toolRpcTimeoutMs);
122
+ timeout.unref?.();
123
+ toolWaiters.set(id, { resolve, reject, timeout });
124
+ });
125
+ },
126
+ close: () => {
127
+ closedByUs = true;
128
+ rl.close();
129
+ },
130
+ };
131
+ }
132
+
133
+ function rejectPendingToolWaiters(toolWaiters, error) {
134
+ for (const [id, waiter] of toolWaiters) {
135
+ toolWaiters.delete(id);
136
+ if (waiter.timeout) clearTimeout(waiter.timeout);
137
+ waiter.reject(error);
138
+ }
139
+ }
140
+
141
+ export function normalizeToolRpcTimeoutMs(value) {
142
+ if (typeof value !== 'number' || !Number.isFinite(value)) return DEFAULT_TOOL_RPC_TIMEOUT_MS;
143
+ const rounded = Math.trunc(value);
144
+ return rounded > 0 ? rounded : DEFAULT_TOOL_RPC_TIMEOUT_MS;
145
+ }
package/mangostudio CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mangostudio/cli-darwin-arm64",
3
- "version": "0.1.0-canary.ea530eb",
3
+ "version": "0.1.0-canary.eb3254e",
4
4
  "description": "MangoStudio prebuilt binary for darwin-arm64.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/shiki-CXvr9CXa.js","assets/index-DPVVPEXE.js","assets/rolldown-runtime-BYbx6iT9.js","assets/vendor-TU_R2f75.js","assets/ui-BEql6gkw.js","assets/vendor-deps-C4ULb-aw.js","assets/index-BYDs1qLs.css","assets/syntax-core-BoMshe5A.js"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{i as t,r as n}from"./ui-BEql6gkw.js";import{i as r,n as i,r as a}from"./index-DPVVPEXE.js";import{n as o,t as s}from"./markdown-parser-B0W8Yv4o.js";var c=e(t(),1),l=n(),u=`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,d=`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;function f({content:e,className:t,copyCodeLabel:n,codeCopiedLabel:i}){let{t:o}=r(),s=(0,c.useRef)(null),{resolvedCodeTheme:u}=a(),[d,f]=(0,c.useState)(null),[_,v]=(0,c.useState)(0),y=n??o.chat.copyCode,b=i??o.chat.codeCopied,x=(0,c.useMemo)(()=>k(e).join(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/shiki-Cm6aTOwF.js","assets/index-DQGJtb18.js","assets/rolldown-runtime-BYbx6iT9.js","assets/vendor-CsAvHWDf.js","assets/ui-BEql6gkw.js","assets/vendor-deps-DbBWw3j9.js","assets/index-hn0J71bD.css","assets/syntax-core-BoMshe5A.js"])))=>i.map(i=>d[i]);
2
+ import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{i as t,r as n}from"./ui-BEql6gkw.js";import{i as r,n as i,r as a}from"./index-DQGJtb18.js";import{n as o,t as s}from"./markdown-parser-B0W8Yv4o.js";var c=e(t(),1),l=n(),u=`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`,d=`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;function f({content:e,className:t,copyCodeLabel:n,codeCopiedLabel:i}){let{t:o}=r(),s=(0,c.useRef)(null),{resolvedCodeTheme:u}=a(),[d,f]=(0,c.useState)(null),[_,v]=(0,c.useState)(0),y=n??o.chat.copyCode,b=i??o.chat.codeCopied,x=(0,c.useMemo)(()=>k(e).join(`
3
3
  `),[e]);p((0,c.useMemo)(()=>x?x.split(`
4
- `):[],[x]),f,v),m(s,y,b);let S=h(e,(0,c.useMemo)(()=>g(u,y,d),[u,y,d,_]));return(0,l.jsx)(`div`,{ref:s,className:`markdown-content ${t??``}`,dangerouslySetInnerHTML:{__html:S}})}function p(e,t,n){(0,c.useEffect)(()=>{if(e.length===0)return;let r=!1;return A(e).then(e=>{r||(t(e),n(e=>e+1))}),()=>{r=!0}},[e,t,n])}function m(e,t,n){(0,c.useEffect)(()=>{let r=e.current;if(!r)return;let i=new Set,a=j(i,t,n);return r.addEventListener(`click`,a),()=>{r.removeEventListener(`click`,a);for(let e of i)clearTimeout(e)}},[e,t,n])}function h(e,t){return(0,c.useMemo)(()=>D(t,e),[e,t])}function g(e,t,n){return new s({gfm:!0,breaks:!0,renderer:_(e,t,n)})}function _(e,t,n){let r=new o;return r.link=v,r.image=y,r.html=e=>z(`text`in e?e.text:``),r.code=r=>w(r.text,r.lang,e,t,n),r}function v({href:e,title:t,tokens:n}){let r=n?.map(e=>`text`in e?e.text:e.raw).join(``)??``,i=C(e),a=t?` title="${z(t)}"`:``;return`<a href="${z(i)}" target="_blank" rel="noopener noreferrer"${a}>${r}</a>`}function y({href:e,title:t,text:n}){let r=C(e),i=t?` title="${z(t)}"`:``,a=n||r;return`<a href="${z(r)}" target="_blank" rel="noopener noreferrer" class="markdown-image-link"${i}>${z(a)}</a>`}var b=new Set([`http:`,`https:`,`mailto:`]),x=`#`,S=`https://markdown.invalid/`;function C(e){if(!e)return x;let t;try{t=new URL(e,S).protocol}catch{return x}return b.has(t)?e:x}function w(e,t,n,r,i){let a=t??``,o=a?i?.highlightCode(e,a,n):null;return o?T(o,a,r):E(e,a,r)}function T(e,t,n){return e.replace(`<pre `,`<pre data-lang="${z(t)}" `).replace(`</pre>`,`${R(n)}</pre>`)}function E(e,t,n){let r=t?` class="language-${z(t)}"`:``;return`<pre${t?` data-lang="${z(t)}"`:``}><code${r}>${z(e)}</code>${R(n)}</pre>`}function D(e,t){return t?e.parse(t,{async:!1}):``}var O=new s({gfm:!0,breaks:!0});function k(e){if(!e)return[];let t=new Set;return O.walkTokens(O.lexer(e),e=>{e.type===`code`&&`lang`in e&&e.lang&&t.add(e.lang)}),[...t].sort()}async function A(e){let t=await i(()=>import(`./shiki-CXvr9CXa.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]));return await t.preloadCodeLanguages(e),t}function j(e,t,n){return r=>{M(r,e,t,n)}}async function M(e,t,n,r){let i=e.target.closest(`.copy-code-btn`);if(!i)return;let a=N(i);a!==null&&await P(i,a,t,n,r)}function N(e){let t=e.closest(`pre`);return t?t.querySelector(`code`)?.textContent??t.textContent??``:null}async function P(e,t,n,r,i){try{await navigator.clipboard.writeText(t),F(e,n,r,i)}catch{}}function F(e,t,n,r){e.innerHTML=d,e.setAttribute(`aria-label`,r),e.classList.add(`copy-code-btn--copied`),I(e,t,n)}function I(e,t,n){let r=setTimeout(()=>{t.delete(r),L(e,n)},2e3);t.add(r)}function L(e,t){e.innerHTML=u,e.setAttribute(`aria-label`,t),e.classList.remove(`copy-code-btn--copied`)}function R(e){return`<button class="copy-code-btn" type="button" aria-label="${z(e)}">${u}</button>`}function z(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}export{f as MarkdownContentRenderer};
4
+ `):[],[x]),f,v),m(s,y,b);let S=h(e,(0,c.useMemo)(()=>g(u,y,d),[u,y,d,_]));return(0,l.jsx)(`div`,{ref:s,className:`markdown-content ${t??``}`,dangerouslySetInnerHTML:{__html:S}})}function p(e,t,n){(0,c.useEffect)(()=>{if(e.length===0)return;let r=!1;return A(e).then(e=>{r||(t(e),n(e=>e+1))}),()=>{r=!0}},[e,t,n])}function m(e,t,n){(0,c.useEffect)(()=>{let r=e.current;if(!r)return;let i=new Set,a=j(i,t,n);return r.addEventListener(`click`,a),()=>{r.removeEventListener(`click`,a);for(let e of i)clearTimeout(e)}},[e,t,n])}function h(e,t){return(0,c.useMemo)(()=>D(t,e),[e,t])}function g(e,t,n){return new s({gfm:!0,breaks:!0,renderer:_(e,t,n)})}function _(e,t,n){let r=new o;return r.link=v,r.image=y,r.html=e=>z(`text`in e?e.text:``),r.code=r=>w(r.text,r.lang,e,t,n),r}function v({href:e,title:t,tokens:n}){let r=n?.map(e=>`text`in e?e.text:e.raw).join(``)??``,i=C(e),a=t?` title="${z(t)}"`:``;return`<a href="${z(i)}" target="_blank" rel="noopener noreferrer"${a}>${r}</a>`}function y({href:e,title:t,text:n}){let r=C(e),i=t?` title="${z(t)}"`:``,a=n||r;return`<a href="${z(r)}" target="_blank" rel="noopener noreferrer" class="markdown-image-link"${i}>${z(a)}</a>`}var b=new Set([`http:`,`https:`,`mailto:`]),x=`#`,S=`https://markdown.invalid/`;function C(e){if(!e)return x;let t;try{t=new URL(e,S).protocol}catch{return x}return b.has(t)?e:x}function w(e,t,n,r,i){let a=t??``,o=a?i?.highlightCode(e,a,n):null;return o?T(o,a,r):E(e,a,r)}function T(e,t,n){return e.replace(`<pre `,`<pre data-lang="${z(t)}" `).replace(`</pre>`,`${R(n)}</pre>`)}function E(e,t,n){let r=t?` class="language-${z(t)}"`:``;return`<pre${t?` data-lang="${z(t)}"`:``}><code${r}>${z(e)}</code>${R(n)}</pre>`}function D(e,t){return t?e.parse(t,{async:!1}):``}var O=new s({gfm:!0,breaks:!0});function k(e){if(!e)return[];let t=new Set;return O.walkTokens(O.lexer(e),e=>{e.type===`code`&&`lang`in e&&e.lang&&t.add(e.lang)}),[...t].sort()}async function A(e){let t=await i(()=>import(`./shiki-Cm6aTOwF.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]));return await t.preloadCodeLanguages(e),t}function j(e,t,n){return r=>{M(r,e,t,n)}}async function M(e,t,n,r){let i=e.target.closest(`.copy-code-btn`);if(!i)return;let a=N(i);a!==null&&await P(i,a,t,n,r)}function N(e){let t=e.closest(`pre`);return t?t.querySelector(`code`)?.textContent??t.textContent??``:null}async function P(e,t,n,r,i){try{await navigator.clipboard.writeText(t),F(e,n,r,i)}catch{}}function F(e,t,n,r){e.innerHTML=d,e.setAttribute(`aria-label`,r),e.classList.add(`copy-code-btn--copied`),I(e,t,n)}function I(e,t,n){let r=setTimeout(()=>{t.delete(r),L(e,n)},2e3);t.add(r)}function L(e,t){e.innerHTML=u,e.setAttribute(`aria-label`,t),e.classList.remove(`copy-code-btn--copied`)}function R(e){return`<button class="copy-code-btn" type="button" aria-label="${z(e)}">${u}</button>`}function z(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}export{f as MarkdownContentRenderer};