opencontrol
Version:
175 lines (166 loc) • 35 kB
JavaScript
// src/index.ts
import { Hono } from "hono";
// src/mcp.ts
import {
CallToolRequestSchema,
InitializeRequestSchema,
ListToolsRequestSchema
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
var RequestSchema = z.union([
InitializeRequestSchema,
ListToolsRequestSchema,
CallToolRequestSchema
]);
function createMcp(input) {
return {
async process(message) {
const parsed = RequestSchema.parse(message);
const result = await (async () => {
if (parsed.method === "initialize")
return {
protocolVersion: "2024-11-05",
capabilities: {
tools: {}
},
serverInfo: {
name: "opencontrol",
version: "0.0.1"
}
};
if (parsed.method === "tools/list") {
return {
tools: input.tools.map((tool) => ({
name: tool.name,
inputSchema: zodToJsonSchema(tool.args || z.object({}), "args").definitions["args"],
description: tool.description
}))
};
}
if (parsed.method === "tools/call") {
const tool = input.tools.find((tool2) => tool2.name === parsed.params.name);
if (!tool)
throw new Error("tool not found");
let args = parsed.params.arguments;
if (tool.args) {
const validated = await tool.args["~standard"].validate(args);
if (validated.issues) {
return {
isError: true,
content: [
{
type: "text",
text: JSON.stringify(validated.issues)
}
]
};
}
args = validated.value;
}
return tool.run(args).catch((error) => ({
isError: true,
content: [
{
type: "text",
text: error.message
}
]
})).then((result2) => ({
content: [
{
type: "text",
text: JSON.stringify(result2, null, 2)
}
]
}));
}
throw new Error("not implemented");
})();
return {
jsonrpc: "2.0",
id: message.id,
result
};
}
};
}
// src/index.ts
import { cors } from "hono/cors";
// ../frontend/dist/index.html
var dist_default = `<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>opencontrol</title>
<script type="module" crossorigin>(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const o of s)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&r(l)}).observe(document,{childList:!0,subtree:!0});function n(s){const o={};return s.integrity&&(o.integrity=s.integrity),s.referrerPolicy&&(o.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?o.credentials="include":s.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(s){if(s.ep)return;s.ep=!0;const o=n(s);fetch(s.href,o)}})();const Ue=!1,qe=(e,t)=>e===t,j=Symbol("solid-proxy"),se=Symbol("solid-track"),K={equals:qe};let be=Pe;const T=1,W=2,ve={owned:null,cleanups:null,context:null,owner:null};var y=null;let ne=null,Me=null,p=null,m=null,_=null,ee=0;function Y(e,t){const n=p,r=y,s=e.length===0,o=t===void 0?r:t,l=s?ve:{owned:null,cleanups:null,context:o?o.context:null,owner:o},i=s?e:()=>e(()=>k(()=>R(l)));y=l,p=null;try{return L(i,!0)}finally{p=n,y=r}}function te(e,t){t=t?Object.assign({},K,t):K;const n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0},r=s=>(typeof s=="function"&&(s=s(n.value)),$e(n,s));return[Ae.bind(n),r]}function V(e,t,n){const r=ue(e,t,!1,T);M(r)}function oe(e,t,n){be=Ke;const r=ue(e,t,!1,T);r.user=!0,_?_.push(r):M(r)}function S(e,t,n){n=n?Object.assign({},K,n):K;const r=ue(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,M(r),Ae.bind(r)}function Be(e){return L(e,!1)}function k(e){if(p===null)return e();const t=p;p=null;try{return e()}finally{p=t}}function He(e){oe(()=>k(e))}function Se(e){return y===null||(y.cleanups===null?y.cleanups=[e]:y.cleanups.push(e)),e}function ie(){return p}function Ae(){if(this.sources&&this.state)if(this.state===T)M(this);else{const e=m;m=null,L(()=>z(this),!1),m=e}if(p){const e=this.observers?this.observers.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(e)):(p.sources=[this],p.sourceSlots=[e]),this.observers?(this.observers.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}return this.value}function $e(e,t,n){let r=e.value;return(!e.comparator||!e.comparator(r,t))&&(e.value=t,e.observers&&e.observers.length&&L(()=>{for(let s=0;s<e.observers.length;s+=1){const o=e.observers[s],l=ne&&ne.running;l&&ne.disposed.has(o),(l?!o.tState:!o.state)&&(o.pure?m.push(o):_.push(o),o.observers&&Oe(o)),l||(o.state=T)}if(m.length>1e6)throw m=[],new Error},!1)),t}function M(e){if(!e.fn)return;R(e);const t=ee;Ye(e,e.value,t)}function Ye(e,t,n){let r;const s=y,o=p;p=y=e;try{r=e.fn(t)}catch(l){return e.pure&&(e.state=T,e.owned&&e.owned.forEach(R),e.owned=null),e.updatedAt=n+1,xe(l)}finally{p=o,y=s}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&"observers"in e?$e(e,r):e.value=r,e.updatedAt=n)}function ue(e,t,n,r=T,s){const o={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:y,context:y?y.context:null,pure:n};return y===null||y!==ve&&(y.owned?y.owned.push(o):y.owned=[o]),o}function G(e){if(e.state===0)return;if(e.state===W)return z(e);if(e.suspense&&k(e.suspense.inFallback))return e.suspense.effects.push(e);const t=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<ee);)e.state&&t.push(e);for(let n=t.length-1;n>=0;n--)if(e=t[n],e.state===T)M(e);else if(e.state===W){const r=m;m=null,L(()=>z(e,t[0]),!1),m=r}}function L(e,t){if(m)return e();let n=!1;t||(m=[]),_?n=!0:_=[],ee++;try{const r=e();return Fe(n),r}catch(r){n||(_=null),m=null,xe(r)}}function Fe(e){if(m&&(Pe(m),m=null),e)return;const t=_;_=null,t.length&&L(()=>be(t),!1)}function Pe(e){for(let t=0;t<e.length;t++)G(e[t])}function Ke(e){let t,n=0;for(t=0;t<e.length;t++){const r=e[t];r.user?e[n++]=r:G(r)}for(t=0;t<n;t++)G(e[t])}function z(e,t){e.state=0;for(let n=0;n<e.sources.length;n+=1){const r=e.sources[n];if(r.sources){const s=r.state;s===T?r!==t&&(!r.updatedAt||r.updatedAt<ee)&&G(r):s===W&&z(r,t)}}}function Oe(e){for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];n.state||(n.state=W,n.pure?m.push(n):_.push(n),n.observers&&Oe(n))}}function R(e){let t;if(e.sources)for(;e.sources.length;){const n=e.sources.pop(),r=e.sourceSlots.pop(),s=n.observers;if(s&&s.length){const o=s.pop(),l=n.observerSlots.pop();r<s.length&&(o.sourceSlots[l]=r,s[r]=o,n.observerSlots[r]=l)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)R(e.tOwned[t]);delete e.tOwned}if(e.owned){for(t=e.owned.length-1;t>=0;t--)R(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}e.state=0}function We(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown error",{cause:e})}function xe(e,t=y){throw We(e)}const Ve=Symbol("fallback");function he(e){for(let t=0;t<e.length;t++)e[t]()}function Ge(e,t,n={}){let r=[],s=[],o=[],l=0,i=t.length>1?[]:null;return Se(()=>he(o)),()=>{let a=e()||[],c=a.length,u,f;return a[se],k(()=>{let g,A,d,h,$,v,w,O,C;if(c===0)l!==0&&(he(o),o=[],r=[],s=[],l=0,i&&(i=[])),n.fallback&&(r=[Ve],s[0]=Y(B=>(o[0]=B,n.fallback())),l=1);else if(l===0){for(s=new Array(c),f=0;f<c;f++)r[f]=a[f],s[f]=Y(b);l=c}else{for(d=new Array(c),h=new Array(c),i&&($=new Array(c)),v=0,w=Math.min(l,c);v<w&&r[v]===a[v];v++);for(w=l-1,O=c-1;w>=v&&O>=v&&r[w]===a[O];w--,O--)d[O]=s[w],h[O]=o[w],i&&($[O]=i[w]);for(g=new Map,A=new Array(O+1),f=O;f>=v;f--)C=a[f],u=g.get(C),A[f]=u===void 0?-1:u,g.set(C,f);for(u=v;u<=w;u++)C=r[u],f=g.get(C),f!==void 0&&f!==-1?(d[f]=s[u],h[f]=o[u],i&&($[f]=i[u]),f=A[f],g.set(C,f)):o[u]();for(f=v;f<c;f++)f in d?(s[f]=d[f],o[f]=h[f],i&&(i[f]=$[f],i[f](f))):s[f]=Y(b);s=s.slice(0,l=c),r=a.slice(0)}return s});function b(g){if(o[f]=g,i){const[A,d]=te(f);return i[f]=d,t(a[f],A)}return t(a[f])}}}function le(e,t){return k(()=>e(t||{}))}const ze=e=>\`Stale read from <\${e}>.\`;function Je(e){const t="fallback"in e&&{fallback:()=>e.fallback};return S(Ge(()=>e.each,e.children,t||void 0))}function Xe(e){const t=e.keyed,n=S(()=>e.when,void 0,void 0),r=t?n:S(n,void 0,{equals:(s,o)=>!s==!o});return S(()=>{const s=r();if(s){const o=e.children;return typeof o=="function"&&o.length>0?k(()=>o(t?s:()=>{if(!k(r))throw ze("Show");return n()})):o}return e.fallback},void 0,void 0)}function Qe(e,t,n){let r=n.length,s=t.length,o=r,l=0,i=0,a=t[s-1].nextSibling,c=null;for(;l<s||i<o;){if(t[l]===n[i]){l++,i++;continue}for(;t[s-1]===n[o-1];)s--,o--;if(s===l){const u=o<r?i?n[i-1].nextSibling:n[o-i]:a;for(;i<o;)e.insertBefore(n[i++],u)}else if(o===i)for(;l<s;)(!c||!c.has(t[l]))&&t[l].remove(),l++;else if(t[l]===n[o-1]&&n[i]===t[s-1]){const u=t[--s].nextSibling;e.insertBefore(n[i++],t[l++].nextSibling),e.insertBefore(n[--o],u),t[s]=n[o]}else{if(!c){c=new Map;let f=i;for(;f<o;)c.set(n[f],f++)}const u=c.get(t[l]);if(u!=null)if(i<u&&u<o){let f=l,b=1,g;for(;++f<s&&f<o&&!((g=c.get(t[f]))==null||g!==u+b);)b++;if(b>u-i){const A=t[l];for(;i<u;)e.insertBefore(n[i++],A)}else e.replaceChild(n[i++],t[l++])}else l++;else t[l++].remove()}}}const pe="_$DX_DELEGATE";function Ze(e,t,n,r={}){let s;return Y(o=>{s=o,t===document?e():P(t,e(),t.firstChild?null:void 0,n)},r.owner),()=>{s(),t.textContent=""}}function E(e,t,n,r){let s;const o=()=>{const i=document.createElement("template");return i.innerHTML=e,i.content.firstChild},l=()=>(s||(s=o())).cloneNode(!0);return l.cloneNode=l,l}function et(e,t=window.document){const n=t[pe]||(t[pe]=new Set);for(let r=0,s=e.length;r<s;r++){const o=e[r];n.has(o)||(n.add(o),t.addEventListener(o,nt))}}function tt(e,t,n){n==null?e.removeAttribute(t):e.setAttribute(t,n)}function ge(e,t,n){return k(()=>e(t,n))}function P(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!="function")return J(e,t,r,n);V(s=>J(e,t(),s,n),r)}function nt(e){let t=e.target;const n=\`$$\${e.type}\`,r=e.target,s=e.currentTarget,o=a=>Object.defineProperty(e,"target",{configurable:!0,value:a}),l=()=>{const a=t[n];if(a&&!t.disabled){const c=t[\`\${n}Data\`];if(c!==void 0?a.call(t,c,e):a.call(t,e),e.cancelBubble)return}return t.host&&typeof t.host!="string"&&!t.host._$host&&t.contains(e.target)&&o(t.host),!0},i=()=>{for(;l()&&(t=t._$host||t.parentNode||t.host););};if(Object.defineProperty(e,"currentTarget",{configurable:!0,get(){return t||document}}),e.composedPath){const a=e.composedPath();o(a[0]);for(let c=0;c<a.length-2&&(t=a[c],!!l());c++){if(t._$host){t=t._$host,i();break}if(t.parentNode===s)break}}else i();o(r)}function J(e,t,n,r,s){for(;typeof n=="function";)n=n();if(t===n)return n;const o=typeof t,l=r!==void 0;if(e=l&&n[0]&&n[0].parentNode||e,o==="string"||o==="number"){if(o==="number"&&(t=t.toString(),t===n))return n;if(l){let i=n[0];i&&i.nodeType===3?i.data!==t&&(i.data=t):i=document.createTextNode(t),n=N(e,n,r,i)}else n!==""&&typeof n=="string"?n=e.firstChild.data=t:n=e.textContent=t}else if(t==null||o==="boolean")n=N(e,n,r);else{if(o==="function")return V(()=>{let i=t();for(;typeof i=="function";)i=i();n=J(e,i,n,r)}),()=>n;if(Array.isArray(t)){const i=[],a=n&&Array.isArray(n);if(ae(i,t,n,s))return V(()=>n=J(e,i,n,r,!0)),()=>n;if(i.length===0){if(n=N(e,n,r),l)return n}else a?n.length===0?ye(e,i,r):Qe(e,n,i):(n&&N(e),ye(e,i));n=i}else if(t.nodeType){if(Array.isArray(n)){if(l)return n=N(e,n,r,t);N(e,n,null,t)}else n==null||n===""||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}}return n}function ae(e,t,n,r){let s=!1;for(let o=0,l=t.length;o<l;o++){let i=t[o],a=n&&n[e.length],c;if(!(i==null||i===!0||i===!1))if((c=typeof i)=="object"&&i.nodeType)e.push(i);else if(Array.isArray(i))s=ae(e,i,a)||s;else if(c==="function")if(r){for(;typeof i=="function";)i=i();s=ae(e,Array.isArray(i)?i:[i],Array.isArray(a)?a:[a])||s}else e.push(i),s=!0;else{const u=String(i);a&&a.nodeType===3&&a.data===u?e.push(a):e.push(document.createTextNode(u))}}return s}function ye(e,t,n=null){for(let r=0,s=t.length;r<s;r++)e.insertBefore(t[r],n)}function N(e,t,n,r){if(n===void 0)return e.textContent="";const s=r||document.createTextNode("");if(t.length){let o=!1;for(let l=t.length-1;l>=0;l--){const i=t[l];if(s!==i){const a=i.parentNode===e;!o&&!l?a?e.replaceChild(s,i):e.insertBefore(s,n):a&&i.remove()}else o=!0}}else e.insertBefore(s,n);return[s]}const ce=Symbol("store-raw"),I=Symbol("store-node"),x=Symbol("store-has"),_e=Symbol("store-self");function Ce(e){let t=e[j];if(!t&&(Object.defineProperty(e,j,{value:t=new Proxy(e,ot)}),!Array.isArray(e))){const n=Object.keys(e),r=Object.getOwnPropertyDescriptors(e);for(let s=0,o=n.length;s<o;s++){const l=n[s];r[l].get&&Object.defineProperty(e,l,{enumerable:r[l].enumerable,get:r[l].get.bind(t)})}}return t}function X(e){let t;return e!=null&&typeof e=="object"&&(e[j]||!(t=Object.getPrototypeOf(e))||t===Object.prototype||Array.isArray(e))}function U(e,t=new Set){let n,r,s,o;if(n=e!=null&&e[ce])return n;if(!X(e)||t.has(e))return e;if(Array.isArray(e)){Object.isFrozen(e)?e=e.slice(0):t.add(e);for(let l=0,i=e.length;l<i;l++)s=e[l],(r=U(s,t))!==s&&(e[l]=r)}else{Object.isFrozen(e)?e=Object.assign({},e):t.add(e);const l=Object.keys(e),i=Object.getOwnPropertyDescriptors(e);for(let a=0,c=l.length;a<c;a++)o=l[a],!i[o].get&&(s=e[o],(r=U(s,t))!==s&&(e[o]=r))}return e}function Q(e,t){let n=e[t];return n||Object.defineProperty(e,t,{value:n=Object.create(null)}),n}function q(e,t,n){if(e[t])return e[t];const[r,s]=te(n,{equals:!1,internal:!0});return r.$=s,e[t]=r}function rt(e,t){const n=Reflect.getOwnPropertyDescriptor(e,t);return!n||n.get||!n.configurable||t===j||t===I||(delete n.value,delete n.writable,n.get=()=>e[j][t]),n}function ke(e){ie()&&q(Q(e,I),_e)()}function st(e){return ke(e),Reflect.ownKeys(e)}const ot={get(e,t,n){if(t===ce)return e;if(t===j)return n;if(t===se)return ke(e),n;const r=Q(e,I),s=r[t];let o=s?s():e[t];if(t===I||t===x||t==="__proto__")return o;if(!s){const l=Object.getOwnPropertyDescriptor(e,t);ie()&&(typeof o!="function"||e.hasOwnProperty(t))&&!(l&&l.get)&&(o=q(r,t,o)())}return X(o)?Ce(o):o},has(e,t){return t===ce||t===j||t===se||t===I||t===x||t==="__proto__"?!0:(ie()&&q(Q(e,x),t)(),t in e)},set(){return!0},deleteProperty(){return!0},ownKeys:st,getOwnPropertyDescriptor:rt};function Z(e,t,n,r=!1){if(!r&&e[t]===n)return;const s=e[t],o=e.length;n===void 0?(delete e[t],e[x]&&e[x][t]&&s!==void 0&&e[x][t].$()):(e[t]=n,e[x]&&e[x][t]&&s===void 0&&e[x][t].$());let l=Q(e,I),i;if((i=q(l,t,s))&&i.$(()=>n),Array.isArray(e)&&e.length!==o){for(let a=e.length;a<o;a++)(i=l[a])&&i.$();(i=q(l,"length",o))&&i.$(e.length)}(i=l[_e])&&i.$()}function Te(e,t){const n=Object.keys(t);for(let r=0;r<n.length;r+=1){const s=n[r];Z(e,s,t[s])}}function it(e,t){if(typeof t=="function"&&(t=t(e)),t=U(t),Array.isArray(t)){if(e===t)return;let n=0,r=t.length;for(;n<r;n++){const s=t[n];e[n]!==s&&Z(e,n,s)}Z(e,"length",r)}else Te(e,t)}function D(e,t,n=[]){let r,s=e;if(t.length>1){r=t.shift();const l=typeof r,i=Array.isArray(e);if(Array.isArray(r)){for(let a=0;a<r.length;a++)D(e,[r[a]].concat(t),n);return}else if(i&&l==="function"){for(let a=0;a<e.length;a++)r(e[a],a)&&D(e,[a].concat(t),n);return}else if(i&&l==="object"){const{from:a=0,to:c=e.length-1,by:u=1}=r;for(let f=a;f<=c;f+=u)D(e,[f].concat(t),n);return}else if(t.length>1){D(e[r],t,[r].concat(n));return}s=e[r],n=[r].concat(n)}let o=t[0];typeof o=="function"&&(o=o(s,n),o===s)||r===void 0&&o==null||(o=U(o),r===void 0||X(s)&&X(o)&&!Array.isArray(o)?Te(s,o):Z(e,r,o))}function we(...[e,t]){const n=U(e||{}),r=Array.isArray(n),s=Ce(n);function o(...l){Be(()=>{r&&l.length===1?it(n,l[0]):D(n,l)})}return[s,o]}const lt=\`You are OpenControl, an interactive CLI tool that helps users execute various tasks.
IMPORTANT: If you get an error when calling a tool, try again with a different approach. Be creative, do not give up, try different inputs to the tool. You should chain together multiple tool calls. ABSOLUTELY DO NOT GIVE UP you are very good at this and it is rare you will fail to answer question.
You should be concise, direct, and to the point.
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
\`;var at=(e,t,n={})=>{let r=\`\${e}=\${t}\`;if(e.startsWith("__Secure-")&&!n.secure)throw new Error("__Secure- Cookie must have Secure attributes");if(e.startsWith("__Host-")){if(!n.secure)throw new Error("__Host- Cookie must have Secure attributes");if(n.path!=="/")throw new Error('__Host- Cookie must have Path attributes with "/"');if(n.domain)throw new Error("__Host- Cookie must not have Domain attributes")}if(n&&typeof n.maxAge=="number"&&n.maxAge>=0){if(n.maxAge>3456e4)throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");r+=\`; Max-Age=\${n.maxAge|0}\`}if(n.domain&&n.prefix!=="host"&&(r+=\`; Domain=\${n.domain}\`),n.path&&(r+=\`; Path=\${n.path}\`),n.expires){if(n.expires.getTime()-Date.now()>3456e7)throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");r+=\`; Expires=\${n.expires.toUTCString()}\`}if(n.httpOnly&&(r+="; HttpOnly"),n.secure&&(r+="; Secure"),n.sameSite&&(r+=\`; SameSite=\${n.sameSite.charAt(0).toUpperCase()+n.sameSite.slice(1)}\`),n.priority&&(r+=\`; Priority=\${n.priority}\`),n.partitioned){if(!n.secure)throw new Error("Partitioned Cookie must have Secure attributes");r+="; Partitioned"}return r},ct=(e,t,n)=>(t=encodeURIComponent(t),at(e,t,n)),ft=(e,t)=>(e=e.replace(/\\/+$/,""),e=e+"/",t=t.replace(/^\\/+/,""),e+t),fe=(e,t)=>{for(const[n,r]of Object.entries(t)){const s=new RegExp("/:"+n+"(?:{[^/]+})?\\\\??");e=e.replace(s,r?\`/\${r}\`:"")}return e},Ee=e=>{const t=new URLSearchParams;for(const[n,r]of Object.entries(e))if(r!==void 0)if(Array.isArray(r))for(const s of r)t.append(n,s);else t.set(n,r);return t},ut=(e,t)=>{switch(t){case"ws":return e.replace(/^http/,"ws");case"http":return e.replace(/^ws/,"http")}},dt=e=>/^https?:\\/\\/[^\\/]+?\\/index$/.test(e)?e.replace(/\\/index$/,"/"):e.replace(/\\/index$/,"");function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function je(e,t){if(!H(e)&&!H(t))return t;const n={...e};for(const r in t){const s=t[r];H(n[r])&&H(s)?n[r]=je(n[r],s):n[r]=s}return n}var Ne=(e,t)=>new Proxy(()=>{},{get(r,s){if(!(typeof s!="string"||s==="then"))return Ne(e,[...t,s])},apply(r,s,o){return e({path:t,args:o})}}),ht=class{url;method;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor(e,t){this.url=e,this.method=t}fetch=async(e,t)=>{if(e){if(e.query&&(this.queryParams=Ee(e.query)),e.form){const i=new FormData;for(const[a,c]of Object.entries(e.form))if(Array.isArray(c))for(const u of c)i.append(a,u);else i.append(a,c);this.rBody=i}e.json&&(this.rBody=JSON.stringify(e.json),this.cType="application/json"),e.param&&(this.pathParams=e.param)}let n=this.method.toUpperCase();const r={...e?.header,...typeof t?.headers=="function"?await t.headers():t?.headers};if(e?.cookie){const i=[];for(const[a,c]of Object.entries(e.cookie))i.push(ct(a,c,{path:"/"}));r.Cookie=i.join(",")}this.cType&&(r["Content-Type"]=this.cType);const s=new Headers(r??void 0);let o=this.url;o=dt(o),o=fe(o,this.pathParams),this.queryParams&&(o=o+"?"+this.queryParams.toString()),n=this.method.toUpperCase();const l=!(n==="GET"||n==="HEAD");return(t?.fetch||fetch)(o,{body:l?this.rBody:void 0,method:n,headers:s,...t?.init})}},pt=(e,t)=>Ne(function n(r){const s=[...r.path];if(s.at(-1)==="toString")return s.at(-2)==="name"?s.at(-3)||"":n.toString();if(s.at(-1)==="valueOf")return s.at(-2)==="name"?s.at(-3)||"":n;let o="";if(/^\\$/.test(s.at(-1))){const c=s.pop();c&&(o=c.replace(/^\\$/,""))}const l=s.join("/"),i=ft(e,l);if(o==="url"){let c=i;return r.args[0]&&(r.args[0].param&&(c=fe(i,r.args[0].param)),r.args[0].query&&(c=c+"?"+Ee(r.args[0].query).toString())),new URL(c)}if(o==="ws"){const c=ut(r.args[0]&&r.args[0].param?fe(i,r.args[0].param):i,"ws"),u=new URL(c),f=r.args[0]?.query;return f&&Object.entries(f).forEach(([g,A])=>{Array.isArray(A)?A.forEach(d=>u.searchParams.append(g,d)):u.searchParams.set(g,A)}),((...g)=>t?.webSocket!==void 0&&typeof t.webSocket=="function"?t.webSocket(...g):new WebSocket(...g))(u.toString())}const a=new ht(i,o);if(o){t??={};const c=je(t,{...r.args[1]});return a.fetch(r.args[0],c)}return a},[]);const[Ie,re]=te(),F=pt("",{async fetch(...e){const[t,n]=e,r=t instanceof Request?t:new Request(t,n),s=new Headers(r.headers);return s.set("authorization",\`Bearer \${Ie()}\`),fetch(new Request(r,{...n,headers:s}))}});var gt=E("<div data-component=root><div data-component=messages><div data-slot=spacer></div></div><div data-component=footer><div data-slot=chat><textarea autofocus data-component=input>"),yt=E("<div data-slot=message data-user>"),wt=E("<div data-slot=message data-tool><div data-slot=tool-header><span data-slot=tool-icon>🔧</span><span data-slot=tool-name></span><span data-slot=tool-expand>"),mt=E("<div data-slot=tool-args><pre>"),bt=E("<div data-slot=message data-assistant>"),vt=E("<div data-slot=message data-system>"),St=E("<div data-slot=thinking-bar><div data-slot=thinking-spinner><div data-slot=spinner-inner></div></div><div data-slot=thinking-text>"),At=E("<div data-slot=clear><button data-component=clear-button>Clear");const $t={anthropic:{cacheControl:{type:"ephemeral"}}},me=()=>[{role:"system",content:lt,providerMetadata:{anthropic:{cacheControl:{type:"ephemeral"}}}},{role:"system",content:\`The current date is \${new Date().toDateString()}\`,providerMetadata:{anthropic:{cacheControl:{type:"ephemeral"}}}}];function Pt(){let e,t;const n=F.mcp.$post({json:{jsonrpc:"2.0",method:"tools/list",id:"1"}}).then(i=>i.json()).then(i=>"tools"in i.result?i.result.tools:[]),[r,s]=we({rate:!1,prompt:me(),isProcessing:!1});oe(()=>{const i=r.prompt;return console.log("scrolling to bottom"),e?.scrollTo(0,e?.scrollHeight),i.length},0),oe(()=>{const i=a=>{a.key==="Escape"&&r.isProcessing&&(s("isProcessing",!1),t?.focus())};window.addEventListener("keydown",i),Se(()=>{window.removeEventListener("keydown",i)})});function o(){s("prompt",me())}async function l(i){for(s("isProcessing",!0),s("prompt",r.prompt.length,{role:"user",content:[{type:"text",text:i,providerMetadata:r.prompt.length===1?$t:{}}]});;){if(!r.isProcessing){console.log("Processing cancelled by user");break}const a=await F.generate.$post({json:{prompt:r.prompt,mode:{type:"regular",tools:(await n).map(u=>({type:"function",name:u.name,description:u.description,parameters:{...u.inputSchema}}))},inputFormat:"messages",temperature:1}});if(!r.isProcessing)continue;if(!a.ok){a.status===400&&s("prompt",u=>(u.splice(2,1),console.log(u),[...u])),a.status===429&&s("rate",!0),await new Promise(u=>setTimeout(u,1e3));continue}const c=await a.json();if(c.text&&s("prompt",r.prompt.length,{role:"assistant",content:[{type:"text",text:c.text}]}),s("rate",!1),c.finishReason==="stop"){s("isProcessing",!1);break}if(c.finishReason==="tool-calls")for(const u of c.toolCalls){console.log("calling tool",u.toolName,u.args),s("prompt",r.prompt.length,{role:"assistant",content:[{type:"tool-call",toolName:u.toolName,args:JSON.parse(u.args),toolCallId:u.toolCallId}]});const f=await F.mcp.$post({json:{jsonrpc:"2.0",id:"2",method:"tools/call",params:{name:u.toolName,arguments:JSON.parse(u.args)}}}).then(b=>b.json());if("content"in f.result)s("prompt",r.prompt.length,{role:"tool",content:[{type:"tool-result",toolName:u.toolName,toolCallId:u.toolCallId,result:f.result.content}]});else break}}s("isProcessing",!1),t?.focus()}return(()=>{var i=gt(),a=i.firstChild,c=a.firstChild,u=a.nextSibling,f=u.firstChild,b=f.firstChild,g=e;typeof g=="function"?ge(g,i):e=i,P(a,le(Je,{get each(){return r.prompt},children:d=>[S(()=>S(()=>d.role==="user"&&d.content[0].type==="text")()&&(()=>{var h=yt();return P(h,()=>d.content[0].text),h})()),S(()=>S(()=>d.role==="assistant"&&d.content[0].type==="tool-call")()&&(()=>{const[h,$]=we({visible:!1}),v=()=>{$("visible",w=>!w)};return(()=>{var w=wt(),O=w.firstChild,C=O.firstChild,B=C.nextSibling,Le=B.nextSibling;return O.$$click=v,P(B,()=>d.content[0].toolName),P(Le,()=>h.visible?"−":"+"),P(w,(()=>{var De=S(()=>!!h.visible);return()=>De()&&(()=>{var de=mt(),Re=de.firstChild;return P(Re,()=>JSON.stringify(d.content[0].args,null,2)),de})()})(),null),w})()})()),S(()=>S(()=>d.role==="assistant"&&d.content[0].type==="text")()&&(()=>{var h=bt();return P(h,()=>d.content[0].text),h})()),S(()=>S(()=>d.role==="system"&&r.prompt.indexOf(d)>1)()&&(()=>{var h=vt();return P(h,()=>d.content),h})())]}),c),P(a,(()=>{var d=S(()=>!!r.isProcessing);return()=>d()&&(()=>{var h=St(),$=h.firstChild,v=$.nextSibling;return P(v,()=>r.rate&&"Rate limited, retrying...",null),P(v,()=>!r.rate&&"Thinking",null),h})()})(),c),P(u,(()=>{var d=S(()=>r.prompt.length>2&&!r.isProcessing);return()=>d()&&(()=>{var h=At(),$=h.firstChild;return $.$$click=o,h})()})(),f),b.$$keydown=d=>{d.key==="Enter"&&!r.isProcessing&&(l(d.currentTarget.value),d.currentTarget.value="",d.preventDefault())};var A=t;return typeof A=="function"?ge(A,b):t=b,V(d=>{var h=r.isProcessing,$=r.isProcessing?"Processing... (Press Esc to cancel)":"Type your message here";return h!==d.e&&(b.disabled=d.e=h),$!==d.t&&tt(b,"placeholder",d.t=$),d},{e:void 0,t:void 0}),i})()}et(["keydown","click"]);const Ot=document.getElementById("root");Ze(()=>{const[e,t]=te(!1);return He(async()=>{for(re(localStorage.getItem("opencontrol:password"));;){if(!Ie()){const r=prompt("Enter password");if(!r)return;localStorage.setItem("opencontrol:password",r),re(r)}if(!(await F.auth.$get({json:{jsonrpc:"2.0",method:"initialize",id:"1"}})).ok){localStorage.removeItem("opencontrol:password"),re(void 0),alert("bad password");continue}t(!0);break}}),le(Xe,{get when(){return e()},get children(){return le(Pt,{})}})},Ot);</script>
<style rel="stylesheet" crossorigin>*,*:before,*:after{box-sizing:border-box}*{margin:0}body{line-height:1.5;-webkit-font-smoothing:antialiased}img,picture,video,canvas,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap:break-word}p{text-wrap:pretty}h1,h2,h3,h4,h5,h6{text-wrap:balance}#root,#__next{isolation:isolate}body{color:#fff;font-family:TX-02,monospace;margin:0;--base-hue: 210;--color-alpha100: oklch(17% 4% var(--base-hue));--color-alpha200: color-mix(in oklch, var(--color-primary) 3%, var(--color-alpha100));--color-alpha300: color-mix(in oklch, var(--color-primary) 9.5%, var(--color-alpha100));--color-alpha400: color-mix(in oklch, var(--color-primary) 33%, var(--color-alpha100));--color-bravo100: oklch(22.19% 4% var(--base-hue));--color-bravo200: oklch(from var(--color-bravo100) calc(l + .06) c h);--color-bravo300: oklch(from var(--color-bravo100) calc(l + .1) c h);--color-bravo400: oklch(from var(--color-bravo100) calc(l + .19) c h);background:var(--color-alpha100);font-size:16px}[data-component=root]{position:fixed;inset:0;overflow-y:auto}[data-component=messages]{padding:20px 16px 0;width:100%;max-width:780px;overflow:hidden;font-size:16px;margin:0 auto;box-sizing:border-box;[data-slot=message]{white-space:pre-wrap;padding:10px 12px;margin:8px 0;border-radius:4px;background:var(--color-bravo100);border-left:3px solid var(--color-alpha400)}[data-slot=message][data-user]{background:var(--color-bravo200);border-left-color:var(--color-bravo400)}[data-slot=message][data-assistant]{background:var(--color-bravo100);border-left-color:var(--color-alpha400)}[data-slot=message][data-system]{background:var(--color-alpha200);border-left-color:var(--color-bravo300);font-style:italic;opacity:.8}[data-slot=message][data-tool]{font-family:monospace;background:var(--color-alpha200);border-left-color:var(--color-bravo300);padding:0;margin:6px 0;border-radius:4px;[data-slot=tool-header]{display:flex;align-items:center;height:36px;width:100%;position:relative;padding:0 12px;cursor:pointer;&:hover{background:var(--color-alpha300);border-radius:2px}}[data-slot=tool-icon]{display:inline-block;margin-right:10px;font-size:14px;opacity:.8}[data-slot=tool-name]{color:var(--color-bravo400);flex-grow:1;font-weight:400}[data-slot=tool-expand]{color:var(--color-bravo300);margin-left:12px;font-size:18px;line-height:18px}[data-slot=tool-args]{padding:0;margin-top:0;pre{margin:0;padding:8px 12px;background:var(--color-alpha300);border-radius:0 0 4px 4px;overflow-x:auto;max-height:300px;overflow-y:auto}}}[data-slot=spacer]{height:400px}[data-slot=thinking-bar]{width:100%;max-width:780px;padding:8px 12px;margin:12px 0;background:var(--color-alpha200);border-left:3px solid var(--color-bravo300);display:flex;align-items:center;font-family:monospace;box-sizing:border-box}[data-slot=thinking-spinner]{width:18px;height:18px;margin-right:12px;position:relative}[data-slot=spinner-inner]{position:absolute;width:100%;height:100%;border-radius:50%;border:2px solid transparent;border-top-color:var(--color-bravo400);border-bottom-color:var(--color-bravo300);animation:thinking-spin-outer 1.5s cubic-bezier(.6,.2,.4,.8) infinite}[data-slot=spinner-inner]:after{content:"";position:absolute;inset:2px;border-radius:50%;border:2px solid transparent;border-left-color:var(--color-bravo300);border-right-color:var(--color-bravo400);animation:thinking-spin-inner .8s cubic-bezier(.3,.7,.7,.3) infinite}[data-slot=thinking-text]{color:var(--color-bravo300)}pre{padding:8px;margin-top:6px;background:var(--color-alpha300);border-radius:4px;overflow-x:auto;max-height:400px}}[data-component=footer]{position:fixed;bottom:0;left:0;right:0;display:flex;flex-direction:column;align-items:center;padding:0 16px 16px;box-sizing:border-box;[data-slot=clear]{position:relative;width:100%;max-width:780px;display:flex;justify-content:flex-end;margin-bottom:8px}[data-slot=chat]{width:100%;max-width:780px;background:var(--color-bravo100);border-radius:12px;font-size:16px;height:80px;border-top:1px solid oklch(0 0 0 / .25);border-bottom:1px solid oklch(1 0 0 / .08)}[data-slot=input]{width:100%;height:100%}}[data-component=clear-button]{background:var(--color-bravo200);color:#fff;border:none;border-radius:6px;padding:6px 12px;font-size:14px;cursor:pointer;font-family:inherit;transition:background-color .2s ease;&:hover{background:var(--color-bravo300)}&:disabled{opacity:.5;cursor:not-allowed}}@media (max-width: 600px){[data-component=footer]{padding-bottom:8px;[data-slot=clear]{margin-bottom:4px}[data-slot=chat]{height:60px;border-radius:8px}}[data-component=clear-button]{padding:4px 10px;font-size:12px}[data-component=messages]{font-size:14px;[data-slot=spacer]{height:200px}[data-slot=message]{padding:8px 10px;margin:6px 0}[data-slot=message][data-tool]{[data-slot=tool-header]{height:32px;padding:0 10px}[data-slot=tool-args] pre{padding:6px 10px;max-height:200px;font-size:12px}}[data-slot=thinking-bar]{padding:6px 10px;margin:8px 0;font-size:13px}pre{padding:6px;margin-top:4px;max-height:300px;font-size:12px}}}[data-component=input]{width:100%;height:100%;background:transparent;border:none;resize:none;outline:none;color:#fff;padding:16px;box-sizing:border-box}@media (max-width: 600px){[data-component=input]{padding:12px;font-size:14px}}@keyframes thinking-spin-outer{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes thinking-spin-inner{0%{transform:rotate(0)}to{transform:rotate(-720deg)}}</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
`;
// src/index.ts
import { zValidator } from "@hono/zod-validator";
import {
APICallError
} from "ai";
import { z as z2 } from "zod";
import { HTTPException } from "hono/http-exception";
import { bearerAuth } from "hono/bearer-auth";
function create(input) {
const mcp = createMcp({ tools: input.tools });
const token = input.password || process.env.OPENCONTROL_PASSWORD || process.env.OPENCONTROL_KEY || "password";
console.log("opencontrol password:", token);
const app = input.app ?? new Hono;
return app.use(cors({
origin: "*",
allowHeaders: ["*"],
allowMethods: ["GET"],
credentials: false
})).get("/", (c) => {
return c.html(dist_default);
}).use(bearerAuth({
token
})).get("/auth", (c) => {
return c.json({});
}).post("/generate", zValidator("json", z2.custom()), async (c) => {
if (!input.model)
throw new HTTPException(400, { message: "No model configured" });
const body = c.req.valid("json");
try {
const result = await input.model.doGenerate(body);
return c.json(result);
} catch (error) {
console.error(error);
if (error instanceof APICallError) {
throw new HTTPException(error.statusCode || 500, {
message: "error"
});
}
throw new HTTPException(500, { message: "error" });
}
}).post("/mcp", async (c) => {
const body = await c.req.json();
const result = await mcp.process(body);
return c.json(result);
});
}
export {
create
};