@lalalic/markcut 3.2.8 → 3.2.9
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 +1 -1
- package/src/mcp/bridge.mjs +1 -1
- package/tests/mcp-preview.test.ts +20 -2
package/package.json
CHANGED
package/src/mcp/bridge.mjs
CHANGED
|
@@ -7,7 +7,7 @@ function send(message){window.parent.postMessage(message,'*');}
|
|
|
7
7
|
function rpcRequest(method,params){const id=++nextRequestId;send({jsonrpc:'2.0',id,method,params});return new Promise((resolve,reject)=>pendingRequests.set(id,{resolve,reject}));}
|
|
8
8
|
function applyToolResult(params){const result=params?.result||params||{},data=result.structuredContent||result.structured_content||{};if(typeof data.path==='string')pathLabel.textContent=data.path;if(typeof data.markdown==='string'){article.innerHTML=data.markdown.split(/\\r?\\n/).map(line=>{const escaped=line.replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));if(line.startsWith('### '))return '<h3>'+escaped.slice(4)+'</h3>';if(line.startsWith('## '))return '<h2>'+escaped.slice(3)+'</h2>';if(line.startsWith('# '))return '<h1>'+escaped.slice(2)+'</h1>';if(line.startsWith('- '))return '<li>'+escaped.slice(2)+'</li>';return line.trim()?'<p>'+escaped+'</p>':''}).join('\\n');}}
|
|
9
9
|
window.addEventListener('message',event=>{if(event.source!==window.parent)return;const message=event.data;if(!message||typeof message!=='object'||message.jsonrpc!=='2.0')return;if(Object.prototype.hasOwnProperty.call(message,'id')&&pendingRequests.has(message.id)){const pending=pendingRequests.get(message.id);pendingRequests.delete(message.id);if(message.error)pending.reject(new Error(message.error.message||'MCP request failed'));else pending.resolve(message.result);return;}if(message.method==='ui/notifications/tool-result')applyToolResult(message.params);});
|
|
10
|
-
async function initializeBridge(){try{await rpcRequest('ui/initialize',{
|
|
10
|
+
async function initializeBridge(){try{await rpcRequest('ui/initialize',{appInfo:{name:'Markcut Preview',version:'1.0.0'},appCapabilities:{},protocolVersion:'2026-01-26'});send({jsonrpc:'2.0',method:'ui/notifications/initialized'});status.textContent='Ready for review.';}catch(error){status.textContent=error.message||'MCP initialization failed.';}}
|
|
11
11
|
async function submit(decision){const value=feedback.value.trim();if(decision==='changes_requested'&&!value){status.textContent='Feedback is required.';feedback.focus();return;}const result={decision};if(value&&decision==='changes_requested')result.feedback=value;status.textContent='Submitting...';try{await rpcRequest('tools/call',{name:'${submitToolName}',arguments:result});send({jsonrpc:'2.0',method:'ui/message',params:{role:'user',content:[{type:'text',text:JSON.stringify(result)}]}});status.textContent=decision==='approved'?'Approved.':'Changes requested.';}catch(error){status.textContent=error.message||'Unable to submit review.';}}
|
|
12
12
|
initializeBridge();
|
|
13
13
|
document.getElementById('approve').onclick=()=>submit('approved');document.getElementById('changes').onclick=()=>submit('changes_requested');
|
|
@@ -53,8 +53,26 @@ describe("MarkCut MCP Markdown preview", () => {
|
|
|
53
53
|
it("performs the MCP Apps handshake and awaits a successful submit", async () => {
|
|
54
54
|
const harness = createBridgeHarness();
|
|
55
55
|
harness.run();
|
|
56
|
-
expect(harness.messages[0]).
|
|
57
|
-
|
|
56
|
+
expect(harness.messages[0]).toEqual({
|
|
57
|
+
jsonrpc: "2.0",
|
|
58
|
+
id: 1,
|
|
59
|
+
method: "ui/initialize",
|
|
60
|
+
params: {
|
|
61
|
+
appInfo: { name: "Markcut Preview", version: "1.0.0" },
|
|
62
|
+
appCapabilities: {},
|
|
63
|
+
protocolVersion: "2026-01-26",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
expect(harness.messages.some((message) => message.method === "ui/notifications/initialized")).toBe(false);
|
|
67
|
+
harness.respond({
|
|
68
|
+
id: 1,
|
|
69
|
+
result: {
|
|
70
|
+
protocolVersion: "2026-01-26",
|
|
71
|
+
hostInfo: { name: "test-host", version: "1" },
|
|
72
|
+
hostCapabilities: {},
|
|
73
|
+
hostContext: {},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
58
76
|
await tick();
|
|
59
77
|
expect(harness.messages[1]).toMatchObject({ method: "ui/notifications/initialized" });
|
|
60
78
|
|