@mangostudio/cli-linux-x64 0.1.0-canary.846512f → 0.1.0-canary.8b6dce7
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/cursor-sidecar/run-agent.mjs +41 -102
- package/cursor-sidecar/sidecar-runtime.mjs +145 -0
- package/mangostudio +0 -0
- package/package.json +1 -1
- package/public/assets/{MarkdownContentRenderer-DwrywcVv.js → MarkdownContentRenderer-DluhqQ8f.js} +3 -3
- package/public/assets/index-DgPknLa7.js +90 -0
- package/public/assets/index-mg8B7wPk.css +2 -0
- package/public/assets/{shiki-B3FV0nsK.js → shiki-Cjk9UNH4.js} +1 -1
- package/public/assets/{vendor-TU_R2f75.js → vendor-Dja0k3Kp.js} +1 -1
- package/public/assets/vendor-deps-DHoTlQF_.js +4 -0
- package/public/index.html +4 -4
- package/public/assets/index-BLb-08lM.js +0 -90
- package/public/assets/index-BYDs1qLs.css +0 -2
- package/public/assets/vendor-deps-C4ULb-aw.js +0 -4
|
@@ -1,43 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Node sidecar for Cursor SDK local agent runs.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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) {
|
|
@@ -210,6 +127,26 @@ async function disposeAgent(agent) {
|
|
|
210
127
|
}
|
|
211
128
|
}
|
|
212
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
|
+
|
|
213
150
|
function readApiKey(request) {
|
|
214
151
|
const apiKey = typeof request.apiKey === 'string' ? request.apiKey.trim() : '';
|
|
215
152
|
if (!apiKey) throw new Error('Sidecar request missing apiKey.');
|
|
@@ -252,9 +189,8 @@ async function runAgent(request, stdinMux) {
|
|
|
252
189
|
const customTools = toolDefs ? createRpcBackedCustomTools(toolDefs, stdinMux) : undefined;
|
|
253
190
|
const settingSources = normalizeSettingSources(request.settingSources);
|
|
254
191
|
|
|
255
|
-
let agent;
|
|
256
192
|
try {
|
|
257
|
-
|
|
193
|
+
activeAgent = await Agent.create({
|
|
258
194
|
apiKey,
|
|
259
195
|
model: { id: model, ...(modelParams ? { params: modelParams } : {}) },
|
|
260
196
|
local: {
|
|
@@ -263,6 +199,7 @@ async function runAgent(request, stdinMux) {
|
|
|
263
199
|
...(customTools ? { customTools } : {}),
|
|
264
200
|
},
|
|
265
201
|
});
|
|
202
|
+
const agent = activeAgent;
|
|
266
203
|
|
|
267
204
|
const run = await agent.send(prompt);
|
|
268
205
|
const emittedToolCalls = new Set();
|
|
@@ -304,12 +241,14 @@ async function runAgent(request, stdinMux) {
|
|
|
304
241
|
|
|
305
242
|
writeEvent({ type: 'done', done: true });
|
|
306
243
|
} finally {
|
|
307
|
-
await
|
|
244
|
+
await disposeActiveAgent();
|
|
308
245
|
}
|
|
309
246
|
}
|
|
310
247
|
|
|
311
248
|
async function main() {
|
|
312
|
-
|
|
249
|
+
writeEvent({ type: 'ready', protocolVersion: PROTOCOL_VERSION });
|
|
250
|
+
|
|
251
|
+
const stdinMux = createStdinMultiplexer({ sidecarLabel: 'Cursor' });
|
|
313
252
|
const request = await stdinMux.readRequest();
|
|
314
253
|
if (!isRecord(request)) throw new Error('Sidecar request must be a JSON object.');
|
|
315
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
package/public/assets/{MarkdownContentRenderer-DwrywcVv.js → MarkdownContentRenderer-DluhqQ8f.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/shiki-
|
|
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-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/shiki-Cjk9UNH4.js","assets/index-DgPknLa7.js","assets/rolldown-runtime-BYbx6iT9.js","assets/vendor-Dja0k3Kp.js","assets/ui-BEql6gkw.js","assets/vendor-deps-DHoTlQF_.js","assets/index-mg8B7wPk.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-DgPknLa7.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-
|
|
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-Cjk9UNH4.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(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`).replaceAll(`"`,`"`).replaceAll(`'`,`'`)}export{f as MarkdownContentRenderer};
|