lsp-mcp: headless-editor MCP server over a language server
Effect 4 MCP server (stdio/HTTP) bridging one LSP process: on-demand document sync with LRU and disk change detection, push/pull diagnostics reconciliation, capability-gated tools, diagnostics resources, tests against a fixture server.
This commit is contained in:
19 files changed
+3693
-38
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# lsp-mcp
|
||||
|
||||
An MCP server that exposes one Language Server to agents as a headless editor.
|
||||
Effect 4 (`effect/unstable/ai` for MCP, `effect/unstable/cli` for the CLI) plus
|
||||
`vscode-languageserver-protocol` for LSP. TypeScript runs directly on Node 26
|
||||
(type stripping); there is no build step.
|
||||
|
||||
## Commands
|
||||
|
||||
- `pnpm tsc` — type-check (tsgo with the Effect language-service plugin)
|
||||
- `pnpm test` — vitest; integration tests spawn `test/fixtures/server.ts`, a real LSP server
|
||||
- `pnpm biome check --write --unsafe` — lint/format (run before committing; its rewrites are safe)
|
||||
- `node src/main.ts --help` — the CLI; smoke-test with `node src/main.ts --root <dir> -- <server> [args]`
|
||||
- Commit with `jj commit -m "..."`, never `git`
|
||||
|
||||
The shell may have an HTTP proxy configured; when curling the `--http` transport locally, pass `--noproxy '*'`.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
src/Model.ts agent-facing Schemas (1-based positions); drives tool input/output schemas
|
||||
src/Tools.ts Toolkit definition + handlers wiring + capability gating (supportedBy)
|
||||
src/Resources.ts MCP resources (lsp://server, lsp://diagnostics[/{file}]) and notifications
|
||||
src/Server.ts layer composition: LanguageServer → Documents+Diagnostics → transport → tools/resources
|
||||
src/main.ts CLI entry (Command/Flag/Argument), logs to stderr, NodeRuntime.runMain
|
||||
src/lsp/ the ONLY place vscode-* packages are used at runtime
|
||||
LanguageServer.ts spawn + JSON-RPC + initialize/shutdown; request() waits for $/progress idle and retries ContentModified
|
||||
Documents.ts on-demand didOpen, LRU via ScopedCache, disk change detection → didChange+didSave, applyEdit
|
||||
Diagnostics.ts publishDiagnostics accumulation; pull (textDocument/diagnostic) or settled push per doc version
|
||||
Editor.ts the operations = MCP tool handlers; LSP results → Model values
|
||||
test/fixtures/server.ts fixture language server (hover/definition/references/rename/symbols/TODO diagnostics)
|
||||
test/fixtures/workspace.ts temp workspace layer running the fixture server
|
||||
```
|
||||
|
||||
Rule: outside `src/lsp/`, `vscode-*` may only be imported as types.
|
||||
|
||||
## Design decisions worth knowing
|
||||
|
||||
- Positions handed to agents are 1-based; `Where` accepts `column` or a `symbol` name to find on the line.
|
||||
- Client capabilities are deliberately narrow (no dynamic registration, no watched files, UTF-16 only) so
|
||||
servers fall back to their own file watching. Settings come from `--settings` via `workspace/configuration`.
|
||||
- Tools are registered after LSP `initialize` so unsupported ones are never offered
|
||||
(`Tools.supportedBy`). `diagnostics` is always offered.
|
||||
- Tool failures are `LspError | DocumentError` (declared `failure` schema), so their messages reach the agent.
|
||||
- Optional fields in `Model` use a local `optional` helper that omits the key when encoding, because MCP
|
||||
`structuredContent` must be JSON (no `undefined`).
|
||||
- Diagnostics waiting: pull if the server supports it; otherwise wait for a publish for the doc's version
|
||||
plus a 250ms quiet period, bounded by 5s, memoized per (uri, version).
|
||||
- Tests that talk to the fixture server use `it.layer(..., { excludeTestServices: true })` so the real
|
||||
clock is used (Stream.debounce / timeouts would hang under TestClock).
|
||||
|
||||
## Status
|
||||
|
||||
Complete for the first release: 13 tools, 2 resources + 1 template, stdio and HTTP transports,
|
||||
verified against the fixture server and `typescript-language-server`.
|
||||
|
||||
Ideas not done: inlay hints, type hierarchy, semantic tokens, partial results, workspace/didChangeWatchedFiles
|
||||
when a server insists on it, restarting a crashed language server (currently requests fail with a clear
|
||||
`LspError` until the MCP client restarts the process).
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env node
|
||||
import{createRequire as e}from"node:module";import*as t from"node:child_process";import{spawn as n}from"node:child_process";import{Duplex as r,PassThrough as i,Readable as a}from"node:stream";import*as o from"node:http";import{createServer as s}from"node:http";import*as c from"node:crypto";import*as l from"node:fs";import*as u from"node:os";import*as d from"node:path";import*as f from"node:stream/promises";import{pipeline as p}from"node:stream/promises";import*as m from"node:zlib";import*as h from"node:url";import*as g from"node:readline";var _=Object.create,v=Object.defineProperty,ee=Object.getOwnPropertyDescriptor,y=Object.getOwnPropertyNames,te=Object.getPrototypeOf,b=Object.prototype.hasOwnProperty,ne=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},x=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),re=(e,t)=>{let n={};for(var r in e)v(n,r,{get:e[r],enumerable:!0});return t||v(n,Symbol.toStringTag,{value:`Module`}),n},ie=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=y(t),a=0,o=i.length,s;a<o;a++)s=i[a],!b.call(e,s)&&s!==n&&v(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=ee(t,s))||r.enumerable});return e},ae=(e,t,n)=>(n=e==null?{}:_(te(e)),ie(t||!e||!e.__esModule||!b.call(e,`default`)?v(n,`default`,{value:e,enumerable:!0}):n,e)),oe=e=>b.call(e,`module.exports`)?e[`module.exports`]:ie(v({},`__esModule`,{value:!0}),e),se=/* @__PURE__ */ e(import.meta.url);const S=(e,t)=>{switch(t.length){case 0:return e;case 1:return t[0](e);case 2:return t[1](t[0](e));case 3:return t[2](t[1](t[0](e)));case 4:return t[3](t[2](t[1](t[0](e))));case 5:return t[4](t[3](t[2](t[1](t[0](e)))));case 6:return t[5](t[4](t[3](t[2](t[1](t[0](e))))));case 7:return t[6](t[5](t[4](t[3](t[2](t[1](t[0](e)))))));case 8:return t[7](t[6](t[5](t[4](t[3](t[2](t[1](t[0](e))))))));case 9:return t[8](t[7](t[6](t[5](t[4](t[3](t[2](t[1](t[0](e)))))))));default:{let n=e;for(let e=0,r=t.length;e<r;e++)n=t[e](n);return n}}},ce={pipe(){return S(this,arguments)}},le=/*#__PURE__*/ function(){function e(){}return e.prototype=ce,e}(),C=function(e,t){if(typeof e==`function`)return function(){return e(arguments)?t.apply(this,arguments):e=>t(e,...arguments)};switch(e){case 0:case 1:throw RangeError(`Invalid arity ${e}`);case 2:return function(e,n){return arguments.length>=2?t(e,n):function(n){return t(n,e)}};case 3:return function(e,n,r){return arguments.length>=3?t(e,n,r):function(r){return t(r,e,n)}};default:return function(){if(arguments.length>=e)return t.apply(this,arguments);let n=arguments;return function(e){return t(e,...n)}}}},w=e=>e,T=e=>()=>e,ue=/*#__PURE__*/ T(!0),de=/*#__PURE__*/ T(!1),fe=/*#__PURE__*/ T(void 0),pe=fe,me=/*#__PURE__*/ C(2,(e,t)=>n=>t(e(n)));function he(e,...t){return S(e,t)}function ge(e,t,n,r,i,a,o,s,c){switch(arguments.length){case 1:return e;case 2:return function(){return t(e.apply(this,arguments))};case 3:return function(){return n(t(e.apply(this,arguments)))};case 4:return function(){return r(n(t(e.apply(this,arguments))))};case 5:return function(){return i(r(n(t(e.apply(this,arguments)))))};case 6:return function(){return a(i(r(n(t(e.apply(this,arguments))))))};case 7:return function(){return o(a(i(r(n(t(e.apply(this,arguments)))))))};case 8:return function(){return s(o(a(i(r(n(t(e.apply(this,arguments))))))))};case 9:return function(){return c(s(o(a(i(r(n(t(e.apply(this,arguments)))))))))}}}function _e(e){let t=/* @__PURE__ */ new WeakMap;return n=>{let r=t.get(n);if(r!==void 0)return r;let i=e(n);return t.set(n,i),i}}function ve(e){let t=/* @__PURE__ */ new WeakMap;return n=>{let r=t.get(n);if(r!==void 0)return r;let i=e(n);return t.set(n,i),t.set(i,i),i}}const ye=e=>{let t=new Set(Reflect.ownKeys(e));if(e.constructor===Object)return t;e instanceof Error&&t.delete(`stack`);let n=Object.getPrototypeOf(e),r=n;for(;r!==null&&r!==Object.prototype;){let e=Reflect.ownKeys(r);for(let n=0;n<e.length;n++)t.add(e[n]);r=Object.getPrototypeOf(r)}return t.has(`constructor`)&&typeof e.constructor==`function`&&n===e.constructor.prototype&&t.delete(`constructor`),t},be=/*#__PURE__*/ new WeakSet;function xe(e){return typeof e==`string`}function Se(e){return typeof e==`number`}function Ce(e){return typeof e==`boolean`}function we(e){return typeof e==`bigint`}function Te(e){return typeof e==`symbol`}function Ee(e){return xe(e)||Se(e)||Te(e)}function De(e){return typeof e==`function`}function Oe(e){return e===void 0}function ke(e){return e!==void 0}function Ae(e){return e!==null}function je(e){return e==null}function Me(e){return e!=null}function Ne(e){return!1}function Pe(e){return!0}function Fe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ie(e){return typeof e==`object`&&!!e||De(e)}const E=/*#__PURE__*/ C(2,(e,t)=>Ie(e)&&t in e),Le=/*#__PURE__*/ C(2,(e,t)=>E(e,`_tag`)&&e._tag===t);function Re(e){return e instanceof Error}function ze(e){return E(e,Symbol.iterator)||xe(e)}const Be=`~effect/Hash`,Ve=e=>{switch(typeof e){case`number`:return Ke(e);case`bi
Line truncated
|
||||
`+a(n+1))}\n${a(n)}]`;else if(e instanceof Date)l=Mt(e);else if(!t?.ignoreToString&&E(e,`toString`)&&typeof e.toString==`function`&&e.toString!==Object.prototype.toString&&e.toString!==Array.prototype.toString){let t=Nt(e);l=e instanceof Error&&e.cause!==void 0?`${t} (cause: ${c(e.cause,n)})`:t}else if(Symbol.iterator in e)l=`${e.constructor.name}(${c(Array.from(e),n)})`;else{let t=s(e);if(!i||t.length<=1){let r=`{${t.map(t=>`${At(t)}:${c(Pt(e,t),n)}`).join(`,`)}}`;l=o(e,r)}else{let r=`{\n${t.map(t=>`${a(n+1)}${At(t)}: ${c(Pt(e,t),n+1)}`).join(`,
|
||||
`)}\n${a(n)}}`;l=o(e,r)}}return r.delete(e),l}return String(e)}return c(e,0)}const kt=`[Circular]`;function At(e){return typeof e==`string`?JSON.stringify(e):String(e)}function jt(e){return e.map(e=>`[${At(e)}]`).join(``)}function Mt(e){try{return e.toISOString()}catch{return`Invalid Date`}}function Nt(e){try{let t=e.toString();return typeof t==`string`?t:String(t)}catch{return`[toString threw]`}}function Pt(e,t){try{return e[t]}catch{return`[property access threw]`}}function Ft(e,t){let n=[];return JSON.stringify(e,function(e,t){let r=Object.getOwnPropertyDescriptor(this,e)?.value,i=E(r,xt)?Ct(r):Ct(t);if(typeof i==`bigint`)return Ot(i);if(typeof i!=`object`||!i)return i;for(;n.length>0&&n[n.length-1]!==this;)n.pop();if(!n.includes(i))return n.push(i),i},t?.space)??`null`}const It=/*#__PURE__*/ Symbol.for(`nodejs.util.inspect.custom`),Lt=e=>{try{return e=Ct(e),E(e,`toJSON`)&&De(e.toJSON)&&e.toJSON.length===0?e.toJSON():Array.isArray(e)?e.map(Lt):e}catch{return`[toJSON threw]`}},Rt=(e,t=2)=>{if(typeof e==`string`)return e;try{return typeof e==`object`?Ft(e,{space:t}):Ot(e,{space:t})}catch{return String(e)}},zt={toJSON(){return Lt(this)},[It](){return this.toJSON()},toString(){return Ot(this.toJSON())}};var Bt=class{[It](){return this.toJSON()}toString(){return Ot(this.toJSON())}};const Vt=/*#__PURE__*/ (()=>{let e=Object.getOwnPropertyDescriptor(Error,`stackTraceLimit`);return e===void 0?Object.isExtensible(Error):Object.hasOwn(e,`writable`)?e.writable===!0:e.set!==void 0})(),Ht=()=>Error.stackTraceLimit,Ut=e=>{Vt&&(Error.stackTraceLimit=e)};var Wt=class e{called=!1;self;constructor(e){this.self=e}next(e){return this.called?{value:e,done:!0}:(this.called=!0,{value:this.self,done:!1})}[Symbol.iterator](){return new e(this.self)}};const Gt=/*#__PURE__*/ (()=>{let e=`~effect/Utils/internal`,t={[e]:e=>e()},n={[e]:e=>{try{return e()}finally{}}};return Ht()!==0&&t[e](()=>(/* @__PURE__ */ Error()).stack)?.includes(e)===!0?t[e]:n[e]})();function Kt(e,t,n){t===`__proto__`?Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0}):e[t]=n}function qt(e,t){for(let n of Reflect.ownKeys(t))Object.prototype.propertyIsEnumerable.call(t,n)&&Kt(e,n,t[n])}const Jt=`~effect/Effect`,Yt=`~effect/Exit`,Xt={_A:w,_E:w,_R:w},Zt=`${Jt}/identifier`,Qt=`${Jt}/args`,$t=`${Jt}/evaluate`,en=`${Jt}/successCont`,tn=`${Jt}/failureCont`,nn=`${Jt}/ensureCont`,rn=/*#__PURE__*/ Symbol.for(`effect/Effect/Yield`),an={pipe(){return S(this,arguments)},toJSON(){return{...this}},toString(){return Ot(this.toJSON(),{ignoreToString:!0,space:2})},[It](){return this.toJSON()}},on={[Jt]:Xt,...an,[Symbol.iterator](){return new Wt(this)},toJSON(){return{_id:`Effect`,op:this[Zt],...Qt in this?{args:this[Qt]}:void 0}}},sn=e=>E(e,Jt),cn=e=>E(e,Yt),ln=`~effect/Cause`,un=`~effect/Cause/Reason`,dn=e=>E(e,ln),fn=e=>E(e,un);var pn=class{constructor(e){this[ln]=ln,this.reasons=e}pipe(){return S(this,arguments)}toJSON(){return{_id:`Cause`,failures:this.reasons.map(e=>e.toJSON())}}toString(){return`Cause(${Ot(this.reasons)})`}[It](){return this.toJSON()}[it](e){return dn(e)&&this.reasons.length===e.reasons.length&&this.reasons.every((t,n)=>at(t,e.reasons[n]))}[Be](){return Ze(this.reasons)}};const mn=/*#__PURE__*/ new WeakMap;var hn=class{[un];annotations;_tag;constructor(e,t,n){if(this[un]=un,this._tag=e,t!==gn&&typeof n==`object`&&n&&t.size>0){let e=mn.get(n);e&&(t=new Map([...e,...t])),mn.set(n,t)}this.annotations=t}annotate(e,t){if(e.mapUnsafe.size===0)return this;let n=new Map(this.annotations);e.mapUnsafe.forEach((e,r)=>{t?.overwrite!==!0&&n.has(r)||n.set(r,e)});let r=Object.assign(Object.create(Object.getPrototypeOf(this)),this);return r.annotations=n,r}pipe(){return S(this,arguments)}toString(){return Ot(this)}[It](){return this.toString()}};const gn=/*#__PURE__*/ new Map;var _n=class extends hn{constructor(e,t=gn){super(`Fail`,t,e),this.error=e}toString(){return`Fail(${Ot(this.error)})`}toJSON(){return{_tag:`Fail`,error:this.error}}[it](e){return wn(e)&&at(this.error,e.error)&&at(this.annotations,e.annotations)}[Be](){return Ue(qe(this._tag))(Ue(Ve(this.error))(Ve(this.annotations)))}};const vn=e=>new pn(e),yn=/*#__PURE__*/ new pn([]),bn=e=>new pn([new _n(e)]);var xn=class extends hn{constructor(e,t=gn){super(`Die`,t,e),this.defect=e}toString(){return`Die(${Ot(this.defect)})`}toJSON(){return{_tag:`Die`,defect:this.defect}}[it](e){return Tn(e)&&at(this.defect,e.defect)&&at(this.annotations,e.annotations)}[Be](){return Ue(qe(this._tag))(Ue(Ve(this.defect))(Ve(this.annotations)))}};const Sn=e=>new pn([new xn(e)]),Cn=/*#__PURE__*/ C(e=>dn(e[0]),(e,t,n)=>t.mapUnsafe.size===0?e:new pn(e.reasons.map(e=>e.annotate(t,n)))),wn=e=>e._tag===`Fail`,Tn=e=>e._tag===`Die`,En=e=>e._tag===`Interrupt`;function Dn(e){return In(`Effect.evaluate: Not implemented`)}const On=e=>({...on,[Zt]:e.op,[$t]:e[$t]??Dn,[en]:e[en],[tn]:e[tn],[nn]:e[nn]}),kn=e=>{let t=On(e),n=function(e){this[Qt]=e};return n.prototype=t,function(e){return new n(e)}},An=e=>{let t={[Yt]:Yt,_taLine truncated
|
||||
/* v8 ignore next 2 */
|
||||
_A:e=>e,_E:e=>e},...an,[Symbol.iterator](){return new Wt(this)}},gr=/*#__PURE__*/ Object.assign(/*#__PURE__*/ Object.create(hr),{_tag:`Success`,_op:`Success`,[it](e){return vr(e)&&br(e)&&at(this.success,e.success)},[Be](){return Ue(Ve(this._tag))(Ve(this.success))},toString(){return`success(${Ot(this.success)})`},toJSON(){return{_id:`Result`,_tag:this._tag,value:Lt(this.success)}}}),_r=/*#__PURE__*/ Object.assign(/*#__PURE__*/ Object.create(hr),{_tag:`Failure`,_op:`Failure`,[it](e){return vr(e)&&yr(e)&&at(this.failure,e.failure)},[Be](){return Ue(Ve(this._tag))(Ve(this.failure))},toString(){return`failure(${Ot(this.failure)})`},toJSON(){return{_id:`Result`,_tag:this._tag,failure:Lt(this.failure)}}}),vr=e=>E(e,mr),yr=e=>e._tag===`Failure`,br=e=>e._tag===`Success`,xr=function(e){this.failure=e};xr.prototype=_r;const Sr=e=>new xr(e),Cr=function(e){this.success=e};Cr.prototype=gr;const wr=e=>new Cr(e);function Tr(e){return(t,n)=>t===n?0:e(t,n)}const Er=/*#__PURE__*/ Tr((e,t)=>globalThis.Number.isNaN(e)&&globalThis.Number.isNaN(t)?0:globalThis.Number.isNaN(e)?-1:globalThis.Number.isNaN(t)?1:e<t?-1:1),Dr=/*#__PURE__*/ C(2,(e,t)=>Tr((n,r)=>e(t(n),t(r)))),Or=e=>C(2,(t,n)=>e(t,n)===-1),kr=e=>C(2,(t,n)=>e(t,n)===1),Ar=e=>C(2,(t,n)=>e(t,n)!==1),jr=e=>C(2,(t,n)=>e(t,n)!==-1),D=()=>dr,O=pr,Mr=cr,Nr=lr,Pr=ur,Fr=/*#__PURE__*/ C(2,(e,{onNone:t,onSome:n})=>Nr(e)?t():n(e.value)),Ir=/*#__PURE__*/ C(2,(e,t)=>Nr(e)?t():e.value),Lr=e=>e==null?D():O(e),Rr=e=>e===void 0?D():O(e),zr=/*#__PURE__*/ Ir(fe),Br=e=>(...t)=>{try{return O(e(...t))}catch{return D()}},Vr=/*#__PURE__*/ C(2,(e,t)=>Nr(e)?D():O(t(e.value))),Hr=/*#__PURE__*/ C(2,(e,t)=>Nr(e)?D():t(e.value)),Ur=/*#__PURE__*/ C(2,(e,t)=>Nr(e)?D():t(e.value)?O(e.value):D()),Wr=/*#__PURE__*/ C(2,(e,t)=>!Nr(e)&&t(e.value)),Gr=wr,Kr=Sr,qr=e=>{if(De(e))try{return Gr(e())}catch(e){return Kr(e)}try{return Gr(e.try())}catch(t){return Kr(e.catch(t))}},Jr=vr,Yr=yr,Xr=br,Zr=/*#__PURE__*/ C(2,(e,t)=>Yr(e)?Kr(t(e.failure)):e),Qr=/*#__PURE__*/ C(2,(e,t)=>Xr(e)?Gr(t(e.success)):e),$r=/*#__PURE__*/ C(2,(e,{onFailure:t,onSuccess:n})=>Yr(e)?t(e.failure):n(e.success)),ei=/*#__PURE__*/ (/* @__PURE__ */ C(2,(e,t)=>{if(Xr(e))return e.success;throw t(e.failure)}))(w),ti=/*#__PURE__*/ C(2,(e,t)=>Yr(e)?Kr(e.failure):t(e.success)),ni=$n,ri=e=>{let t=e[Symbol.iterator]().next();if(t.done)throw Error(`headUnsafe: empty iterable`);return t.value},ii=/*#__PURE__*/ C(2,(e,t)=>{let n=0;for(let r of e){let e=t(r,n);if(Ce(e)){if(e)return O(r)}else if(Pr(e))return e;n++}return D()}),ai={[Symbol.iterator](){return oi}},oi={next(){return{done:!0,value:void 0}}},si=()=>ai,ci=e=>Object.keys(e).length===0,li=/*#__PURE__*/ C(2,(e,t)=>Object.hasOwn(e,t)),ui=/*#__PURE__*/ C(2,(e,t)=>{let n={...e};for(let r of di(e))Kt(n,r,t(e[r],r));return n}),di=e=>Object.keys(e),fi=e=>C(2,(t,n)=>{for(let r of di(t))if(!li(n,r)||!e(t[r],n[r]))return!1;return!0}),pi=e=>{let t=fi(e);return(e,n)=>t(e,n)&&t(n,e)},mi=globalThis.Array,hi=e=>mi.isArray(e)?e:mi.from(e),gi=/*#__PURE__*/ C(2,(e,{onEmpty:t,onNonEmpty:n})=>yi(e)?n(e):t()),_i=/*#__PURE__*/ C(2,(e,t)=>[...e,t]);mi.isArray;const vi=tr,yi=tr;function bi(e,t){return!Number.isFinite(e)||e<0||e>=t.length}const xi=/*#__PURE__*/ C(2,(e,t)=>{let n=Math.floor(t);if(bi(n,e))throw Error(`Index out of bounds: ${n}`);return e[n]}),Si=e=>yi(e)?O(Ci(e)):D(),Ci=e=>e[e.length-1],wi=(e,t)=>Math.min(nr(e),t),Ti=/*#__PURE__*/ C(2,(e,t)=>{let n=hi(e);return n.slice(0,wi(t,n.length))}),Ei=/*#__PURE__*/ C(2,(e,t)=>{let n=0;for(let r of e){if(t(r,n))return O(n);n++}return D()}),Di=ii,Oi=/*#__PURE__*/ C(2,(e,t)=>{let n=hi(e);for(let e=n.length-1;e>=0;e--){let r=n[e],i=t(r,e);if(typeof i==`boolean`){if(i)return O(r)}else if(Pr(i))return i}return D()}),ki=e=>mi.from(e).reverse(),Ai=()=>[],ji=e=>[e],Mi=/*#__PURE__*/ C(2,(e,t)=>e.map(t)),Ni=/*#__PURE__*/ C(3,(e,t,n)=>hi(e).reduce((e,t,r)=>n(e,t,r),t)),Pi=er,Fi=e=>On({op:e.label,[$t]:e.evaluate}),Ii=`~effect/Context/Service`,Li=function(){function e(){}let t=e;Object.setPrototypeOf(t,Ri);let n=(e,n)=>(t.key=e,n?.defaultValue&&(t[Bi]=Bi,t.defaultValue=n.defaultValue),n?.make&&(t.make=n.make),n?.fiberCached&&zi.add(e),t);return arguments.length>0?n(arguments[0],arguments[1]):n},Ri={[Ii]:Ii,.../*#__PURE__*/ Fi({label:`Service`,evaluate(e){return jn(sa(e.context,this))}}),toJSON(){return{_id:`Service`,key:this.key}},of(e){return e},context(e){return ta(this,e)},use(e){return Ln(t=>e(sa(t.context,this)))},useSync(e){return Ln(t=>jn(e(sa(t.context,this))))}},zi=/*#__PURE__*/ new Set,Bi=`~effect/Context/Reference`,Vi=`~effect/Context`,Hi=(e,t,n,r)=>{let i=Object.create(Yi);return i.cacheRoot=e??i,i.base=t,i.overlay=n,i.depth=r,i._flat=void 0,i.baseHits=0,i},Ui=(e,t)=>{t&&(Ui(e,t.parent),e.set(t.key,t.value))},Wi=e=>{if(e._flat)return e._flat;if(!e.overlay)return e._flat=e.base;let t=new Map(e.base);return Ui(t,e.overlay),e._flat=t},Gi=(e,t)=>{let n=new Map(e.mapUnsafe);return t(n),Ji(n)},Ki=/*#__PURE__*/ Symbol(),qi=(e,t)=>{let n=e;for(let e=n.overlay;e;e=e.parent)if(e.keLine truncated
|
||||
`);e.splice(1,3),t.stack=e.join(`
|
||||
`)}return t},da=/*#__PURE__*/ C(2,(e,t)=>{let n=qi(e,t.key);return n===Ki?Qi(t)?O(la(t)):D():O(n)}),fa=/*#__PURE__*/ C(2,(e,t)=>e.mapUnsafe.size===0?t:t.mapUnsafe.size===0?e:Gi(e,e=>t.mapUnsafe.forEach((t,n)=>e.set(n,t)))),pa=(...e)=>{let t=/* @__PURE__ */ new Map;for(let n=0;n<e.length;n++)e[n].mapUnsafe.forEach((e,n)=>{t.set(n,e)});return Ji(t)},ma=Li,ha=`~effect/Duration`,ga=/*#__PURE__*/ BigInt(0),_a=/*#__PURE__*/ BigInt(1),va=/*#__PURE__*/ BigInt(2),ya=/*#__PURE__*/ BigInt(10),ba=/*#__PURE__*/ BigInt(24),xa=/*#__PURE__*/ BigInt(60),Sa=/*#__PURE__*/ BigInt(1e3),Ca=/*#__PURE__*/ BigInt(1e6),wa=e=>BigInt(e<0?Math.ceil(e-.5):Math.floor(e+.5)),Ta=e=>wa(e*1e6),Ea=(e,t)=>{let n=e.indexOf(`.`);if(n===-1)return BigInt(e)*t;let r=e[0]===`-`,i=e.slice(n+1),a=ya**BigInt(i.length),o=(BigInt(e.slice(+!!r,n))*a+BigInt(i))*t,s=o/a+(o%a*va>=a?_a:ga);return r?-s:s},Da=/^(-?\d+(?:\.\d+)?)\s+(nanos?|micros?|millis?|seconds?|minutes?|hours?|days?|weeks?)$/,Oa=e=>{switch(typeof e){case`number`:return Wa(e);case`bigint`:return Ua(e);case`string`:{if(e===`Infinity`)return Va;if(e===`-Infinity`)return Ha;let t=Da.exec(e);if(!t)break;let[n,r,i]=t;if(i===`nano`||i===`nanos`)return Ua(Ea(r,_a));if(i===`micro`||i===`micros`)return Ua(Ea(r,Sa));let a=Number(r);switch(i){case`milli`:case`millis`:return Wa(a);case`second`:case`seconds`:return Ga(a);case`minute`:case`minutes`:return Ka(a);case`hour`:case`hours`:return qa(a);case`day`:case`days`:return Ja(a);case`week`:case`weeks`:return Ya(a)}break}case`object`:{if(e===null)break;if(ha in e)return e;if(Array.isArray(e))return e.length!==2||!e.every(Se)?ka(e):Number.isNaN(e[0])||Number.isNaN(e[1])?Ba:e[0]===-1/0||e[1]===-1/0?Ha:e[0]===1/0||e[1]===1/0?Va:Pa(wa(e[0]*1e9+e[1]));let t=e,n=0;return t.weeks&&(n+=t.weeks*6048e5),t.days&&(n+=t.days*864e5),t.hours&&(n+=t.hours*36e5),t.minutes&&(n+=t.minutes*6e4),t.seconds&&(n+=t.seconds*1e3),t.milliseconds&&(n+=t.milliseconds),!t.microseconds&&!t.nanoseconds?Pa(n):Pa(wa(n*1e6+(t.microseconds??0)*1e3+(t.nanoseconds??0)))}}return ka(e)},ka=e=>{throw Error(`Invalid Input: ${e}`)},Aa={_tag:`Millis`,millis:0},ja={_tag:`Infinity`},Ma={_tag:`NegativeInfinity`},Na={[ha]:ha,[Be](){switch(this.value._tag){case`Millis`:{let e=this.value.millis*1e6;return Number.isFinite(e)?Ve(wa(e)):Ke(this.value.millis)}case`Nanos`:return Ve(this.value.nanos);default:return Ye(this.value)}},[it](e){return Fa(e)&&io(this,e)},toString(){switch(this.value._tag){case`Infinity`:return`Infinity`;case`NegativeInfinity`:return`-Infinity`;case`Nanos`:return`${this.value.nanos} nanos`;case`Millis`:return`${this.value.millis} millis`}},toJSON(){switch(this.value._tag){case`Millis`:return{_id:`Duration`,_tag:`Millis`,millis:this.value.millis};case`Nanos`:return{_id:`Duration`,_tag:`Nanos`,nanos:String(this.value.nanos)};case`Infinity`:return{_id:`Duration`,_tag:`Infinity`};case`NegativeInfinity`:return{_id:`Duration`,_tag:`NegativeInfinity`}}},[It](){return this.toJSON()},pipe(){return S(this,arguments)}},Pa=e=>{let t=Object.create(Na);return t.value=typeof e==`number`?isNaN(e)||e===0||Object.is(e,-0)?Aa:Number.isFinite(e)?Number.isInteger(e)?{_tag:`Millis`,millis:e}:{_tag:`Nanos`,nanos:Ta(e)}:e>0?ja:Ma:e===ga?Aa:{_tag:`Nanos`,nanos:e},t},Fa=e=>E(e,ha),Ia=e=>e.value._tag!==`Infinity`&&e.value._tag!==`NegativeInfinity`,La=e=>{switch(e.value._tag){case`Millis`:return e.value.millis===0;case`Nanos`:return e.value.nanos===ga;case`Infinity`:case`NegativeInfinity`:return!1}},Ra=e=>{switch(e.value._tag){case`Millis`:return e.value.millis<0;case`Nanos`:return e.value.nanos<ga;case`NegativeInfinity`:return!0;case`Infinity`:return!1}},za=e=>{switch(e.value._tag){case`Infinity`:case`NegativeInfinity`:return Va;case`Millis`:return e.value.millis<0?Pa(-e.value.millis):e;case`Nanos`:return e.value.nanos<ga?Pa(-e.value.nanos):e}},Ba=/*#__PURE__*/ Pa(0),Va=/*#__PURE__*/ Pa(1/0),Ha=/*#__PURE__*/ Pa(-1/0),Ua=e=>Pa(e),Wa=e=>Pa(e),Ga=e=>Pa(e*1e3),Ka=e=>Pa(e*6e4),qa=e=>Pa(e*36e5),Ja=e=>Pa(e*864e5),Ya=e=>Pa(e*6048e5),Xa=e=>$a(Oa(e),{onMillis:w,onNanos:e=>Number(e)/1e6,onInfinity:()=>1/0,onNegativeInfinity:()=>-1/0}),Za=e=>$a(Oa(e),{onMillis:e=>e/1e3,onNanos:e=>Number(e)/1e9,onInfinity:()=>1/0,onNegativeInfinity:()=>-1/0}),Qa=e=>{let t=Oa(e);switch(t.value._tag){case`Infinity`:case`NegativeInfinity`:throw Error(`Cannot convert infinite duration to nanos`);case`Nanos`:return t.value.nanos;case`Millis`:return Ta(t.value.millis)}},$a=/*#__PURE__*/ C(2,(e,t)=>{switch(e.value._tag){case`Millis`:return t.onMillis(e.value.millis);case`Nanos`:return t.onNanos(e.value.nanos);case`Infinity`:return t.onInfinity();case`NegativeInfinity`:return(t.onNegativeInfinity??t.onInfinity)()}}),eo=/*#__PURE__*/ C(3,(e,t,n)=>e.value._tag===`Infinity`||e.value._tag===`NegativeInfinity`||t.value._tag===`Infinity`||t.value._tag===`NegativeInfinity`?n.onInfinity(e,t):e.value._tag===`Millis`?t.value._tag===`Millis`?n.onMillis(e.value.millis,t.value.millis):n.onNanos(Qa(e),t.value.nanos):n.onNanos(e.value.nanos,Qa(t))),to=/*#__PURE__
Line truncated
|
||||
`);if(i[e]!==void 0)return n=i[e].trim(),n}},ls=/*#__PURE__*/ cs(3);var us=class extends hn{constructor(e,t=gn){super(`Interrupt`,t,`Interrupted`),this.fiberId=e}toString(){return`Interrupt(${this.fiberId})`}toJSON(){return{_tag:`Interrupt`,fiberId:this.fiberId}}[it](e){return En(e)&&this.fiberId===e.fiberId&&this.annotations===e.annotations}[Be](){return Ue(qe(`${this._tag}:${this.fiberId}`))(He(this.annotations))}};const ds=e=>new us(e),fs=e=>new pn([new us(e)]),ps=e=>{let t=e.reasons.find(wn);return t?Gr(t):Kr(e)},ms=e=>{for(let t=0;t<e.reasons.length;t++){let n=e.reasons[t];if(n._tag===`Fail`)return Gr(n.error)}return Kr(e)},hs=e=>e.reasons.some(Tn),gs=e=>{let t=e.reasons.find(Tn);return t?Gr(t.defect):Kr(e)},_s=e=>e.reasons.some(En),vs=e=>{let t;for(let n=0;n<e.reasons.length;n++){let r=e.reasons[n];r._tag===`Interrupt`&&(t??=/* @__PURE__ */ new Set,r.fiberId!==void 0&&t.add(r.fiberId))}return t?Gr(t):Kr(e)},ys=e=>{let t=vs(e);return Yr(t)?bs:t.success},bs=/*#__PURE__*/ new Set,xs=e=>e.reasons.length>0&&e.reasons.every(En),Ss=(e,t)=>{let n=/* @__PURE__ */ new Map,r=[];for(let i of e.concat(t)){let e=Ve(i),t=n.get(e);if(t===void 0)n.set(e,[i]);else if(t.some(e=>at(e,i)))continue;else t.push(i);r.push(i)}return r},Cs=/*#__PURE__*/ C(2,(e,t)=>{if(e.reasons.length===0)return t;if(t.reasons.length===0)return e;let n=new pn(Ss(e.reasons,t.reasons));return at(e,n)?e:n}),ws=/*#__PURE__*/ C(2,(e,t)=>{let n=!1,r=e.reasons.map(e=>wn(e)?(n=!0,new _n(t(e.error),e.annotations)):e);return n?vn(r):e}),Ts=e=>{let t={Fail:[],Die:[],Interrupt:[]};for(let n=0;n<e.reasons.length;n++)t[e.reasons[n]._tag].push(e.reasons[n]);return t},Es=e=>{let t=Ts(e);return t.Fail.length>0?t.Fail[0].error:t.Die.length>0?t.Die[0].defect:t.Interrupt.length>0?new globalThis.Error(`All fibers interrupted without error`):new globalThis.Error(`Empty cause`)},Ds=(e,t)=>{let n=[],r=[];if(e.reasons.length===0)return n;let i=Ht();i!==0&&Ut(1);for(let i of e.reasons){if(i._tag===`Interrupt`){r.push(i);continue}n.push(Os(i._tag===`Die`?i.defect:i.error,i.annotations,t))}if(n.length===0){let e=/* @__PURE__ */ Error(`The fiber was interrupted by:`);e.name=`InterruptCause`,e.stack=Ns(e,r);let i=new globalThis.Error(`All fibers interrupted without error`,{cause:e});i.name=`InterruptError`,i.stack=`${i.name}: ${i.message}`,n.push(Os(i,r[0].annotations,t))}return i!==0&&Ut(i),n},Os=(e,t,n)=>{let r=typeof e,i;if(e&&r===`object`){if(i=new globalThis.Error(ks(e),{cause:e.cause?Os(e.cause):void 0}),typeof e.name==`string`&&(i.name=e.name),typeof e.stack==`string`)i.stack=js(e.stack,i,t);else{let e=`${i.name}: ${i.message}`;i.stack=t?Ms(e,t):e}n?.includeCauseInStack&&(i.stack=Is(i));for(let t of Object.keys(e))t in i||(i[t]=e[t])}else i=new globalThis.Error(e?r===`string`?e:Ft(e):`Unknown error: ${e}`);return i},ks=e=>{if(typeof e.message==`string`)return e.message;if(typeof e.toString==`function`&&e.toString!==Object.prototype.toString&&e.toString!==Array.prototype.toString)try{return e.toString()}catch{}return Ft(e)},As=/\((.*)\)/g,js=(e,t,n)=>{let r=`${t.name}: ${t.message}`,i=(e.startsWith(r)?e.slice(r.length):e).split(`
|
||||
`),a=[r];for(let e=1;e<i.length&&!/(?:Generator\.next|~effect\/Effect)/.test(i[e]);e++)a.push(i[e]);return n?Ms(a.join(`
|
||||
`),n):a.join(`
|
||||
`)},Ms=(e,t)=>{let n=t?.get(Mn.key);return n&&(e=`${e}\n${Ps(n)}`),e},Ns=(e,t)=>{let n=[`${e.name}: ${e.message}`];for(let e of t){let t=e.fiberId===void 0?`unknown`:`#${e.fiberId}`,r=e.annotations.get(Nn.key);n.push(` at fiber (${t})`),r&&n.push(Ps(r))}return n.join(`
|
||||
`)},Ps=e=>{let t=[],n=e,r=0;for(;n&&r<10;){let e=n.stack();if(e){let r=e.matchAll(As),i=!1;for(let[,e]of r)i=!0,t.push(` at ${n.name} (${e})`);i||t.push(` at ${n.name} (${e.replace(/^at /,``)})`)}else t.push(` at ${n.name}`);n=n.parent,r++}return t.join(`
|
||||
`)},Fs=e=>Ds(e).map(Is).join(`
|
||||
`),Is=e=>e.cause?`${e.stack} {\n${Ls(e.cause,` `)}\n}`:e.stack,Ls=(e,t)=>{let n=e.stack.split(`
|
||||
`),r=`${t}[cause]: ${n[0]}`;for(let e=1,i=n.length;e<i;e++)r+=`\n${t}${n[e]}`;return e.cause&&(r+=` {\n${Ls(e.cause,`${t} `)}\n${t}}`),r},Rs=`~effect/Fiber`,zs={_A:w,_E:w},Bs={id:0},Vs=()=>globalThis[Tt];var Hs=class{constructor(e,t=!0){this[Rs]=zs,this.setContext(e),this.id=++Bs.id,this.currentOpCount=0,this.interruptible=t,this._stack=[],this._observers=void 0,this._exit=void 0,this._children=void 0,this._interruptedCause=void 0,this._yielded=void 0,this._running=!1,this._deferredInterrupt=!1,this._parent=void 0,this.cache.runtimeMetrics?.recordFiberStart(this.context)}[Rs];id;interruptible;currentOpCount;_stack;_observers;_exit;_children;_interruptedCause;_yielded;_running;_deferredInterrupt;_parent;context;cache;_dispatcher=void 0;get currentDispatcher(){return this._dispatcher??=this.cache.scheduler.makeDispatcher()}getRef(e){return sa(this.context,e)}addObserver(e){return this._exit?(e(this._exit),pe):(this._observers===void 0?this._observers=[e]:this._observers.push(e),()=>{if(this._exit||this._observers===void 0)return;let t=this._observers.indexOf(e);t>=0&&this._observers.splice(t,1)})}interruptUnsafe(e,t){if(this._exit)return;let n=fs(e);this.cache.stackFrame&&(n=Cn(n,ta(Mn,this.cache.stackFrame))),t&&(n=Cn(n,t)),this._interruptedCause=this._interruptedCause?Cs(this._interruptedCause,n):n,this.interruptible&&(this._running?this._deferredInterrupt=!0:this.evaluate(ec(this._interruptedCause)))}pollUnsafe(){return this._exit}evaluate(e){if(this._exit)return;if(this._yielded!==void 0){let e=this._yielded;this._yielded=void 0,e()}let t=this.runLoop(e);if(t===rn)return;let n=Gs.interruptChildren&&Gs.interruptChildren(this);if(n!==void 0)return this.evaluate(Gc(n,()=>t));if(this._exit=t,this.cache.runtimeMetrics?.recordFiberEnd(this.context,this._exit),this._parent&&=(this._parent._children?.delete(this),void 0),this._observers!==void 0){let e=this._observers;this._observers=void 0;for(let n=0;n<e.length;n++)e[n](t)}this._stack.length=0,this._children=void 0,this.context=$i()}runLoop(e){let t=globalThis[Tt];globalThis[Tt]=this;let n=this._running;this._running=!0;let r=!1,i=e;this.currentOpCount=0;try{for(;;){this._deferredInterrupt&&(this._deferredInterrupt=!1,i=ec(this._interruptedCause)),this.currentOpCount++;let e=this.cache;if(!r&&!e.preventYield&&e.scheduler.shouldYield(this)){r=!0;let e=i;i=Gc(oc,()=>e)}if(i=e.tracerContext?e.tracerContext(i,this):i[$t](this),i===rn){let e=this._yielded;if(Yt in e)return this._deferredInterrupt=!1,this._yielded=void 0,e;if(this._deferredInterrupt){this._yielded=void 0,e();continue}return rn}}}catch(e){return E(i,$t)?this.runLoop(In(e)):In(`Fiber.runLoop: Not a valid effect: ${String(i)}`)}finally{this._running=n,globalThis[Tt]=t}}getCont(e){if(this._deferredInterrupt)return this._deferredInterrupt=!1,Ws;for(;;){let t=this._stack.pop();if(!t)return;let n=t[nn];if(n!==void 0){let r=n.call(t,this);if(r)return r[e]=r,r}if(t[e])return t}}yieldWith(e){return this._yielded=e,rn}children(){return this._children??=/* @__PURE__ */ new Set}pipe(){return S(this,arguments)}setContext(e){let t=this.context;if(this.context=e,t!==void 0&&Xi(t,e))return;let n=e.cacheRoot,r=n._fiberCache??=Us(e);this.cache!==void 0&&this.cache.scheduler!==r.scheduler&&(this._dispatcher=void 0),this.cache=r}get currentSpanLocal(){let e=this.cache.span;return e?._tag===`Span`?e:void 0}};const Us=e=>{let t=aa(e,qo);return{scheduler:sa(e,uo),tracer:t,tracerContext:t?t.context:void 0,tracerEnabled:sa(e,$o),span:aa(e,Bo),logLevel:sa(e,is),minimumLogLevel:sa(e,as),stackFrame:sa(e,Qo),runtimeMetrics:aa(e,`effect/Metric/FiberRuntimeMetrics`),maxOpsBeforeYield:sa(e,vo),preventYield:sa(e,yo)}},Ws={[en](e,t){return ec(t._interruptedCause)},[tn](e,t){return ec(t._interruptedCause)}},Gs={interruptChildren:void 0},Ks=e=>{if(!e.cache.stackFrame)return;let t=/* @__PURE__ */ new Map;return t.set(Nn.key,e.cache.stackFrame),Ji(t)},qs=e=>{if(e._children!==void 0&&e._children.size!==0)return $s(e._children)},Js=e=>{let t=e;return t._exit?A(t._exit):_c(n=>t._exit?n(A(t._exit)):nc(e.addObserver(e=>n(A(e)))))},Ys=e=>_c(t=>{let n=e[Symbol.iterator](),r=[],i;function a(){let e=n.next();for(;!e.done;){if(e.value._exit){r.push(e.value._exit),e=n.next();continue}i=e.value.addObserver(e=>{r.push(e),a()});return}t(A(r))}return a(),nc(()=>i?.())}),Xs=e=>{let t=e;return t._exit?t._exit:_c(n=>t._exit?n(t._exit):nc(e.addObserver(n)))},Zs=e=>Ln(t=>Qs(e,t.id)),Qs=/*#__PURE__*/ C(e=>E(e[0],Rs),(e,t,n)=>Ln(r=>{let i=Ks(r);return i=i&&n?fa(i,n):i??n,e.interruptUnsafe(t,i),Vc(Js(e))})),$s=e=>Ln(t=>{let n=Ks(t),r=Ai();for(let i of e)i.interruptUnsafe(t.id,n),r.push(i);return Vc(Ys(r))}),A=jn,ec=Pn,tc=Fn,nc=/*#__PURE__*/ kn({op:`Sync`,[$t](e){let t=this[Qt](),n=e.getCont(en);return n?n[en](t,e):e.yieldWith(jn(t))}}),rc=/*#__PURE__*/ kn({op:`Suspend`,[$t](e){return this[Qt]()}}),ic=/*#__PURE__*/ C(e=>e.length>=2||Mr(e[0]),(e,t)=>Nr(e)?tc(t?t():new Un(`Effect.fromOption: Option.none`)):A(e.value)),ac=/*#__PURE__*/ $r({onFailure:tc,onSuccess:
Line truncated
|
||||
`);for(n&&=(o===0&&(e=1,o=a.indexOf(`
|
||||
`,e)),!1);r!==-1||o!==-1;)r===-1||o!==-1&&o<r?(i(a.substring(e,o)),e=o+1,o=a.indexOf(`
|
||||
`,e)):(i(a.substring(e,r)),a.length===r+1?(n=!0,e=a.length,r=-1):(e=r+(o===r+1?2:1),r=a.indexOf(`\r`,e),o=a.indexOf(`
|
||||
`,e)));t+=a.substring(e)}}return yi(r)?r:null}let a=M(()=>r._tag===`Some`?Wp(r.value):bm(e,{onSuccess:o,onFailure:Qm,onDone:e=>{if(r=O(e),t.length>0){let e=t;return t=``,n=!1,j([e])}return Wp(e)}}));function o(e){let t=i(e);return t===null?a:j(t)}return a})),Dy=/*#__PURE__*/ C(2,(e,t)=>Gv((n,r)=>I(Yv(e)(n,r),e=>Yv(t)(e,r)))),Oy=/*#__PURE__*/ C(2,(e,t)=>Gv((n,r)=>I(Yv(e)(n,r),e=>{let n=vh(e,e=>hm(e)?Qm(e):eh(Up(e)));return L(Yv(t)(n,r),e=>yh(e,e=>Hp(e)?Qm(e.value):eh(e)))}))),ky=e=>Gv((t,n)=>{let r;return j(M(()=>r||e.pipe(Bf(n),I(e=>Yv(e)(t,n)),I(e=>r=e))))}),Ay=/*#__PURE__*/ C(2,(e,t)=>Kv(e,e=>j(mm(e,e=>I(t,()=>Wp(e)))))),jy=(e,t,n)=>M(()=>{let r=zf(),i=Yv(e)(Wp(),r);return mm(I(i,t),n||j).pipe(eg(e=>Wf(r,e)))}),My=/*#__PURE__*/ C(2,(e,t)=>Gv((n,r)=>L(Hh(Yv(e)(n,r),t),Hh(t)))),Ny=/*#__PURE__*/ C(2,(e,t)=>jy(e,e=>cg(I(e,t),{disableYield:!0}))),Py=e=>M(()=>{let t=D();return jy(e,e=>e.pipe(ph,I(e=>(t=e,Wp()))),()=>j(t))}),Fy=/*#__PURE__*/ C(3,(e,t,n)=>M(()=>{let r=t();return jy(e,e=>Km({while:ue,body:()=>e,step:e=>{r=n(r,e)}}),()=>j(r))})),Iy=(e,t)=>Yv(e)(Wp(),t),Ly={_R:w,_E:w,_A:w},Ry=function(e){this.channel=e};Ry.prototype={"~effect/Stream":Ly,pipe(){return S(this,arguments)}};const zy=e=>new Ry(e),By=`~effect/Sink`,Vy=/*#__PURE__*/ j([void 0]),Hy={_A:w,_In:w,_L:w,_E:w,_R:w},Uy={[By]:Hy,pipe(){return S(this,arguments)}},Wy=e=>E(e,By),Gy=e=>Ky((t,n)=>Yv(e)(t,n).pipe(I(cg({disableYield:!0})),mm(j))),Ky=e=>{let t=Object.create(Uy);return t.transform=e,t},qy=e=>Gv((t,n)=>j(I(e.transform(t,n),Wp))),Jy=/*#__PURE__*/ Ky(e=>mm(cg(e,{disableYield:!0}),()=>Vy)),Yy=/*#__PURE__*/ ((e,t)=>Ky(n=>{let r=e();return n.pipe(I(e=>(r=t(r,e),P)),cg({disableYield:!0}),mm(()=>j([r])))}))(D,(e,t)=>Si(t)),Xy=()=>Yy,Zy=e=>Qy(Gm(t=>e(t),{discard:!0})),Qy=e=>Ky(t=>t.pipe(I(e),cg({disableYield:!0}),mm(()=>Vy))),$y=e=>Gy(ky(L(e,qy))),eb=`~effect/MutableHashMap`,tb={[eb]:eb,[Symbol.iterator](){return this.backing[Symbol.iterator]()},toString(){return`MutableHashMap(${Ot(Array.from(this))})`},toJSON(){return{_id:`MutableHashMap`,values:Lt(Array.from(this))}},[It](){return this.toJSON()},pipe(){return S(this,arguments)}},nb=()=>{let e=Object.create(tb);return e.backing=/* @__PURE__ */ new Map,e.buckets=/* @__PURE__ */ new Map,e},rb=/*#__PURE__*/ C(2,(e,t)=>{if(e.backing.has(t))return O(e.backing.get(t));if(ab(t))return D();let n=ib.get(e);if(n!==void 0)return e.backing.has(n)?O(e.backing.get(n)):D();let r=Ve(t),i=e.buckets.get(r);return i===void 0?D():sb(e,i,t)}),ib=/*#__PURE__*/ new WeakMap,ab=e=>typeof e!=`object`&&typeof e!=`function`,ob=e=>e.backing.values(),sb=(e,t,n)=>{for(let r=0,i=t.length;r<i;r++)if(at(n,t[r])){let i=t[r];return ib.set(n,i),O(e.backing.get(i))}return D()},cb=/*#__PURE__*/ C(3,(e,t,n)=>{if(e.backing.has(t)||ab(t))return e.backing.set(t,n),e;let r=ib.get(e);if(r!==void 0&&e.backing.has(r))return e.backing.set(r,n),e;let i=Ve(t),a=e.buckets.get(i);return a===void 0?(e.buckets.set(i,[t]),e.backing.set(t,n),e):(r=lb(a,t),r===void 0&&(a.push(t),r=t),e.backing.set(r,n),e)}),lb=(e,t)=>{for(let n=0,r=e.length;n<r;n++)if(at(t,e[n]))return ib.set(t,e[n]),e[n]},ub=/*#__PURE__*/ C(2,(e,t)=>{if(ab(t))return e.backing.delete(t),e;let n=ib.get(e)??t,r=Ve(n),i=e.buckets.get(r);if(i===void 0)return e;for(let t=0,r=i.length;t<r;t++){let r=i[t];if(r===n||at(n,r)){e.backing.delete(r),i.splice(t,1);break}}return i.length===0&&e.buckets.delete(r),e}),db=e=>(e.backing.clear(),e.buckets.clear(),e),fb=e=>e.backing.size,pb=`~effect/RcMap`,mb=e=>({[pb]:pb,lookup:e.lookup,context:e.context,scope:e.scope,idleTimeToLive:e.idleTimeToLive,capacity:e.capacity,state:{_tag:`Open`,map:nb()},pipe(){return S(this,arguments)}}),hb=e=>rh(t=>{let n=t.context,r=sa(n,Lf),i=mb({lookup:e.lookup,context:n,scope:r,idleTimeToLive:typeof e.idleTimeToLive==`function`?ge(e.idleTimeToLive,Oa):T(Oa(e.idleTimeToLive??Ba)),capacity:Math.max(e.capacity??1/0,0)});return fh(Vf(r,()=>{if(i.state._tag===`Closed`)return P;let e=i.state.map;return i.state={_tag:`Closed`},Gm(e,([,e])=>dh(_b(e))).pipe(ch(()=>N(()=>{db(e)})))}),i)}),gb=/*#__PURE__*/ C(2,(e,t)=>og(n=>{if(e.state._tag===`Closed`)return ng;let r=e.state,i=m_(),a=rb(r.map,t),o;if(a._tag===`Some`)o=a.value,o.refCount++;else if(Number.isFinite(e.capacity)&&fb(e.state.map)>=e.capacity)return F(new Kp(`RcMap attempted to exceed capacity of ${e.capacity}`));else{o={deferred:df(),scope:zf(),idleTimeToLive:e.idleTimeToLive(t),finalizer:void 0,fiber:void 0,expiresAt:0,refCount:1},o.finalizer=vb(e,t,o),cb(r.map,t,o);let n=new Map(e.context.mapUnsafe);i.context.mapUnsafe.forEach((e,t)=>{n.set(t,e)}),n.set(Lf.key,o.scope),M(()=>e.lookup(t)).pipe(yg(Ji(n)),h_(o.scope)).addObserver(e=>xf(o.deferred,e))}let s=oa(i.context,Lf);return Hf(s,o.finalizer).pipe(sh(n(pf(o.deferred))))})),_b=e=>e.fiber?f_(e.fiber).pipe(sh(Wf(e.scope,kf))):Wf(e.scope,kf),vb=(e,t,n)=>rh(r=>{if(n.refCount--,n.refCount>0)return P;if(e.state._tag===`Closed`)return _b(n);let i=rb(e.state.map,t);if(i._tag===`None`||i.value!==n)return _b(n);if(La(n.idleTimeToL
Line truncated
|
||||
`);n=uS(e)??aS(Ox(e.ast),e);break;default:n=tS(e)}return t?`${n}\n at ${t}`:n}function uS(e){if(e._tag===`Pointer`)return;if(e._tag===`Encoding`)return uS(e.issue);let t=(e._tag===`Filter`?e.filter.annotations:`annotations`in e?e.annotations:e.ast.annotations)?.[e._tag===`MissingKey`?`messageMissingKey`:e._tag===`UnexpectedKey`?`messageUnexpectedKey`:`message`];if(typeof t==`string`)return t}function dS(e){let t;for(let n of e.reasons){if(!wp(n)||!Lx(n.error))return;t??=n.error}return t}function fS(e,t){let n=dS(e);if(n===void 0)throw Error(t,{cause:e});return n}const pS=tm,mS=nm,hS=am,gS=sm,_S=cm,vS=dm,yS=class extends le{run;constructor(e){super(),this.run=e}map(e){return new yS((t,n)=>this.run(t,n).pipe(Ng(Vr(e))))}compose(e){return wS(this)?e:wS(e)?this:new yS((t,n)=>this.run(t,n).pipe(Ig(t=>e.run(t,n))))}};function bS(e){return new yS((t,n)=>F(e(t,n)))}function xS(e){return bS((t,n)=>{let r={message:e(t)};return Pr(t)?new Yx(r,t.value,n):new Yx(r)})}const SS=/*#__PURE__*/ xS(()=>`Encoding is not supported`),CS=/*#__PURE__*/ new yS(j);function wS(e){return e.run===CS.run}function TS(){return CS}function ES(e){return new yS((t,n)=>Nr(t)?Jm:e(t.value,n))}function DS(e){return kS(Vr(e))}function OS(e){return ES((t,n)=>e(t,n).pipe(Ng(O)))}function kS(e){return new yS(t=>j(e(t)))}function AS(){return new yS(()=>Jm)}function jS(e){return new yS(t=>{let n=Ur(t,ke);return Pr(n)?j(n):Ng(e,O)})}function MS(){return DS(globalThis.String)}function NS(){return DS(globalThis.Number)}function PS(){return DS(globalThis.BigInt)}function FS(e){return ES((t,n)=>th({try:()=>O(JSON.parse(t,e?.reviver)),catch:()=>new qx({expected:`a valid JSON string`},t,n)}))}function IS(e){return ES((t,n)=>th({try:()=>{let n=JSON.stringify(t,e?.replacer,e?.space);if(n===void 0)throw TypeError(`Value cannot be represented as JSON`);return O(n)},catch:()=>new qx({expected:`a JSON-serializable value`},t,n)}))}function LS(){return DS(Do)}function RS(){return OS((e,t)=>Pg(ih(Oo(e)),()=>new qx({expected:`a valid Base64 string`},e,t)))}const zS=`~effect/BigDecimal`,BS={[zS]:zS,[Be](){let e=JS(this);return Ue(Ve(e.value),Ke(e.scale))},[it](e){return VS(e)&&nC(this,e)},toString(){return`BigDecimal(${rC(this)})`},toJSON(){return{_id:`BigDecimal`,value:String(this.value),scale:this.scale}},[It](){return this.toJSON()},pipe(){return S(this,arguments)}},VS=e=>E(e,zS),HS=(e,t)=>{if(!Number.isSafeInteger(t))throw RangeError(`Scale must be a safe integer, got ${t}`);let n=Object.create(BS);return n.value=e,n.scale=t,n},US=(e,t)=>{if(e!==WS&&e%KS===WS)throw RangeError(`Value must be normalized`);let n=HS(e,t);return n.normalized=n,n},WS=/*#__PURE__*/ BigInt(0),GS=/*#__PURE__*/ BigInt(1),KS=/*#__PURE__*/ BigInt(10),qS=/*#__PURE__*/ US(WS,0),JS=e=>{if(e.normalized===void 0){if(e.value===WS)e.normalized=qS;else{let t=`${e.value}`,n=0;for(let e=t.length-1;e>=0&&t[e]===`0`;e--)n++;n===0&&(e.normalized=e);let r=BigInt(t.substring(0,t.length-n)),i=e.scale-n;e.normalized=US(r,i)}}return e.normalized},YS=[GS],XS=(e,t)=>e===t?0:e<t?-1:1,ZS=(e,t)=>{let n=`${e.value<WS?-e.value:e.value}`,r=`${t.value<WS?-t.value:t.value}`,i=BigInt(n.length-r.length)-BigInt(e.scale)+BigInt(t.scale);if(i!==WS)return i<WS?-1:1;let a=Math.max(n.length,r.length);for(let e=0;e<a;e++){let t=e<n.length?n.charCodeAt(e):48,i=e<r.length?r.charCodeAt(e):48;if(t!==i)return t<i?-1:1}return 0},QS=(e,t)=>{if(e.scale===t.scale)return XS(e.value,t.value);let n=$S(e),r=$S(t);if(n!==r)return n<r?-1:1;if(n===0)return 0;let i=e.scale-t.scale,a=Math.abs(i);if(a>100)return n===-1?ZS(t,e):ZS(e,t);let o=YS[a]??=KS**BigInt(a);return i>0?XS(e.value,t.value*o):XS(e.value*o,t.value)},$S=e=>e.value===WS?0:e.value<WS?-1:1,eC=e=>e.value<WS?HS(-e.value,e.scale):e,tC=/*#__PURE__*/ Xn((e,t)=>QS(e,t)===0),nC=/*#__PURE__*/ C(2,(e,t)=>tC(e,t)),rC=e=>{let t=JS(e);if(Math.abs(t.scale)>=16)return iC(t);let n=t.value<WS,r=n?`${t.value}`.substring(1):`${t.value}`,i,a;if(t.scale>=r.length)i=`0`,a=`0`.repeat(t.scale-r.length)+r;else{let e=r.length-t.scale;if(e>r.length){let t=e-r.length;i=`${r}${`0`.repeat(t)}`,a=``}else a=r.slice(e),i=r.slice(0,e)}let o=a===``?i:`${i}.${a}`;return n?`-${o}`:o},iC=e=>{if(aC(e))return`0e+0`;let t=JS(e),n=`${eC(t).value}`,r=n.slice(0,1),i=n.slice(1),a=`${oC(t)?`-`:``}${r}`;i!==``&&(a+=`.${i}`);let o=i.length-t.scale;return`${a}e${o>=0?`+`:``}${o}`},aC=e=>e.value===WS,oC=e=>e.value<WS,sC=`~effect/SchemaTransformation/Transformation`,cC=class{[sC]=sC;_tag=`Transformation`;decode;encode;constructor(e,t){this.decode=e,this.encode=t}flip(){return new cC(this.encode,this.decode)}compose(e){return new cC(this.decode.compose(e.decode),e.encode.compose(this.encode))}};function lC(e){return E(e,sC)&&e[sC]===sC}const uC=e=>lC(e)?e:new cC(e.decode,e.encode);function dC(e){return new cC(OS(e.decode),OS(e.encode))}function fC(e){return new cC(DS(e.decode),DS(e.encode))}const pC=/*#__PURE__*/ new cC(/*#__PURE__*/ TS(),/*#__PURE__*/ TS());function mC(){return pC}const hC=/*#__PURE__*/ new cC(/*#__PURE__*/ NS(),/
Line truncated
|
||||
`]),wE={x:3,u:5},TE=(e,t)=>{if(t.length===0)return{tokens:[],hasLeadingWhitespace:!1,hasTrailingWhitespace:!1};let n=CE.has(t[0]),r=[],i=0;for(let n=0,a=0;n<e.length;n+=1,a+=1){let o=t[a];if(CE.has(o))i!==n&&r.push(e.slice(i,n)),i=n+1;else if(o===`\\`){let e=t[a+1];if(e===`
|
||||
`)--n,a+=1;else if(e===`u`&&t[a+2]===`{`){let e=t.indexOf(`}`,a+3);parseInt(t.slice(a+3,e),16)>65535&&(n+=1),a=e}else a+=wE[e]??1}}let a=i===e.length;return a||r.push(e.slice(i)),{tokens:r,hasLeadingWhitespace:n,hasTrailingWhitespace:a}},EE=(e,t,n)=>n||e.length===0||t.length===0?[...e,...t]:[...e.slice(0,-1),`${e.at(-1)}${t.at(0)}`,...t.slice(1)],DE=(e,t,n)=>{let r=e.detached??n!==`win32`;return{...t,detached:r,shell:e.shell,windowsHide:e.windowsHide??!r}},OE=(e,t)=>(n,[r])=>{let i=`Unknown`;switch(n.code){case`ENOENT`:i=`NotFound`;break;case`EACCES`:i=`PermissionDenied`;break;case`EEXIST`:i=`AlreadyExists`;break;case`EISDIR`:i=`BadResource`;break;case`ENOTDIR`:i=`BadResource`;break;case`EBUSY`:i=`Busy`;break;case`ELOOP`:i=`BadResource`}return l_({_tag:i,module:e,method:t,pathOrDescriptor:r,syscall:n.syscall,cause:n})},kE=e=>Gy(ly(AE(e),e=>[e])),AE=e=>Gv(t=>{let n=e.evaluate();return j(jE({...e,writable:n,pull:t}))}),jE=e=>e.pull.pipe(I(t=>{let n=0;return Ym(r=>{let i=!1,a=()=>{for(;n<t.length;){if(i)return;if(!e.writable.write(t[n++],e.encoding)){i||e.writable.once(`drain`,a);return}}i||r(P)};return a(),N(()=>{i=!0,e.writable.off(`drain`,a)})})}),cg({disableYield:!0}),e.endOnDone===!1?w:mm(t=>`closed`in e.writable&&e.writable.closed?Wp(t):Ym(n=>{let r=()=>n(Wp(t));return e.writable.once(`finish`,r),e.writable.end(),N(()=>{e.writable.off(`finish`,r)})})),Nh(Ym(t=>{let n=n=>t(F(e.onError(n)));return e.writable.once(`error`,n),N(()=>{e.writable.off(`error`,n)})}))),ME=e=>kb(NE(e)),NE=e=>Gv((t,n)=>RE({scope:n,readable:e.evaluate(),onError:e.onError??zE,chunkSize:e.chunkSize,closeOnDone:e.closeOnDone})),PE=e=>Gv((t,n)=>{let r=e.evaluate(),i=b_(void 0),a=g_(!1);return jE({pull:t,writable:r,onError:e.onError??zE,endOnDone:e.endOnDone,encoding:e.encoding}).pipe(vh(e=>hm(e)?P:(i.current=Tf(e),a.openUnsafe(),P)),hg(n),I(()=>RE({scope:n,exit:i,latch:a,readable:r,onError:e.onError??zE,chunkSize:e.chunkSize})))}),FE=/*#__PURE__*/ C(2,(e,t)=>tx(e,PE(t))),IE=(e,t)=>{let n=BE(t?.maxBytes),r=t?.onError??zE;return Ym(t=>{let i=e(),a=[],o=0;return i.once(`error`,e=>{`closed`in i&&!i.closed&&i.destroy(),t(F(r(e)))}),i.once(`end`,()=>{let e=a.length===1?a[0]:Buffer.concat(a);if(e.byteOffset===0&&e.buffer.byteLength===e.byteLength)return t(j(e.buffer));t(j(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)))}),i.on(`data`,e=>{a.push(e),o+=e.length,n!==void 0&&o>n&&(`closed`in i&&!i.closed&&i.destroy(),t(F(r(/* @__PURE__ */ Error(`maxBytes exceeded`)))))}),N(()=>{`closed`in i&&!i.closed&&i.destroy()})})},LE=(e,t)=>L(IE(e,t),e=>new Uint8Array(e)),RE=e=>{let t=e.readable,n=e.closeOnDone??!0,r=e.exit??b_(void 0),i=e.latch??g_(!1);function a(){i.openUnsafe()}function o(t){r.current=Ef(e.onError(t)),i.openUnsafe()}function s(){r.current=Ef(Up()),i.openUnsafe()}t.on(`readable`,a),t.once(`error`,o),t.once(`end`,s);let c=M(function n(){let a=e.readable.read(e.chunkSize);if(a===null)return r.current?r.current:t.readableEnded?F(Up()):(i.closeUnsafe(),I(i.await,n));let o=ji(a);for(;a=e.readable.read(e.chunkSize),a!==null;)o.push(a);return j(o)});return fh(Hf(e.scope,N(()=>{t.off(`readable`,a),t.off(`error`,o),t.off(`end`,s),n&&`closed`in e.readable&&!e.readable.closed&&e.readable.destroy()})),c)},zE=e=>new qp(e),BE=e=>e===void 0||e===1/0?void 0:Number(t_(e)),VE=e=>e instanceof globalThis.Error?e:new globalThis.Error(String(e)),HE=(e,t,n)=>{let{commands:r}=qE(n),i=r.reduce((e,t)=>{let n=`${t.command} ${t.args.join(` `)}`;return e.length===0?n:`${e} | ${n}`},``);return OE(`ChildProcess`,e)(t,[i])},UE=1e3,WE=(e,t)=>{if(!yf(t))return!0;if(globalThis.process.platform===`win32`)return!1;try{return globalThis.process.kill(-e.pid,0),!0}catch{return!1}},GE=(e,n=()=>{})=>t.execFile(`taskkill`,[`/pid`,String(e.pid),`/T`,`/F`],{windowsHide:!0},n),KE=/*#__PURE__*/ cp(fE,/* @__PURE__ */ Zm(function*(){let e=yield*px,n=yield*vx,r=z(function*(t){if(!Oe(t.cwd))return yield*e.access(t.cwd),n.resolve(t.cwd)}),a=e=>e.extendEnv?{...globalThis.process.env,...e.env}:e.env,o=e=>Ob(e)?`pipe`:e,s=e=>Wy(e)?`pipe`:e,c=e=>{let t={stream:`pipe`,encoding:`utf-8`,endOnDone:!0};return Oe(e.stdin)?t:typeof e.stdin==`string`||Ob(e.stdin)?{...t,stream:e.stdin}:{stream:e.stdin.stream,encoding:e.stdin.encoding??t.encoding,endOnDone:e.stdin.endOnDone??t.endOnDone}},l=(e,t)=>{let n=e[t];return Oe(n)?{stream:`pipe`}:typeof n==`string`||Wy(n)?{stream:n}:{stream:n.stream}},u=e=>{if(Oe(e.additionalFds))return[];let t=[];for(let[n,r]of Object.entries(e.additionalFds)){let e=vE(n);ke(e)&&t.push({fd:e,config:r})}return t.sort((e,t)=>e.fd-t.fd)},d=(e,t,n,r)=>{let i=[o(e.stream),s(t.stream),s(n.stream)];if(r.length===0)return i;let a=r.reduce((e,{fd:t})=>Math.max(e,t),2);for(let e=3;e<=a;e++)i[e]=`ignore`;for(let{fd:e}of r)i[e]=`pipe`;return i},f=z(function*(e,t,n){if(n.length===0)return{getInputFd:()=>Jy,getOutputFd:()=>Fb};let r=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Map;for(let{config:o,fd:s}of n){let n=t.stdio[s];switch(o.type){case`input`:{let t=Jy;n&&`write`in n&&(t=kE(
Line truncated
|
||||
`);function DF(e){return e.filename!==void 0||e.contentType===`application/octet-stream`}function OF(e){return uF(e[`content-type`]).parameters.boundary}function kF(e){}const AF=e=>e===1/0?1/0:Number(t_(e));function jF({headers:e,onFile:t,onField:n,onError:r,onDone:i,isFile:a=DF,maxParts:o=1/0,maxTotalSize:s=1/0,maxPartSize:c=1/0,maxFieldSize:l=1048576}){let u=AF(s),d=AF(c),f=AF(l),p=OF(e);if(p===void 0)return r({_tag:`InvalidBoundary`}),{write:kF,end(){}};let m={state:yF.headers,index:0,parts:0,onChunk:kF,info:void 0,headerSkip:0,partSize:0,totalSize:0,isFile:!1,fieldChunks:[],fieldSize:0,done:!1,stopped:!1};function h(){m.state=yF.body,m.isFile=!0,m.onChunk=kF}function g(e){m.stopped=!0,m.state===yF.body&&m.isFile&&m.onChunk(null),r(e)}let _=gF(),v=vF(`\r\n--${p}`,function(e,s){if(!m.stopped){if(e===0){h();return}if(e!==m.index){if(m.index>0){if(m.isFile)m.onChunk(null);else{if(m.fieldChunks.length===1)n(m.info,m.fieldChunks[0]);else{let e=new Uint8Array(m.fieldSize),t=0;for(let n=0;n<m.fieldChunks.length;n++){let r=m.fieldChunks[n];e.set(r,t),t+=r.length}n(m.info,e)}m.fieldSize=0,m.fieldChunks=[]}}if(m.partSize=0,m.state=yF.headers,m.index=e,m.headerSkip=2,s[0]===45&&s[1]===45)return m.done=!0,i();if(m.parts++,m.parts>o)return g(SF)}if((m.partSize+=s.length)>d)return g(wF);if(m.state===yF.headers){let e=_(s,m.headerSkip);if(m.headerSkip=0,e._tag===`Continue`)return;if(e._tag===`Failure`)return h(),r({_tag:`BadHeaders`,error:e});let n=uF(e.headers[`content-type`]),i=uF(e.headers[`content-disposition`],!0);if(i.value===`form-data`&&!(`name`in i.parameters))return h(),r(bF);let o;if(`filename*`in i.parameters){let e=i.parameters[`filename*`].split(`''`);if(e.length===2)try{o=decodeURIComponent(e[1])}catch{o=e[1]}}if(m.info={name:i.parameters.name??``,filename:o??i.parameters.filename,contentType:n.value===``?i.parameters.filename===void 0?`text/plain`:`application/octet-stream`:n.value,contentTypeParameters:n.parameters,contentDisposition:i.value,contentDispositionParameters:i.parameters,headers:e.headers},m.state=yF.body,m.isFile=a(m.info),m.isFile&&(m.onChunk=t(m.info)),e.endPosition<s.length){if(m.isFile)m.onChunk(s.subarray(e.endPosition));else{let t=s.subarray(e.endPosition);if((m.fieldSize+=t.length)>f)return g(TF);m.fieldChunks.push(t)}}}else if(m.isFile)m.onChunk(s);else{if((m.fieldSize+=s.length)>f)return g(TF);m.fieldChunks.push(s)}}},EF,2);return{write(e){if(!m.stopped)return(m.totalSize+=e.length)>u?g(CF):v.write(e)},end(){v.end(),!m.done&&!m.stopped&&g(xF),m.state=yF.headers,m.index=0,m.parts=0,m.onChunk=kF,m.info=void 0,m.totalSize=0,m.partSize=0,m.fieldChunks=[],m.fieldSize=0,m.done=!1,m.stopped=!1}}}const MF=/*#__PURE__*/ new TextDecoder(`utf-8`);function NF(e){if(e===`utf-8`||e===`utf8`||e===``)return MF;try{return new TextDecoder(e)}catch{return MF}}function PF(e,t){return NF(e.contentTypeParameters.charset??`utf-8`).decode(t)}const FF=jF,IF=DF,LF=PF,RF=`~effect/http/Multipart`,zF=`~effect/http/Multipart/MultipartError`;var BF=class extends Co{};const VF={FileTooLarge:413,FieldTooLarge:413,BodyTooLarge:413,TooManyParts:413,InternalError:500,Parse:400};var HF=class e extends (/*#__PURE__*/ wo(`MultipartError`)){static fromReason(t,n){return new e({reason:new BF({_tag:t,cause:n})})}[zF]=zF;[ZN]=!0;[xP](){return j(nP({status:VF[this.reason._tag]}))}get message(){return this.reason._tag}};const UF=e=>rh(t=>{let n=sa(t.context,ZF);return j({headers:e,maxParts:t.getRef(JF),maxFieldSize:t.getRef(YF),maxPartSize:t.getRef(XF),maxTotalSize:t.getRef(aN),isFile:n.length===0?void 0:e=>!n.some(t=>e.contentType.includes(t))&&IF(e)})});var WF=class extends Bt{[RF];constructor(){super(),this[RF]=RF}};const GF=(e,t)=>I(px,n=>R(ox(t.content,n.sink(e)),e=>HF.fromReason(`InternalError`,e))),KF=(e,t=GF)=>Zm(function*(){let n=yield*px,r=yield*vx,i=yield*n.makeTempDirectoryScoped(),a=Object.create(null),o=/* @__PURE__ */ new Set,s=0;return yield*lx(e,e=>{if(e._tag===`Field`)return e.key in a?typeof a[e.key]==`string`?a[e.key]=[a[e.key],e.value]:a[e.key].push(e.value):a[e.key]=e.value,P;if(e.name===``)return P;let n=e,c=r.basename(n.name).slice(-128),l=r.join(i,c);for(;o.has(l);)l=r.join(i,`${s++}-${c}`);o.add(l);let u=new qF(n.key,n.name,n.contentType,l);return Array.isArray(a[e.key])?a[e.key].push(u):a[e.key]=[u],t(l,n)}),a}).pipe(gh(`PlatformError`,e=>F(HF.fromReason(`InternalError`,e))));var qF=class extends WF{_tag=`PersistedFile`;key;name;contentType;path;constructor(e,t,n,r){super(),this.key=e,this.name=t,this.contentType=n,this.path=r}toJSON(){return{_id:`@effect/platform/Multipart/Part`,_tag:`PersistedFile`,key:this.key,name:this.name,contentType:this.contentType,path:this.path}}};const JF=/*#__PURE__*/ ma(`effect/http/Multipart/MaxParts`,{defaultValue:()=>void 0}),YF=/*#__PURE__*/ ma(`effect/http/Multipart/MaxFieldSize`,{defaultValue:/*#__PURE__*/ T(/*#__PURE__*/ i_(10))}),XF=/*#__PURE__*/ ma(`effect/http/Multipart/MaxFileSize`,{defaultValue:()=>void 0}),ZF=/*#__PURE__*/ ma(`effect/http/Multipart/FieldMLine truncated
|
||||
`,a),s=[];for(;o!==-1;){OL(o-a,t)&&r(t);let e=JSON.parse(n.slice(a,o));s.push(e),a=o+1,o=n.indexOf(`
|
||||
`,a)}return n=n.slice(a),OL(n.length,t)&&r(t),s},encode:e=>{if(Array.isArray(e)){if(e.length===0)return;let t=``;for(let n=0;n<e.length;n++)t+=JSON.stringify(e[n])+`
|
||||
`;return t}return JSON.stringify(e)+`
|
||||
`}}}})})(),AL=e=>EL.of({contentType:e?.contentType??`application/json`,includesFraming:!1,codecFor:CL,makeUnsafe:()=>{let e=/* @__PURE__ */ new Map;return{decode:t=>jL(JSON.parse(typeof t==`string`?t:TL(t)),e),encode:t=>{let n=PL(t,e);return n&&JSON.stringify(n)}}}});function jL(e,t){if(Array.isArray(e)){let n={size:0,responses:/* @__PURE__ */ new Map},r=[];for(let i=0;i<e.length;i++){let a=ML(e[i]);r.push(a),a._tag===`Request`&&!a.isNotification&&(n.size++,t.set(a.id,n))}return r}return[ML(e)]}function ML(e){if(Object.hasOwn(e,`method`)){let t=e;if(je(t.id)&&t.method.startsWith(`@effect/rpc/`)){let e=t.method.slice(12),n=t.params?.requestId;return n===void 0?{_tag:e}:{_tag:e,requestId:n}}return{_tag:`Request`,id:t.id??``,tag:t.method,payload:t.params??null,headers:t.headers??[],...E(t,`id`)?{}:{isNotification:!0},...t.spanId?{traceId:t.traceId,spanId:t.spanId,sampled:t.sampled}:{}}}let t=e,n=Object.hasOwn(t,`error`);return n&&t.error&&t.error._tag===`Defect`?{_tag:`Defect`,defect:t.error.data}:Object.hasOwn(t,`chunk`)&&t.chunk===!0?{_tag:`Chunk`,requestId:t.id??``,values:t.result}:{_tag:`Exit`,requestId:t.id??``,exit:n&&t.error!=null?{_tag:`Failure`,cause:t.error._tag===`Cause`?t.error.data:[{_tag:`Die`,defect:t.error}]}:{_tag:`Success`,value:t.result}}}function NL(e,t){if(!(`requestId`in e))return FL(e);let n=t.get(e.requestId);return n?(t.delete(e.requestId),n.responses.set(e.requestId,e),n.size===n.responses.size?Array.from(n.responses.values(),FL):void 0):FL(e)}function PL(e,t){if(Array.isArray(e)===!1)return NL(e,t);if(e.length===0)return;let n=[];for(let r=0;r<e.length;r++){let i=NL(e[r],t);i!==void 0&&n.push(i)}if(n.length===0)return;if(n.length===1)return n[0];let r=[];for(let e=0;e<n.length;e++){let t=n[e];Array.isArray(t)?r.push(...t):r.push(t)}return r}function FL(e){switch(e._tag){case`Request`:return{jsonrpc:`2.0`,method:e.tag,params:e.payload,...e.isNotification?{}:{id:e.id},...e.headers?.length>0?{headers:e.headers}:{},traceId:e.traceId,spanId:e.spanId,sampled:e.sampled};case`Ping`:case`Pong`:case`Interrupt`:case`Ack`:case`Eof`:return{jsonrpc:`2.0`,method:`@effect/rpc/${e._tag}`,params:`requestId`in e?{requestId:e.requestId}:void 0};case`Chunk`:return{jsonrpc:`2.0`,chunk:!0,id:e.requestId,result:e.values};case`Exit`:{if(e.exit._tag===`Success`)return{jsonrpc:`2.0`,id:e.requestId??void 0,result:e.exit.value};let t=e.exit.cause.find(e=>e._tag===`Fail`),n=t?._tag===`Fail`?t.error:void 0;return{jsonrpc:`2.0`,id:e.requestId??void 0,error:e.exit._tag===`Failure`?{_tag:`Cause`,code:n&&E(n,`code`)?Number(n.code):0,message:n&&E(n,`message`)?n.message:JSON.stringify(e.exit.cause),data:e.exit.cause}:void 0}}case`Defect`:return{jsonrpc:`2.0`,id:IL,error:{_tag:`Defect`,code:1,message:`A defect occurred`,data:e.defect}};case`ClientProtocolError`:return{}}}const IL=-32603,LL=e=>op(EL)(AL(e)),RL=()=>e=>M(()=>{let t=Rv(1),n=[],r=(...e)=>Bh(t=>(n.push([e,t]),P));return L(e((...e)=>r(...e)),e=>({...e,run(e){return t.withPermits(1)(Zm(function*(){let t=r;r=e;for(let[t,r]of n)yield*Hh(M(()=>e(...t)),r);return n=[],yield*eg(Xm,()=>(r=t,P))}))}}))}),zL=e=>M(()=>{let t=/* @__PURE__ */ new Set,n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map,i=(e,t)=>Bh(r=>{let i=n.get(e);return i||(i=[],n.set(e,i)),i.push([t,r]),P});return L(e((e,t)=>{let n=r.get(e);return n?n(t):i(e,t)},t),e=>({...e,run(e,i){return Zm(function*(){t.add(e),r.set(e,i);let a=n.get(e);if(a){n.delete(e);for(let[e,t]of a)yield*Hh(M(()=>i(e)),t)}return yield*eg(Xm,()=>(t.delete(e),r.delete(e),P))})}}))});let BL=0;const VL=/*#__PURE__*/ z(function*(e,t){let n=t?.spanPrefix??`RpcClient`,r=t?.supportsAck??!0,i=t?.disableTracing??!1,a=t?.generateRequestId??(()=>BL++),o=yield*zh(),s=sa(o,Lf),c=/* @__PURE__ */ new Map,l=!1;yield*Hf(s,rh(e=>(l=!0,u(Of(e.id)))));let u=z(function*(e){for(let[t,n]of c)c.delete(t),n._tag===`Queue`?yield*e._tag===`Success`?hv(n.queue):pv(n.queue,e.cause):n.resume(e)}),d=e=>{let r=sL(e.successSchema),a=m(e);return(o,s)=>{let c=s?.headers?kD(s.headers):OD,l=s?.context??$i();if(!r){let r=t=>f(e,a,t,e.payloadSchema.make(o),c,l,s?.discard??!1);return i?r(void 0):dg(`${n}.${e._tag}`,{attributes:t.spanAttributes},r)}let u=p(e,a,e.payloadSchema.make(o),c,s?.streamBufferSize??16,l);return s?.asQueue?u:Ub(L(u,Bb))}},f=(e,n,r,i,o,s,u)=>rh(d=>{if(l)return ng;let f=a(),p=n(e=>t.onFromClient({message:e,context:s,discard:u}),{_tag:`Request`,id:f,tag:e._tag,payload:i,...r?{traceId:r.traceId,spanId:r.spanId,sampled:r.sampled}:{},headers:ND(d.getRef(GL),o)});if(u)return p;let m;return ig(Ym(t=>{let n={_tag:`Effect`,rpc:e,context:s,resume(e){t(e),m&&!m.pollUnsafe()&&d.currentDispatcher.scheduleTask(()=>{m.interruptUnsafe(d.id)},0)}};c.set(f,n),m=p.pipe(r?pg(r,{captureStackTrace:!1}):w,yg(d.context)),m.addObserver(e=>{if(e._tag===`Failure`)return t(e)})}),e=>(c.delete(f),sh(f_(m),h(f,Array.from(e),s))))}),p=z(function*(e,r,o,s,u,d){if(l)return yield*ng;let f=i?void 0:yield*ug(`${n}.${e._tag}`,{attributes:t.spanAttributes}),p=m_(),m=a(),g=oa(p.conte
Line truncated
|
||||
/* istanbul ignore else */
|
||||
if(t.exports={concat:i,mask:a,toArrayBuffer:s,toBuffer:c,unmask:o},!process.env.WS_NO_BUFFER_UTIL)try{let e=se(`bufferutil`);t.exports.mask=function(t,n,r,i,o){o<48?a(t,n,r,i,o):e.mask(t,n,r,i,o)},t.exports.unmask=function(t,n){t.length<32?o(t,n):e.unmask(t,n)}}catch{}})),SR=/* @__PURE__ */ x(((e,t)=>{let n=Symbol(`kDone`),r=Symbol(`kRun`);t.exports=class{constructor(e){this[n]=()=>{this.pending--,this[r]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[r]()}[r](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[n])}}}})),CR=/* @__PURE__ */ x(((e,t)=>{let n=se(`zlib`),r=xR(),i=SR(),{kStatusCode:a}=bR(),o=Buffer[Symbol.species],s=Buffer.from([0,0,255,255]),c=Symbol(`permessage-deflate`),l=Symbol(`total-length`),u=Symbol(`callback`),d=Symbol(`buffers`),f=Symbol(`error`),p;t.exports=class{constructor(e){if(this._options=e||{},this._threshold=this._options.threshold===void 0?1024:this._options.threshold,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,!p){let e=this._options.concurrencyLimit===void 0?10:this._options.concurrencyLimit;p=new i(e)}}static get extensionName(){return`permessage-deflate`}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits??(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&=(this._inflate.close(),null),this._deflate){let e=this._deflate[u];this._deflate.close(),this._deflate=null,e&&e(/* @__PURE__ */ Error(`The deflate stream was closed while data was being processed`))}}acceptAsServer(e){let t=this._options,n=e.find(e=>!(t.serverNoContextTakeover===!1&&e.server_no_context_takeover||e.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits==`number`&&t.serverMaxWindowBits>e.server_max_window_bits)||typeof t.clientMaxWindowBits==`number`&&(typeof e.client_max_window_bits==`number`?t.clientMaxWindowBits>e.client_max_window_bits:!e.client_max_window_bits)));if(!n)throw Error(`None of the extension offers can be accepted`);return t.serverNoContextTakeover&&(n.server_no_context_takeover=!0),t.clientNoContextTakeover&&(n.client_no_context_takeover=!0),typeof t.serverMaxWindowBits==`number`&&(n.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits==`number`?n.client_max_window_bits=t.clientMaxWindowBits:(n.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete n.client_max_window_bits,n}acceptAsClient(e){let t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw Error(`Unexpected parameter "client_no_context_takeover"`);if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits==`number`&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits==`number`&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw Error(`Unexpected or invalid parameter "client_max_window_bits"`);return t}normalizeParams(e){return e.forEach(e=>{Object.keys(e).forEach(t=>{let n=e[t];if(n.length>1)throw Error(`Parameter "${t}" must have only a single value`);if(n=n[0],t===`client_max_window_bits`){if(n!==!0){let e=+n;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${n}`);n=e}else if(!this._isServer)throw TypeError(`Invalid value for parameter "${t}": ${n}`)}else if(t===`server_max_window_bits`){let e=+n;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${n}`);n=e}else if(t===`client_no_context_takeover`||t===`server_no_context_takeover`){if(n!==!0)throw TypeError(`Invalid value for parameter "${t}": ${n}`)}else throw Error(`Unknown parameter "${t}"`);e[t]=n})}),e}decompress(e,t,n){p.add(r=>{this._decompress(e,t,(e,t)=>{r(),n(e,t)})})}compress(e,t,n){p.add(r=>{this._compress(e,t,(e,t)=>{r(),n(e,t)})})}_decompress(e,t,i){let a=this._isServer?`client`:`server`;if(!this._inflate){let e=`${a}_max_window_bits`,t=typeof this.params[e]==`number`?this.params[e]:n.Z_DEFAULT_WINDOWBITS;this._inflate=n.createInflateRaw({...this._options.zlibInflateOptions,windowBits:t}),this._inflate[c]=this,this._inflate[l]=0,this._inflate[d]=[],this._inflate.on(`error`,g),this._inflate.on(`data`,h)}this._inflate[u]=i,this._inflate.write(e),t&&this._inflate.write(s),this._inflate.flush(()=>{let e=this._inflate[f];if(e){this._inflate.close(),this._inflate=null,i(e);return}let n=r.concat(this._inflate[d],this._inflate[l]);tLine truncated
|
||||
/* istanbul ignore else */
|
||||
(g===void 0&&(g=Buffer.alloc(h)),r(g,0,h),_=0),n[0]=g[_++],n[1]=g[_++],n[2]=g[_++],n[3]=g[_++]),o=(n[0]|n[1]|n[2]|n[3])===0,a=6);let s;typeof e==`string`?(!t.mask||o)&&t[p]!==void 0?s=t[p]:(e=Buffer.from(e),s=e.length):(s=e.length,i=t.mask&&t.readOnly&&!o);let c=s;s>=65536?(a+=8,c=127):s>125&&(a+=2,c=126);let l=Buffer.allocUnsafe(i?s+a:a);return l[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(l[0]|=64),l[1]=c,c===126?l.writeUInt16BE(s,2):c===127&&(l[2]=l[3]=0,l.writeUIntBE(s,4,6)),!t.mask||(l[1]|=128,l[a-4]=n[0],l[a-3]=n[1],l[a-2]=n[2],l[a-1]=n[3],o)?[l,e]:i?(d(e,n,l,a,s),[l]):(d(e,n,e,0,s),[l,e])}close(t,n,r,a){let s;if(t===void 0)s=o;else if(typeof t!=`number`||!u(t))throw TypeError(`First argument must be a valid error code number`);else if(n===void 0||!n.length)s=Buffer.allocUnsafe(2),s.writeUInt16BE(t,0);else{let e=Buffer.byteLength(n);if(e>123)throw RangeError(`The message must not be greater than 123 bytes`);if(s=Buffer.allocUnsafe(2+e),s.writeUInt16BE(t,0),typeof n==`string`)s.write(n,2);else if(i(n))s.set(n,2);else throw TypeError(`Second argument must be a string or a Uint8Array`)}let c={[p]:s.length,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state===0?this.sendFrame(e.frame(s,c),a):this.enqueue([this.dispatch,s,!1,c,a])}ping(t,n,r){let i,a;if(typeof t==`string`?(i=Buffer.byteLength(t),a=!1):l(t)?(i=t.size,a=!1):(t=f(t),i=t.length,a=f.readOnly),i>125)throw RangeError(`The data size must not be greater than 125 bytes`);let o={[p]:i,fin:!0,generateMask:this._generateMask,mask:n,maskBuffer:this._maskBuffer,opcode:9,readOnly:a,rsv1:!1};l(t)?this._state===0?this.getBlobData(t,!1,o,r):this.enqueue([this.getBlobData,t,!1,o,r]):this._state===0?this.sendFrame(e.frame(t,o),r):this.enqueue([this.dispatch,t,!1,o,r])}pong(t,n,r){let i,a;if(typeof t==`string`?(i=Buffer.byteLength(t),a=!1):l(t)?(i=t.size,a=!1):(t=f(t),i=t.length,a=f.readOnly),i>125)throw RangeError(`The data size must not be greater than 125 bytes`);let o={[p]:i,fin:!0,generateMask:this._generateMask,mask:n,maskBuffer:this._maskBuffer,opcode:10,readOnly:a,rsv1:!1};l(t)?this._state===0?this.getBlobData(t,!1,o,r):this.enqueue([this.getBlobData,t,!1,o,r]):this._state===0?this.sendFrame(e.frame(t,o),r):this.enqueue([this.dispatch,t,!1,o,r])}send(e,t,n){let r=this._extensions[a.extensionName],i=t.binary?2:1,o=t.compress,s,c;typeof e==`string`?(s=Buffer.byteLength(e),c=!1):l(e)?(s=e.size,c=!1):(e=f(e),s=e.length,c=f.readOnly),this._firstFragment?(this._firstFragment=!1,o&&r&&r.params[r._isServer?`server_no_context_takeover`:`client_no_context_takeover`]&&(o=s>=r._threshold),this._compress=o):(o=!1,i=0),t.fin&&(this._firstFragment=!0);let u={[p]:s,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:i,readOnly:c,rsv1:o};l(e)?this._state===0?this.getBlobData(e,this._compress,u,n):this.enqueue([this.getBlobData,e,this._compress,u,n]):this._state===0?this.dispatch(e,this._compress,u,n):this.enqueue([this.dispatch,e,this._compress,u,n])}getBlobData(t,n,r,i){this._bufferedBytes+=r[p],this._state=2,t.arrayBuffer().then(t=>{if(this._socket.destroyed){let e=/* @__PURE__ */ Error(`The socket was closed while the blob was being read`);process.nextTick(v,this,e,i);return}this._bufferedBytes-=r[p];let a=f(t);n?this.dispatch(a,n,r,i):(this._state=0,this.sendFrame(e.frame(a,r),i),this.dequeue())}).catch(e=>{process.nextTick(ee,this,e,i)})}dispatch(t,n,r,i){if(!n){this.sendFrame(e.frame(t,r),i);return}let o=this._extensions[a.extensionName];this._bufferedBytes+=r[p],this._state=1,o.compress(t,r.fin,(t,n)=>{if(this._socket.destroyed){let e=/* @__PURE__ */ Error(`The socket was closed while data was being compressed`);v(this,e,i);return}this._bufferedBytes-=r[p],this._state=0,r.readOnly=!1,this.sendFrame(e.frame(n,r),i),this.dequeue()})}dequeue(){for(;this._state===0&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][p],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][p],this._queue.push(e)}sendFrame(e,t){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],t),this._socket.uncork()):this._socket.write(e[0],t)}};function v(e,t,n){typeof n==`function`&&n(t);for(let n=0;n<e._queue.length;n++){let r=e._queue[n],i=r[r.length-1];typeof i==`function`&&i(t)}}function ee(e,t,n){v(e,t,n),e.onerror(t)}})),DR=/* @__PURE__ */ x(((e,t)=>{let{kForOnEventAttribute:n,kListener:r}=bR(),i=Symbol(`kCode`),a=Symbol(`kData`),o=Symbol(`kError`),s=Symbol(`kMessage`),c=Symbol(`kReason`),l=Symbol(`kTarget`),u=Symbol(`kType`),d=Symbol(`kWasClean`);var f=class{constructor(e){this[l]=null,this[u]=e}get target(){return this[l]}get type(){return this[u]}};Object.defineProperty(f.prototype,"target",{enumerable:!0}),Object.defineProperty(f.prototype,"type",{enumerable:!0});var p=class extends f{constructor(e,t={}){super(e),this[i]=t.code===void 0?0:t.code,this[c]=t.reason===void 0?``:t.reason,this[d]=t.wasClean!==void 0&&t.wasClLine truncated
|
||||
/* istanbul ignore next */
|
||||
get onclose(){return null}
|
||||
/* istanbul ignore next */
|
||||
get onerror(){return null}
|
||||
/* istanbul ignore next */
|
||||
get onopen(){return null}
|
||||
/* istanbul ignore next */
|
||||
get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(t,n,r){let i=new p({allowSynchronousEvents:r.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxBufferedChunks:r.maxBufferedChunks,maxFragments:r.maxFragments,maxPayload:r.maxPayload,skipUTF8Validation:r.skipUTF8Validation}),a=new m(t,this._extensions,r.generateMask);this._receiver=i,this._sender=a,this._socket=t,i[ne]=this,a[ne]=this,t[ne]=this,i.on(`conclude`,ge),i.on(`drain`,_e),i.on(`error`,ve),i.on(`message`,be),i.on(`ping`,xe),i.on(`pong`,Se),a.onerror=we,t.setTimeout&&t.setTimeout(0),t.setNoDelay&&t.setNoDelay(),n.length>0&&t.unshift(n),t.on(`close`,Ee),t.on(`data`,De),t.on(`end`,Oe),t.on(`error`,ke),this._readyState=e.OPEN,this.emit(`open`)}emitClose(){if(!this._socket){this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage);return}this._extensions[f.extensionName]&&this._extensions[f.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage)}close(t,n){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){me(this,this._req,`WebSocket was closed before the connection was established`);return}if(this.readyState===e.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=e.CLOSING,this._sender.close(t,n,!this._isServer,e=>{e||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),Te(this)}}pause(){this.readyState!==e.CONNECTING&&this.readyState!==e.CLOSED&&(this._paused=!0,this._socket.pause())}ping(t,n,r){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(r=t,t=n=void 0):typeof n==`function`&&(r=n,n=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){he(this,t,r);return}n===void 0&&(n=!this._isServer),this._sender.ping(t||v,n,r)}pong(t,n,r){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(r=t,t=n=void 0):typeof n==`function`&&(r=n,n=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){he(this,t,r);return}n===void 0&&(n=!this._isServer),this._sender.pong(t||v,n,r)}resume(){this.readyState!==e.CONNECTING&&this.readyState!==e.CLOSED&&(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(t,n,r){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof n==`function`&&(r=n,n={}),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){he(this,t,r);return}let i={binary:typeof t!=`string`,mask:!this._isServer,compress:!0,fin:!0,...n};this._extensions[f.extensionName]||(i.compress=!1),this._sender.send(t||v,i,r)}terminate(){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){me(this,this._req,`WebSocket was closed before the connection was established`);return}this._socket&&(this._readyState=e.CLOSING,this._socket.destroy())}}};Object.defineProperty(T,"CONNECTING",{enumerable:!0,value:C.indexOf(`CONNECTING`)}),Object.defineProperty(T.prototype,"CONNECTING",{enumerable:!0,value:C.indexOf(`CONNECTING`)}),Object.defineProperty(T,"OPEN",{enumerable:!0,value:C.indexOf(`OPEN`)}),Object.defineProperty(T.prototype,"OPEN",{enumerable:!0,value:C.indexOf(`OPEN`)}),Object.defineProperty(T,"CLOSING",{enumerable:!0,value:C.indexOf(`CLOSING`)}),Object.defineProperty(T.prototype,"CLOSING",{enumerable:!0,value:C.indexOf(`CLOSING`)}),Object.defineProperty(T,"CLOSED",{enumerable:!0,value:C.indexOf(`CLOSED`)}),Object.defineProperty(T.prototype,"CLOSED",{enumerable:!0,value:C.indexOf(`CLOSED`)}),[`binaryType`,`bufferedAmount`,`extensions`,`isPaused`,`protocol`,`readyState`,`url`].forEach(e=>{Object.defineProperty(T.prototype,e,{enumerable:!0})}),[`open`,`error`,`close`,`message`].forEach(e=>{Object.defineProperty(T.prototype,`on${e}`,{enumerable:!0,get(){for(let t of this.listeners(e))if(t[y])return t[te];return null},set(t){for(let t of this.listeners(e))if(t[y]){this.removeListener(e,t);break}typeof t==`function`&&this.addEventListener(e,t,{[y]:!0})}})}),T.prototype.addEventListener=re,T.prototype.removeEventListener=ie,t.exports=T;function ue(e,t,n,a){let o={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:_,protocolVersion:le[1],maxBufferedChunks:262144,maxFragments:16384,maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...a,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:`GET`,host:void 0,path:void 0,port:void 0};if(e._autoPong=o.autoPong,e._closeTimeout=o.closeTimeout,!le.includes(o.protocolVersion))throw RangeError(`Unsupported protocol version: ${o.protocolVersion} (supported versions: ${le.join(`, `)})`);lLine truncated
|
||||
`).join(`\r
|
||||
`)),i.removeListener(`error`,g),p.setSocket(i,c,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxBufferedChunks:this.options.maxBufferedChunks,maxFragments:this.options.maxFragments,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(p),p.on(`close`,()=>{this.clients.delete(p),this._shouldEmitClose&&!this.clients.size&&process.nextTick(h,this)})),l(p,r)}};function m(e,t){for(let n of Object.keys(t))e.on(n,t[n]);return function(){for(let n of Object.keys(t))e.removeListener(n,t[n])}}function h(e){e._state=2,e.emit(`close`)}function g(){this.destroy()}function _(e,t,n,i){n||=r.STATUS_CODES[t],i={Connection:`close`,"Content-Type":`text/html`,"Content-Length":Buffer.byteLength(n),...i},e.once(`finish`,e.destroy),e.end(`HTTP/1.1 ${t} ${r.STATUS_CODES[t]}\r\n`+Object.keys(i).map(e=>`${e}: ${i[e]}`).join(`\r
|
||||
`)+`\r
|
||||
\r
|
||||
`+n)}function v(e,t,n,r,i,a){if(e.listenerCount(`wsClientError`)){let r=Error(i);Error.captureStackTrace(r,v),e.emit(`wsClientError`,r,n,t)}else _(n,r,i,a)}}));AR(),OR(),CR(),TR(),ER(),jR(),kR();var NR=/* @__PURE__ */ ae(MR(),1);const PR=e=>{switch(e){case`SHA-1`:return`sha1`;case`SHA-256`:return`sha256`;case`SHA-384`:return`sha384`;case`SHA-512`:return`sha512`}},FR=/* @__PURE__ */ op(_R,/* @__PURE__ */ vR({randomBytes:c.randomBytes,digest:(e,t)=>th({try:()=>Uint8Array.from(c.createHash(PR(e)).update(t).digest()),catch:e=>l_({module:`Crypto`,method:`digest`,_tag:`Unknown`,description:`Could not compute digest`,cause:e})})})),IR=e=>t=>u_({module:`FileSystem`,method:e,description:t.message??String(t)}),LR=(e,t)=>{let n=Number(e);if(!Number.isSafeInteger(n))throw RangeError(`${t} exceeds the safe integer range: ${e}`);return n},RR=e=>Hr(Lr(e),zg),zR=(e,t)=>th({try:()=>LR(e,`position`),catch:IR(t)}),BR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.access,/*#__PURE__*/ OE(`FileSystem`,`access`),/*#__PURE__*/ IR(`access`));return(t,n)=>{let r=l.constants.F_OK;return n?.readable&&(r|=l.constants.R_OK),n?.writable&&(r|=l.constants.W_OK),e(t,r)}})(),VR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.cp,/*#__PURE__*/ OE(`FileSystem`,`copy`),/*#__PURE__*/ IR(`copy`));return(t,n,r)=>e(t,n,{force:r?.overwrite??!1,preserveTimestamps:r?.preserveTimestamps??!1,recursive:!0})})(),HR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.copyFile,/*#__PURE__*/ OE(`FileSystem`,`copyFile`),/*#__PURE__*/ IR(`copyFile`));return(t,n)=>e(t,n)})(),UR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.chmod,/*#__PURE__*/ OE(`FileSystem`,`chmod`),/*#__PURE__*/ IR(`chmod`));return(t,n)=>e(t,n)})(),WR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.chown,/*#__PURE__*/ OE(`FileSystem`,`chown`),/*#__PURE__*/ IR(`chown`));return(t,n,r)=>e(t,n,r)})(),GR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.glob,/*#__PURE__*/ OE(`FileSystem`,`glob`),/*#__PURE__*/ IR(`glob`));return(t,n)=>e(t,{cwd:n?.root,exclude:n?.exclude})})(),KR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.link,/*#__PURE__*/ OE(`FileSystem`,`link`),/*#__PURE__*/ IR(`link`));return(t,n)=>e(t,n)})(),qR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ Mg(l.mkdir,/*#__PURE__*/ OE(`FileSystem`,`makeDirectory`),/*#__PURE__*/ IR(`makeDirectory`));return(t,n)=>e(t,{recursive:n?.recursive??!1,mode:n?.mode})})(),JR=e=>{let t=Mg(l.mkdtemp,OE(`FileSystem`,e),IR(e));return e=>M(()=>{let n=e?.prefix??``,r=typeof e?.directory==`string`?d.join(e.directory,`.`):u.tmpdir();return t(n?d.join(r,n):r+`/`)})},YR=/*#__PURE__*/ JR(`makeTempDirectory`),XR=e=>{let t=Mg(l.rm,OE(`FileSystem`,e),IR(e));return(e,n)=>t(e,{recursive:n?.recursive??!1,force:n?.force??!1})},ZR=/*#__PURE__*/ XR(`remove`),QR=/*#__PURE__*/ (()=>{let e=/*#__PURE__*/ JR(`makeTempDirectoryScoped`),t=/*#__PURE__*/ XR(`makeTempDirectoryScoped`);return n=>Yh(e(n),e=>xh(t(e,{recursive:!0})))})(),$R=/*#__PURE__*/ (e=>{let t=Mg(l.open,OE(`FileSystem`,e),IR(e)),n=Mg(l.close,OE(`FileSystem`,e),IR(e));return(e,r)=>he(Yh(t(e,r?.flag??`r`,r?.mode),e=>xh(n(e))),L(e=>ez(e,r?.flag?.startsWith(`a`)??!1)))})(`open`),ez=/*#__PURE__*/ (()=>{let e=e=>Mg(l.read,OE(`FileSystem`,e),IR(e)),t=/*#__PURE__*/ e(`read`),n=/*#__PURE__*/ e(`readAlloc`),r=/*#__PURE__*/ Mg(l.fstat,/*#__PURE__*/ OE(`FileSystem`,`stat`),/*#__PURE__*/ IR(`stat`)),i=/*#__PURE__*/ Mg(l.ftruncate,/*#__PURE__*/ OE(`FileSystem`,`truncate`),/*#__PURE__*/ IR(`truncate`)),a=/*#__PURE__*/ Mg(l.fsync,/*#__PURE__*/ OE(`FileSystem`,`sync`),/*#__PURE__*/ IR(`sync`)),o=e=>Mg(l.write,OE(`FileSystem`,e),IR(e)),s=/*#__PURE__*/ o(`write`),c=/*#__PURE__*/ o(`writeAll`);class u{[hx];fd;append;position=/*#__PURE__*/ BigInt(0);constructor(e,t){this[hx]=hx,this.fd=e,this.append=t}get stat(){return I(r(this.fd,{bigint:!0}),lz)}get sync(){return a(this.fd)}seek(e,t){return M(()=>{let n=t===`start`?e:this.position+e;return n<BigInt(0)?F(u_({module:`FileSystem`,method:`seek`,description:`Cannot seek before the start of the file`})):(this.position=n,j(n))})}read(e){return M(()=>{let n=this.position;return L(t(this.fd,{buffer:e,position:n}),e=>(this.position=n+BigInt(e),e))})}readAlloc(e){return M(()=>{try{if(!Number.isInteger(e)||e<0)throw RangeError(`size must be a non-negative integer`);let t=Buffer.allocUnsafeSlow(e),r=this.position;return L(n(this.fd,{buffer:t,position:r}),n=>{if(n===0)return D();if(this.position=r+BigInt(n),n===e)return O(t);let i=Buffer.allocUnsafeSlow(n);return t.copy(i,0,0,n),O(i)})}catch(e){return F(IR(`readAlloc`)(e))}})}truncate(e){return L(i(this.fd,e||void 0),()=>{if(!this.append){let t=BigInt(e??0);this.position>t&&(this.position=t)}})}write(e){return M(()=>{let t=this.position;return I(this.append?j(void 0):zR(t,`write`),n=>L(s(this.fd,e,void 0,void 0,n),e=>(this.append||(this.position=t+BigInt(e)),e)))})}writeAllChunk(e){return M(()=>{let t=this.position;return I(this.append?j(void 0):zR(t,`writeAll`),n=>I(c(this.fd,e,void 0,void 0,n),n=>n===0?F(l_({module:`FileSystem`,method:`writeAll`,_tag:`WriteZero`,pathOrDes
Line truncated
|
||||
`)}`:``;return(this.command?`Unrecognized flag: ${this.option} in command ${this.command.join(` `)}`:`Unrecognized flag: ${this.option}`)+e}},uV=class extends (/*#__PURE__*/ IM(`${sV}/DuplicateOption`)(`DuplicateOption`,{option:V,parentCommand:V,childCommand:V})){[sV]=sV;get message(){return`Duplicate flag name "${this.option}" in parent command "${this.parentCommand}" and subcommand "${this.childCommand}". Parent will always claim this flag (Mode A semantics). Consider renaming one of them to avoid confusion.`}},dV=class extends (/*#__PURE__*/ IM(`${sV}/MissingOption`)(`MissingOption`,{option:V})){[sV]=sV;get message(){return`Missing required flag: --${this.option}`}},fV=class extends (/*#__PURE__*/ IM(`${sV}/MissingArgument`)(`MissingArgument`,{argument:V})){[sV]=sV;get message(){return`Missing required argument: ${this.argument}`}},pV=class extends (/*#__PURE__*/ IM(`${sV}/UnexpectedArgument`)(`UnexpectedArgument`,{arguments:/*#__PURE__*/ U(V)})){[sV]=sV;get message(){return`Unexpected positional ${this.arguments.length===1?`argument`:`arguments`}: ${this.arguments.map(e=>JSON.stringify(e)).join(`, `)}`}},mV=class extends (/*#__PURE__*/ IM(`${sV}/InvalidValue`)(`InvalidValue`,{option:V,value:V,expected:V,kind:/*#__PURE__*/ W([/*#__PURE__*/ B(`flag`),/*#__PURE__*/ B(`argument`)])})){[sV]=sV;get message(){let e=this.expected.startsWith(`Expected `)||this.expected.startsWith(`Expected:`)?this.expected:`Expected: ${this.expected}`;return this.kind===`argument`?`Invalid value for argument <${this.option}>: "${this.value}". ${e}`:this.value.length===0?`Missing value for flag --${this.option}. ${e}`:`Invalid value for flag --${this.option}: "${this.value}". ${e}`}},hV=class extends (/*#__PURE__*/ IM(`${sV}/UnknownSubcommand`)(`UnknownSubcommand`,{subcommand:V,parent:/*#__PURE__*/ pj(/*#__PURE__*/ U(V)),suggestions:/*#__PURE__*/ U(V)})){[sV]=sV;get message(){let e=this.suggestions.length>0?`\n\n Did you mean this?\n ${this.suggestions.join(`
|
||||
`)}`:``;return this.parent?`Unknown subcommand "${this.subcommand}" for "${this.parent.join(` `)}"${e}`:`Unknown subcommand "${this.subcommand}"${e}`}};const gV=/*#__PURE__*/ W([lV,uV,dV,fV,pV,mV,hV,class extends (/*#__PURE__*/ IM(`${sV}/UserError`)(`UserError`,{cause:/*#__PURE__*/ uM(),userMessage:/*#__PURE__*/ fj(V)})){[sV]=sV;[gB]=!0;get message(){return this.userMessage?this.userMessage:typeof this.cause==`string`&&this.cause?this.cause:this.cause instanceof Error&&this.cause.message?this.cause.message:`An error occurred`}}]);var _V=class extends (/*#__PURE__*/ IM(`${sV}/ShowHelp`)(`ShowHelp`,{commandPath:/*#__PURE__*/ U(V),errors:/*#__PURE__*/ U(gV)})){[sV]=sV;[mB]=+!!this.errors.length;[gB]=!1;get message(){return`Help requested`}};const vV={"~effect/cli/Primitive":{_A:w}},yV=/*#__PURE__*/ tj(Bj),bV=/*#__PURE__*/ tj(Vj),xV=e=>e._tag===`Boolean`,SV=(e,t)=>Object.assign(Object.create(vV),{_tag:e,parse:t}),CV=(e,t)=>{let n=nj(zM(t));return SV(e,e=>R(n(e),e=>e.message))},wV=/*#__PURE__*/ CV(`Boolean`,Hj),TV=/*#__PURE__*/ CV(`Int`,oM),EV=/*#__PURE__*/ SV(`String`,e=>j(e)),DV=e=>{let t=new Map(e),n=e.map(([e])=>Ot(e)).join(` | `),r=SV(`Choice`,e=>t.has(e)?j(t.get(e)):F(n));return Object.assign(r,{choiceKeys:e.map(([e])=>e)})},OV=(e,t)=>{let n=SV(`Path`,z(function*(n){let r=yield*px,i=yield*vx,a=i.isAbsolute(n)?n:i.resolve(n),o=yield*R(r.exists(a),e=>`Failed to check path existence: ${e.message}`);if(t===!0&&!o)return yield*F(`Path does not exist: ${a}`);if(o&&e!==`either`){let t=yield*R(r.stat(a),e=>`Failed to stat path: ${e.message}`);if(e===`file`&&t.type!==`File`)return yield*F(`Path is not a file: ${a}`);if(e===`directory`&&t.type!==`Directory`)return yield*F(`Path is not a directory: ${a}`)}return a}));return Object.assign(n,{pathType:e})},kV=/*#__PURE__*/ SV(`KeyValuePair`,/*#__PURE__*/ z(function*(e){let t=e.indexOf(`=`);if(t===-1)return yield*F(`Invalid key=value format. Expected format: key=value, got: ${e}`);let n=e.slice(0,t),r=e.slice(t+1);return!n||!r?yield*F(`Invalid key=value format. Both key and value must be non-empty. Got: ${e}`):{[n]:r}})),AV=e=>{switch(e._tag){case`Boolean`:return`boolean`;case`String`:return`string`;case`Int`:return`integer`;case`Finite`:return`number`;case`Date`:return`date`;case`Path`:return`path`;case`Choice`:return`choice`;case`Redacted`:return`string`;case`FileText`:return`file`;case`FileParse`:return`file`;case`FileSchema`:return`file`;case`KeyValuePair`:return`key=value`;case`Never`:return`none`;default:return`value`}},jV=e=>e._tag===`Choice`?e.choiceKeys:void 0,MV=e=>e._tag===`Path`?e.pathType:void 0,NV=`\x1B[1m`,PV=`\x1B[4m`,FV=`\x1B[?25l`,IV=`\x1B[31m`,LV=`\x1B[32m`,RV=`\x1B[37m`,zV=`\x1B[90m`,BV=`\x1B[96m`,VV=(e,...t)=>`${t.flat().join(``)}${e}[0m`,HV=(...e)=>e,UV=(e,t)=>t===void 0?`[${Math.max(e+1,0)}G`:`[${t+1};${Math.max(e+1,0)}H`,WV=(e=1)=>`[${e}B`,GV=(e,t=0)=>{let n=``;return t<0&&(n+=`[${-t}A`),t>0&&(n+=`[${t}B`),e>0&&(n+=`[${e}C`),e<0&&(n+=`[${-e}D`),n},KV=e=>{let t=``;for(let n=0;n<e;n++)t+=`\x1B[2K`+(n<e-1?`\x1B[1A`:``);return e>0&&(t+=`\x1B[G`),t},qV={prefix:`?`,arrowUp:`↑`,arrowDown:`↓`,checkboxOn:`☒`,checkboxOff:`☐`,tick:`✔`,ellipsis:`…`,pointerSmall:`›`,pointer:`❯`,descriptionSeparator:`- `,passwordMask:`*`,toggleSeparator:`/`,primaryColor:BV,mutedColor:zV,successColor:LV,errorColor:IV,submittedColor:RV},JV={...qV,checkboxOn:`[*]`,checkboxOff:`[ ]`,tick:`√`,ellipsis:`...`,pointerSmall:`»`,pointer:`>`},YV=/*#__PURE__*/ ma(`effect/unstable/cli/Prompt/Theme`,{defaultValue:e=>({...process.platform===`win32`?JV:qV,...e})}),XV=e=>L(YV,t=>({...t,...e.theme})),ZV=e=>VV(e,NV),QV=(e,t)=>VV(e,HV(`\x1B[3m`,t)),$V=(e,...t)=>e.length===0?``:VV(e,...t),eH=(e,t)=>e.length===0?t:e+` `+t,tH=(e,t,n)=>{let r=Math.max(e.arrowUp.length,e.arrowDown.length);return t?e.arrowUp.padEnd(r):n?e.arrowDown.padEnd(r):` `.repeat(r)},nH=e=>{let t={initial:!1,...e,label:{confirm:`yes`,deny:`no`,...e.label},placeholder:{defaultConfirm:`(Y/n)`,defaultDeny:`(y/N)`,...e.placeholder}},n={value:t.initial};return rH(n,{render:DH(t),process:e=>AH(e,t.initial),clear:CH(t)})},rH=(e,...t)=>{let[n,r]=t.length===1?[void 0,t[0]]:[t[0],t[1]],i=Object.create(gH);return i._tag=`Loop`,i.initialState=e,i.render=r.render,i.process=r.process,i.clear=r.clear,i.events=n,i},iH=e=>{let t={initial:new globalThis.Date,dateMask:`YYYY-MM-DD HH:mm:ss`,validate:j,...e,locales:{...UH,...e.locales}},n=JH(t.dateMask,t.initial,t.locales),r={dateParts:n,typed:``,cursor:n.findIndex(e=>!e.isToken()),value:t.initial,error:D()};return rH(r,{render:WH(t),process:GH(t),clear:jH(t)})},aH=/*#__PURE__*/ C(2,(e,t)=>{let n=Object.create(gH);return n._tag=`OnSuccess`,n.prompt=e,n.onSuccess=t,n}),oH=e=>{let t={default:0,min:globalThis.Number.NEGATIVE_INFINITY,max:globalThis.Number.POSITIVE_INFINITY,incrementBy:1,decrementBy:1,precision:2,validate:e=>e<t.min?F(`${e} must be greater than or equal to ${t.min}`):e>t.max?F(`${e} must be less than or equal to ${t.max}`):j(e),...e},n=e.default===void 0?`Line truncated
|
||||
`}),DH=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>TH(t,e),Submit:({value:t})=>EH(t,e)}),OH=/^y|t$/,kH=/^n|f$/,AH=(e,t)=>{let n=Ir(e.input,()=>``);return e.key.name===`enter`||e.key.name===`return`?j(q.Submit({value:t})):OH.test(n.toLowerCase())?j(q.Submit({value:!0})):kH.test(n.toLowerCase())?j(q.Submit({value:!1})):j(q.Beep())},jH=e=>z(function*(t,n){let r=yield*(yield*Zz).columns,i=yield*XV(e),a=Ni(t.dateParts,``,(e,t)=>e+t.toString()),o=PH(i.prefix,i.pointerSmall,a,e,{plain:!0}),s=Pr(t.error)?gi(t.error.value.split(SH),{onEmpty:()=>``,onNonEmpty:e=>eH(i.pointerSmall,e.join(`
|
||||
`))}):``;return xH(o,r,s)+`\x1B[2K\x1B[G`}),MH=(e,t,n)=>{if(Pr(e.error)){let r=e.error.value.split(SH);if(yi(r)){let e=$V(t,n.errorColor),i=Mi(r,e=>QV(e,n.errorColor));return`\x1B[s
|
||||
`+eH(e,i.join(`
|
||||
`))+`\x1B[u`}}return``},NH=(e,t,n=!1)=>Ni(e.dateParts,``,(r,i,a)=>{let o=i.toString();if(a===e.cursor&&!n){let e=HV(PV,t.primaryColor);return r+VV(o,e)}return r+o}),PH=(e,t,n,r,i)=>aU(n,r.message,e,t,i),FH=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.prefix,n.primaryColor),i=$V(n.pointerSmall,n.mutedColor),a=NH(e,n),o=PH(r,i,a,t),s=MH(e,n.pointerSmall,n);return FV+o+s}),IH=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.tick,n.successColor),i=$V(n.ellipsis,n.mutedColor),a=NH(e,n,!0);return PH(r,i,a,t)+`
|
||||
`}),LH=e=>(e.dateParts[e.cursor].increment(),q.NextFrame({state:{...e,typed:``}})),RH=e=>(e.dateParts[e.cursor].decrement(),q.NextFrame({state:{...e,typed:``}})),zH=e=>{let t=e.dateParts[e.cursor].previousPart();return Pr(t)?q.NextFrame({state:{...e,typed:``,cursor:e.dateParts.indexOf(t.value)}}):q.Beep()},BH=e=>{let t=e.dateParts[e.cursor].nextPart();return Pr(t)?q.NextFrame({state:{...e,typed:``,cursor:e.dateParts.indexOf(t.value)}}):q.Beep()},VH=e=>{let t=e.dateParts[e.cursor].nextPart(),n=Fr(t,{onNone:()=>e.dateParts.findIndex(e=>!e.isToken()),onSome:t=>e.dateParts.indexOf(t)});return q.NextFrame({state:{...e,typed:``,cursor:n}})},HH=(e,t)=>{if(/\d/.test(e)){let n=t.typed+e;return t.dateParts[t.cursor].setValue(n),q.NextFrame({state:{...t,typed:n}})}return q.Beep()},UH={months:[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],monthsShort:[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],weekdays:[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],weekdaysShort:[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`]},WH=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>FH(t,e),Submit:()=>IH(t,e)}),GH=e=>(t,n)=>{switch(t.key.name){case`left`:return j(zH(n));case`right`:return j(BH(n));case`k`:case`up`:return j(LH(n));case`j`:case`down`:return j(RH(n));case`tab`:return j(VH(n));case`enter`:case`return`:return Fh(e.validate(n.value),{onFailure:e=>q.NextFrame({state:{...n,error:O(e)}}),onSuccess:e=>q.Submit({value:e})});default:return j(HH(Ir(t.input,()=>``),n))}},KH=/\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g,qH={1:({token:e,...t})=>new XH({token:e.replace(/\\(.)/g,`$1`),...t}),2:e=>new tU(e),3:e=>new nU(e),4:e=>new rU(e),5:e=>new iU(e),6:e=>new eU(e),7:e=>new $H(e),8:e=>new QH(e),9:e=>new ZH(e)},JH=(e,t,n)=>{let r=[],i=null;for(;i=KH.exec(e);){let e=i.shift(),a=i.findIndex(e=>e!==void 0);if(a in qH){let o=i[a]||e;r.push(qH[a]({token:o,date:t,parts:r,locales:n}))}else r.push(new XH({token:i[a]||e,date:t,parts:r,locales:n}))}let a=r.reduce((e,t)=>{let n=e[e.length-1];return t.isToken()&&n!==void 0&&n.isToken()?n.setValue(t.token):e.push(t),e},Ai());return r.splice(0,r.length,...a),r};var YH=class{token;date;parts;locales;constructor(e){this.token=e.token,this.locales=e.locales,this.date=e.date||new globalThis.Date,this.parts=e.parts||[this]}isToken(){return!1}nextPart(){let e=Ir(Ei(this.parts,e=>e===this),()=>0);return Di(this.parts.slice(e+1),e=>!e.isToken())}previousPart(){let e=Ei(this.parts,e=>e===this);return Pr(e)?Oi(this.parts.slice(0,e.value),e=>!e.isToken()):D()}toString(){return globalThis.String(this.date)}},XH=class extends YH{increment(){}decrement(){}setValue(e){this.token+=e}isToken(){return!0}toString(){return this.token}},ZH=class extends YH{increment(){this.date.setMilliseconds(this.date.getMilliseconds()+1)}decrement(){this.date.setMilliseconds(this.date.getMilliseconds()-1)}setValue(e){this.date.setMilliseconds(globalThis.Number.parseInt(e.slice(-this.token.length)))}toString(){return`${this.date.getMilliseconds()}`.padStart(4,`0`).substring(0,this.token.length)}},QH=class extends YH{increment(){this.date.setSeconds(this.date.getSeconds()+1)}decrement(){this.date.setSeconds(this.date.getSeconds()-1)}setValue(e){this.date.setSeconds(globalThis.Number.parseInt(e.slice(-2)))}toString(){let e=`${this.date.getSeconds()}`;return this.token.length>1?e.padStart(2,`0`):e}},$H=class extends YH{increment(){this.date.setMinutes(this.date.getMinutes()+1)}decrement(){this.date.setMinutes(this.date.getMinutes()-1)}setValue(e){this.date.setMinutes(globalThis.Number.parseInt(e.slice(-2)))}toString(){let e=`${this.date.getMinutes()}`;return this.token.length>1?e.padStart(2,`0`):e}},eU=class extends YH{increment(){this.date.setHours(this.date.getHours()+1)}decrement(){this.date.setHours(this.date.getHours()-1)}setValue(e){this.date.setHours(globalThis.Number.parseInt(e.slice(-2)))}toString(){let e=/h/.test(this.token)?this.date.getHours()%12||12:this.date.getHours();return this.token.length>1?`${e}`.padStart(2,`0`):`${e}`}},tU=class extends YH{increment(){this.date.setDate(this.date.getDate()+1)}decrement(){this.date.setDate(this.date.getDate()-1)}setValue(e){this.date.setDate(globalThis.Number.parseInt(e.slice(-2)))}toString(){let e=this.date.getDate(),t=this.date.getDay();switch(this.token){case`DD`:return`${e}`.padStart(2,`0`);case`Do`:return`${e}${this.ordinalIndicator(e)}`;case`d`:return`${t+1}`;case`ddd`:return this.locales.weekdaysShort[t];case`dddd`:return this.locales.weekdays[t];default:return`${e}`}}ordinalIndicator(e){if(e>=11&&e<=13)return`th`;switch(e%10){case 1:return`st`;case 2:return`nd`;case 3:return`rd`;default:return`th`}}},nU=class extends YH{increment(){this.date.setMonth(this.date.getMonth()+1)}decrement(){this.date.setMonth(this.date.getMonth()-1)}setValue(e){let t=globalThis.Number.parseInt(e.slice(-2)
Line truncated
|
||||
`))}})},oU=(e,t,n,r)=>{if(!e.disabled&&e.description&&t){let t=n.descriptionSeparator+e.description;return r?.plain===!0?t:VV(t,n.mutedColor)}return``},sU=e=>z(function*(t,n){let r=yield*(yield*Zz).columns,i=yield*XV(e),a=lU(t,i.pointerSmall,i,{plain:!0}),o=uU(t,i.prefix,i.pointerSmall,e,i,{plain:!0});return xH(o,r,a)+`\x1B[2K\x1B[G`}),cU=(e,t,n,r)=>{let i=e.value===``?``:`${e.value}`;if(t||r?.plain===!0)return i;let a=Pr(e.error)?n.errorColor:HV(PV,n.primaryColor);return VV(i,a)},lU=(e,t,n,r)=>Pr(e.error)?gi(e.error.value.split(SH),{onEmpty:()=>``,onNonEmpty:e=>{if(r?.plain===!0)return eH(t,e.join(`
|
||||
`));let i=$V(t,n.errorColor),a=Mi(e,e=>QV(e,n.errorColor));return`\x1B[s
|
||||
`+eH(i,a.join(`
|
||||
`))+`\x1B[u`}}):``,uU=(e,t,n,r,i,a,o=!1)=>{let s=cU(e,o,i,a);return aU(s,r.message,t,n,a)},dU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.prefix,n.primaryColor),i=$V(n.pointerSmall,n.mutedColor),a=lU(e,n.pointerSmall,n);return uU(e,r,i,t,n)+a}),fU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.tick,n.successColor),i=$V(n.ellipsis,n.mutedColor);return uU(e,r,i,t,n,void 0,!0)+`
|
||||
`}),pU=e=>{if(e.value.length<=0)return j(q.Beep());let t=e.value.slice(0,e.value.length-1);return j(q.NextFrame({state:{...e,value:t,error:D()}}))},mU=e=>j(q.NextFrame({state:{...e,cursor:0,value:``,error:D()}})),hU=(e,t)=>{if(t.value.length===0&&e===`-`)return j(q.NextFrame({state:{...t,value:`-`,error:D()}}));let n=globalThis.Number.parseInt(t.value+e);return globalThis.Number.isNaN(n)?j(q.Beep()):j(q.NextFrame({state:{...t,value:`${n}`,error:D()}}))},gU=(e,t)=>{if(e===`.`&&t.value.includes(`.`))return j(q.Beep());if(t.value.length===0&&e===`-`)return j(q.NextFrame({state:{...t,value:`-`,error:D()}}));let n=globalThis.Number.parseFloat(t.value+e);return globalThis.Number.isNaN(n)?j(q.Beep()):j(q.NextFrame({state:{...t,value:e===`.`?`${n}.`:t.value.includes(`.`)&&/^\d$/.test(e)?t.value+e:`${n}`,error:D()}}))},_U=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>dU(t,e),Submit:()=>fU(t,e)}),vU=e=>(t,n)=>{if(t.key.ctrl&&t.key.name===`u`)return mU(n);switch(t.key.name){case`backspace`:return pU(n);case`k`:case`up`:return j(q.NextFrame({state:{...n,value:n.value===``||n.value===`-`?`${e.incrementBy}`:`${globalThis.Number.parseInt(n.value)+e.incrementBy}`,error:D()}}));case`j`:case`down`:return j(q.NextFrame({state:{...n,value:n.value===``||n.value===`-`?`-${e.decrementBy}`:`${globalThis.Number.parseInt(n.value)-e.decrementBy}`,error:D()}}));case`enter`:case`return`:{let t=globalThis.Number.parseInt(n.value);return globalThis.Number.isNaN(t)?j(q.NextFrame({state:{...n,error:O(`Must provide an integer value`)}})):Fh(e.validate(t),{onFailure:e=>q.NextFrame({state:{...n,error:O(e)}}),onSuccess:e=>q.Submit({value:e})})}default:return hU(Ir(t.input,()=>``),n)}},yU=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>dU(t,e),Submit:()=>fU(t,e)}),bU=e=>(t,n)=>{if(t.key.ctrl&&t.key.name===`u`)return mU(n);switch(t.key.name){case`backspace`:return pU(n);case`k`:case`up`:return j(q.NextFrame({state:{...n,value:n.value===``||n.value===`-`?`${e.incrementBy}`:`${globalThis.Number.parseFloat(n.value)+e.incrementBy}`,error:D()}}));case`j`:case`down`:return j(q.NextFrame({state:{...n,value:n.value===``||n.value===`-`?`-${e.decrementBy}`:`${globalThis.Number.parseFloat(n.value)-e.decrementBy}`,error:D()}}));case`enter`:case`return`:{let t=globalThis.Number.parseFloat(n.value);return globalThis.Number.isNaN(t)?j(q.NextFrame({state:{...n,error:O(`Must provide a floating point value`)}})):I(N(()=>fm(t,e.precision)),t=>Fh(e.validate(t),{onFailure:e=>q.NextFrame({state:{...n,error:O(e)}}),onSuccess:e=>q.Submit({value:e})}))}default:return gU(Ir(t.input,()=>``),n)}},xU=(e,t,n,r)=>n.message===void 0?void 0:aU(``,n.message,e,t,r),SU=(e,t)=>e===void 0?t:e+`
|
||||
`+t,CU=(e,t,n,r,i,a)=>{let o=tH(i,r===n.startIndex&&n.startIndex>0,r===n.endIndex-1&&n.endIndex<t.length);if(a?.plain===!0)return e===r?i.pointer+o:o+` `.repeat(i.pointer.length);if(t[r].disabled){let t=HV(NV,i.mutedColor);return e===r?$V(i.pointer,t)+o:o+` `.repeat(i.pointer.length)}return e===r?$V(i.pointer,i.primaryColor)+o:o+` `.repeat(i.pointer.length)},wU=(e,t,n,r)=>{if(r?.plain===!0)return e.title;let i=e.title;return t?e.disabled?VV(i,HV(PV,n.mutedColor)):VV(i,HV(PV,n.primaryColor)):e.disabled?VV(i,HV(`\x1B[9m`,n.mutedColor)):i},TU=(e,t,n,r)=>{let i=t.choices,a=sW(e,i.length,t.maxPerPage),o=[];for(let t=a.startIndex;t<a.endIndex;t++){let s=i[t],c=e===t,l=CU(e,i,a,t,n,r),u=wU(s,c,n,r),d=oU(s,c,n,r);o.push(l+u+` `+d)}return o.join(`
|
||||
`)},EU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=TU(e,t,n),i=$V(n.prefix,n.primaryColor),a=$V(n.pointerSmall,n.mutedColor),o=xU(i,a,t);return FV+SU(o,r)}),DU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=t.choices[e].title,i=$V(n.tick,n.successColor),a=$V(n.ellipsis,n.mutedColor);return(xU(i,a,t)??i)+` `+VV(r,n.submittedColor)+`
|
||||
`}),OU=(e,t)=>j(e===0?q.NextFrame({state:t.length-1}):q.NextFrame({state:e-1})),kU=(e,t)=>e===t.length-1?j(q.NextFrame({state:0})):j(q.NextFrame({state:e+1})),AU=(e,t)=>j(q.NextFrame({state:(e+1)%t.length})),jU=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>EU(t,e),Submit:()=>DU(t,e)}),MU=e=>z(function*(t,n){let r=yield*(yield*Zz).columns,i=yield*XV(e),a=xU(i.prefix,i.pointerSmall,e,{plain:!0}),o=TU(t,e,i,{plain:!0});return yH(SU(a,o),r)+`\x1B[2K\x1B[G`}),NU=e=>(t,n)=>{switch(t.key.name){case`k`:case`up`:return OU(n,e.choices);case`j`:case`down`:return kU(n,e.choices);case`tab`:return AU(n,e.choices);case`enter`:case`return`:{let t=e.choices[n];return t.disabled?j(q.Beep()):j(q.Submit({value:t.value}))}default:return j(q.Beep())}},PU=/*#__PURE__*/ z(function*(e,t){let n=yield*(yield*Zz).columns,r=yield*XV(t),i=IU(e,r.pointerSmall,r,{plain:!0});return xH(LU(e,r.prefix,r.pointerSmall,t,r,{plain:!0}),n,i)+`\x1B[2K\x1B[G`}),FU=(e,t,n,r,i)=>{let a=e.value;if(i?.plain===!0)switch(t.type){case`hidden`:return``;case`password`:return n.passwordMask.repeat(a.length);case`text`:return a}if(a.length===0)return``;let o=Pr(e.error)?n.errorColor:r?n.submittedColor:HV(PV,n.primaryColor);switch(t.type){case`hidden`:return``;case`password`:return $V(n.passwordMask.repeat(a.length),o);case`text`:return VV(a,o)}},IU=(e,t,n,r)=>Pr(e.error)?gi(e.error.value.split(SH),{onEmpty:()=>``,onNonEmpty:e=>{if(r?.plain===!0)return eH(t,e.join(`
|
||||
`));let i=$V(t,n.errorColor),a=Mi(e,e=>QV(e,n.errorColor));return`\x1B[s
|
||||
`+eH(i,a.join(`
|
||||
`))+`\x1B[u`}}):``,LU=(e,t,n,r,i,a,o=!1)=>{let s=FU(e,r,i,o,a);return aU(s,r.message,t,n,a)},RU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.prefix,n.primaryColor),i=$V(n.pointerSmall,n.mutedColor),a=LU(e,r,i,t,n),o=IU(e,n.pointerSmall,n),s=t.type===`password`?n.passwordMask.length:1,c=(e.cursor-e.value.length)*s;return a+o+GV(c)}),zU=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.tick,n.successColor),i=$V(n.ellipsis,n.mutedColor);return LU(e,r,i,t,n,void 0,!0)+`
|
||||
`}),BU=e=>{if(e.cursor<=0)return j(q.Beep());let t=e.value.slice(0,e.cursor-1),n=e.value.slice(e.cursor),r=e.cursor-1,i=`${t}${n}`;return j(q.NextFrame({state:{...e,cursor:r,value:i,error:D()}}))},VU=e=>j(q.NextFrame({state:{...e,cursor:0,value:``,error:D()}})),HU=e=>{if(e.cursor<=0)return j(q.Beep());let t=e.cursor-1;return j(q.NextFrame({state:{...e,cursor:t,error:D()}}))},UU=e=>{if(e.cursor>=e.value.length)return j(q.Beep());let t=Math.min(e.cursor+1,e.value.length);return j(q.NextFrame({state:{...e,cursor:t,error:D()}}))},WU=e=>j(q.NextFrame({state:{...e,cursor:0,error:D()}})),GU=e=>j(q.NextFrame({state:{...e,cursor:e.value.length,error:D()}})),KU=(e,t)=>{if(e.value===t.default)return j(q.Beep());let n=e.value.length===0?t.default:e.value;return j(q.NextFrame({state:{...e,value:n,cursor:n.length,error:D()}}))},qU=(e,t)=>{let n=`${t.value.slice(0,t.cursor)}${e}${t.value.slice(t.cursor)}`,r=t.cursor+e.length;return j(q.NextFrame({state:{...t,cursor:r,value:n,error:D()}}))},JU=e=>(t,n)=>q.$match(n,{Beep:()=>j(`\x07`),NextFrame:({state:t})=>RU(t,e),Submit:()=>zU(t,e)}),YU=e=>(t,n)=>{if(t.key.ctrl)switch(t.key.name){case`u`:return VU(n);case`a`:return WU(n);case`e`:return GU(n);default:return j(q.Beep())}switch(t.key.name){case`backspace`:return BU(n);case`left`:return HU(n);case`right`:return UU(n);case`home`:return WU(n);case`end`:return GU(n);case`enter`:case`return`:{let t=n.value;return Fh(e.validate(t),{onFailure:e=>q.NextFrame({state:{...n,value:t,error:O(e)}}),onSuccess:e=>q.Submit({value:e})})}case`tab`:return KU(n,e);default:return qU(Ir(t.input,()=>``),n)}},XU=e=>(t,n)=>PU(t,e),ZU=(e,t)=>{let n={default:``,type:t,validate:j,...e},r={cursor:n.default.length,value:n.default,error:D()};return rH(r,{render:JU(n),process:YU(n),clear:XU(n)})},QU=/*#__PURE__*/ z(function*(e){let t=yield*(yield*Zz).columns,n=yield*XV(e),r=e.active+` `+eH(n.toggleSeparator,e.inactive),i=aU(r,e.message,n.prefix,n.pointerSmall,{plain:!0});return yH(i,t)+`\x1B[2K\x1B[G`}),$U=(e,t,n,r=!1)=>{let i=$V(n.toggleSeparator,n.mutedColor),a=HV(PV,r?n.submittedColor:n.primaryColor),o=e?t.inactive:VV(t.inactive,a);return(e?VV(t.active,a):t.active)+` `+eH(i,o)},eW=(e,t,n,r)=>aU(e,r.message,t,n),tW=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.prefix,n.primaryColor),i=$V(n.pointerSmall,n.mutedColor),a=$U(e,t,n),o=eW(a,r,i,t);return FV+o}),nW=/*#__PURE__*/ z(function*(e,t){let n=yield*XV(t),r=$V(n.tick,n.successColor),i=$V(n.ellipsis,n.mutedColor),a=$U(e,t,n,!0);return eW(a,r,i,t)+`
|
||||
`}),rW=/*#__PURE__*/ j(/*#__PURE__*/ q.NextFrame({state:!0})),iW=/*#__PURE__*/ j(/*#__PURE__*/ q.NextFrame({state:!1})),aW=e=>(t,n)=>{switch(n._tag){case`Beep`:return j(`\x07`);case`NextFrame`:return tW(t,e);case`Submit`:return nW(t,e)}},oW=(e,t)=>{switch(e.key.name){case`0`:case`j`:case`delete`:case`right`:case`down`:return iW;case`1`:case`k`:case`left`:case`up`:return rW;case` `:case`tab`:return t?iW:rW;case`enter`:case`return`:return j(q.Submit({value:t}));default:return j(q.Beep())}},sW=(e,t,n)=>{let r=n===void 0?t:n,i=Math.min(t-r,e-Math.floor(r/2));i<0&&(i=0);let a=Math.min(i+r,t);return{startIndex:i,endIndex:a}},cW=`~effect/cli/Param`,lW=`flag`,uW={[cW]:{_A:w},pipe(){return S(this,arguments)}},dW=e=>E(e,cW),fW=e=>e.kind===`flag`,pW=e=>{let t=t=>e.kind===`argument`?PW(e.name,e.primitiveType,t):FW(e.name,e.primitiveType,t);return Object.setPrototypeOf({_tag:`Single`,...e,description:e.description??D(),aliases:e.aliases??[],hidden:e.hidden??!1,parse:t},uW)},mW=(e,t)=>pW({name:t,primitiveType:EV,kind:e}),hW=(e,t)=>pW({name:t,primitiveType:wV,kind:e}),gW=(e,t)=>pW({name:t,primitiveType:TV,kind:e}),_W=(e,t,n)=>pW({name:t,primitiveType:DV(n),kind:e}),vW=(e,t,n)=>{let r=n.map(e=>[e,e]);return _W(e,t,r)},yW=(e,t,n)=>pW({name:t,kind:e,primitiveType:OV(n?.pathType??`either`,n?.mustExist),typeName:n?.typeName}),bW=(e,t,n)=>yW(e,t,{pathType:`directory`,typeName:`directory`,mustExist:n?.mustExist}),xW=(e,t)=>TW(AW(pW({name:t,primitiveType:kV,kind:e}),{min:1}),e=>Object.fromEntries(e.flatMap(Object.entries))),SW=/^-+/,CW=/*#__PURE__*/ C(2,(e,t)=>zW(e,e=>pW({...e,aliases:[...e.aliases,t.replace(SW,``)]}))),wW=/*#__PURE__*/ C(2,(e,t)=>zW(e,e=>pW({...e,description:O(t)}))),TW=/*#__PURE__*/ C(2,(e,t)=>Object.assign(Object.create(uW),{_tag:`Map`,kind:e.kind,param:e,f:t,parse:n=>L(e.parse(n),([e,n])=>[e,t(n)])})),EW=(e,t,n=[])=>{let r=n.map(e=>()=>e().parse);return Object.assign(Object.create(uW),{_tag:`Transform`,kind:e.kind,param:e,alternatives:n,f:t,parse:t(e.parse,r)})},DW=/*#__PURE__*/ C(2,(e,t)=>EW(e,e=>n=>I(e(n),([e,n])=>t(n).pipe(L(t=>[e,t]))))),OW=e=>Object.assign(Object.create(uW),{_tag:`Optional`,kind:e.kind,param:e,parse:t=>e.parse(t).pipe(L(([e,t])=>[e,O(t)]),_h({MissingOption:()=>j([t.arguments,D()]),MissingArgument:()=>j([t.arguments,D()])}))}),kW=/*#__PURE__*/ C(2,(e,t)=>Um(t)?DW(OW(e),Fr({onNone:()=>t,onSome:j})):TW(OW(e),Ir(()=>t))),AW=(e,t)=>{let n=VW(e);return Object.assign(Object.create(uW),{_tag:`Variadic`,kind:e.kind,param:e,min:Rr(t?.min),max:Rr(t?.max),parse:r=>n.kind===`argument`?IW(e,n,r,t):LW(e,n,r,t)})},jW=/*#__PURE__*/ C(2,(e,t)=>zW(e,e=>pW({...e,typeName:t}))),MW=/*#__PURE__*/ C(2,(e,t)=>{let n=nj(t);return DW(e,t=>R(n(t),n=>{let r=VW(e);return new mV({option:r.name,value:globalThis.String(t),expected:`Schema validation failed: ${n.message}`,kind:r.kind})}))}),NW=/*#__PURE__*/ C(2,(e,t)=>EW(e,(e,t)=>n=>hh(e(n),()=>t[0]()(n)),[t])),PW=/*#__PURE__*/ z(function*(e,t,n){if(n.arguments.length===0)return yield*new fV({argument:e});let r=n.arguments[0],i=yield*R(t.parse(r),t=>new mV({option:e,value:r,expected:t,kind:`argument`}));return[n.arguments.slice(1),i]}),FW=/*#__PURE__*/ z(function*(e,t,n){let r=n.flags[e];if(r===void 0||r.length===0)return yield*new dV({option:e});let i=r[0],a=yield*R(t.parse(i),t=>new mV({option:e,value:i,expected:t,kind:`flag`}));return[n.arguments,a]}),IW=/*#__PURE__*/ z(function*(e,t,n,r){let i=[],a=r?.min??0,o=r?.max??1/0,s=0,c=n.arguments;for(;c.length>0&&s<o;){let[t,r]=yield*e.parse({flags:n.flags,arguments:c});i.push(r),c=t,s++}return s<a?yield*s===0?new fV({argument:t.name}):new mV({option:t.name,value:`${s} values`,expected:`at least ${a} value${a===1?``:`s`}`,kind:t.kind}):[c,i]}),LW=/*#__PURE__*/ z(function*(e,t,n,r){let i=[],a=[t.name,...t.aliases].flatMap(e=>n.flags[e]??[]),o=a.length;if(ke(r?.min)&&o<r.min)return yield*o===0?new dV({option:t.name}):new mV({option:t.name,value:`${o} occurrences`,expected:`at least ${r.min} value${r.min===1?``:`s`}`,kind:t.kind});if(ke(r?.max)&&o>r.max)return yield*new mV({option:t.name,value:`${o} occurrences`,expected:`at most ${r.max} value${r.max===1?``:`s`}`,kind:t.kind});for(let n of a){let[,r]=yield*e.parse({flags:{[t.name]:[n]},arguments:[]});i.push(r)}return[n.arguments,i]}),RW=(e,t)=>{let n=e;switch(n._tag){case`Single`:return t.Single(n);case`Map`:return t.Map(n);case`Transform`:return t.Transform(n);case`Optional`:return t.Optional(n);case`Variadic`:return t.Variadic(n)}},zW=(e,t)=>RW(e,{Single:e=>t(e),Map:e=>TW(zW(e.param,t),e.f),Transform:e=>EW(zW(e.param,t),e.f,e.alternatives.map(e=>()=>zW(e(),t))),Optional:e=>OW(zW(e.param,t)),Variadic:e=>AW(zW(e.param,t),{min:zr(e.min),max:zr(e.max)})}),BW=e=>RW(e,{Single:e=>[e],Map:e=>BW(e.param),Transform:e=>[...BW(e.param),...e.alternatives.flatMap(e=>BW(e()))],Optional:e=>BW(e.param),Variadic:e=>BW(e.param)}),VW=e=>{let t=BW(e);if(t.length===0)throw Error(`No Single param found in param structure`);if(t.length>1)throw Error(`Multiple Single params found: ${t.map(e=>e.namLine truncated
|
||||
`)},formatVersion:(e,t)=>`${i.bold(e)} ${i.dim(`v`)}${i.bold(t)}`}},YW=e=>e.replace(/\u001B\[[0-9;]*m/g,``),XW=/*#__PURE__*/ new Intl.Segmenter(void 0,{granularity:`grapheme`}),ZW=/[\p{Mark}\p{Control}\p{Default_Ignorable_Code_Point}]/gu,QW=/\p{Emoji_Presentation}/u,$W=e=>e<4352?!1:e<=4447||e===9001||e===9002||e>=11904&&e<=12350||e>=12352&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65135||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=110592&&e<=111359||e>=127488&&e<=127569||e>=131072&&e<=262141,eG=e=>{let t=e.replace(ZW,``);return t.length===0?0:QW.test(e)||e.includes(`️`)||$W(t.codePointAt(0))?2:1},tG=e=>{let t=0;for(let{segment:n}of XW.segment(YW(e)))t+=eG(n);return t},nG=(e,t)=>{let n=tG(e),r=Math.max(0,t-n);return e+` `.repeat(r)},rG=(e,t)=>{let n=Math.max(...e.map(e=>tG(e.left)))+4,r=t===void 0?n:Math.min(n,t);return e.map(({left:e,right:t})=>` ${nG(e,Math.max(r,tG(e)+1))}${t}`).join(`
|
||||
`)},iG=(e,t)=>t?`${e}, ${t}`:e,aG=(e,t)=>{let n=[];if(e.description&&(n.push(t.bold(`DESCRIPTION`)),n.push(` ${e.description}`),n.push(``)),n.push(t.bold(`USAGE`)),n.push(` ${t.cyan(e.usage)}`),n.push(``),e.args&&e.args.length>0){n.push(t.bold(`ARGUMENTS`));let r=e.args.map(e=>{let n=e.name;e.variadic&&(n+=`...`);let r=`${t.green(n)} ${t.dim(e.type)}`,i=e.required?``:t.dim(` (optional)`);return{left:r,right:Ir(e.description,()=>``)+i}});n.push(rG(r,25)),n.push(``)}if(e.flags.length>0){n.push(t.bold(`FLAGS`));let r=e.flags.map(e=>{let n=[];n.push(t.green(`--${e.name}`));for(let r of e.aliases)n.push(t.green(r));return{left:n.join(`, `)+(e.type===`boolean`?``:` ${t.dim(e.type)}`),right:Ir(e.description,()=>``)}});n.push(rG(r)),n.push(``)}if(e.globalFlags&&e.globalFlags.length>0){n.push(t.bold(`GLOBAL FLAGS`));let r=e.globalFlags.map(e=>{let n=[];n.push(t.green(`--${e.name}`));for(let r of e.aliases)n.push(t.green(r));return{left:n.join(`, `)+(e.type===`boolean`?``:` ${t.dim(e.type)}`),right:Ir(e.description,()=>``)}});n.push(rG(r)),n.push(``)}if(e.subcommands&&e.subcommands.length>0){let r=e.subcommands.find(e=>e.group===void 0);r&&(n.push(t.bold(`SUBCOMMANDS`)),n.push(rG(r.commands.map(e=>({left:t.cyan(iG(e.name,e.alias)),right:e.shortDescription??e.description})),20)),e.subcommands.length>1&&n.push(``));for(let r of e.subcommands)r.group!==void 0&&(n.push(t.bold(`${r.group}:`)),n.push(rG(r.commands.map(e=>({left:t.cyan(iG(e.name,e.alias)),right:e.shortDescription??e.description})),20)),n.push(``))}if(e.examples&&e.examples.length>0){n.push(t.bold(`EXAMPLES`));let r=!0,i=!1;for(let a of e.examples)a.description?(r||n.push(``),n.push(` ${t.dim(`# ${a.description}`)}`)):i&&n.push(``),n.push(` ${t.cyan(a.command)}`),r=!1,i=!!a.description;n.push(``)}return n[n.length-1]===``&&n.pop(),n.join(`
|
||||
`)},oG=e=>e.replace(/'/g,`'\\''`),sG=e=>e.replace(/[^a-zA-Z0-9_]/g,`_`),cG=e=>{let t=[`--${e.name}`];for(let n of e.aliases)t.push(n.length===1?`-${n}`:`--${n}`);return e.type._tag===`Boolean`&&t.push(`--no-${e.name}`),t},lG=(e,t)=>{if(e.length===0)return;let n=e.map(cG);t.push(` local ${n.map((e,t)=>`_used_${t}=""`).join(` `)}`),t.push(` for ((i = 1; i < cword; i++)); do`),t.push(' case "${words[i]%%=*}" in'),n.forEach((e,n)=>{t.push(` ${e.join(`|`)}) _used_${n}=1 ;;`)}),t.push(` esac`),t.push(` done`),t.push(` local _filtered_flags=""`),n.forEach((e,n)=>{t.push(` [[ -n "$_used_${n}" ]] || _filtered_flags+=" ${e.join(` `)}"`)}),t.push(``)},uG=(e,t)=>{t.push(`${e}()`),t.push(`{`),t.push(` local _cur="$1" _word="$2"; shift 2`),t.push(``),t.push(' local _head="${_cur%"$_word"}"'),t.push(` local _open=""`),t.push(` case "$_head" in`),t.push(` *\\') _open="'" ;;`),t.push(` *\\") _open='"' ;;`),t.push(` esac`),t.push(``),t.push(` local _prefix="$_cur" _committed="$_head"`),t.push(" _prefix=${_prefix//\\\\/}; _prefix=${_prefix//\\\"/}; _prefix=${_prefix//\\'/}"),t.push(" _committed=${_committed//\\\\/}; _committed=${_committed//\\\"/}; _committed=${_committed//\\'/}"),t.push(``),t.push(` COMPREPLY=()`),t.push(` local _choice _rest _match`),t.push(` for _choice in "$@"; do`),t.push(` [[ "$_choice" == "$_prefix"* ]] || continue`),t.push(' _rest="${_choice#"$_committed"}"'),t.push(` case "$_open" in`),t.push(` "'")`),t.push(` if [[ "$_head" == "'" ]]; then`),t.push(" _match=${_rest//\\'/\\'\\\\\\'\\'}"),t.push(` else`),t.push(` [[ "$_rest" == *\\'* ]] && continue`),t.push(` _match="$_rest"`),t.push(` fi`),t.push(` ;;`),t.push(` '"')`),t.push(' _match="${_rest//\\\\/\\\\\\\\}"'),t.push(' _match="${_match//\\$/\\\\$}"'),t.push(' _match="${_match//\\`/\\\\\\`}"'),t.push(' _match="${_match//\\"/\\\\\\"}"'),t.push(` ;;`),t.push(` *)`),t.push(` printf -v _match '%q' "$_rest"`),t.push(` [[ -z "$_head" && "$_match" == '~'* ]] && _match="\\\\$_match"`),t.push(` ;;`),t.push(` esac`),t.push(` [[ -n "$_open" && "$_match" == *"$_open" ]] && _match+="$_open"`),t.push(` COMPREPLY+=("$_match")`),t.push(` done`),t.push(`}`),t.push(``)},dG=(e,t)=>`${e} "$cur" "$_comp_word" ${t.map(e=>`'${oG(e)}'`).join(` `)}`,fG=(e,t)=>{switch(e._tag){case`Boolean`:return;case`Choice`:return dG(t,e.values);case`Path`:return e.pathType===`directory`?`COMPREPLY=( $(compgen -d -- "$cur") )`:`COMPREPLY=( $(compgen -f -- "$cur") )`;default:return}},pG=(e,t)=>{switch(e._tag){case`Choice`:return dG(t,e.values);case`Path`:return e.pathType===`directory`?`COMPREPLY=( $(compgen -d -- "$cur") )`:`COMPREPLY=( $(compgen -f -- "$cur") )`;default:return}},mG=(e,t,n,r)=>{let i=[...t,e.name],a=`_${i.map(sG).join(`_`)}`;n.push(`${a}()`),n.push(`{`),n.push(` local cur prev words cword i`),n.push(t.length===0?` local _command_index=0`:` local _command_index="$1"`),n.push(` _init_completion -n "$COMP_WORDBREAKS" || return`),t.length===0&&n.push(` local _comp_word="$2"`),n.push(``);let o=e.flags.filter(e=>e.type._tag!==`Boolean`);if(o.length>0){n.push(` # Flag value completions`),n.push(` case "$prev" in`);for(let e of o){let t=[`--${e.name}`];for(let n of e.aliases)t.push(n.length===1?`-${n}`:`--${n}`);let i=fG(e.type,r);i&&(n.push(` ${t.join(`|`)})`),n.push(` ${i}`),n.push(` return`),n.push(` ;;`))}n.push(` esac`),n.push(``)}if(e.subcommands.length>0){n.push(` # Subcommand dispatch`),n.push(` local cmd _skip_next=0`),n.push(` for ((i = _command_index + 1; i < cword; i++)); do`),n.push(` if (( _skip_next )); then`),n.push(` _skip_next=0`),n.push(` continue`),n.push(` fi`),n.push(' case "${words[i]}" in');for(let t of e.flags){if(t.type._tag===`Boolean`)continue;let e=cG(t);n.push(` ${e.join(`|`)}) _skip_next=1 ;;`),n.push(` ${e.map(e=>`${e}=*`).join(`|`)}) ;;`)}for(let t of e.subcommands){let e=`_${[...i,t.name].map(sG).join(`_`)}`;n.push(` ${t.name})`),n.push(` ${e} "$i"`),n.push(` return`),n.push(` ;;`)}n.push(` esac`),n.push(` done`),n.push(``)}lG(e.flags,n),(e.flags.length>0||e.subcommands.length>0)&&(n.push(` # Complete flags (filtered) and subcommands`),n.push(` if [[ "$cur" == -* ]]; then`),e.flags.length>0&&n.push(` COMPREPLY=( $(compgen -W "$_filtered_flags" -- "$cur") )`),n.push(` return`),n.push(` fi`),n.push(``));let s=e.arguments.flatMap((e,t)=>{let n=pG(e.type,r);return n===void 0?[]:[{argument:e,completion:n,index:t}]});if(s.length>0){n.push(` # Positional argument completions`),n.push(` local _position=0 _skip_next=0 _end_of_options=0`),n.push(` for ((i = _command_index + 1; i < cword; i++)); do`),n.push(` if (( _skip_next )); then`),n.push(` _skip_next=0`),n.push(` continue`),n.push(` fi`),n.push(` if (( _end_of_options )); then`),n.push(` ((_position += 1)
Line truncated
|
||||
`)},gG=e=>e.replace(/\\/g,`\\\\`).replace(/'/g,`\\'`),_G=e=>gG(e.replace(/[^A-Za-z0-9_.,/@%+-]/gu,`\\$&`)),vG=(e,t)=>{if(e.length===0)return t.length>0?`__fish_use_subcommand`:``;let n=e.map(e=>`__fish_seen_subcommand_from ${e}`).join(`; and `);return t.length>0?`${n}; and not __fish_seen_subcommand_from ${t.join(` `)}`:n},yG=e=>{let t=[];for(let n of e.aliases)n.length===1&&t.push(`-s ${n}`);t.push(e.name);for(let n of e.aliases)n.length>1&&t.push(n);return e.type._tag===`Boolean`&&t.push(`no-${e.name}`),`not __fish_contains_opt ${t.join(` `)}`},bG=e=>{let t=[`--${e.name}`];for(let n of e.aliases)t.push(n.length===1?`-${n}`:`--${n}`);return`begin; ${yG(e)}; or contains -- (commandline -poc)[-1] ${t.join(` `)}; end`},xG=e=>{let t=[`-l ${e.name}`];for(let n of e.aliases)n.length===1?t.push(`-s ${n}`):t.push(`-l ${n}`);e.description&&t.push(`-d '${gG(e.description)}'`);let n=SG(e.type);return n&&t.push(n),t},SG=e=>{switch(e._tag){case`Boolean`:return;case`Choice`:return`-r -f -a '${e.values.map(_G).join(` `)}'`;case`Path`:return e.pathType,`-r -F`;default:return`-r -f`}},CG=e=>{switch(e._tag){case`Choice`:return`-r -f -a '${e.values.map(_G).join(` `)}'`;case`Path`:return`-r -F`;default:return}},wG=(e,t,n,r)=>{let i=t.subcommands.map(e=>e.name),a=vG(n,i),o=a?`-n '${a}'`:``;if(!t.arguments.some(e=>e.type._tag===`Path`)){let t=[`complete -c ${e}`];o&&t.push(o),t.push(`-f`),r.push(t.join(` `))}for(let n of t.subcommands){let t=[`complete -c ${e}`];o&&t.push(o),t.push(`-f -a '${gG(n.name)}'`),n.description&&t.push(`-d '${gG(n.description)}'`),r.push(t.join(` `))}for(let n of t.flags){let t=n.type._tag===`Boolean`,i=t?yG(n):bG(n),o=a?`${a}; and ${i}`:i,s=o?`-n '${o}'`:``,c=[`complete -c ${e}`];if(s&&c.push(s),c.push(...xG(n)),r.push(c.join(` `)),t){let t=[`complete -c ${e}`];s&&t.push(s),t.push(`-l no-${n.name}`),n.description&&t.push(`-d '${gG(`Disable ${n.name}`)}'`),r.push(t.join(` `))}}if(t.flags.length>0){let n=`not string match -q -- "-*" (commandline -ct)`,i=a?`${a}; and ${n}`:n;for(let n of t.flags){let t=`${i}; and ${yG(n)}`,a=n.type._tag===`Boolean`,o=[`complete -c ${e}`];if(o.push(`-n '${t}'`),o.push(`-f -a '--${n.name}'`),n.description&&o.push(`-d '${gG(n.description)}'`),r.push(o.join(` `)),a){let i=[`complete -c ${e}`];i.push(`-n '${t}'`),i.push(`-f -a '--no-${n.name}'`),n.description&&i.push(`-d '${gG(`Disable ${n.name}`)}'`),r.push(i.join(` `))}}}for(let n of t.arguments){let t=CG(n.type);if(t){let i=[`complete -c ${e}`];o&&i.push(o),i.push(t),n.description&&i.push(`-d '${gG(n.description)}'`),r.push(i.join(` `))}}for(let i of t.subcommands)wG(e,i,[...n,i.name],r)},TG=(e,t)=>{let n=[];return n.push(`###-begin-${e}-completions-###`),n.push(`#`),n.push(`# Static completion script for Fish`),n.push(`#`),n.push(`# Installation:`),n.push(`# ${e} --completions fish > ~/.config/fish/completions/${e}.fish`),n.push(`#`),n.push(``),wG(e,t,[],n),n.push(``),n.push(`###-end-${e}-completions-###`),n.join(`
|
||||
`)},EG=e=>e.replace(/\\/g,`\\\\`).replace(/'/g,`'\\''`).replace(/:/g,`\\:`),DG=e=>e.replace(/[^A-Za-z0-9_.,/@%+-]/gu,`\\$&`).replace(/'/g,`'\\''`),OG=e=>e.replace(/[^a-zA-Z0-9_]/g,`_`),kG=e=>{let t=[`--${e.name}`];for(let n of e.aliases)t.push(n.length===1?`-${n}`:`--${n}`);return e.type._tag===`Boolean`&&t.push(`--no-${e.name}`),t},AG=e=>{switch(e._tag){case`Boolean`:return``;case`Choice`:return`:value:(${e.values.map(DG).join(` `)})`;case`Path`:return e.pathType===`directory`?`:directory:_directories`:`:file:_files`;case`Int`:return`:integer:`;case`Finite`:return`:float:`;case`Date`:return`:date:`;default:return`:value:`}},jG=e=>{switch(e._tag){case`Choice`:return`(${e.values.map(DG).join(` `)})`;case`Path`:return e.pathType===`directory`?`_directories`:`_files`;default:return``}},MG=e=>{let t=[],n=e.description?`[${EG(e.description)}]`:``,r=AG(e.type),i=`(${kG(e).join(` `)})`;t.push(`'${i}--${e.name}${n}${r}'`);for(let a of e.aliases){let e=a.length===1?`-`:`--`;t.push(`'${i}${e}${a}${n}${r}'`)}if(e.type._tag===`Boolean`){let n=e.description?`[${EG(`Disable ${e.name}`)}]`:``;t.push(`'${i}--no-${e.name}${n}'`)}return t},NG=e=>{let t=e.description?EG(e.description):e.name,n=jG(e.type);return`'${e.variadic?`*`:``}:${t}:${n}'`},PG=(e,t,n)=>{let r=[...t,e.name],i=`_${r.map(OG).join(`_`)}`;if(n.push(`${i}() {`),e.subcommands.length>0){n.push(` local context state state_descr line`),n.push(` typeset -A opt_args`),n.push(``),n.push(` local -a commands`),n.push(` commands=(`);for(let t of e.subcommands){let e=t.description?EG(t.description):``;n.push(` '${t.name}:${e}'`)}n.push(` )`),n.push(``),n.push(` local -a specs`),n.push(` specs=(`);for(let t of e.flags)for(let e of MG(t))n.push(` ${e}`);if(e.arguments.length>0){n.push(` -`),n.push(` parent-arguments`);for(let t of e.arguments)n.push(` ${NG(t)}`);n.push(` -`),n.push(` subcommands`)}n.push(` '1:command:->command'`),n.push(` '*::arg:->args'`),n.push(` )`),n.push(``),n.push(' _arguments -C "${specs[@]}"'),n.push(``),n.push(` case "$state" in`),n.push(` command)`),n.push(` _describe -t commands 'commands' commands`),n.push(` ;;`),n.push(` args)`),n.push(` case "$words[1]" in`);for(let t of e.subcommands){let e=`_${[...r,t.name].map(OG).join(`_`)}`;n.push(` ${t.name})`),n.push(` ${e}`),n.push(` ;;`)}n.push(` esac`),n.push(` ;;`),n.push(` esac`)}else{let t=[];for(let n of e.flags)t.push(...MG(n));for(let n of e.arguments)t.push(NG(n));if(t.length>0){n.push(` local -a specs`),n.push(` specs=(`);for(let e of t)n.push(` ${e}`);n.push(` )`),n.push(' _arguments "${specs[@]}"')}}n.push(`}`),n.push(``);for(let t of e.subcommands)PG(t,r,n)},FG=(e,t)=>{let n=[],r=OG(e);return n.push(`#compdef ${e}`),n.push(`###-begin-${e}-completions-###`),n.push(`#`),n.push(`# Static completion script for Zsh`),n.push(`#`),n.push(`# Installation:`),n.push(`# ${e} --completions zsh > ~/.zsh/completions/_${e}`),n.push(`# then add ~/.zsh/completions to your fpath`),n.push(`#`),n.push(``),PG(t,[],n),n.push(`# Handle both direct invocation and autoload`),n.push('if [[ "${zsh_eval_context[-1]}" == "loadautofunc" ]]; then'),n.push(` _${r} "$@"`),n.push(`else`),n.push(` compdef _${r} ${e}`),n.push(`fi`),n.push(`###-end-${e}-completions-###`),n.join(`
|
||||
`)},IG=(e,t,n)=>{switch(t){case`bash`:return hG(e,n);case`zsh`:return FG(e,n);case`fish`:return TG(e,n)}},LG=e=>mW(lW,e),RG=e=>hW(lW,e),zG=e=>gW(lW,e),BG=(e,t)=>_W(lW,e,t),VG=(e,t)=>vW(lW,e,t),HG=(e,t)=>bW(lW,e,t),UG=e=>xW(lW,e),WG=/*#__PURE__*/ C(2,(e,t)=>CW(e,t)),GG=/*#__PURE__*/ C(2,(e,t)=>wW(e,t)),KG=/*#__PURE__*/ C(2,(e,t)=>jW(e,t)),qG=e=>OW(e),JG=kW,YG=/*#__PURE__*/ C(2,(e,t)=>TW(e,t)),XG=/*#__PURE__*/ C(2,(e,t)=>NW(e,t)),ZG=/*#__PURE__*/ C(2,(e,t)=>MW(e,t)),QG=`~effect/cli/Command/Config/Internal`,$G=e=>{let t=[],n=[],r=[];function i(e){let t=Object.create(null);for(let n of Object.keys(e))t[n]=a(e[n]);return t}function a(e){if(Array.isArray(e))return{_tag:`Array`,children:e.map(e=>a(e))};if(dW(e)){let i=t.length;return t.push(e),e.kind===`argument`?r.push(e):n.push(e),{_tag:`Param`,index:i}}return{_tag:`Nested`,tree:i(e)}}return{[QG]:QG,flags:n,arguments:r,orderedParams:t,tree:i(e)}},eK=/*#__PURE__*/ $G({}),tK=(e,t)=>{let n={};for(let t of Object.keys(e))Kt(n,t,r(e[t]));return n;function r(e){switch(e._tag){case`Param`:return t[e.index];case`Array`:return e.children.map(e=>r(e));case`Nested`:return tK(e.tree,t)}}},nK=`~effect/cli/Command`,rK=e=>e,iK={.../*#__PURE__*/ Fi({label:`Command`,evaluate(){return rK(this).service}})},aK=e=>{let t=e.config,n=e.contextConfig??eK,r=e.service??Li(`~effect/cli/Command/${e.name}`),i=e.annotations??$i(),a=e.globalFlags??[],o=e.subcommands??[],s=(t,n)=>ke(e.handle)?e.handle(t,n):F(new _V({commandPath:n,errors:[]})),c=e.parse??cK(t),l=e.parseContext??cK(n,{allowLeftovers:!0}),u=n=>{let r=[],a=[];for(let e of t.arguments){let t=BW(e),n=HW(e);for(let e of t)r.push({name:e.name,type:e.typeName??AV(e.primitiveType),description:e.description,required:!n.isOptional&&(!n.isVariadic||Wr(n.variadicMin,e=>e>0)),variadic:n.isVariadic})}let s=n.length>0?n.join(` `):e.name;o.some(e=>e.commands.some(e=>!e.unlisted))&&(s+=` <subcommand>`),s+=` [flags]`;for(let e of r){let t=e.variadic?`<${e.name}...>`:`<${e.name}>`;s+=` ${e.required?t:`[${t}]`}`}for(let e of t.flags){let t=BW(e),n=HW(e);for(let e of t)e.hidden||a.push(oK(e,n))}let c=[];for(let e of o){let t=e.commands.filter(e=>!e.unlisted);t.length!==0&&c.push({group:e.group,commands:Mi(t,e=>({name:e.name,alias:e.alias,shortDescription:e.shortDescription,description:e.description??``}))})}let l=e.examples??[];return{description:e.description??``,usage:s,flags:a,annotations:i,...r.length>0&&{args:r},...c.length>0&&{subcommands:c},...l.length>0&&{examples:l}}};return Object.assign(Object.create(iK),{[nK]:nK,name:e.name,examples:e.examples??[],annotations:i,globalFlags:a,subcommands:o,unlisted:e.unlisted??!1,config:t,contextConfig:n,service:r,parse:c,parseContext:l,handle:s,buildHelpDoc:u,...ke(e.description)?{description:e.description}:{},...ke(e.shortDescription)?{shortDescription:e.shortDescription}:{},...ke(e.alias)?{alias:e.alias}:{}})},oK=(e,t)=>{let n=e.aliases.map(e=>e.length===1?`-${e}`:`--${e}`);return{name:e.name,aliases:n,type:e.typeName??AV(e.primitiveType),description:sK(e.description,jV(e.primitiveType)),required:e.primitiveType._tag!==`Boolean`&&!t.isOptional}},sK=(e,t)=>{if(t===void 0||t.length===0)return e;let n=`(choices: ${t.join(`, `)})`;return Fr(e,{onNone:()=>O(n),onSome:e=>O(`${e} ${n}`)})},cK=(e,t)=>z(function*(n){let r={flags:n.flags,arguments:n.arguments},[i,a]=yield*lK(r,e.orderedParams);return t?.allowLeftovers!==!0&&i.length>0?yield*new pV({arguments:i}):tK(e.tree,a)}),lK=/*#__PURE__*/ z(function*(e,t){let n=[],r=e.arguments;for(let i of t){let[t,a]=yield*i.parse({flags:e.flags,arguments:r});n.push(a),r=t}return[r,n]}),uK=e=>{switch(e.primitiveType._tag){case`Boolean`:return{_tag:`Boolean`};case`Int`:return{_tag:`Int`};case`Finite`:return{_tag:`Finite`};case`Date`:return{_tag:`Date`};case`Choice`:return{_tag:`Choice`,values:jV(e.primitiveType)??[]};case`Path`:return{_tag:`Path`,pathType:MV(e.primitiveType)??`either`};case`FileText`:case`FileParse`:case`FileSchema`:return{_tag:`Path`,pathType:`file`};default:return{_tag:`String`}}},dK=e=>{switch(e.primitiveType._tag){case`Int`:return{_tag:`Int`};case`Finite`:return{_tag:`Finite`};case`Date`:return{_tag:`Date`};case`Choice`:return{_tag:`Choice`,values:jV(e.primitiveType)??[]};case`Path`:return{_tag:`Path`,pathType:MV(e.primitiveType)??`either`};case`FileText`:case`FileParse`:case`FileSchema`:return{_tag:`Path`,pathType:`file`};default:return{_tag:`String`}}},fK=(e,t=[])=>{let n=rK(e),r=n.config,i=[],a=/* @__PURE__ */ new Set;for(let[e,n]of[...r.flags,...t].entries()){let t=BW(n);for(let n of t)n.kind===`flag`&&(n.hidden||e>=r.flags.length&&a.has(n.name)||(a.add(n.name),i.push({name:n.name,aliases:n.aliases,description:zr(n.description),type:uK(n)})))}let o=[];for(let e of r.arguments){let t=BW(e),n=HW(e);for(let e of t)e.kind===`argument`&&o.push({name:e.name,description:zr(e.description),required:!n.isOptional,variadic:n.isVariadic,type:dK(e)})}let s=[],c=[...t,...n.contextConfig.flags];for(let t of e.subcommands)for(let e of t.commands){if(e.unlisted)co
Line truncated
|
||||
`),wq=e=>Eq(`Command ready`,e,BV,LV),Tq=()=>`\n${VV(`Wizard cancelled.`,IV)}`,Eq=(e,t,n,r=RV)=>{let i=Dq(t);return[VV(e,NV,r),...i.map(e=>VV(e,n)),``].join(`
|
||||
`)},Dq=e=>{let t=` $ `,n=` `,r=e.map(Oq),i=[],a=t;for(let e of r){let r=a===t||a===n?``:` `;a.length+r.length+e.length>88&&a!==t?(i.push(`${a} \\`),a=`${n}${e}`):a+=`${r}${e}`}return a!==t&&i.push(a),i},Oq=e=>/^[A-Za-z0-9_./:@%+=,-]+$/.test(e)?e:`'${e.replaceAll(`'`,`'"'"'`)}'`,kq=(e,t,n)=>{let r=$G(t??{});return aK({name:e,config:r,...ke(n)?{handle:n}:{}})},Aq=/*#__PURE__*/ C(2,(e,t)=>aK({...rK(e),description:t})),jq=/*#__PURE__*/ C(2,(e,t)=>aK({...rK(e),examples:t})),Mq=(e,t,n,r)=>{let i=new Set(t),a=[],o=/* @__PURE__ */ new Set;for(let t of e){if(i.has(t))continue;let e=BW(t.flag);for(let t of e){let e=n[t.name];if(!e||e.length===0)continue;let i=`--${t.name}`;o.has(i)||(o.add(i),a.push(new lV({option:i,suggestions:[],command:r})))}}return a},Nq=(e,t,n)=>Zm(function*(){let{builtIns:r}=yield*kK,i=yield*KW,a=yield*yK(e,t.commandPath,r);yield*SB(i.formatHelpDoc(a)),n&&t.errors.length>0&&(yield*xB(i.formatErrors(t.errors)))}),Pq=e=>Zm(function*(){let t=yield*KW;yield*xB(t.formatError(e)),e[gB]=!1}),Fq=/*#__PURE__*/ C(2,(e,t)=>JL.use(({args:n})=>I(n,n=>Iq(e,t)(n)))),Iq=(e,t)=>{let n=rK(e);return z(function*(r){let{builtIns:i}=yield*kK,{tokens:a,trailingOperands:o}=jK(r),s=vK(e,i),c=s.flatMap(e=>BW(e.flag)),l=RK(c.filter(fW)),{flagMap:u,remainder:d,errors:f}=nq(a,e,l),p={flags:u,arguments:[]},m=yield*IK({tokens:d,trailingOperands:o},e),h=[e.name,...FK(m)],g={builtIns:i,command:e,commandPath:h,version:t.version},_=hK(e,h,i),v=Mq(s,_,u,h);if(v.length>0||f.length>0){let e=m.errors??[];return yield*new _V({commandPath:h,errors:[...f,...v,...e]})}for(let n of _){if(n._tag!==`Action`||!BW(n.flag).some(e=>{let t=u[e.name];return t!==void 0&&t.length>0}))continue;let[,i]=yield*n.flag.parse(p);if(n===TK)return yield*Zm(function*(){yield*SB(Cq(e.name,t.version,e.description));let n=[e.name,...r.filter(e=>e!==`--wizard`&&!e.startsWith(`--wizard=`))],i=yield*uq(e,{commandPath:h,prefix:n});yield*SB(wq(i.displayArgs)),(yield*uH(hH({message:`Run this command?`,initial:!0,active:`yes`,inactive:`no`})))&&(yield*SB(),yield*Iq(e,{...t,renderErrors:!1})(i.args.slice(1)))}).pipe(gh(`QuitError`,()=>SB(Tq())));yield*n.run(i,g);return}if(m.errors&&m.errors.length>0)return yield*new _V({commandPath:h,errors:m.errors});let ee=yield*lh(n.parse(m));if(ee._tag===`Failure`)return yield*new _V({commandPath:h,errors:[ee.failure]});let y=n.handle(ee.success,[e.name]),te=_.includes(DK)?(yield*DK.flag.parse(p))[1]:D();y=Gh(y,DK,te);for(let e of _){if(e._tag!==`Setting`||e===DK)continue;let[,t]=yield*e.flag.parse(p);y=Gh(y,e,t)}let b=Fr(te,{onNone:()=>$i(),onSome:e=>ta(Ff,e)});yield*Hh(y,b)},bh(e=>cV(e)&&e._tag===`ShowHelp`?Gr(e):Kr(e),n=>sh(Nq(e,n,t.renderErrors!==!1),F(n))),bh(e=>t.renderErrors!==!1&&cV(e)&&e._tag===`UserError`?Gr(e):Kr(e),e=>sh(Pq(e),F(e))),bh(e=>Xz(e)?Gr(e):Kr(e),e=>ng))},Lq=/*#__PURE__*/ H({method:Pj([`GET`,`POST`,`PATCH`,`PUT`,`DELETE`,`HEAD`,`OPTIONS`,`TRACE`]),url:V,urlParams:U(jj([V,V])),hash:pj(V),headers:Oj(V,W([V,EM(V)]))}).annotate({identifier:`HttpRequestDetails`}),Rq=/*#__PURE__*/ H({status:oM,headers:Oj(V,W([V,EM(V)]))}).annotate({identifier:`HttpResponseDetails`}),zq=`~effect/ai/AiError/Reason`,Bq=()=>Uq.pipe(Gj(j({})),qj(j({}))),Vq=e=>{let t=Ct(e),n={};for(let e in t){let r=t[e];Kt(n,e,yD(r)?r.toString():r)}return n};var Hq=class e extends (/*#__PURE__*/ FM(`effect/ai/AiError/NetworkError`)({_tag:/*#__PURE__*/ G(`NetworkError`),reason:/*#__PURE__*/ Pj([`TransportError`,`EncodeError`,`InvalidUrlError`]),request:Lq,description:/*#__PURE__*/ pj(V)})){[zq]=zq;get isRetryable(){return this.reason===`TransportError`}static fromRequestError(t){return new e({description:t.description,reason:t._tag,request:{hash:zr(t.request.hash),headers:Vq(t.request.headers),method:t.request.method,url:t.request.url,urlParams:Array.from(t.request.urlParams)}})}get message(){let e=`${this.request.method} ${this.request.url}`,t=this.description?`${this.reason}: ${this.description}`:`${this.reason}: A network error occurred.`;t+=` (${e})`;let n=``;switch(this.reason){case`EncodeError`:n+=`Check that the request body data is properly formatted and matches the expected content type.`;break;case`InvalidUrlError`:n+=`Verify that the URL format is correct and that all required parameters have been provided.`,n+=` Check for any special characters that may need encoding.`;break;case`TransportError`:n+=`Check your network connection and verify that the requested URL is accessible.`}return t+=`\n\n${n}`,t}};const Uq=/*#__PURE__*/ Oj(V,/*#__PURE__*/ Fj(HM)),Wq=/*#__PURE__*/ H({promptTokens:pj(oM),completionTokens:pj(oM),totalTokens:pj(oM)}).annotate({identifier:`UsageInfo`}),Gq=/*#__PURE__*/ H({request:Lq,response:pj(Rq),body:pj(V)}).annotate({identifier:`HttpContext`});var Kq=class extends (/*#__PURE__*/ FM(`effect/ai/AiError/RateLimitError`)({_tag:/*#__PURE__*/ G(`RateLimitError`),retryAfter:/*#__PURE__*/ pj(wM),metadata:/*#__PURE__*/ Bq(),http:/*#__PURE__*/ pj(Gq)})){[zq]=zq;get isRetryable(){return!0}get message(){let e=`Rate limit exceedLine truncated
|
||||
`;let n=r.encode(e);return n===void 0?void 0:`${n}\n`}}}})},d0=e=>{let t=a0(e.protocols),n=nP({status:405,headers:{allow:`POST`}}),r=t=>p0(t,e.allowedOrigins)?j(n):j(nP({status:403})),i=hp(AI(`GET`,e.path,r),AI(`PUT`,e.path,r),AI(`PATCH`,e.path,r),AI(`DELETE`,e.path,r),AI(`OPTIONS`,e.path,r));return gp(c0(e),i).pipe(vp(f0(e)),vp(t),vp(LL()))},f0=e=>cp(tR)(Zm(function*(){let t=yield*r0,{httpEffect:n,protocol:r}=yield*nR();return yield*(yield*wI).add(`POST`,e.path,r=>{if(!p0(r,e.allowedOrigins))return j(nP({status:403}));if(m0(r.headers[`content-type`])[0]!==`application/json`)return j(nP({status:415}));let i=m0(r.headers.accept);if(!i.includes(`application/json`)||!i.includes(`text/event-stream`))return j(nP({status:406}));let a=r.headers[$1],o=r.headers[Q1],s=o===void 0?void 0:t.sessions.bySessionId.get(o);if(o!==void 0&&s===void 0)return j(nP({status:404}));let c=a!==void 0&&!t.protocolRegistry.protocols.some(e=>e.protocolVersion===a)||s?.protocol.transport.requiresVersionHeader===!0&&a!==s.protocol.protocolVersion,l=c?nP({status:400}):oP({jsonrpc:`2.0`,id:null,error:new eY({message:`Parse error`})});return r.text.pipe(I(nj(pM)),Rh({onFailure:()=>j(l),onSuccess:e=>{if(!Array.isArray(e)){let t=E(e,`id`),r=t&&(typeof e.id==`string`||typeof e.id==`number`)?e.id:null,i=E(e,`jsonrpc`)&&e.jsonrpc===`2.0`,a=!t||typeof e.id==`string`||typeof e.id==`number`,s=i&&a&&E(e,`method`)&&typeof e.method==`string`,l=t&&(typeof e.id==`string`||typeof e.id==`number`||e.id===null),u=E(e,`result`),d=E(e,`error`),f=i&&l&&u!==d,p=s&&g0(e);return!p&&c?j(nP({status:400})):!s&&!f?j(oP({jsonrpc:`2.0`,id:r,error:new tY({message:`Invalid Request`})})):p&&o!==void 0||!p&&s&&o===void 0?j(nP({status:400})):n}return c?j(nP({status:400})):e.length===0?j(oP({jsonrpc:`2.0`,id:null,error:new tY({message:`Invalid Request`})},{status:400})):e.some(g0)||s===void 0?j(nP({status:400})):s.protocol.transport.acceptsJsonRpcBatches?n:j(nP({status:400}))}}))}),r})),p0=(e,t)=>{let n=e.headers.origin;return n===void 0||(t??[]).includes(n)},m0=e=>e===void 0?[]:e.split(`,`).flatMap(e=>{let[t,...n]=e.split(`;`),r=n.map(e=>e.trim().toLowerCase()).find(e=>e.startsWith(`q=`));if(r!==void 0){let e=Number(r.slice(2));if(!Number.isFinite(e)||e<=0||e>1)return[]}return[t.trim().toLowerCase()]}),h0=/*#__PURE__*/ H({method:/*#__PURE__*/ B(`initialize`)}),g0=e=>Xr(rj(h0)(e)),_0=/*#__PURE__*/ H({params:/*#__PURE__*/ H({protocolVersion:V})}),v0=e=>{let t=rj(_0)(e);return Xr(t)?t.success.params.protocolVersion:void 0},y0=`Tool execution failed due to an internal server error.`,b0=e=>new EY({isError:!0,content:[{type:`text`,text:e}]}),x0=/*#__PURE__*/ z(function*(e){let t=yield*Z1,n=yield*e,r=yield*zh(),i=e=>Hh(XN(e),r);for(let e of Object.values(n.tools)){let a=e.annotations,o=ia(a,SJ),s=tj(e.failureSchema),c=yJ(e.successSchema),l=c.type===`object`?yield*nj(wY)(c).pipe(xh):void 0,u=yield*nj(wY)(vJ(e)).pipe(xh),d=new TY({name:e.name,description:_J(e),inputSchema:u,...l===void 0?{}:{outputSchema:l},annotations:{...da(e.annotations,xJ).pipe(Vr(e=>({title:e})),zr),readOnlyHint:sa(e.annotations,CJ),destructiveHint:sa(e.annotations,wJ),idempotentHint:sa(e.annotations,TJ),openWorldHint:sa(e.annotations,EJ)},_meta:o});yield*t.addTool({tool:d,annotations:a,handle(t){return n.handle(e.name,t??{}).pipe(Ub,ox(Xy()),I(ah),L(e=>new EY({isError:!1,structuredContent:J1(e.encodedResult),content:e.encodedResult===void 0?[]:[{type:`text`,text:JSON.stringify(e.encodedResult)}]})),Hh(r),Ch(Dg),vh(e=>{let t=Fp(e);if(Yr(t))return Ip(e)?fh(i(e),b0(y0)):Qm(t.failure);let n=t.success;if(lJ(n)){let t=n.reason;return t._tag===`ToolParameterValidationError`?F(new rY({message:t.message})):fh(i(e),b0(y0))}let r=s(n)&&n instanceof Error?n.message:y0;return fh(i(e),b0(r))}))}})}}),S0=function(){if(arguments.length===1){let e=arguments[0];return Zm(function*(){let t=yield*zh();yield*(yield*Z1).addResource({resource:new dY({...e,annotations:e}),handle:e.content.pipe(Hh(t),L(t=>D0(e.uri,t)),vh(e=>{let t=Bp(e)[0];return F(new iY({message:t.message}))})),annotations:e.annotations??$i()})})}let{params:e,routerPath:t,schema:n,uriPath:r}=w0(...arguments);return z(function*(i){let a=yield*zh(),o=yield*Z1,s=nj(n),c=new fY({...i,uriTemplate:r,annotations:i}),l=Object.create(null);for(let[t,n]of Object.entries(i.completion??{})){let r=oj(U(e[t]));l[t]=(e,t)=>n(e,t).pipe(I(r),L(e=>({completion:{values:e,total:e.length,hasMore:!1}})),vh(e=>{let t=Bp(e)[0];return F(new iY({message:t.message}))}),Hh(a))}yield*o.addResourceTemplate({template:c,routerPath:t,completions:l,annotations:i.annotations??$i(),handle:(e,t)=>s(t).pipe(R(e=>new rY({message:e.message})),I(t=>i.content(e,...t).pipe(L(t=>D0(e,t)),vh(e=>{let t=Bp(e)[0];return F(new iY({message:t.message}))}))),Hh(a))})})},C0=()=>{let e=HN({ignoreTrailingSlash:!0,ignoreDuplicateSlashes:!0,caseSensitive:!0});return{add:(t,n)=>{e.on(`GET`,`/${t}`,n)},find:t=>e.find(`GET`,`/${t}`)}},w0=(e,...t)=>{let n=e[0].replace(`:`,`::`),r=e[0],i=Object.create(null),a=jj([]);if(t.leng
Line truncated
|
||||
`),n.push(`\r
|
||||
`),this.doWrite(e,n,t)},e=>{throw this.fireError(e),e}))}async doWrite(e,t,n){try{return await this.writable.write(t.join(``),`ascii`),this.writable.write(n)}catch(t){return this.handleError(t,e),Promise.reject(t)}}handleError(e,t){this.errorCount++,this.fireError(e,t,this.errorCount)}end(){this.writable.end()}}})),J0=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AbstractMessageBuffer=void 0,e.AbstractMessageBuffer=class{_encoding;_chunks;_totalLength;constructor(e=`utf-8`){this._encoding=e,this._chunks=[],this._totalLength=0}get encoding(){return this._encoding}append(e){let t=typeof e==`string`?this.fromString(e,this._encoding):e;this._chunks.push(t),this._totalLength+=t.byteLength}tryReadHeaders(e=!1){if(this._chunks.length===0)return;let t=0,n=0,r=0,i=0;row:for(;n<this._chunks.length;){let e=this._chunks[n];for(r=0;r<e.length;){switch(e[r]){case 13:switch(t){case 0:t=1;break;case 2:t=3;break;default:t=0}break;case 10:switch(t){case 1:t=2;break;case 3:t=4,r++;break row;default:t=0}break;default:t=0}r++}i+=e.byteLength,n++}if(t!==4)return;let a=this._read(i+r),o=/* @__PURE__ */ new Map,s=this.toString(a,`ascii`).split(`\r
|
||||
`);if(s.length<2)return o;for(let t=0;t<s.length-2;t++){let n=s[t],r=n.indexOf(`:`);if(r===-1)throw Error(`Message header must separate key and value using ':'\n${n}`);let i=n.substr(0,r),a=n.substr(r+1).trim();o.set(e?i.toLowerCase():i,a)}return o}tryReadBody(e){if(!(this._totalLength<e))return this._read(e)}get numberOfBytes(){return this._totalLength}_read(e){if(e===0)return this.emptyBuffer();if(e>this._totalLength)throw Error(`Cannot read so many bytes!`);if(this._chunks[0].byteLength===e){let t=this._chunks[0];return this._chunks.shift(),this._totalLength-=e,this.asNative(t)}if(this._chunks[0].byteLength>e){let t=this._chunks[0],n=this.asNative(t,e);return this._chunks[0]=t.slice(e),this._totalLength-=e,n}let t=this.allocNative(e),n=0;for(;e>0;){let r=this._chunks[0];if(r.byteLength>e){let i=r.slice(0,e);t.set(i,n),n+=e,this._chunks[0]=r.slice(e),this._totalLength-=e,e-=e}else t.set(r,n),n+=r.byteLength,this._chunks.shift(),this._totalLength-=r.byteLength,e-=r.byteLength}return t}}})),Y0=/* @__PURE__ */ x((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;o<a.length;o++)a[o]!=="default"&&t(i,r,a[o]);return n(i,r),i}})(),i=e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.ConnectionOptions=e.MessageStrategy=e.CancellationStrategy=e.CancellationSenderStrategy=e.CancellationReceiverStrategy=e.RequestCancellationReceiverStrategy=e.IdCancellationReceiverStrategy=e.ConnectionStrategy=e.ConnectionError=e.ConnectionErrors=e.LogTraceNotification=e.SetTraceNotification=e.TraceFormat=e.TraceValues=e.TraceValue=e.Trace=e.NullLogger=e.ProgressType=e.ProgressToken=void 0,e.createMessageConnection=ce;let a=i(V0()),o=r(L0()),s=R0(),c=z0(),l=H0(),u=U0();var d;(function(e){e.type=new s.NotificationType(`$/cancelRequest`)})(d||={});var f;(function(e){function t(e){return typeof e==`string`||typeof e==`number`}e.is=t})(f||(e.ProgressToken=f={}));var p;(function(e){e.type=new s.NotificationType(`$/progress`)})(p||={}),e.ProgressType=class{__;_pr;constructor(){}};var m;(function(e){function t(e){return o.func(e)}e.is=t})(m||={}),e.NullLogger=Object.freeze({error:()=>{},warn:()=>{},info:()=>{},log:()=>{}});var h;(function(e){e[e.Off=0]=`Off`,e[e.Messages=1]=`Messages`,e[e.Compact=2]=`Compact`,e[e.Verbose=3]=`Verbose`})(h||(e.Trace=h={}));var g;(function(e){e.Off=`off`,e.Messages=`messages`,e.Compact=`compact`,e.Verbose=`verbose`})(g||(e.TraceValue=g={})),e.TraceValues=g,(function(e){function t(t){if(!o.string(t))return e.Off;switch(t=t.toLowerCase(),t){case`off`:return e.Off;case`messages`:return e.Messages;case`compact`:return e.Compact;case`verbose`:return e.Verbose;default:return e.Off}}e.fromString=t;function n(t){switch(t){case e.Off:return`off`;case e.Messages:return`messages`;case e.Compact:return`compact`;case e.Verbose:return`verbose`;default:return`off`}}e.toString=n})(h||(e.Trace=h={}));var _;(function(e){e.Text=`text`,e.JSON=`json`})(_||(e.TraceFormat=_={})),(function(e){function t(t){return o.string(t)?(t=t.toLowerCase(),t===`json`?e.JSON:e.Text):e.Text}e.fromString=t})(_||(e.TraceFormat=_={}));var v;(function(e){e.type=new s.NotificationType(`$/setTrace`)})(v||(e.SetTraceNotification=v={}));var ee;(function(e){e.type=new s.NotificationType(`$/logTrace`)})(ee||(e.LogTraceNotification=ee={}));var y;(function(e){e[e.Closed=1]=`Closed`,e[e.Disposed=2]=`Disposed`,e[e.AlreadyListening=3]=`AlreadyListening`})(y||(e.ConnectionErrors=y={}));var te=class e extends Error{code;constructor(t,n){super(n),this.code=t,Object.setPrototypeOf(this,e.prototype)}};e.ConnectionError=te;var b;(function(e){function t(e){let t=e;return t&&o.func(t.cancelUndispatched)}e.is=t})(b||(e.ConnectionStrategy=b={}));var ne;(function(e){function t(e){let t=e;return t&&(t.kind===void 0||t.kind===`id`)&&o.func(t.createCancellationTokenSource)&&(t.dispose===void 0||o.func(t.dispose))}e.is=t})(ne||(e.IdCancellationReceiverStrategy=ne={}));var x;(function(e){function t(e){let t=e;return t&&t.kind===`request`&&o.func(t.createCancellationTokenSource)&&(t.dispose===void 0||o.func(t.dispose))}e.is=t})(x||(e.RequestCancellationReceiverStrategy=x={}));var re;(function(e){e.Message=Object.freeze({createCancellationTokenSource(e){return new u.CancellationTokenSource}});function t(e){return ne.is(e)||x
Line truncated
|
||||
`,`\r
|
||||
`,`\r`],(function(e){function t(e,t,n,r){return new j4(e,t,n,r)}e.create=t;function n(e){let t=e;return!!($.defined(t)&&$.string(t.uri)&&($.undefined(t.languageId)||$.string(t.languageId))&&$.uinteger(t.lineCount)&&$.func(t.getText)&&$.func(t.positionAt)&&$.func(t.offsetAt))}e.is=n;function r(e,t){let n=e.getText(),r=i(t,(e,t)=>{let n=e.range.start.line-t.range.start.line;return n===0?e.range.start.character-t.range.start.character:n}),a=n.length;for(let t=r.length-1;t>=0;t--){let i=r[t],o=e.offsetAt(i.range.start),s=e.offsetAt(i.range.end);if(s<=a)n=n.substring(0,o)+i.newText+n.substring(s,n.length);else throw Error(`Overlapping edit`);a=o}return n}e.applyEdits=r;function i(e,t){if(e.length<=1)return e;let n=e.length/2|0,r=e.slice(0,n),a=e.slice(n);i(r,t),i(a,t);let o=0,s=0,c=0;for(;o<r.length&&s<a.length;)t(r[o],a[s])<=0?e[c++]=r[o++]:e[c++]=a[s++];for(;o<r.length;)e[c++]=r[o++];for(;s<a.length;)e[c++]=a[s++];return e}})(A4||={}),j4=class{constructor(e,t,n,r){this._uri=e,this._languageId=t,this._version=n,this._content=r,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let t=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(t,n)}return this._content}update(e,t){this._content=e.text,this._version=t,this._lineOffsets=void 0}getLineOffsets(){if(this._lineOffsets===void 0){let e=[],t=this._content,n=!0;for(let r=0;r<t.length;r++){n&&=(e.push(r),!1);let i=t.charAt(r);n=i===`\r`||i===`
|
||||
`,i===`\r`&&r+1<t.length&&t.charAt(r+1)===`
|
||||
`&&r++}n&&t.length>0&&e.push(t.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let t=this.getLineOffsets(),n=0,r=t.length;if(r===0)return n2.create(0,e);for(;n<r;){let i=Math.floor((n+r)/2);t[i]>e?r=i:n=i+1}let i=n-1;return n2.create(i,e-t[i])}offsetAt(e){let t=this.getLineOffsets();if(e.line>=t.length)return this._content.length;if(e.line<0)return 0;let n=t[e.line],r=e.line+1<t.length?t[e.line+1]:this._content.length;return Math.max(Math.min(n+e.character,r),n)}get lineCount(){return this.getLineOffsets().length}},(function(e){let t=Object.prototype.toString;function n(e){return e!==void 0}e.defined=n;function r(e){return e===void 0}e.undefined=r;function i(e){return e===!0||e===!1}e.boolean=i;function a(e){return t.call(e)===`[object String]`}e.string=a;function o(e){return t.call(e)===`[object Number]`}e.number=o;function s(e,n,r){return t.call(e)===`[object Number]`&&n<=e&&e<=r}e.numberRange=s;function c(e){return t.call(e)===`[object Number]`&&-2147483648<=e&&e<=2147483647}e.integer=c;function l(e){return t.call(e)===`[object Number]`&&0<=e&&e<=2147483647}e.uinteger=l;function u(e){return t.call(e)===`[object Function]`}e.func=u;function d(e){return typeof e==`object`&&!!e}e.objectLiteral=d;function f(e,t){return Array.isArray(e)&&e.every(t)}e.typedArray=f})($||={})})),N4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.CM=e.ProtocolNotificationType=e.ProtocolNotificationType0=e.ProtocolRequestType=e.ProtocolRequestType0=e.RegistrationType=e.MessageDirection=void 0;let t=X0();var n;(function(e){e.clientToServer=`clientToServer`,e.serverToClient=`serverToClient`,e.both=`both`})(n||(e.MessageDirection=n={})),e.RegistrationType=class{____;method;constructor(e){this.method=e}},e.ProtocolRequestType0=class extends t.RequestType0{__;___;____;_pr;constructor(e){super(e)}},e.ProtocolRequestType=class extends t.RequestType{__;___;____;_pr;constructor(e){super(e,t.ParameterStructures.byName)}},e.ProtocolNotificationType0=class extends t.NotificationType0{___;____;constructor(e){super(e)}},e.ProtocolNotificationType=class extends t.NotificationType{___;____;constructor(e){super(e,t.ParameterStructures.byName)}};var r;(function(e){function t(e,t){return{client:e,server:t}}e.create=t})(r||(e.CM=r={}))})),P4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.boolean=t,e.string=n,e.number=r,e.error=i,e.func=a,e.array=o,e.stringArray=s,e.typedArray=c,e.objectLiteral=l;function t(e){return e===!0||e===!1}function n(e){return typeof e==`string`||e instanceof String}function r(e){return typeof e==`number`||e instanceof Number}function i(e){return e instanceof Error}function a(e){return typeof e==`function`}function o(e){return Array.isArray(e)}function s(e){return o(e)&&e.every(e=>n(e))}function c(e,t){return Array.isArray(e)&&e.every(t)}function l(e){return typeof e==`object`&&!!e}})),F4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ImplementationRequest=void 0;let t=N4();var n;(function(e){e.method=`textDocument/implementation`,e.messageDirection=t.MessageDirection.clientToServer,e.type=new t.ProtocolRequestType(e.method),e.capabilities=t.CM.create(`textDocument.implementation`,`implementationProvider`)})(n||(e.ImplementationRequest=n={}))})),I4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.TypeDefinitionRequest=void 0;let t=N4();var n;(function(e){e.method=`textDocument/typeDefinition`,e.messageDirection=t.MessageDirection.clientToServer,e.type=new t.ProtocolRequestType(e.method),e.capabilities=t.CM.create(`textDocument.typeDefinition`,`typeDefinitionProvider`)})(n||(e.TypeDefinitionRequest=n={}))})),L4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DidChangeWorkspaceFoldersNotification=e.WorkspaceFoldersRequest=void 0;let t=N4();var n;(function(e){e.method=`workspace/workspaceFolders`,e.messageDirection=t.MessageDirection.serverToClient,e.type=new t.ProtocolRequestType0(e.method),e.capabilities=t.CM.create(`workspace.workspaceFolders`,`workspace.workspaceFolders`)})(n||(e.WorkspaceFoldersRequest=n={}));var r;(function(e){e.method=`workspace/didChangeWorkspaceFolders`,e.messageDirection=t.MessageDirection.clientToServer,e.type=new t.ProtocolNotificationType(e.method),e.capabilities=t.CM.create(void 0,`workspace.workspaceFolders.changeNotifications`)})(r||(e.DidChangeWorkspaceFoldersNotification=r={}))})),R4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ConfigurationRequest=void 0;let t=N4();var n;(function(e){e.method=`workspace/configuration`,e.messageDirection=t.MessageDirection.serverToClient,e.type=new t.ProtocolRequestType(e.method),e.capabilities=t.CM.create(`workspace.configuration`,void 0)})(n||(e.ConfigurationRequest=n={}))})),z4=/* @__PURE__ */ x((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ColorPresentationRequest=e.DocumentColorRequest=void 0;let t=N4();var n;(function(e){e
Line truncated
|
||||
|
||||
`):`kind`in e?e.value:`\`\`\`${e.language}\n${e.value}\n\`\`\``,d6=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[t,e[0]?.toLowerCase()+e.slice(1)])),f6=d6(l3.SymbolKind),p6=d6(l3.CompletionItemKind),m6=[`error`,`warning`,`information`,`hint`],h6=e=>new F3({method:e,message:`the language server does not support ${e}`}),g6=(e,t)=>e[t]?P:F(h6(t)),_6=Sg(`Editor.locate`)(function*(e){let t=yield*(yield*n6).open(e.file),n=e.line-1;if(n>=t.lineCount)return yield*new F3({method:`locate`,message:`${e.file} has only ${t.lineCount} lines`});let r=c6(t,n),i=e.column===void 0?e.symbol===void 0?Math.max(0,r.search(/\S/)):v6(r,e.symbol):e.column-1;return i<0?yield*new F3({method:`locate`,message:`"${e.symbol}" does not occur on line ${e.line}`}):{doc:t,position:{line:n,character:Math.min(i,r.length)},textDocument:{uri:t.uri}}}),v6=(e,t)=>{let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),r=e.search(RegExp(`(?<![\\p{L}\\p{N}_$])${n}(?![\\p{L}\\p{N}_$])`,`u`));return r>=0?r:e.indexOf(t)},y6=Sg(`Editor.locations`)(function*(e){let t=yield*n6,n=e.map(e=>`targetUri`in e?{uri:e.targetUri,range:e.targetSelectionRange}:e),r=new Map(yield*Gm([...new Set(n.map(e=>e.uri))],e=>t.peek(e).pipe(uh,L(t=>[e,zr(t)]))));return n.map(({uri:e,range:n})=>({file:t.file(e),...s6(n),preview:l6(r.get(e),n.start.line)}))}),b6=Sg(`Editor.workspaceEdit`)(function*(e,t){let n=yield*n6,r=[],i=[];for(let t of r6(e))l3.TextDocumentEdit.is(t)?r.push({file:n.file(t.textDocument.uri),edits:t.edits.flatMap(e=>`newText`in e?[{...s6(e.range),newText:e.newText}]:[])}):t.kind===`rename`?i.push(`rename ${n.file(t.oldUri)} -> ${n.file(t.newUri)}`):i.push(`${t.kind} ${n.file(t.uri)}`);return t&&(yield*n.applyEdit(e)),{applied:t,files:r,operations:i}}),x6=Sg(`Editor.hover`)(function*(e){let t=yield*I3,{textDocument:n,position:r}=yield*_6(e),i=yield*t.request(l3.HoverRequest.type,{textDocument:n,position:r});return i===null?null:{contents:u6(i.contents),range:i.range&&s6(i.range)}}),S6={definition:l3.DefinitionRequest.type,typeDefinition:l3.TypeDefinitionRequest.type,implementation:l3.ImplementationRequest.type,declaration:l3.DeclarationRequest.type},C6=Sg(`Editor.definition`)(function*({kind:e=`definition`,...t}){let n=yield*I3;yield*g6(n.capabilities,`${e}Provider`);let{textDocument:r,position:i}=yield*_6(t),a=yield*n.request(S6[e],{textDocument:r,position:i});return yield*y6(a===null?[]:Array.isArray(a)?a:[a])}),w6=Sg(`Editor.references`)(function*({includeDeclaration:e=!0,...t}){let n=yield*I3,{textDocument:r,position:i}=yield*_6(t),a=yield*n.request(l3.ReferencesRequest.type,{textDocument:r,position:i,context:{includeDeclaration:e}});return yield*y6(a??[])}),T6=Sg(`Editor.documentSymbols`)(function*({file:e}){let t=yield*I3,n=yield*(yield*n6).open(e),r=yield*t.request(l3.DocumentSymbolRequest.type,{textDocument:{uri:n.uri}}),i=e=>({name:e.name,kind:f6[e.kind]??`unknown`,detail:e.detail||void 0,...s6(e.range),children:e.children?.length?e.children.map(i):void 0});return(r??[]).map(e=>`range`in e?i(e):{name:e.name,kind:f6[e.kind]??`unknown`,container:e.containerName||void 0,...s6(e.location.range)})}),E6=Sg(`Editor.workspaceSymbols`)(function*({query:e,limit:t=50}){let n=yield*I3,r=yield*n6;return((yield*n.request(l3.WorkspaceSymbolRequest.type,{query:e}))??[]).slice(0,t).map(e=>({name:e.name,kind:f6[e.kind]??`unknown`,container:e.containerName||void 0,file:r.file(e.location.uri),...`range`in e.location?{line:e.location.range.start.line+1,column:e.location.range.start.character+1}:{}}))}),D6=Sg(`Editor.diagnostics`)(function*({file:e,severity:t=`hint`}){let n=yield*n6,r=yield*q3,i=e=>t=>({file:n.file(e),...s6(t.range),severity:m6[(t.severity??1)-1]??`error`,code:t.code===void 0?void 0:String(t.code),source:t.source,message:u6(t.message),related:t.relatedInformation?.map(e=>({file:n.file(e.location.uri),line:e.location.range.start.line+1,column:e.location.range.start.character+1,message:e.message}))}),a=e===void 0?(yield*r.all).flatMap(e=>e.diagnostics.map(i(e.uri))):yield*n.open(e).pipe(I(e=>L(r.forDocument(e),t=>t.map(i(e.uri))))),o=m6.indexOf(t);return a.filter(e=>m6.indexOf(e.severity)<=o).sort((e,t)=>e.file.localeCompare(t.file)||e.line-t.line||e.column-t.column)}),O6=Sg(`Editor.completions`)(function*({prefix:e,limit:t=20,...n}){let r=yield*I3,{textDocument:i,position:a}=yield*_6(n),o=yield*r.request(l3.CompletionRequest.type,{textDocument:i,position:a,context:{triggerKind:l3.CompletionTriggerKind.Invoked}}),s=Array.isArray(o)?o:o?.items??[],c=e?.toLowerCase();return s.filter(e=>c===void 0||(e.filterText??e.label).toLowerCase().startsWith(c)).sort((e,t)=>(e.sortText??e.label).localeCompare(t.sortText??t.label)).slice(0,t).map(e=>({label:e.label,kind:p6[e.kind??1]??`text`,detail:e.detail,documentation:e.documentation===void 0?void 0:u6(e.documentation)}))}),k6=Sg(`Editor.signatureHelp`)(function*(e){let t=yield*I3,{textDocument:n,position:r}=yield*_6(e),i=yield*t.request(l3.SignatureHelpRequest.type,{textDocument:n,position:r});return{active:i?.activeSignLine truncated
|
||||
+20
-10
@@ -1,15 +1,19 @@
|
||||
{
|
||||
"name": "lsp-mcp",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"version": "0.1.0",
|
||||
"description": "MCP server exposing a Language Server's capabilities to agents as a headless editor",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"lsp-mcp": "./src/main.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node src/main.ts",
|
||||
"check": "tsc",
|
||||
"test": "vitest run",
|
||||
"lint": "biome check --write --unsafe",
|
||||
"prepare": "effect-tsgo patch --typescript --no-oxlint"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devEngines": {
|
||||
"packageManager": {
|
||||
"name": "pnpm",
|
||||
@@ -18,14 +22,20 @@
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@12.4.2",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@effect/platform-node": "4.0.0-rc.115",
|
||||
"effect": "4.0.0-rc.115"
|
||||
"effect": "4.0.0-rc.115",
|
||||
"vscode-languageserver-protocol": "^3.18.3",
|
||||
"vscode-languageserver-textdocument": "^1.0.14",
|
||||
"vscode-uri": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.5.14",
|
||||
"@effect/tsgo": "0.45.0",
|
||||
"typescript": "^7.0.2"
|
||||
"@effect/vitest": "4.0.0-rc.115",
|
||||
"@types/node": "^26.6.1",
|
||||
"typescript": "^7.0.2",
|
||||
"vitest": "^5.0.1",
|
||||
"vscode-languageserver": "^10.1.1"
|
||||
}
|
||||
}
|
||||
Generated
+697
@@ -172,6 +172,15 @@ importers:
|
||||
effect:
|
||||
specifier: 4.0.0-rc.115
|
||||
version: 4.0.0-rc.115
|
||||
vscode-languageserver-protocol:
|
||||
specifier: ^3.18.3
|
||||
version: 3.18.3
|
||||
vscode-languageserver-textdocument:
|
||||
specifier: ^1.0.14
|
||||
version: 1.0.14
|
||||
vscode-uri:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0
|
||||
devDependencies:
|
||||
'@biomejs/biome':
|
||||
specifier: 2.5.14
|
||||
@@ -179,9 +188,21 @@ importers:
|
||||
'@effect/tsgo':
|
||||
specifier: 0.45.0
|
||||
version: 0.45.0
|
||||
'@effect/vitest':
|
||||
specifier: 4.0.0-rc.115
|
||||
version: 4.0.0-rc.115(effect@4.0.0-rc.115)(vitest@5.0.1(@types/node@26.6.1)(vite@8.3.0(@types/node@26.6.1)))
|
||||
'@types/node':
|
||||
specifier: ^26.6.1
|
||||
version: 26.6.1
|
||||
typescript:
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2
|
||||
vitest:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1(@types/node@26.6.1)(vite@8.3.0(@types/node@26.6.1))
|
||||
vscode-languageserver:
|
||||
specifier: ^10.1.1
|
||||
version: 10.1.1
|
||||
|
||||
packages:
|
||||
|
||||
@@ -294,6 +315,25 @@ packages:
|
||||
resolution: {integrity: sha512-gPG0ixVHgtYBUe5DbKX9vzHlhqd9+ZEfs4m/XWy0808av0A2XqMzaG3F5rnPBN7EUJRPlo9TluIi8WHx/pBV+A==}
|
||||
hasBin: true
|
||||
|
||||
'@effect/vitest@4.0.0-rc.115':
|
||||
resolution: {integrity: sha512-DJR0hfdr3HNXAkzW8AzfvUz6VmrNFLrKk9tZGDURi33faMyxkc7ZewxELMMZwGpOTGN4mfqYVbX2CXgI+ZJBeQ==}
|
||||
peerDependencies:
|
||||
effect: ^4.0.0-rc.115
|
||||
vitest: '>=5.0.0 <6.0.0'
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.6.0':
|
||||
resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@oxc-project/types@0.150.0':
|
||||
resolution: {integrity: sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==}
|
||||
|
||||
'@redis/bloom@6.2.1':
|
||||
resolution: {integrity: sha512-huQgNLaCIZfQ9SeLn4q9124uOUd8HbZDYHwwUzNcRgHqCHiHKl2dDxMqJCeWh8cMqZAoWuHR8XnWbDMIf+o7ag==}
|
||||
engines: {node: '>= 20.0.0'}
|
||||
@@ -330,6 +370,114 @@ packages:
|
||||
peerDependencies:
|
||||
'@redis/client': ^6.2.1
|
||||
|
||||
'@rolldown/binding-android-arm-eabi@1.2.9':
|
||||
resolution: {integrity: sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.9':
|
||||
resolution: {integrity: sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.9':
|
||||
resolution: {integrity: sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.9':
|
||||
resolution: {integrity: sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.9':
|
||||
resolution: {integrity: sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.9':
|
||||
resolution: {integrity: sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.9':
|
||||
resolution: {integrity: sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.9':
|
||||
resolution: {integrity: sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.9':
|
||||
resolution: {integrity: sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.9':
|
||||
resolution: {integrity: sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.9':
|
||||
resolution: {integrity: sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.9':
|
||||
resolution: {integrity: sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.9':
|
||||
resolution: {integrity: sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.9':
|
||||
resolution: {integrity: sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.9':
|
||||
resolution: {integrity: sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/pluginutils@1.0.1':
|
||||
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
|
||||
|
||||
'@types/chai@5.2.3':
|
||||
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
|
||||
|
||||
'@types/deep-eql@4.0.2':
|
||||
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
||||
|
||||
'@types/estree@1.0.9':
|
||||
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
|
||||
|
||||
'@types/node@26.6.1':
|
||||
resolution: {integrity: sha512-VqGJBMCtdhqkBUCcBLvywI0NJ+KLuVzgNnlBUNFOQjqVxzo2lxLUNg1DSey8+u2u6ktswSAxg+s68QLzWHNOuA==}
|
||||
|
||||
@@ -456,17 +604,194 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@vitest/mocker@5.0.1':
|
||||
resolution: {integrity: sha512-6K1DoBNAPGvuOcSsGA4D6x+5zEEff/KmOOP3uetT2TrGpVfI+HRHRnJJfKi5ib/g1vx8IYHQD8s0pbJz8WQI7Q==}
|
||||
peerDependencies:
|
||||
msw: ^2.4.9
|
||||
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
msw:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
|
||||
'@vitest/spy@5.0.1':
|
||||
resolution: {integrity: sha512-rbto/mF/SGERxEgYOek7Xm6B9b+y+mVoo+f4b2LymYO8zM1b7uB5nHuhVMTP2hxdzgxvGiZYGxGIaMvL5y180Q==}
|
||||
|
||||
assertion-error@2.0.1:
|
||||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
chai@6.2.2:
|
||||
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
cluster-key-slot@1.1.2:
|
||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
effect@4.0.0-rc.115:
|
||||
resolution: {integrity: sha512-ogYulZ5ffeOzrJqQrG0XOkDO5lKn2s9KNHhoxJy/6wKUkF0i12dlVXWA9TgsgQ+zV/JzizyG0+XMPepZEQX6vw==}
|
||||
|
||||
es-module-lexer@2.3.2:
|
||||
resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==}
|
||||
|
||||
estree-walker@3.0.3:
|
||||
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
||||
|
||||
expect-type@1.4.0:
|
||||
resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
fdir@6.5.0:
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
picomatch: ^3 || ^4
|
||||
peerDependenciesMeta:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
lightningcss-android-arm64@1.33.0:
|
||||
resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
lightningcss-darwin-arm64@1.33.0:
|
||||
resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
lightningcss-darwin-x64@1.33.0:
|
||||
resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
lightningcss-freebsd-x64@1.33.0:
|
||||
resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
lightningcss-linux-arm-gnueabihf@1.33.0:
|
||||
resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
lightningcss-linux-arm64-gnu@1.33.0:
|
||||
resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.33.0:
|
||||
resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.33.0:
|
||||
resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.33.0:
|
||||
resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.33.0:
|
||||
resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
lightningcss-win32-x64-msvc@1.33.0:
|
||||
resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
lightningcss@1.33.0:
|
||||
resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
||||
magic-string@1.4.1:
|
||||
resolution: {integrity: sha512-8lyCu36ErXR0J9uaGKlKQoiLZKmtI63YGLE8G2o9jyRPdr4X47LusSOwgOJOzcVtp81fTAAjxR7BwKz682Jhow==}
|
||||
|
||||
nanoid@3.3.19:
|
||||
resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
obug@2.2.1:
|
||||
resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
picomatch@4.0.7:
|
||||
resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postcss@8.5.28:
|
||||
resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
redis@6.2.1:
|
||||
resolution: {integrity: sha512-Z9VHtgYs48PiQC77X9O2Er8Hj4T+5BtFjT91/vi5Is1D04N72cA946ZslM1ImJw8ZctFBZWAVjM7S5wJNeHMpg==}
|
||||
engines: {node: '>= 20.0.0'}
|
||||
|
||||
rolldown@1.2.9:
|
||||
resolution: {integrity: sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
siginfo@2.0.0:
|
||||
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
stackback@0.0.2:
|
||||
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||
|
||||
std-env@4.2.0:
|
||||
resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==}
|
||||
|
||||
tinybench@6.1.4:
|
||||
resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
tinyexec@1.3.0:
|
||||
resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tinyglobby@0.2.17:
|
||||
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
typescript@7.0.2:
|
||||
resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
@@ -479,6 +804,115 @@ packages:
|
||||
resolution: {integrity: sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==}
|
||||
engines: {node: '>=22.19.0'}
|
||||
|
||||
vite@8.3.0:
|
||||
resolution: {integrity: sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@types/node': ^20.19.0 || >=22.12.0
|
||||
'@vitejs/devtools': ^0.7.1
|
||||
esbuild: ^0.27.0 || ^0.28.0
|
||||
jiti: '>=1.21.0'
|
||||
less: ^4.0.0
|
||||
sass: ^1.70.0
|
||||
sass-embedded: ^1.70.0
|
||||
stylus: '>=0.54.8'
|
||||
sugarss: ^5.0.0
|
||||
terser: ^5.16.0
|
||||
tsx: ^4.8.1
|
||||
yaml: ^2.4.2
|
||||
peerDependenciesMeta:
|
||||
'@types/node':
|
||||
optional: true
|
||||
'@vitejs/devtools':
|
||||
optional: true
|
||||
esbuild:
|
||||
optional: true
|
||||
jiti:
|
||||
optional: true
|
||||
less:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
sass-embedded:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
sugarss:
|
||||
optional: true
|
||||
terser:
|
||||
optional: true
|
||||
tsx:
|
||||
optional: true
|
||||
yaml:
|
||||
optional: true
|
||||
|
||||
vitest@5.0.1:
|
||||
resolution: {integrity: sha512-iA95lQbKEkvrtTkdAgnWbXfbipWiiWe/hDl2P5tMi6WFwD76G0NxXAGp/M9EOcYupeGJRr6wppMc7CoA41TQjg==}
|
||||
engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@edge-runtime/vm': '*'
|
||||
'@opentelemetry/api': ^1.9.0
|
||||
'@types/node': ^22.0.0 || >=24.0.0
|
||||
'@vitest/browser-playwright': 5.0.1
|
||||
'@vitest/browser-preview': 5.0.1
|
||||
'@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0
|
||||
'@vitest/coverage-istanbul': 5.0.1
|
||||
'@vitest/coverage-v8': 5.0.1
|
||||
'@vitest/ui': 5.0.1
|
||||
happy-dom: '*'
|
||||
jsdom: '*'
|
||||
vite: ^6.4.0 || ^7.0.0 || ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
'@edge-runtime/vm':
|
||||
optional: true
|
||||
'@opentelemetry/api':
|
||||
optional: true
|
||||
'@types/node':
|
||||
optional: true
|
||||
'@vitest/browser-playwright':
|
||||
optional: true
|
||||
'@vitest/browser-preview':
|
||||
optional: true
|
||||
'@vitest/browser-webdriverio':
|
||||
optional: true
|
||||
'@vitest/coverage-istanbul':
|
||||
optional: true
|
||||
'@vitest/coverage-v8':
|
||||
optional: true
|
||||
'@vitest/ui':
|
||||
optional: true
|
||||
happy-dom:
|
||||
optional: true
|
||||
jsdom:
|
||||
optional: true
|
||||
|
||||
vscode-jsonrpc@9.0.2:
|
||||
resolution: {integrity: sha512-SbQSV9yRemARxeXw6LU5sS6Zq0e9/DgCCX5yelH263ZQWukbTk8EF8fjTrr1dziasf4GwlJbvTwFnTrnQFWZXQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
vscode-languageserver-protocol@3.18.3:
|
||||
resolution: {integrity: sha512-DF49+WeV5py4zO5hhobp60jjsDSK0lAqA0OuKBLBvp423HPWQcCbhZz3JgyfIewsEz2f8U+X75xNIFHdiXZm2w==}
|
||||
|
||||
vscode-languageserver-textdocument@1.0.14:
|
||||
resolution: {integrity: sha512-EQyqJMi552E4ZTf46izQ4Fj6XquqxCySR3J5ZSD1SisMf6RfpeOWHxGBE8Gr6V0/3GHIGdAzDn8F8+1nTGCnoQ==}
|
||||
|
||||
vscode-languageserver-types@3.18.3:
|
||||
resolution: {integrity: sha512-XIlzJ7Qp/jzSI1ds7/FwPAWrPeTZA7pAtlW4hdJ1J6xXWJL6dR9QYnDhJOdLzdKhUQ5Mm6mvUMw+3DcOQQasPw==}
|
||||
|
||||
vscode-languageserver@10.1.1:
|
||||
resolution: {integrity: sha512-/cG04Fiq99rEtoDrfPpv0k6NyUFlck5GNtZLQZv1rxkBkc/4FrJNvEKTN5k1Si3O1hRguP++ciYlX9cdjdYxFQ==}
|
||||
hasBin: true
|
||||
|
||||
vscode-uri@3.2.0:
|
||||
resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==}
|
||||
|
||||
why-is-node-running@2.3.0:
|
||||
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
|
||||
ws@8.21.3:
|
||||
resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -578,6 +1012,22 @@ snapshots:
|
||||
'@effect/tsgo-win32-arm64': 0.45.0
|
||||
'@effect/tsgo-win32-x64': 0.45.0
|
||||
|
||||
'@effect/vitest@4.0.0-rc.115(effect@4.0.0-rc.115)(vitest@5.0.1(@types/node@26.6.1)(vite@8.3.0(@types/node@26.6.1)))':
|
||||
dependencies:
|
||||
effect: 4.0.0-rc.115
|
||||
vitest: 5.0.1(@types/node@26.6.1)(vite@8.3.0(@types/node@26.6.1))
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.6.0': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.6.0
|
||||
|
||||
'@oxc-project/types@0.150.0': {}
|
||||
|
||||
'@redis/bloom@6.2.1(@redis/client@6.2.1)':
|
||||
dependencies:
|
||||
'@redis/client': 6.2.1
|
||||
@@ -598,6 +1048,62 @@ snapshots:
|
||||
dependencies:
|
||||
'@redis/client': 6.2.1
|
||||
|
||||
'@rolldown/binding-android-arm-eabi@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.9':
|
||||
optional: true
|
||||
|
||||
'@rolldown/pluginutils@1.0.1': {}
|
||||
|
||||
'@types/chai@5.2.3':
|
||||
dependencies:
|
||||
'@types/deep-eql': 4.0.2
|
||||
assertion-error: 2.0.1
|
||||
|
||||
'@types/deep-eql@4.0.2': {}
|
||||
|
||||
'@types/estree@1.0.9': {}
|
||||
|
||||
'@types/node@26.6.1':
|
||||
dependencies:
|
||||
undici-types: 8.9.0
|
||||
@@ -666,10 +1172,109 @@ snapshots:
|
||||
'@typescript/typescript-win32-x64@7.0.2':
|
||||
optional: true
|
||||
|
||||
'@vitest/mocker@5.0.1(vite@8.3.0(@types/node@26.6.1))':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
'@vitest/spy': 5.0.1
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 1.4.1
|
||||
optionalDependencies:
|
||||
vite: 8.3.0(@types/node@26.6.1)
|
||||
|
||||
'@vitest/spy@5.0.1': {}
|
||||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
chai@6.2.2: {}
|
||||
|
||||
cluster-key-slot@1.1.2: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
effect@4.0.0-rc.115: {}
|
||||
|
||||
es-module-lexer@2.3.2: {}
|
||||
|
||||
estree-walker@3.0.3:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.9
|
||||
|
||||
expect-type@1.4.0: {}
|
||||
|
||||
fdir@6.5.0(picomatch@4.0.7):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.7
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
lightningcss-android-arm64@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-darwin-arm64@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-darwin-x64@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-freebsd-x64@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-linux-arm-gnueabihf@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-linux-arm64-gnu@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-linux-arm64-musl@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-linux-x64-gnu@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-linux-x64-musl@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss-win32-x64-msvc@1.33.0:
|
||||
optional: true
|
||||
|
||||
lightningcss@1.33.0:
|
||||
dependencies:
|
||||
detect-libc: 2.1.2
|
||||
optionalDependencies:
|
||||
lightningcss-android-arm64: 1.33.0
|
||||
lightningcss-darwin-arm64: 1.33.0
|
||||
lightningcss-darwin-x64: 1.33.0
|
||||
lightningcss-freebsd-x64: 1.33.0
|
||||
lightningcss-linux-arm-gnueabihf: 1.33.0
|
||||
lightningcss-linux-arm64-gnu: 1.33.0
|
||||
lightningcss-linux-arm64-musl: 1.33.0
|
||||
lightningcss-linux-x64-gnu: 1.33.0
|
||||
lightningcss-linux-x64-musl: 1.33.0
|
||||
lightningcss-win32-arm64-msvc: 1.33.0
|
||||
lightningcss-win32-x64-msvc: 1.33.0
|
||||
|
||||
magic-string@1.4.1:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.6.0
|
||||
|
||||
nanoid@3.3.19: {}
|
||||
|
||||
obug@2.2.1: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@4.0.7: {}
|
||||
|
||||
postcss@8.5.28:
|
||||
dependencies:
|
||||
nanoid: 3.3.19
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
redis@6.2.1:
|
||||
dependencies:
|
||||
'@redis/bloom': 6.2.1(@redis/client@6.2.1)
|
||||
@@ -681,6 +1286,44 @@ snapshots:
|
||||
- '@node-rs/xxhash'
|
||||
- '@opentelemetry/api'
|
||||
|
||||
rolldown@1.2.9:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.150.0
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
optionalDependencies:
|
||||
'@rolldown/binding-android-arm-eabi': 1.2.9
|
||||
'@rolldown/binding-android-arm64': 1.2.9
|
||||
'@rolldown/binding-darwin-arm64': 1.2.9
|
||||
'@rolldown/binding-darwin-x64': 1.2.9
|
||||
'@rolldown/binding-freebsd-x64': 1.2.9
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.2.9
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.2.9
|
||||
'@rolldown/binding-linux-arm64-musl': 1.2.9
|
||||
'@rolldown/binding-linux-ppc64-gnu': 1.2.9
|
||||
'@rolldown/binding-linux-s390x-gnu': 1.2.9
|
||||
'@rolldown/binding-linux-x64-gnu': 1.2.9
|
||||
'@rolldown/binding-linux-x64-musl': 1.2.9
|
||||
'@rolldown/binding-openharmony-arm64': 1.2.9
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.2.9
|
||||
'@rolldown/binding-win32-x64-msvc': 1.2.9
|
||||
|
||||
siginfo@2.0.0: {}
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
stackback@0.0.2: {}
|
||||
|
||||
std-env@4.2.0: {}
|
||||
|
||||
tinybench@6.1.4: {}
|
||||
|
||||
tinyexec@1.3.0: {}
|
||||
|
||||
tinyglobby@0.2.17:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.7)
|
||||
picomatch: 4.0.7
|
||||
|
||||
typescript@7.0.2:
|
||||
optionalDependencies:
|
||||
'@typescript/typescript-aix-ppc64': 7.0.2
|
||||
@@ -708,4 +1351,58 @@ snapshots:
|
||||
|
||||
undici@8.10.2: {}
|
||||
|
||||
vite@8.3.0(@types/node@26.6.1):
|
||||
dependencies:
|
||||
lightningcss: 1.33.0
|
||||
picomatch: 4.0.7
|
||||
postcss: 8.5.28
|
||||
rolldown: 1.2.9
|
||||
tinyglobby: 0.2.17
|
||||
optionalDependencies:
|
||||
'@types/node': 26.6.1
|
||||
fsevents: 2.3.3
|
||||
|
||||
vitest@5.0.1(@types/node@26.6.1)(vite@8.3.0(@types/node@26.6.1)):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.3
|
||||
'@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@26.6.1))
|
||||
chai: 6.2.2
|
||||
es-module-lexer: 2.3.2
|
||||
expect-type: 1.4.0
|
||||
magic-string: 1.4.1
|
||||
obug: 2.2.1
|
||||
picomatch: 4.0.7
|
||||
std-env: 4.2.0
|
||||
tinybench: 6.1.4
|
||||
tinyexec: 1.3.0
|
||||
tinyglobby: 0.2.17
|
||||
vite: 8.3.0(@types/node@26.6.1)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 26.6.1
|
||||
transitivePeerDependencies:
|
||||
- msw
|
||||
|
||||
vscode-jsonrpc@9.0.2: {}
|
||||
|
||||
vscode-languageserver-protocol@3.18.3:
|
||||
dependencies:
|
||||
vscode-jsonrpc: 9.0.2
|
||||
vscode-languageserver-types: 3.18.3
|
||||
|
||||
vscode-languageserver-textdocument@1.0.14: {}
|
||||
|
||||
vscode-languageserver-types@3.18.3: {}
|
||||
|
||||
vscode-languageserver@10.1.1:
|
||||
dependencies:
|
||||
vscode-languageserver-protocol: 3.18.3
|
||||
|
||||
vscode-uri@3.2.0: {}
|
||||
|
||||
why-is-node-running@2.3.0:
|
||||
dependencies:
|
||||
siginfo: 2.0.0
|
||||
stackback: 0.0.2
|
||||
|
||||
ws@8.21.3: {}
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
* The agent-facing vocabulary of the server.
|
||||
*
|
||||
* Everything an agent sends or receives is described here as `Schema`, so the
|
||||
* same definitions drive MCP tool input/output schemas and the values the
|
||||
* `lsp/` bridge produces. Positions are 1-based (line and column), the way
|
||||
* agents and editors display them; the bridge converts to LSP's 0-based form.
|
||||
*/
|
||||
import { Option, Predicate, Schema, SchemaGetter } from "effect";
|
||||
|
||||
/** An optional field whose key is omitted, rather than set to `undefined`, in JSON output. */
|
||||
const optional = <S extends Schema.Top>(schema: S) =>
|
||||
Schema.optional(schema).pipe(
|
||||
Schema.encodeTo(Schema.optionalKey(schema), {
|
||||
decode: SchemaGetter.passthrough(),
|
||||
encode: SchemaGetter.transformOptional(
|
||||
Option.filter(Predicate.isNotUndefined),
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
const positive = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));
|
||||
|
||||
export const File = Schema.String.annotate({
|
||||
description: "File path, absolute or relative to the workspace root",
|
||||
});
|
||||
export const Line = positive.annotate({ description: "1-based line number" });
|
||||
export const Column = positive.annotate({
|
||||
description:
|
||||
"1-based column, counted in UTF-16 code units (plain characters for ASCII)",
|
||||
});
|
||||
|
||||
export const Where = Schema.Struct({
|
||||
file: File,
|
||||
line: Line,
|
||||
column: optional(
|
||||
positive.annotate({
|
||||
description:
|
||||
"1-based column. Omit to place the cursor on `symbol`, or on the first non-blank character of the line",
|
||||
}),
|
||||
),
|
||||
symbol: optional(
|
||||
Schema.String.annotate({
|
||||
description:
|
||||
"Identifier on the line to place the cursor at; used when `column` is omitted",
|
||||
}),
|
||||
),
|
||||
});
|
||||
export type Where = typeof Where.Type;
|
||||
|
||||
export const Range = Schema.Struct({
|
||||
line: Line,
|
||||
column: Column,
|
||||
endLine: Line,
|
||||
endColumn: Column,
|
||||
});
|
||||
export type Range = typeof Range.Type;
|
||||
|
||||
export const Location = Schema.Struct({
|
||||
file: Schema.String,
|
||||
...Range.fields,
|
||||
preview: Schema.String.annotate({
|
||||
description: "Trimmed source text of the starting line",
|
||||
}),
|
||||
});
|
||||
export type Location = typeof Location.Type;
|
||||
|
||||
export const Hover = Schema.Struct({
|
||||
contents: Schema.String.annotate({ description: "Markdown" }),
|
||||
range: optional(Range),
|
||||
});
|
||||
export type Hover = typeof Hover.Type;
|
||||
|
||||
export const GotoKind = Schema.Literals([
|
||||
"definition",
|
||||
"typeDefinition",
|
||||
"implementation",
|
||||
"declaration",
|
||||
]);
|
||||
export const Goto = Schema.Struct({
|
||||
...Where.fields,
|
||||
kind: optional(
|
||||
GotoKind.annotate({
|
||||
description: "What to navigate to (default: definition)",
|
||||
}),
|
||||
),
|
||||
});
|
||||
export type Goto = typeof Goto.Type;
|
||||
|
||||
export const References = Schema.Struct({
|
||||
...Where.fields,
|
||||
includeDeclaration: optional(
|
||||
Schema.Boolean.annotate({ description: "Default: true" }),
|
||||
),
|
||||
});
|
||||
export type References = typeof References.Type;
|
||||
|
||||
export interface DocumentSymbol extends Range {
|
||||
readonly name: string;
|
||||
readonly kind: string;
|
||||
readonly detail?: string | undefined;
|
||||
readonly container?: string | undefined;
|
||||
readonly children?: ReadonlyArray<DocumentSymbol> | undefined;
|
||||
}
|
||||
export const DocumentSymbol: Schema.Codec<DocumentSymbol> = Schema.Struct({
|
||||
name: Schema.String,
|
||||
kind: Schema.String,
|
||||
detail: optional(Schema.String),
|
||||
container: optional(Schema.String),
|
||||
...Range.fields,
|
||||
children: optional(
|
||||
Schema.Array(
|
||||
Schema.suspend((): Schema.Codec<DocumentSymbol> => DocumentSymbol),
|
||||
),
|
||||
),
|
||||
});
|
||||
|
||||
export const WorkspaceSymbol = Schema.Struct({
|
||||
name: Schema.String,
|
||||
kind: Schema.String,
|
||||
container: optional(Schema.String),
|
||||
file: Schema.String,
|
||||
line: optional(Line),
|
||||
column: optional(Column),
|
||||
});
|
||||
export type WorkspaceSymbol = typeof WorkspaceSymbol.Type;
|
||||
|
||||
export const WorkspaceQuery = Schema.Struct({
|
||||
query: Schema.String.annotate({
|
||||
description:
|
||||
"Symbol name or fragment; matching is fuzzy and server-defined",
|
||||
}),
|
||||
limit: optional(positive.annotate({ description: "Default: 50" })),
|
||||
});
|
||||
export type WorkspaceQuery = typeof WorkspaceQuery.Type;
|
||||
|
||||
export const Severity = Schema.Literals([
|
||||
"error",
|
||||
"warning",
|
||||
"information",
|
||||
"hint",
|
||||
]);
|
||||
export type Severity = typeof Severity.Type;
|
||||
|
||||
export const Diagnostic = Schema.Struct({
|
||||
file: Schema.String,
|
||||
...Range.fields,
|
||||
severity: Severity,
|
||||
code: optional(Schema.String),
|
||||
source: optional(Schema.String),
|
||||
message: Schema.String,
|
||||
related: optional(
|
||||
Schema.Array(
|
||||
Schema.Struct({
|
||||
file: Schema.String,
|
||||
line: Line,
|
||||
column: Column,
|
||||
message: Schema.String,
|
||||
}),
|
||||
),
|
||||
),
|
||||
});
|
||||
export type Diagnostic = typeof Diagnostic.Type;
|
||||
|
||||
export const DiagnosticsQuery = Schema.Struct({
|
||||
file: optional(
|
||||
File.annotate({
|
||||
description:
|
||||
"Restrict to one file; omit for every file the server has reported on",
|
||||
}),
|
||||
),
|
||||
severity: optional(
|
||||
Severity.annotate({
|
||||
description:
|
||||
"Least severe level to include (default: hint, i.e. everything)",
|
||||
}),
|
||||
),
|
||||
});
|
||||
export type DiagnosticsQuery = typeof DiagnosticsQuery.Type;
|
||||
|
||||
export const Completions = Schema.Struct({
|
||||
...Where.fields,
|
||||
prefix: optional(
|
||||
Schema.String.annotate({
|
||||
description: "Keep only items whose label starts with this",
|
||||
}),
|
||||
),
|
||||
limit: optional(positive.annotate({ description: "Default: 20" })),
|
||||
});
|
||||
export type Completions = typeof Completions.Type;
|
||||
|
||||
export const Completion = Schema.Struct({
|
||||
label: Schema.String,
|
||||
kind: Schema.String,
|
||||
detail: optional(Schema.String),
|
||||
documentation: optional(Schema.String),
|
||||
});
|
||||
export type Completion = typeof Completion.Type;
|
||||
|
||||
export const Signature = Schema.Struct({
|
||||
label: Schema.String,
|
||||
documentation: optional(Schema.String),
|
||||
parameters: Schema.Array(Schema.String),
|
||||
activeParameter: optional(Schema.Int),
|
||||
});
|
||||
export const SignatureHelp = Schema.Struct({
|
||||
signatures: Schema.Array(Signature),
|
||||
active: Schema.Int,
|
||||
});
|
||||
export type SignatureHelp = typeof SignatureHelp.Type;
|
||||
|
||||
export const TextEdit = Schema.Struct({
|
||||
...Range.fields,
|
||||
newText: Schema.String,
|
||||
});
|
||||
export const FileEdits = Schema.Struct({
|
||||
file: Schema.String,
|
||||
edits: Schema.Array(TextEdit),
|
||||
});
|
||||
export const WorkspaceEdit = Schema.Struct({
|
||||
applied: Schema.Boolean.annotate({
|
||||
description: "Whether the edits were written to disk",
|
||||
}),
|
||||
files: Schema.Array(FileEdits),
|
||||
operations: Schema.Array(Schema.String).annotate({
|
||||
description: "File creations, renames, deletions and executed commands",
|
||||
}),
|
||||
});
|
||||
export type WorkspaceEdit = typeof WorkspaceEdit.Type;
|
||||
|
||||
const apply = optional(
|
||||
Schema.Boolean.annotate({
|
||||
description:
|
||||
"Write the resulting edits to disk (default: false, preview only)",
|
||||
}),
|
||||
);
|
||||
|
||||
export const Rename = Schema.Struct({
|
||||
...Where.fields,
|
||||
newName: Schema.String,
|
||||
apply,
|
||||
});
|
||||
export type Rename = typeof Rename.Type;
|
||||
|
||||
export const Selection = Schema.Struct({
|
||||
file: File,
|
||||
line: Line,
|
||||
column: optional(Column.annotate({ description: "Default: start of line" })),
|
||||
endLine: optional(Line.annotate({ description: "Default: same as line" })),
|
||||
endColumn: optional(
|
||||
Column.annotate({ description: "Default: end of endLine" }),
|
||||
),
|
||||
});
|
||||
export type Selection = typeof Selection.Type;
|
||||
|
||||
export const CodeActions = Schema.Struct({
|
||||
...Selection.fields,
|
||||
kind: optional(
|
||||
Schema.String.annotate({
|
||||
description:
|
||||
"Only actions of this kind prefix, e.g. quickfix, refactor, refactor.extract, source.organizeImports",
|
||||
}),
|
||||
),
|
||||
});
|
||||
export type CodeActions = typeof CodeActions.Type;
|
||||
|
||||
export const CodeAction = Schema.Struct({
|
||||
title: Schema.String,
|
||||
kind: optional(Schema.String),
|
||||
preferred: Schema.Boolean,
|
||||
fixes: Schema.Array(Schema.String).annotate({
|
||||
description: "Messages of the diagnostics this action addresses",
|
||||
}),
|
||||
});
|
||||
export type CodeAction = typeof CodeAction.Type;
|
||||
|
||||
export const ApplyCodeAction = Schema.Struct({
|
||||
...CodeActions.fields,
|
||||
title: Schema.String.annotate({
|
||||
description:
|
||||
"Exact title of an action returned by code_actions for the same selection",
|
||||
}),
|
||||
});
|
||||
export type ApplyCodeAction = typeof ApplyCodeAction.Type;
|
||||
|
||||
export const Format = Schema.Struct({
|
||||
file: File,
|
||||
tabSize: optional(positive.annotate({ description: "Default: 4" })),
|
||||
insertSpaces: optional(
|
||||
Schema.Boolean.annotate({ description: "Default: true" }),
|
||||
),
|
||||
apply,
|
||||
});
|
||||
export type Format = typeof Format.Type;
|
||||
|
||||
export const CallDirection = Schema.Literals(["incoming", "outgoing"]);
|
||||
export const CallHierarchy = Schema.Struct({
|
||||
...Where.fields,
|
||||
direction: optional(
|
||||
CallDirection.annotate({
|
||||
description:
|
||||
"incoming: who calls this; outgoing: what this calls (default: incoming)",
|
||||
}),
|
||||
),
|
||||
});
|
||||
export type CallHierarchy = typeof CallHierarchy.Type;
|
||||
|
||||
export const Call = Schema.Struct({
|
||||
name: Schema.String,
|
||||
kind: Schema.String,
|
||||
detail: optional(Schema.String),
|
||||
file: Schema.String,
|
||||
line: Line,
|
||||
column: Column,
|
||||
sites: Schema.Array(Schema.Struct({ line: Line, column: Column })).annotate({
|
||||
description: "Call sites, located in the caller's file",
|
||||
}),
|
||||
});
|
||||
export type Call = typeof Call.Type;
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* MCP resources and notifications: the server's identity and capabilities,
|
||||
* live diagnostics (subscribable), and the language server's log messages
|
||||
* forwarded as MCP log notifications.
|
||||
*/
|
||||
import { Effect, Layer, Schema, Stream } from "effect";
|
||||
import { McpServer } from "effect/unstable/ai";
|
||||
import { Diagnostics } from "./lsp/Diagnostics.ts";
|
||||
import { Documents } from "./lsp/Documents.ts";
|
||||
import * as Editor from "./lsp/Editor.ts";
|
||||
import { LanguageServer } from "./lsp/LanguageServer.ts";
|
||||
|
||||
const json = (value: unknown) => JSON.stringify(value, null, 2);
|
||||
const diagnosticsUri = "lsp://diagnostics";
|
||||
const fileDiagnosticsUri = (file: string) =>
|
||||
`${diagnosticsUri}/${encodeURIComponent(file)}`;
|
||||
|
||||
export const layer = Layer.effectDiscard(
|
||||
Effect.gen(function* () {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
const diagnostics = yield* Diagnostics;
|
||||
const mcp = yield* McpServer.McpServer;
|
||||
|
||||
yield* McpServer.registerResource({
|
||||
uri: "lsp://server",
|
||||
name: "Language server",
|
||||
description:
|
||||
"Name, version, workspace root and capabilities of the connected language server",
|
||||
mimeType: "application/json",
|
||||
content: Effect.succeed(
|
||||
json({
|
||||
...lsp.serverInfo,
|
||||
root: lsp.root,
|
||||
capabilities: lsp.capabilities,
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
yield* McpServer.registerResource({
|
||||
uri: diagnosticsUri,
|
||||
name: "Diagnostics",
|
||||
description:
|
||||
"All diagnostics the language server has reported. Subscribe to be told when they change.",
|
||||
mimeType: "application/json",
|
||||
content: Effect.map(Editor.diagnostics({}), json),
|
||||
});
|
||||
|
||||
yield* McpServer.registerResource`lsp://diagnostics/${Schema.String}`({
|
||||
name: "File diagnostics",
|
||||
description:
|
||||
"Diagnostics of one file (path URL-encoded, relative to the workspace root)",
|
||||
mimeType: "application/json",
|
||||
completion: {
|
||||
param0: (input) =>
|
||||
Effect.map(docs.opened, (uris) =>
|
||||
uris.map(docs.file).filter((file) => file.startsWith(input)),
|
||||
),
|
||||
},
|
||||
content: (_, file) =>
|
||||
Effect.map(
|
||||
Editor.diagnostics({ file: decodeURIComponent(file) }),
|
||||
json,
|
||||
),
|
||||
});
|
||||
|
||||
const updated = (uri: string) =>
|
||||
mcp.notifications["notifications/resources/updated"]({ uri });
|
||||
yield* diagnostics.changes.pipe(
|
||||
Stream.runForEach((uri) =>
|
||||
Effect.all([
|
||||
updated(diagnosticsUri),
|
||||
updated(fileDiagnosticsUri(docs.file(uri))),
|
||||
]),
|
||||
),
|
||||
Effect.forkScoped,
|
||||
);
|
||||
|
||||
yield* lsp.logs.pipe(
|
||||
Stream.runForEach(({ level, message }) =>
|
||||
mcp.notifications["notifications/message"]({
|
||||
level,
|
||||
logger: "lsp",
|
||||
data: message,
|
||||
}),
|
||||
),
|
||||
Effect.forkScoped,
|
||||
);
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Wires the language server, the headless editor and the MCP server together.
|
||||
*
|
||||
* Build order matters: the language server initializes first (so tool
|
||||
* registration can consult its capabilities), then the editor services, then
|
||||
* the MCP transport, then tools and resources are registered.
|
||||
*/
|
||||
import { createServer } from "node:http";
|
||||
import { NodeHttpServer } from "@effect/platform-node";
|
||||
import { Effect, Layer } from "effect";
|
||||
import { McpProtocol, McpServer } from "effect/unstable/ai";
|
||||
import { HttpRouter } from "effect/unstable/http";
|
||||
import { Diagnostics } from "./lsp/Diagnostics.ts";
|
||||
import * as Documents from "./lsp/Documents.ts";
|
||||
import * as LanguageServer from "./lsp/LanguageServer.ts";
|
||||
import * as Resources from "./Resources.ts";
|
||||
import * as Tools from "./Tools.ts";
|
||||
|
||||
export type Transport =
|
||||
| { readonly _tag: "stdio" }
|
||||
| { readonly _tag: "http"; readonly port: number };
|
||||
|
||||
export interface Options {
|
||||
readonly transport: Transport;
|
||||
readonly server: LanguageServer.Options;
|
||||
readonly documents: Documents.Options;
|
||||
}
|
||||
|
||||
const info = {
|
||||
name: "lsp-mcp",
|
||||
version: "0.1.0",
|
||||
protocols: [
|
||||
McpProtocol.v2025_11_25,
|
||||
McpProtocol.v2025_06_18,
|
||||
McpProtocol.v2025_03_26,
|
||||
McpProtocol.v2024_11_05,
|
||||
],
|
||||
} as const;
|
||||
|
||||
const transport = (transport: Transport) =>
|
||||
transport._tag === "stdio"
|
||||
? McpServer.layerStdio(info)
|
||||
: HttpRouter.serve(McpServer.layerHttp({ ...info, path: "/mcp" }), {
|
||||
disableLogger: true,
|
||||
}).pipe(
|
||||
Layer.provide(
|
||||
NodeHttpServer.layer(createServer, { port: transport.port }),
|
||||
),
|
||||
);
|
||||
|
||||
/** Registers the tools the connected server can serve. */
|
||||
export const tools = Layer.effectDiscard(
|
||||
Effect.gen(function* () {
|
||||
const { capabilities } = yield* LanguageServer.LanguageServer;
|
||||
yield* McpServer.registerToolkit(Tools.supportedBy(capabilities));
|
||||
}),
|
||||
).pipe(Layer.provide(Tools.layer));
|
||||
|
||||
export const layer = (options: Options) =>
|
||||
Layer.mergeAll(tools, Resources.layer).pipe(
|
||||
Layer.provide(transport(options.transport)),
|
||||
Layer.provide(
|
||||
Layer.mergeAll(
|
||||
Documents.Documents.layer(options.documents),
|
||||
Diagnostics.layer,
|
||||
),
|
||||
),
|
||||
Layer.provide(LanguageServer.LanguageServer.layer(options.server)),
|
||||
);
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* The MCP tools: one per editor operation, described for agents. Tools whose
|
||||
* capability the connected language server lacks are not offered.
|
||||
*/
|
||||
import { Schema } from "effect";
|
||||
import { Tool, Toolkit } from "effect/unstable/ai";
|
||||
import type { ServerCapabilities } from "vscode-languageserver-protocol";
|
||||
import { Diagnostics } from "./lsp/Diagnostics.ts";
|
||||
import { DocumentError, Documents } from "./lsp/Documents.ts";
|
||||
import * as Editor from "./lsp/Editor.ts";
|
||||
import { LanguageServer, LspError } from "./lsp/LanguageServer.ts";
|
||||
import * as Model from "./Model.ts";
|
||||
|
||||
const Failure = Schema.Union([LspError, DocumentError]);
|
||||
|
||||
const define = <
|
||||
const Name extends string,
|
||||
Parameters extends Schema.Constraint,
|
||||
Success extends Schema.Constraint,
|
||||
>(
|
||||
name: Name,
|
||||
options: {
|
||||
readonly description: string;
|
||||
readonly parameters: Parameters;
|
||||
readonly success: Success;
|
||||
readonly mutates?: boolean;
|
||||
},
|
||||
) =>
|
||||
Tool.make(name, {
|
||||
description: options.description,
|
||||
parameters: options.parameters,
|
||||
success: options.success,
|
||||
failure: Failure,
|
||||
dependencies: [LanguageServer, Documents, Diagnostics],
|
||||
})
|
||||
.annotate(Tool.Readonly, !options.mutates)
|
||||
.annotate(Tool.Destructive, false)
|
||||
.annotate(Tool.Idempotent, !options.mutates)
|
||||
.annotate(Tool.OpenWorld, false);
|
||||
|
||||
const positions =
|
||||
"Positions are 1-based lines and columns; instead of a column you may name the `symbol` on that line to point at.";
|
||||
const preview =
|
||||
"Without `apply` the edits are only previewed; with `apply: true` they are written to disk.";
|
||||
|
||||
export const Tools = Toolkit.make(
|
||||
define("hover", {
|
||||
description: `Type signature and documentation of the symbol at a position, as an editor shows on hover. ${positions}`,
|
||||
parameters: Model.Where,
|
||||
success: Schema.NullOr(Model.Hover),
|
||||
}),
|
||||
define("definition", {
|
||||
description: `Where the symbol at a position is defined (or its type definition, implementations, or declaration). Returns locations with a preview of each target line. ${positions}`,
|
||||
parameters: Model.Goto,
|
||||
success: Schema.Array(Model.Location),
|
||||
}),
|
||||
define("references", {
|
||||
description: `Every place the symbol at a position is used across the workspace, with a preview of each line. ${positions}`,
|
||||
parameters: Model.References,
|
||||
success: Schema.Array(Model.Location),
|
||||
}),
|
||||
define("document_symbols", {
|
||||
description:
|
||||
"Outline of a file: its functions, classes, methods, variables and so on, with their ranges, as a tree.",
|
||||
parameters: Schema.Struct({ file: Model.File }),
|
||||
success: Schema.Array(Model.DocumentSymbol),
|
||||
}),
|
||||
define("workspace_symbols", {
|
||||
description:
|
||||
"Find symbols by name across the whole workspace, including files you have not opened.",
|
||||
parameters: Model.WorkspaceQuery,
|
||||
success: Schema.Array(Model.WorkspaceSymbol),
|
||||
}),
|
||||
define("diagnostics", {
|
||||
description:
|
||||
"Errors, warnings and hints from the language server. Files are re-read from disk first, so call this right after editing to check your changes. Without `file`, returns everything reported so far.",
|
||||
parameters: Model.DiagnosticsQuery,
|
||||
success: Schema.Array(Model.Diagnostic),
|
||||
}),
|
||||
define("completions", {
|
||||
description: `Completion items at a position: discover members, imports, or valid identifiers the server suggests. ${positions}`,
|
||||
parameters: Model.Completions,
|
||||
success: Schema.Array(Model.Completion),
|
||||
}),
|
||||
define("signature_help", {
|
||||
description: `Signatures and parameters of the call surrounding a position. ${positions}`,
|
||||
parameters: Model.Where,
|
||||
success: Model.SignatureHelp,
|
||||
}),
|
||||
define("rename", {
|
||||
description: `Rename the symbol at a position everywhere it is referenced, across files. ${positions} ${preview}`,
|
||||
parameters: Model.Rename,
|
||||
success: Model.WorkspaceEdit,
|
||||
mutates: true,
|
||||
}),
|
||||
define("code_actions", {
|
||||
description:
|
||||
"Quick fixes and refactorings the server offers for a selection (whole lines unless columns are given), including fixes for the diagnostics there. Apply one with apply_code_action.",
|
||||
parameters: Model.CodeActions,
|
||||
success: Schema.Array(Model.CodeAction),
|
||||
}),
|
||||
define("apply_code_action", {
|
||||
description:
|
||||
"Apply a code action by title, for the same selection given to code_actions. Edits are written to disk.",
|
||||
parameters: Model.ApplyCodeAction,
|
||||
success: Model.WorkspaceEdit,
|
||||
mutates: true,
|
||||
}),
|
||||
define("format", {
|
||||
description: `Format a whole file with the language server's formatter. ${preview}`,
|
||||
parameters: Model.Format,
|
||||
success: Model.WorkspaceEdit,
|
||||
mutates: true,
|
||||
}),
|
||||
define("call_hierarchy", {
|
||||
description: `Callers of the function at a position (incoming) or the functions it calls (outgoing). ${positions}`,
|
||||
parameters: Model.CallHierarchy,
|
||||
success: Schema.Array(Model.Call),
|
||||
}),
|
||||
);
|
||||
|
||||
export const layer = Tools.toLayer({
|
||||
hover: Editor.hover,
|
||||
definition: Editor.definition,
|
||||
references: Editor.references,
|
||||
document_symbols: Editor.documentSymbols,
|
||||
workspace_symbols: Editor.workspaceSymbols,
|
||||
diagnostics: Editor.diagnostics,
|
||||
completions: Editor.completions,
|
||||
signature_help: Editor.signatureHelp,
|
||||
rename: Editor.rename,
|
||||
code_actions: Editor.codeActions,
|
||||
apply_code_action: Editor.applyCodeAction,
|
||||
format: Editor.format,
|
||||
call_hierarchy: Editor.callHierarchy,
|
||||
});
|
||||
|
||||
const requirements: Record<
|
||||
keyof typeof Tools.tools,
|
||||
(c: ServerCapabilities) => unknown
|
||||
> = {
|
||||
hover: (c) => c.hoverProvider,
|
||||
definition: (c) =>
|
||||
c.definitionProvider ??
|
||||
c.typeDefinitionProvider ??
|
||||
c.implementationProvider ??
|
||||
c.declarationProvider,
|
||||
references: (c) => c.referencesProvider,
|
||||
document_symbols: (c) => c.documentSymbolProvider,
|
||||
workspace_symbols: (c) => c.workspaceSymbolProvider,
|
||||
diagnostics: () => true,
|
||||
completions: (c) => c.completionProvider,
|
||||
signature_help: (c) => c.signatureHelpProvider,
|
||||
rename: (c) => c.renameProvider,
|
||||
code_actions: (c) => c.codeActionProvider,
|
||||
apply_code_action: (c) => c.codeActionProvider,
|
||||
format: (c) => c.documentFormattingProvider,
|
||||
call_hierarchy: (c) => c.callHierarchyProvider,
|
||||
};
|
||||
|
||||
/** The subset of `Tools` the server can serve; handled by the same `layer`. */
|
||||
export const supportedBy = (capabilities: ServerCapabilities): typeof Tools =>
|
||||
Toolkit.make(
|
||||
...Object.values(Tools.tools).filter((tool) =>
|
||||
requirements[tool.name](capabilities),
|
||||
),
|
||||
) as typeof Tools;
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Diagnostics reconcile LSP's push model with the agent's pull model.
|
||||
*
|
||||
* Published diagnostics are accumulated per URI. Asking for a document's
|
||||
* diagnostics either pulls them (when the server supports
|
||||
* `textDocument/diagnostic`) or waits for the push that follows the document's
|
||||
* latest version to settle, bounded by a timeout.
|
||||
*/
|
||||
import {
|
||||
Context,
|
||||
Effect,
|
||||
HashMap,
|
||||
Layer,
|
||||
Option,
|
||||
PubSub,
|
||||
Ref,
|
||||
Stream,
|
||||
} from "effect";
|
||||
import {
|
||||
type Diagnostic,
|
||||
DocumentDiagnosticReportKind,
|
||||
DocumentDiagnosticRequest,
|
||||
PublishDiagnosticsNotification,
|
||||
type PublishDiagnosticsParams,
|
||||
WorkspaceDiagnosticRequest,
|
||||
} from "vscode-languageserver-protocol";
|
||||
import type { TextDocument } from "vscode-languageserver-textdocument";
|
||||
import { LanguageServer, type LspError } from "./LanguageServer.ts";
|
||||
|
||||
/** Quiet period after a publish before diagnostics count as settled. */
|
||||
const settle = "250 millis";
|
||||
/** How long to wait for a server that never publishes for a change. */
|
||||
const patience = "5 seconds";
|
||||
|
||||
const make = Effect.gen(function* () {
|
||||
const lsp = yield* LanguageServer;
|
||||
const state = yield* Ref.make(
|
||||
HashMap.empty<string, PublishDiagnosticsParams>(),
|
||||
);
|
||||
const updates = yield* PubSub.unbounded<string>();
|
||||
const settled = new Map<string, number>();
|
||||
const provider = lsp.capabilities.diagnosticProvider;
|
||||
|
||||
const publish = (params: PublishDiagnosticsParams) =>
|
||||
Ref.update(state, HashMap.set(params.uri, params)).pipe(
|
||||
Effect.andThen(PubSub.publish(updates, params.uri)),
|
||||
);
|
||||
yield* lsp
|
||||
.notifications(PublishDiagnosticsNotification.type)
|
||||
.pipe(Stream.runForEach(publish), Effect.forkScoped);
|
||||
|
||||
const current = (uri: string) =>
|
||||
Ref.get(state).pipe(
|
||||
Effect.map((map) => Option.getOrUndefined(HashMap.get(map, uri))),
|
||||
);
|
||||
|
||||
const pull = Effect.fn("Diagnostics.pull")(function* (doc: TextDocument) {
|
||||
const report = yield* lsp.request(DocumentDiagnosticRequest.type, {
|
||||
textDocument: { uri: doc.uri },
|
||||
});
|
||||
if (report.kind === DocumentDiagnosticReportKind.Full) {
|
||||
yield* publish({
|
||||
uri: doc.uri,
|
||||
version: doc.version,
|
||||
diagnostics: report.items,
|
||||
});
|
||||
}
|
||||
return (yield* current(doc.uri))?.diagnostics ?? [];
|
||||
});
|
||||
|
||||
const awaitPush = Effect.fn("Diagnostics.awaitPush")(function* (
|
||||
doc: TextDocument,
|
||||
) {
|
||||
if (settled.get(doc.uri) !== doc.version) {
|
||||
yield* Effect.scoped(
|
||||
Effect.gen(function* () {
|
||||
const subscription = yield* PubSub.subscribe(updates);
|
||||
const fresh = (yield* current(doc.uri))?.version === doc.version;
|
||||
yield* Stream.fromSubscription(subscription).pipe(
|
||||
Stream.filter((uri) => uri === doc.uri),
|
||||
Stream.debounce(settle),
|
||||
Stream.runHead,
|
||||
Effect.timeoutOption(fresh ? settle : patience),
|
||||
);
|
||||
}),
|
||||
);
|
||||
settled.set(doc.uri, doc.version);
|
||||
}
|
||||
return (yield* current(doc.uri))?.diagnostics ?? [];
|
||||
});
|
||||
|
||||
const all = Effect.gen(function* () {
|
||||
if (provider?.workspaceDiagnostics) {
|
||||
const report = yield* lsp.request(WorkspaceDiagnosticRequest.type, {
|
||||
previousResultIds: [],
|
||||
});
|
||||
for (const item of report.items) {
|
||||
if (item.kind === DocumentDiagnosticReportKind.Full) {
|
||||
yield* publish({
|
||||
uri: item.uri,
|
||||
diagnostics: item.items,
|
||||
...(item.version === null ? {} : { version: item.version }),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return Array.from(HashMap.values(yield* Ref.get(state)));
|
||||
});
|
||||
|
||||
return Diagnostics.of({
|
||||
all,
|
||||
forDocument: provider ? pull : awaitPush,
|
||||
changes: Stream.fromPubSub(updates),
|
||||
});
|
||||
});
|
||||
|
||||
export class Diagnostics extends Context.Service<
|
||||
Diagnostics,
|
||||
{
|
||||
/** Everything the server has reported, per URI. */
|
||||
readonly all: Effect.Effect<
|
||||
ReadonlyArray<PublishDiagnosticsParams>,
|
||||
LspError
|
||||
>;
|
||||
/** Diagnostics matching the document's current version. */
|
||||
readonly forDocument: (
|
||||
doc: TextDocument,
|
||||
) => Effect.Effect<ReadonlyArray<Diagnostic>, LspError>;
|
||||
/** URIs whose diagnostics changed. */
|
||||
readonly changes: Stream.Stream<string>;
|
||||
}
|
||||
>()("lsp-mcp/lsp/Diagnostics") {
|
||||
static readonly layer = Layer.effect(Diagnostics, make);
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
* The headless editor's document store.
|
||||
*
|
||||
* Documents are opened in the language server on demand and kept in an LRU
|
||||
* set; the least recently used one is closed when the capacity is exceeded.
|
||||
* Every access re-checks the file on disk and, if it changed, pushes the new
|
||||
* content as `didChange` + `didSave`, so edits agents make with other tools
|
||||
* are visible to the server without any explicit synchronization step.
|
||||
*/
|
||||
import {
|
||||
Context,
|
||||
Duration,
|
||||
Effect,
|
||||
Exit,
|
||||
FileSystem,
|
||||
Layer,
|
||||
Option,
|
||||
Path,
|
||||
type PlatformError,
|
||||
Schema,
|
||||
ScopedCache,
|
||||
Semaphore,
|
||||
} from "effect";
|
||||
import {
|
||||
ApplyWorkspaceEditRequest,
|
||||
CreateFile,
|
||||
DeleteFile,
|
||||
DidChangeTextDocumentNotification,
|
||||
DidCloseTextDocumentNotification,
|
||||
DidOpenTextDocumentNotification,
|
||||
DidSaveTextDocumentNotification,
|
||||
RenameFile,
|
||||
type TextDocumentEdit,
|
||||
type TextEdit,
|
||||
type WorkspaceEdit,
|
||||
} from "vscode-languageserver-protocol";
|
||||
import { TextDocument } from "vscode-languageserver-textdocument";
|
||||
import { URI } from "vscode-uri";
|
||||
import { LanguageServer } from "./LanguageServer.ts";
|
||||
|
||||
export interface Options {
|
||||
/** How many documents stay open in the server before the least recently used is closed. */
|
||||
readonly capacity: number;
|
||||
/** Extra file extension (without dot) to LSP `languageId` mappings. */
|
||||
readonly languages: Readonly<Record<string, string>>;
|
||||
}
|
||||
|
||||
export class DocumentError extends Schema.TaggedError<DocumentError>()(
|
||||
"DocumentError",
|
||||
{
|
||||
file: Schema.String,
|
||||
message: Schema.String,
|
||||
},
|
||||
) {}
|
||||
|
||||
export type Change = TextDocumentEdit | CreateFile | RenameFile | DeleteFile;
|
||||
|
||||
export class Documents extends Context.Service<
|
||||
Documents,
|
||||
{
|
||||
/** URI for a path that is absolute or relative to the workspace root. */
|
||||
readonly uri: (file: string) => string;
|
||||
/** Display path for a URI: relative to the root when inside it. */
|
||||
readonly file: (uri: string) => string;
|
||||
/** Open (or refresh) a document in the server and return its current text. */
|
||||
readonly open: (file: string) => Effect.Effect<TextDocument, DocumentError>;
|
||||
/** Current content of a URI without opening it in the server. */
|
||||
readonly peek: (uri: string) => Effect.Effect<TextDocument, DocumentError>;
|
||||
/** Replace an open document's content on disk and in the server. */
|
||||
readonly write: (
|
||||
uri: string,
|
||||
text: string,
|
||||
) => Effect.Effect<void, DocumentError>;
|
||||
/** Apply a server-provided edit to disk, in order, refusing stale versions. */
|
||||
readonly applyEdit: (
|
||||
edit: WorkspaceEdit,
|
||||
) => Effect.Effect<void, DocumentError>;
|
||||
readonly opened: Effect.Effect<ReadonlyArray<string>>;
|
||||
}
|
||||
>()("lsp-mcp/lsp/Documents") {
|
||||
static readonly layer = (options: Options) =>
|
||||
Layer.effect(Documents, make(options));
|
||||
}
|
||||
|
||||
/** The ordered list of changes described by a `WorkspaceEdit`. */
|
||||
export const changes = (edit: WorkspaceEdit): ReadonlyArray<Change> =>
|
||||
edit.documentChanges ??
|
||||
Object.entries(edit.changes ?? {}).map(([uri, edits]) => ({
|
||||
textDocument: { uri, version: null },
|
||||
edits,
|
||||
}));
|
||||
|
||||
const textEdits = (edit: TextDocumentEdit): Array<TextEdit> =>
|
||||
edit.edits.filter((e): e is TextEdit => "newText" in e);
|
||||
|
||||
interface Entry {
|
||||
readonly doc: TextDocument;
|
||||
stamp: string;
|
||||
}
|
||||
|
||||
const make = Effect.fn("Documents.make")(function* (options: Options) {
|
||||
const fs = yield* FileSystem.FileSystem;
|
||||
const path = yield* Path.Path;
|
||||
const lsp = yield* LanguageServer;
|
||||
const lock = yield* Semaphore.make(1);
|
||||
const sync = lsp.capabilities.textDocumentSync;
|
||||
const save = typeof sync === "object" ? sync.save : undefined;
|
||||
|
||||
const uri = (file: string) =>
|
||||
URI.file(path.resolve(lsp.root, file)).toString();
|
||||
const fsPath = (uri: string) => URI.parse(uri).fsPath;
|
||||
const file = (uri: string) => {
|
||||
const parsed = URI.parse(uri);
|
||||
if (parsed.scheme !== "file") return uri;
|
||||
const relative = path.relative(lsp.root, parsed.fsPath);
|
||||
return relative.startsWith("..") || path.isAbsolute(relative)
|
||||
? parsed.fsPath
|
||||
: relative;
|
||||
};
|
||||
const io = (uri: string) => (error: PlatformError.PlatformError) =>
|
||||
new DocumentError({ file: file(uri), message: error.message });
|
||||
const read = (uri: string) =>
|
||||
fs.readFileString(fsPath(uri)).pipe(Effect.mapError(io(uri)));
|
||||
const stamp = (uri: string) =>
|
||||
fs.stat(fsPath(uri)).pipe(
|
||||
Effect.map(
|
||||
(info) =>
|
||||
`${Option.getOrUndefined(info.mtime)?.getTime()}:${info.size}`,
|
||||
),
|
||||
Effect.mapError(io(uri)),
|
||||
);
|
||||
|
||||
const languageId = (uri: string) => {
|
||||
const name = path.basename(fsPath(uri)).toLowerCase();
|
||||
const ext = path.extname(name).slice(1);
|
||||
return (
|
||||
options.languages[ext] ?? languages[ext] ?? languages[name] ?? "plaintext"
|
||||
);
|
||||
};
|
||||
|
||||
const cache = yield* ScopedCache.makeWith<string, Entry, DocumentError>({
|
||||
capacity: options.capacity,
|
||||
timeToLive: (exit) =>
|
||||
Exit.isFailure(exit) ? Duration.zero : Duration.infinity,
|
||||
lookup: (uri) =>
|
||||
Effect.gen(function* () {
|
||||
const [text, current] = yield* Effect.all([read(uri), stamp(uri)]);
|
||||
const doc = TextDocument.create(uri, languageId(uri), 1, text);
|
||||
yield* Effect.acquireRelease(
|
||||
lsp.notify(DidOpenTextDocumentNotification.type, {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId: doc.languageId,
|
||||
version: doc.version,
|
||||
text,
|
||||
},
|
||||
}),
|
||||
() =>
|
||||
lsp.notify(DidCloseTextDocumentNotification.type, {
|
||||
textDocument: { uri },
|
||||
}),
|
||||
);
|
||||
return { doc, stamp: current } satisfies Entry;
|
||||
}),
|
||||
});
|
||||
|
||||
const change = Effect.fn("Documents.change")(function* (
|
||||
entry: Entry,
|
||||
text: string,
|
||||
) {
|
||||
const { uri } = entry.doc;
|
||||
const version = entry.doc.version + 1;
|
||||
TextDocument.update(entry.doc, [{ text }], version);
|
||||
yield* lsp.notify(DidChangeTextDocumentNotification.type, {
|
||||
textDocument: { uri, version },
|
||||
contentChanges: [{ text }],
|
||||
});
|
||||
if (save) {
|
||||
yield* lsp.notify(DidSaveTextDocumentNotification.type, {
|
||||
textDocument: { uri },
|
||||
...(typeof save === "object" && save.includeText ? { text } : {}),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/** Bring an open document in line with the file on disk. */
|
||||
const refresh = Effect.fn("Documents.refresh")(function* (uri: string) {
|
||||
const entry = yield* ScopedCache.get(cache, uri);
|
||||
const current = yield* stamp(uri).pipe(
|
||||
Effect.tapError(() => ScopedCache.invalidate(cache, uri)),
|
||||
);
|
||||
if (current !== entry.stamp) {
|
||||
const text = yield* read(uri);
|
||||
entry.stamp = current;
|
||||
if (text !== entry.doc.getText()) yield* change(entry, text);
|
||||
}
|
||||
return entry.doc;
|
||||
});
|
||||
|
||||
const open = (file: string) => lock.withPermits(1)(refresh(uri(file)));
|
||||
|
||||
const peek = (uri: string) =>
|
||||
Effect.flatMap(ScopedCache.has(cache, uri), (open) =>
|
||||
open
|
||||
? lock.withPermits(1)(refresh(uri))
|
||||
: Effect.map(read(uri), (text) =>
|
||||
TextDocument.create(uri, "", 0, text),
|
||||
),
|
||||
);
|
||||
|
||||
/** Persist new content for an open document and tell the server. */
|
||||
const store = Effect.fn("Documents.store")(function* (
|
||||
uri: string,
|
||||
text: string,
|
||||
) {
|
||||
const entry = yield* ScopedCache.get(cache, uri);
|
||||
yield* fs.writeFileString(fsPath(uri), text).pipe(Effect.mapError(io(uri)));
|
||||
entry.stamp = yield* stamp(uri);
|
||||
if (text !== entry.doc.getText()) yield* change(entry, text);
|
||||
});
|
||||
|
||||
const write = (uri: string, text: string) =>
|
||||
lock.withPermits(1)(store(uri, text));
|
||||
|
||||
const forget = (uri: string) => ScopedCache.invalidate(cache, uri);
|
||||
|
||||
const apply = Effect.fn("Documents.applyChange")(function* (change: Change) {
|
||||
if (CreateFile.is(change)) {
|
||||
const target = fsPath(change.uri);
|
||||
if (
|
||||
change.options?.ignoreIfExists &&
|
||||
(yield* fs.exists(target).pipe(Effect.mapError(io(change.uri))))
|
||||
)
|
||||
return;
|
||||
yield* fs
|
||||
.makeDirectory(path.dirname(target), { recursive: true })
|
||||
.pipe(
|
||||
Effect.andThen(fs.writeFileString(target, "")),
|
||||
Effect.mapError(io(change.uri)),
|
||||
);
|
||||
} else if (RenameFile.is(change)) {
|
||||
yield* Effect.all([forget(change.oldUri), forget(change.newUri)]);
|
||||
yield* fs
|
||||
.rename(fsPath(change.oldUri), fsPath(change.newUri))
|
||||
.pipe(Effect.mapError(io(change.oldUri)));
|
||||
} else if (DeleteFile.is(change)) {
|
||||
yield* forget(change.uri);
|
||||
yield* fs
|
||||
.remove(fsPath(change.uri), {
|
||||
recursive: change.options?.recursive ?? false,
|
||||
})
|
||||
.pipe(Effect.mapError(io(change.uri)));
|
||||
} else {
|
||||
const { uri, version } = change.textDocument;
|
||||
const doc = yield* refresh(uri);
|
||||
if (
|
||||
version !== null &&
|
||||
version !== undefined &&
|
||||
version !== doc.version
|
||||
) {
|
||||
return yield* new DocumentError({
|
||||
file: file(uri),
|
||||
message: "document changed since the edit was computed",
|
||||
});
|
||||
}
|
||||
yield* store(uri, TextDocument.applyEdits(doc, textEdits(change)));
|
||||
}
|
||||
});
|
||||
|
||||
const applyEdit = (edit: WorkspaceEdit) =>
|
||||
lock.withPermits(1)(
|
||||
Effect.forEach(changes(edit), apply, { discard: true }),
|
||||
);
|
||||
|
||||
yield* lsp.onRequest(ApplyWorkspaceEditRequest.type, ({ edit }) =>
|
||||
applyEdit(edit).pipe(
|
||||
Effect.as({ applied: true }),
|
||||
Effect.catch((error) =>
|
||||
Effect.succeed({ applied: false, failureReason: error.message }),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return Documents.of({
|
||||
uri,
|
||||
file,
|
||||
open,
|
||||
peek,
|
||||
write,
|
||||
applyEdit,
|
||||
opened: ScopedCache.keys(cache),
|
||||
});
|
||||
});
|
||||
|
||||
const languages: Record<string, string> = {
|
||||
ts: "typescript",
|
||||
mts: "typescript",
|
||||
cts: "typescript",
|
||||
tsx: "typescriptreact",
|
||||
js: "javascript",
|
||||
mjs: "javascript",
|
||||
cjs: "javascript",
|
||||
jsx: "javascriptreact",
|
||||
json: "json",
|
||||
jsonc: "jsonc",
|
||||
py: "python",
|
||||
pyi: "python",
|
||||
rs: "rust",
|
||||
go: "go",
|
||||
c: "c",
|
||||
h: "c",
|
||||
cc: "cpp",
|
||||
cpp: "cpp",
|
||||
cxx: "cpp",
|
||||
hpp: "cpp",
|
||||
hh: "cpp",
|
||||
java: "java",
|
||||
kt: "kotlin",
|
||||
kts: "kotlin",
|
||||
scala: "scala",
|
||||
cs: "csharp",
|
||||
fs: "fsharp",
|
||||
swift: "swift",
|
||||
rb: "ruby",
|
||||
php: "php",
|
||||
lua: "lua",
|
||||
zig: "zig",
|
||||
hs: "haskell",
|
||||
ml: "ocaml",
|
||||
mli: "ocaml",
|
||||
ex: "elixir",
|
||||
exs: "elixir",
|
||||
erl: "erlang",
|
||||
clj: "clojure",
|
||||
cljs: "clojurescript",
|
||||
dart: "dart",
|
||||
elm: "elm",
|
||||
nix: "nix",
|
||||
r: "r",
|
||||
jl: "julia",
|
||||
vue: "vue",
|
||||
svelte: "svelte",
|
||||
astro: "astro",
|
||||
html: "html",
|
||||
css: "css",
|
||||
scss: "scss",
|
||||
less: "less",
|
||||
md: "markdown",
|
||||
yaml: "yaml",
|
||||
yml: "yaml",
|
||||
toml: "toml",
|
||||
xml: "xml",
|
||||
sql: "sql",
|
||||
sh: "shellscript",
|
||||
bash: "shellscript",
|
||||
zsh: "shellscript",
|
||||
fish: "fish",
|
||||
tf: "terraform",
|
||||
proto: "proto",
|
||||
graphql: "graphql",
|
||||
gql: "graphql",
|
||||
tex: "latex",
|
||||
vim: "vim",
|
||||
dockerfile: "dockerfile",
|
||||
makefile: "makefile",
|
||||
};
|
||||
@@ -0,0 +1,608 @@
|
||||
/**
|
||||
* The operations an agent performs on the headless editor.
|
||||
*
|
||||
* Each function resolves agent-facing input (paths, 1-based positions,
|
||||
* symbols on a line) to LSP requests and presents the results in the
|
||||
* `Model` vocabulary. These functions are the MCP tool handlers.
|
||||
*/
|
||||
import { Effect, Option } from "effect";
|
||||
import {
|
||||
CallHierarchyIncomingCallsRequest,
|
||||
CallHierarchyOutgoingCallsRequest,
|
||||
CallHierarchyPrepareRequest,
|
||||
CodeAction,
|
||||
CodeActionRequest,
|
||||
CodeActionResolveRequest,
|
||||
CodeActionTriggerKind,
|
||||
type Command,
|
||||
CompletionItemKind,
|
||||
CompletionRequest,
|
||||
CompletionTriggerKind,
|
||||
DeclarationRequest,
|
||||
DefinitionRequest,
|
||||
type Diagnostic,
|
||||
DocumentFormattingRequest,
|
||||
type DocumentSymbol,
|
||||
DocumentSymbolRequest,
|
||||
ExecuteCommandRequest,
|
||||
type Hover,
|
||||
HoverRequest,
|
||||
ImplementationRequest,
|
||||
type Location,
|
||||
type LocationLink,
|
||||
type MarkupContent,
|
||||
type Position,
|
||||
type Range,
|
||||
ReferencesRequest,
|
||||
RenameRequest,
|
||||
type ServerCapabilities,
|
||||
SignatureHelpRequest,
|
||||
SymbolKind,
|
||||
TextDocumentEdit,
|
||||
TypeDefinitionRequest,
|
||||
type WorkspaceEdit,
|
||||
WorkspaceSymbolRequest,
|
||||
} from "vscode-languageserver-protocol";
|
||||
import { TextDocument } from "vscode-languageserver-textdocument";
|
||||
import type * as Model from "../Model.ts";
|
||||
import { Diagnostics } from "./Diagnostics.ts";
|
||||
import { changes, Documents } from "./Documents.ts";
|
||||
import { LanguageServer, LspError } from "./LanguageServer.ts";
|
||||
|
||||
// --- Presentation ----------------------------------------------------------
|
||||
|
||||
const range = (r: Range): Model.Range => ({
|
||||
line: r.start.line + 1,
|
||||
column: r.start.character + 1,
|
||||
endLine: r.end.line + 1,
|
||||
endColumn: r.end.character + 1,
|
||||
});
|
||||
|
||||
const lineText = (doc: TextDocument, line: number) =>
|
||||
doc
|
||||
.getText()
|
||||
.slice(
|
||||
doc.offsetAt({ line, character: 0 }),
|
||||
doc.offsetAt({ line: line + 1, character: 0 }),
|
||||
)
|
||||
.replace(/\r?\n$/, "");
|
||||
|
||||
const preview = (doc: TextDocument | undefined, line: number) =>
|
||||
doc === undefined ? "" : lineText(doc, line).trim();
|
||||
|
||||
const markup = (content: Hover["contents"] | MarkupContent | string): string =>
|
||||
typeof content === "string"
|
||||
? content
|
||||
: Array.isArray(content)
|
||||
? content.map(markup).join("\n\n")
|
||||
: "kind" in content
|
||||
? content.value
|
||||
: `\`\`\`${content.language}\n${content.value}\n\`\`\``;
|
||||
|
||||
/** `{ Class: 5 }` → `{ 5: "class" }`, `{ TypeParameter: 26 }` → `{ 26: "typeParameter" }`. */
|
||||
const kindNames = (kinds: Record<string, number>): Record<number, string> =>
|
||||
Object.fromEntries(
|
||||
Object.entries(kinds).map(([name, value]) => [
|
||||
value,
|
||||
name[0]?.toLowerCase() + name.slice(1),
|
||||
]),
|
||||
);
|
||||
const symbolKinds = kindNames(SymbolKind);
|
||||
const completionKinds = kindNames(CompletionItemKind);
|
||||
const severities = [
|
||||
"error",
|
||||
"warning",
|
||||
"information",
|
||||
"hint",
|
||||
] as const satisfies ReadonlyArray<Model.Severity>;
|
||||
|
||||
// --- Resolution ------------------------------------------------------------
|
||||
|
||||
const unsupported = (feature: string) =>
|
||||
new LspError({
|
||||
method: feature,
|
||||
message: `the language server does not support ${feature}`,
|
||||
});
|
||||
|
||||
const ensure = (
|
||||
capabilities: ServerCapabilities,
|
||||
key: keyof ServerCapabilities,
|
||||
) => (capabilities[key] ? Effect.void : Effect.fail(unsupported(key)));
|
||||
|
||||
/** Turn agent-facing `Where` into an LSP text document position. */
|
||||
const locate = Effect.fn("Editor.locate")(function* (where: Model.Where) {
|
||||
const docs = yield* Documents;
|
||||
const doc = yield* docs.open(where.file);
|
||||
const line = where.line - 1;
|
||||
if (line >= doc.lineCount) {
|
||||
return yield* new LspError({
|
||||
method: "locate",
|
||||
message: `${where.file} has only ${doc.lineCount} lines`,
|
||||
});
|
||||
}
|
||||
const text = lineText(doc, line);
|
||||
const character =
|
||||
where.column !== undefined
|
||||
? where.column - 1
|
||||
: where.symbol !== undefined
|
||||
? yield* Effect.orElseSucceed(findSymbol(text, where.symbol), () => -1)
|
||||
: Math.max(0, text.search(/\S/));
|
||||
if (character < 0) {
|
||||
return yield* new LspError({
|
||||
method: "locate",
|
||||
message: `"${where.symbol}" does not occur on line ${where.line}`,
|
||||
});
|
||||
}
|
||||
const position: Position = {
|
||||
line,
|
||||
character: Math.min(character, text.length),
|
||||
};
|
||||
return { doc, position, textDocument: { uri: doc.uri } };
|
||||
});
|
||||
|
||||
const findSymbol = (text: string, symbol: string) => {
|
||||
const escaped = symbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const index = text.search(
|
||||
new RegExp(`(?<![\\p{L}\\p{N}_$])${escaped}(?![\\p{L}\\p{N}_$])`, "u"),
|
||||
);
|
||||
const found = index >= 0 ? index : text.indexOf(symbol);
|
||||
return found >= 0 ? Effect.succeed(found) : Effect.fail(found);
|
||||
};
|
||||
|
||||
const locations = Effect.fn("Editor.locations")(function* (
|
||||
items: ReadonlyArray<Location | LocationLink>,
|
||||
) {
|
||||
const docs = yield* Documents;
|
||||
const targets = items.map((item) =>
|
||||
"targetUri" in item
|
||||
? { uri: item.targetUri, range: item.targetSelectionRange }
|
||||
: item,
|
||||
);
|
||||
const previews = new Map(
|
||||
yield* Effect.forEach([...new Set(targets.map((t) => t.uri))], (uri) =>
|
||||
docs.peek(uri).pipe(
|
||||
Effect.option,
|
||||
Effect.map((doc) => [uri, Option.getOrUndefined(doc)] as const),
|
||||
),
|
||||
),
|
||||
);
|
||||
return targets.map(
|
||||
({ uri, range: r }): Model.Location => ({
|
||||
file: docs.file(uri),
|
||||
...range(r),
|
||||
preview: preview(previews.get(uri), r.start.line),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
const workspaceEdit = Effect.fn("Editor.workspaceEdit")(function* (
|
||||
edit: WorkspaceEdit,
|
||||
apply: boolean,
|
||||
) {
|
||||
const docs = yield* Documents;
|
||||
const files: Array<typeof Model.FileEdits.Type> = [];
|
||||
const operations: Array<string> = [];
|
||||
for (const change of changes(edit)) {
|
||||
if (TextDocumentEdit.is(change)) {
|
||||
files.push({
|
||||
file: docs.file(change.textDocument.uri),
|
||||
edits: change.edits.flatMap((e) =>
|
||||
"newText" in e ? [{ ...range(e.range), newText: e.newText }] : [],
|
||||
),
|
||||
});
|
||||
} else if (change.kind === "rename") {
|
||||
operations.push(
|
||||
`rename ${docs.file(change.oldUri)} -> ${docs.file(change.newUri)}`,
|
||||
);
|
||||
} else {
|
||||
operations.push(`${change.kind} ${docs.file(change.uri)}`);
|
||||
}
|
||||
}
|
||||
if (apply) yield* docs.applyEdit(edit);
|
||||
return { applied: apply, files, operations } satisfies Model.WorkspaceEdit;
|
||||
});
|
||||
|
||||
// --- Operations ------------------------------------------------------------
|
||||
|
||||
export const hover = Effect.fn("Editor.hover")(function* (where: Model.Where) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const result = yield* lsp.request(HoverRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
});
|
||||
return result === null
|
||||
? null
|
||||
: ({
|
||||
contents: markup(result.contents),
|
||||
range: result.range && range(result.range),
|
||||
} satisfies Model.Hover);
|
||||
});
|
||||
|
||||
const gotoRequests = {
|
||||
definition: DefinitionRequest.type,
|
||||
typeDefinition: TypeDefinitionRequest.type,
|
||||
implementation: ImplementationRequest.type,
|
||||
declaration: DeclarationRequest.type,
|
||||
};
|
||||
|
||||
export const definition = Effect.fn("Editor.definition")(function* ({
|
||||
kind = "definition",
|
||||
...where
|
||||
}: Model.Goto) {
|
||||
const lsp = yield* LanguageServer;
|
||||
yield* ensure(lsp.capabilities, `${kind}Provider`);
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const result = yield* lsp.request(
|
||||
gotoRequests[kind] as typeof DefinitionRequest.type,
|
||||
{ textDocument, position },
|
||||
);
|
||||
return yield* locations(
|
||||
result === null ? [] : Array.isArray(result) ? result : [result],
|
||||
);
|
||||
});
|
||||
|
||||
export const references = Effect.fn("Editor.references")(function* ({
|
||||
includeDeclaration = true,
|
||||
...where
|
||||
}: Model.References) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const result = yield* lsp.request(ReferencesRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
context: { includeDeclaration },
|
||||
});
|
||||
return yield* locations(result ?? []);
|
||||
});
|
||||
|
||||
export const documentSymbols = Effect.fn("Editor.documentSymbols")(function* ({
|
||||
file,
|
||||
}: {
|
||||
readonly file: string;
|
||||
}) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
const doc = yield* docs.open(file);
|
||||
const result = yield* lsp.request(DocumentSymbolRequest.type, {
|
||||
textDocument: { uri: doc.uri },
|
||||
});
|
||||
const present = (symbol: DocumentSymbol): Model.DocumentSymbol => ({
|
||||
name: symbol.name,
|
||||
kind: symbolKinds[symbol.kind] ?? "unknown",
|
||||
detail: symbol.detail || undefined,
|
||||
...range(symbol.range),
|
||||
children: symbol.children?.length
|
||||
? symbol.children.map(present)
|
||||
: undefined,
|
||||
});
|
||||
return (result ?? []).map(
|
||||
(symbol): Model.DocumentSymbol =>
|
||||
"range" in symbol
|
||||
? present(symbol)
|
||||
: {
|
||||
name: symbol.name,
|
||||
kind: symbolKinds[symbol.kind] ?? "unknown",
|
||||
container: symbol.containerName || undefined,
|
||||
...range(symbol.location.range),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
export const workspaceSymbols = Effect.fn("Editor.workspaceSymbols")(
|
||||
function* ({ query, limit = 50 }: Model.WorkspaceQuery) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
const result = yield* lsp.request(WorkspaceSymbolRequest.type, { query });
|
||||
return (result ?? []).slice(0, limit).map(
|
||||
(symbol): Model.WorkspaceSymbol => ({
|
||||
name: symbol.name,
|
||||
kind: symbolKinds[symbol.kind] ?? "unknown",
|
||||
container: symbol.containerName || undefined,
|
||||
file: docs.file(symbol.location.uri),
|
||||
...("range" in symbol.location
|
||||
? {
|
||||
line: symbol.location.range.start.line + 1,
|
||||
column: symbol.location.range.start.character + 1,
|
||||
}
|
||||
: {}),
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const diagnostics = Effect.fn("Editor.diagnostics")(function* ({
|
||||
file,
|
||||
severity = "hint",
|
||||
}: Model.DiagnosticsQuery) {
|
||||
const docs = yield* Documents;
|
||||
const diags = yield* Diagnostics;
|
||||
const present =
|
||||
(uri: string) =>
|
||||
(d: Diagnostic): Model.Diagnostic => ({
|
||||
file: docs.file(uri),
|
||||
...range(d.range),
|
||||
severity: severities[(d.severity ?? 1) - 1] ?? "error",
|
||||
code: d.code === undefined ? undefined : String(d.code),
|
||||
source: d.source,
|
||||
message: markup(d.message),
|
||||
related: d.relatedInformation?.map((r) => ({
|
||||
file: docs.file(r.location.uri),
|
||||
line: r.location.range.start.line + 1,
|
||||
column: r.location.range.start.character + 1,
|
||||
message: r.message,
|
||||
})),
|
||||
});
|
||||
const items =
|
||||
file === undefined
|
||||
? (yield* diags.all).flatMap((p) => p.diagnostics.map(present(p.uri)))
|
||||
: yield* docs
|
||||
.open(file)
|
||||
.pipe(
|
||||
Effect.flatMap((doc) =>
|
||||
Effect.map(diags.forDocument(doc), (ds) =>
|
||||
ds.map(present(doc.uri)),
|
||||
),
|
||||
),
|
||||
);
|
||||
const threshold = severities.indexOf(severity);
|
||||
return items
|
||||
.filter((d) => severities.indexOf(d.severity) <= threshold)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column,
|
||||
);
|
||||
});
|
||||
|
||||
export const completions = Effect.fn("Editor.completions")(function* ({
|
||||
prefix,
|
||||
limit = 20,
|
||||
...where
|
||||
}: Model.Completions) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const result = yield* lsp.request(CompletionRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
context: { triggerKind: CompletionTriggerKind.Invoked },
|
||||
});
|
||||
const items = Array.isArray(result) ? result : (result?.items ?? []);
|
||||
const lower = prefix?.toLowerCase();
|
||||
return items
|
||||
.filter(
|
||||
(item) =>
|
||||
lower === undefined ||
|
||||
(item.filterText ?? item.label).toLowerCase().startsWith(lower),
|
||||
)
|
||||
.sort((a, b) =>
|
||||
(a.sortText ?? a.label).localeCompare(b.sortText ?? b.label),
|
||||
)
|
||||
.slice(0, limit)
|
||||
.map(
|
||||
(item): Model.Completion => ({
|
||||
label: item.label,
|
||||
kind: completionKinds[item.kind ?? 1] ?? "text",
|
||||
detail: item.detail,
|
||||
documentation:
|
||||
item.documentation === undefined
|
||||
? undefined
|
||||
: markup(item.documentation),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
export const signatureHelp = Effect.fn("Editor.signatureHelp")(function* (
|
||||
where: Model.Where,
|
||||
) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const result = yield* lsp.request(SignatureHelpRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
});
|
||||
return {
|
||||
active: result?.activeSignature ?? 0,
|
||||
signatures: (result?.signatures ?? []).map((s) => ({
|
||||
label: s.label,
|
||||
documentation:
|
||||
s.documentation === undefined ? undefined : markup(s.documentation),
|
||||
parameters: (s.parameters ?? []).map((p) =>
|
||||
typeof p.label === "string"
|
||||
? p.label
|
||||
: s.label.slice(p.label[0], p.label[1]),
|
||||
),
|
||||
activeParameter:
|
||||
s.activeParameter ?? result?.activeParameter ?? undefined,
|
||||
})),
|
||||
} satisfies Model.SignatureHelp;
|
||||
});
|
||||
|
||||
export const rename = Effect.fn("Editor.rename")(function* ({
|
||||
newName,
|
||||
apply = false,
|
||||
...where
|
||||
}: Model.Rename) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const edit = yield* lsp.request(RenameRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
newName,
|
||||
});
|
||||
if (edit === null)
|
||||
return yield* new LspError({
|
||||
method: "rename",
|
||||
message: "nothing to rename at this position",
|
||||
});
|
||||
return yield* workspaceEdit(edit, apply);
|
||||
});
|
||||
|
||||
const selection = Effect.fn("Editor.selection")(function* ({
|
||||
file,
|
||||
line,
|
||||
column,
|
||||
endLine,
|
||||
endColumn,
|
||||
}: Model.Selection) {
|
||||
const docs = yield* Documents;
|
||||
const doc = yield* docs.open(file);
|
||||
const end = (endLine ?? line) - 1;
|
||||
const range: Range = {
|
||||
start: { line: line - 1, character: column === undefined ? 0 : column - 1 },
|
||||
end: {
|
||||
line: end,
|
||||
character:
|
||||
endColumn === undefined ? lineText(doc, end).length : endColumn - 1,
|
||||
},
|
||||
};
|
||||
return { doc, textDocument: { uri: doc.uri }, range };
|
||||
});
|
||||
|
||||
const overlaps = (a: Range, b: Range) =>
|
||||
(a.start.line < b.end.line ||
|
||||
(a.start.line === b.end.line && a.start.character <= b.end.character)) &&
|
||||
(b.start.line < a.end.line ||
|
||||
(b.start.line === a.end.line && b.start.character <= a.end.character));
|
||||
|
||||
const codeActionsAt = Effect.fn("Editor.codeActionsAt")(function* ({
|
||||
kind,
|
||||
...where
|
||||
}: Model.CodeActions) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const diags = yield* Diagnostics;
|
||||
const { doc, textDocument, range } = yield* selection(where);
|
||||
const diagnostics = (yield* diags.forDocument(doc)).filter((d) =>
|
||||
overlaps(d.range, range),
|
||||
);
|
||||
const actions = yield* lsp.request(CodeActionRequest.type, {
|
||||
textDocument,
|
||||
range,
|
||||
context: {
|
||||
diagnostics,
|
||||
triggerKind: CodeActionTriggerKind.Invoked,
|
||||
...(kind === undefined ? {} : { only: [kind] }),
|
||||
},
|
||||
});
|
||||
return actions ?? [];
|
||||
});
|
||||
|
||||
export const codeActions = Effect.fn("Editor.codeActions")(function* (
|
||||
params: Model.CodeActions,
|
||||
) {
|
||||
return (yield* codeActionsAt(params)).map(
|
||||
(action): Model.CodeAction => ({
|
||||
title: action.title,
|
||||
kind: CodeAction.is(action) ? action.kind : undefined,
|
||||
preferred: CodeAction.is(action) && action.isPreferred === true,
|
||||
fixes: CodeAction.is(action)
|
||||
? (action.diagnostics ?? []).map((d) => markup(d.message))
|
||||
: [],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
export const applyCodeAction = Effect.fn("Editor.applyCodeAction")(function* ({
|
||||
title,
|
||||
...params
|
||||
}: Model.ApplyCodeAction) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const action = (yield* codeActionsAt(params)).find((a) => a.title === title);
|
||||
if (action === undefined)
|
||||
return yield* new LspError({
|
||||
method: "codeAction",
|
||||
message: `no code action titled "${title}"`,
|
||||
});
|
||||
const execute = (command: Command) =>
|
||||
lsp
|
||||
.request(ExecuteCommandRequest.type, {
|
||||
command: command.command,
|
||||
...(command.arguments && { arguments: command.arguments }),
|
||||
})
|
||||
.pipe(Effect.as(`command ${command.command}`));
|
||||
if (!CodeAction.is(action)) {
|
||||
return {
|
||||
applied: true,
|
||||
files: [],
|
||||
operations: [yield* execute(action)],
|
||||
} satisfies Model.WorkspaceEdit;
|
||||
}
|
||||
const resolved =
|
||||
action.edit === undefined &&
|
||||
action.command === undefined &&
|
||||
lsp.capabilities.codeActionProvider
|
||||
? yield* lsp.request(CodeActionResolveRequest.type, action)
|
||||
: action;
|
||||
const result = yield* workspaceEdit(resolved.edit ?? {}, true);
|
||||
const operations = resolved.command
|
||||
? [...result.operations, yield* execute(resolved.command)]
|
||||
: result.operations;
|
||||
return { ...result, operations };
|
||||
});
|
||||
|
||||
export const format = Effect.fn("Editor.format")(function* ({
|
||||
file,
|
||||
tabSize = 4,
|
||||
insertSpaces = true,
|
||||
apply = false,
|
||||
}: Model.Format) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
const doc = yield* docs.open(file);
|
||||
const edits =
|
||||
(yield* lsp.request(DocumentFormattingRequest.type, {
|
||||
textDocument: { uri: doc.uri },
|
||||
options: { tabSize, insertSpaces },
|
||||
})) ?? [];
|
||||
if (apply && edits.length > 0)
|
||||
yield* docs.write(doc.uri, TextDocument.applyEdits(doc, edits));
|
||||
return {
|
||||
applied: apply,
|
||||
files: [
|
||||
{
|
||||
file: docs.file(doc.uri),
|
||||
edits: edits.map((e) => ({ ...range(e.range), newText: e.newText })),
|
||||
},
|
||||
],
|
||||
operations: [],
|
||||
} satisfies Model.WorkspaceEdit;
|
||||
});
|
||||
|
||||
export const callHierarchy = Effect.fn("Editor.callHierarchy")(function* ({
|
||||
direction = "incoming",
|
||||
...where
|
||||
}: Model.CallHierarchy) {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
const { textDocument, position } = yield* locate(where);
|
||||
const item = (yield* lsp.request(CallHierarchyPrepareRequest.type, {
|
||||
textDocument,
|
||||
position,
|
||||
}))?.[0];
|
||||
if (item === undefined) return [];
|
||||
const calls =
|
||||
direction === "incoming"
|
||||
? (
|
||||
(yield* lsp.request(CallHierarchyIncomingCallsRequest.type, {
|
||||
item,
|
||||
})) ?? []
|
||||
).map((c) => ({ item: c.from, sites: c.fromRanges }))
|
||||
: (
|
||||
(yield* lsp.request(CallHierarchyOutgoingCallsRequest.type, {
|
||||
item,
|
||||
})) ?? []
|
||||
).map((c) => ({ item: c.to, sites: c.fromRanges }));
|
||||
return calls.map(
|
||||
({ item, sites }): Model.Call => ({
|
||||
name: item.name,
|
||||
kind: symbolKinds[item.kind] ?? "unknown",
|
||||
detail: item.detail,
|
||||
file: docs.file(item.uri),
|
||||
line: item.selectionRange.start.line + 1,
|
||||
column: item.selectionRange.start.character + 1,
|
||||
sites: sites.map((r) => ({
|
||||
line: r.start.line + 1,
|
||||
column: r.start.character + 1,
|
||||
})),
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,444 @@
|
||||
/**
|
||||
* A running language server: process, JSON-RPC connection and the LSP
|
||||
* lifecycle, exposed as an Effect service.
|
||||
*
|
||||
* `request` waits for the server to become idle (no `$/progress` work in
|
||||
* flight) and retries transient `ContentModified` / `ServerCancelled`
|
||||
* failures, so callers can treat the server as if it were always ready.
|
||||
*/
|
||||
import { spawn } from "node:child_process";
|
||||
import { NodeStream } from "@effect/platform-node";
|
||||
import {
|
||||
Context,
|
||||
Deferred,
|
||||
Effect,
|
||||
FiberSet,
|
||||
HashSet,
|
||||
Layer,
|
||||
PubSub,
|
||||
Schedule,
|
||||
Schema,
|
||||
type Scope,
|
||||
Stream,
|
||||
SubscriptionRef,
|
||||
} from "effect";
|
||||
import {
|
||||
CancellationTokenSource,
|
||||
type ClientCapabilities,
|
||||
ConfigurationRequest,
|
||||
createMessageConnection,
|
||||
DidChangeConfigurationNotification,
|
||||
ErrorCodes,
|
||||
ExitNotification,
|
||||
type HandlerResult,
|
||||
InitializedNotification,
|
||||
InitializeRequest,
|
||||
LogMessageNotification,
|
||||
type LSPAny,
|
||||
LSPErrorCodes,
|
||||
type MessageType,
|
||||
type NotificationType,
|
||||
RegistrationRequest,
|
||||
type RequestType,
|
||||
ResponseError,
|
||||
type ServerCapabilities,
|
||||
ShowMessageNotification,
|
||||
ShutdownRequest,
|
||||
StreamMessageReader,
|
||||
StreamMessageWriter,
|
||||
UnregistrationRequest,
|
||||
WorkDoneProgressCreateRequest,
|
||||
WorkspaceFoldersRequest,
|
||||
} from "vscode-languageserver-protocol/node";
|
||||
import { URI } from "vscode-uri";
|
||||
|
||||
export interface Options {
|
||||
readonly command: string;
|
||||
readonly args: ReadonlyArray<string>;
|
||||
/** Absolute path of the workspace root. */
|
||||
readonly root: string;
|
||||
readonly initializationOptions?: unknown;
|
||||
/** Served as `workspace/configuration` and pushed via `didChangeConfiguration`. */
|
||||
readonly settings?: unknown;
|
||||
}
|
||||
|
||||
export class LspError extends Schema.TaggedError<LspError>()("LspError", {
|
||||
method: Schema.String,
|
||||
message: Schema.String,
|
||||
code: Schema.optional(Schema.Int),
|
||||
}) {
|
||||
get retryable() {
|
||||
return (
|
||||
this.code === LSPErrorCodes.ContentModified ||
|
||||
this.code === LSPErrorCodes.ServerCancelled
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export type LogLevel = "error" | "warning" | "info" | "debug";
|
||||
export interface LogMessage {
|
||||
readonly level: LogLevel;
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
export class LanguageServer extends Context.Service<
|
||||
LanguageServer,
|
||||
{
|
||||
readonly root: string;
|
||||
readonly capabilities: ServerCapabilities;
|
||||
readonly serverInfo:
|
||||
| { readonly name: string; readonly version?: string | undefined }
|
||||
| undefined;
|
||||
readonly request: <P, R>(
|
||||
type: RequestType<P, R, unknown>,
|
||||
params: P,
|
||||
) => Effect.Effect<R, LspError>;
|
||||
readonly notify: <P>(
|
||||
type: NotificationType<P>,
|
||||
params: P,
|
||||
) => Effect.Effect<void>;
|
||||
readonly notifications: <P>(type: NotificationType<P>) => Stream.Stream<P>;
|
||||
/** Handle a request the server sends to us; unhandled methods answer `MethodNotFound`. */
|
||||
readonly onRequest: <P, R>(
|
||||
type: RequestType<P, R, unknown>,
|
||||
handler: (params: P) => Effect.Effect<R, unknown>,
|
||||
) => Effect.Effect<void, never, Scope.Scope>;
|
||||
/** `window/logMessage` and `window/showMessage` traffic. */
|
||||
readonly logs: Stream.Stream<LogMessage>;
|
||||
}
|
||||
>()("lsp-mcp/lsp/LanguageServer") {
|
||||
static readonly layer = (options: Options) =>
|
||||
Layer.effect(LanguageServer, make(options));
|
||||
}
|
||||
|
||||
const make = Effect.fn("LanguageServer.make")(function* (options: Options) {
|
||||
const run = yield* FiberSet.makeRuntime<never>();
|
||||
const runPromise = yield* FiberSet.makeRuntimePromise<never>();
|
||||
const exited = yield* Deferred.make<never, LspError>();
|
||||
const events = yield* PubSub.unbounded<{
|
||||
readonly method: string;
|
||||
readonly params: unknown;
|
||||
}>();
|
||||
const progress = yield* SubscriptionRef.make(
|
||||
HashSet.empty<string | number>(),
|
||||
);
|
||||
const exit = (message: string) =>
|
||||
Deferred.doneUnsafe(
|
||||
exited,
|
||||
Effect.fail(new LspError({ method: "connection", message })),
|
||||
);
|
||||
|
||||
const child = yield* Effect.acquireRelease(
|
||||
Effect.sync(() =>
|
||||
spawn(options.command, options.args, {
|
||||
cwd: options.root,
|
||||
stdio: "pipe",
|
||||
}),
|
||||
),
|
||||
(child) =>
|
||||
Effect.sync(() => void (child.exitCode === null && child.kill())),
|
||||
);
|
||||
child.on("error", (error) =>
|
||||
exit(`failed to start ${options.command}: ${error.message}`),
|
||||
);
|
||||
child.on("exit", (code, signal) =>
|
||||
exit(`${options.command} exited (${signal ?? code})`),
|
||||
);
|
||||
yield* NodeStream.fromReadable<Uint8Array, never>({
|
||||
evaluate: () => child.stderr,
|
||||
onError: () => undefined as never,
|
||||
}).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.splitLines,
|
||||
Stream.runForEach((line) => Effect.logDebug(line)),
|
||||
Effect.annotateLogs("source", `${options.command}:stderr`),
|
||||
Effect.forkScoped,
|
||||
);
|
||||
|
||||
const connection = createMessageConnection(
|
||||
new StreamMessageReader(child.stdout),
|
||||
new StreamMessageWriter(child.stdin),
|
||||
{
|
||||
error: (m) => run(Effect.logError(m)),
|
||||
warn: (m) => run(Effect.logWarning(m)),
|
||||
info: (m) => run(Effect.logInfo(m)),
|
||||
log: (m) => run(Effect.logDebug(m)),
|
||||
},
|
||||
);
|
||||
yield* Effect.addFinalizer(() => Effect.sync(() => connection.dispose()));
|
||||
connection.onClose(() => exit(`${options.command} closed the connection`));
|
||||
connection.onNotification((method, params) => {
|
||||
PubSub.publishUnsafe(events, { method, params });
|
||||
});
|
||||
connection.onUnhandledProgress(({ token, value }) =>
|
||||
run(
|
||||
SubscriptionRef.update(progress, (active) =>
|
||||
value.kind === "begin"
|
||||
? HashSet.add(active, token)
|
||||
: value.kind === "end"
|
||||
? HashSet.remove(active, token)
|
||||
: active,
|
||||
),
|
||||
),
|
||||
);
|
||||
connection.onRequest(WorkDoneProgressCreateRequest.type, () => undefined);
|
||||
connection.onRequest(RegistrationRequest.type, () => undefined);
|
||||
connection.onRequest(UnregistrationRequest.type, () => undefined);
|
||||
connection.onRequest(ConfigurationRequest.type, ({ items }) =>
|
||||
items.map((item) => section(options.settings, item.section)),
|
||||
);
|
||||
const rootUri = URI.file(options.root).toString();
|
||||
const workspaceFolders = [
|
||||
{ uri: rootUri, name: options.root.split(/[\\/]/).pop() ?? options.root },
|
||||
];
|
||||
connection.onRequest(WorkspaceFoldersRequest.type, () => workspaceFolders);
|
||||
connection.listen();
|
||||
|
||||
const failure = (method: string, error: unknown) =>
|
||||
error instanceof ResponseError
|
||||
? new LspError({ method, message: error.message, code: error.code })
|
||||
: new LspError({
|
||||
method,
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
|
||||
const send = <P, R>(type: RequestType<P, R, unknown>, params: P) =>
|
||||
Effect.callback<R, LspError>((resume) => {
|
||||
const cancellation = new CancellationTokenSource();
|
||||
try {
|
||||
connection.sendRequest(type, params as never, cancellation.token).then(
|
||||
(result) => resume(Effect.succeed(result)),
|
||||
(error) => resume(Effect.fail(failure(type.method, error))),
|
||||
);
|
||||
} catch (error) {
|
||||
resume(Effect.fail(failure(type.method, error)));
|
||||
}
|
||||
return Effect.ignore(Effect.try(() => cancellation.cancel()));
|
||||
}).pipe(Effect.raceFirst(Deferred.await(exited)));
|
||||
|
||||
const idle = SubscriptionRef.changes(progress).pipe(
|
||||
Stream.filter(HashSet.isEmpty),
|
||||
Stream.runHead,
|
||||
Effect.timeoutOption("15 seconds"),
|
||||
Effect.asVoid,
|
||||
);
|
||||
|
||||
const request = <P, R>(type: RequestType<P, R, unknown>, params: P) =>
|
||||
idle.pipe(
|
||||
Effect.andThen(send(type, params)),
|
||||
Effect.retry({
|
||||
while: (error) => error.retryable,
|
||||
schedule: Schedule.exponential("100 millis").pipe(
|
||||
Schedule.upTo({ times: 5 }),
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
const notify = <P>(type: NotificationType<P>, params: P) =>
|
||||
Effect.tryPromise({
|
||||
try: () => connection.sendNotification(type, params as never),
|
||||
catch: (error) => failure(type.method, error),
|
||||
}).pipe(Effect.catch((error) => Effect.logWarning(error.message)));
|
||||
|
||||
const notifications = <P>(type: NotificationType<P>): Stream.Stream<P> =>
|
||||
Stream.fromPubSub(events).pipe(
|
||||
Stream.filter((event) => event.method === type.method),
|
||||
Stream.map((event) => event.params as P),
|
||||
);
|
||||
|
||||
const onRequest = <P, R>(
|
||||
type: RequestType<P, R, unknown>,
|
||||
handler: (params: P) => Effect.Effect<R, unknown>,
|
||||
) =>
|
||||
Effect.acquireRelease(
|
||||
Effect.sync(() =>
|
||||
connection.onRequest(
|
||||
type.method,
|
||||
(params: P): HandlerResult<R, unknown> =>
|
||||
runPromise(
|
||||
handler(params).pipe(
|
||||
Effect.mapError((error) =>
|
||||
error instanceof ResponseError
|
||||
? error
|
||||
: new ResponseError(
|
||||
ErrorCodes.InternalError,
|
||||
error instanceof Error ? error.message : String(error),
|
||||
),
|
||||
),
|
||||
),
|
||||
) as Promise<never>,
|
||||
),
|
||||
),
|
||||
(disposable) => Effect.sync(() => disposable.dispose()),
|
||||
).pipe(Effect.asVoid);
|
||||
|
||||
const initialized = yield* send(InitializeRequest.type, {
|
||||
processId: process.pid,
|
||||
clientInfo: { name: "lsp-mcp", version: "0.1.0" },
|
||||
locale: "en",
|
||||
rootPath: options.root,
|
||||
rootUri,
|
||||
workspaceFolders,
|
||||
capabilities: clientCapabilities,
|
||||
initializationOptions: options.initializationOptions as LSPAny,
|
||||
});
|
||||
yield* notify(InitializedNotification.type, {});
|
||||
if (options.settings !== undefined) {
|
||||
yield* notify(DidChangeConfigurationNotification.type, {
|
||||
settings: options.settings as LSPAny,
|
||||
});
|
||||
}
|
||||
yield* Effect.addFinalizer(() =>
|
||||
Effect.tryPromise(() => connection.sendRequest(ShutdownRequest.type)).pipe(
|
||||
Effect.timeout("3 seconds"),
|
||||
Effect.andThen(
|
||||
Effect.tryPromise(() =>
|
||||
connection.sendNotification(ExitNotification.type),
|
||||
),
|
||||
),
|
||||
Effect.andThen(Deferred.await(exited).pipe(Effect.timeout("2 seconds"))),
|
||||
Effect.ignore,
|
||||
),
|
||||
);
|
||||
|
||||
const logs = Stream.merge(
|
||||
notifications(LogMessageNotification.type),
|
||||
notifications(ShowMessageNotification.type),
|
||||
).pipe(
|
||||
Stream.map(
|
||||
({ type, message }): LogMessage => ({
|
||||
level: logLevels[type] ?? "info",
|
||||
message,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return LanguageServer.of({
|
||||
root: options.root,
|
||||
capabilities: initialized.capabilities,
|
||||
serverInfo: initialized.serverInfo,
|
||||
request,
|
||||
notify,
|
||||
notifications,
|
||||
onRequest,
|
||||
logs,
|
||||
});
|
||||
});
|
||||
|
||||
const logLevels: Record<MessageType, LogLevel> = {
|
||||
1: "error",
|
||||
2: "warning",
|
||||
3: "info",
|
||||
4: "debug",
|
||||
5: "debug",
|
||||
};
|
||||
|
||||
/** Resolve a dotted `section` path inside the configured settings. */
|
||||
const section = (settings: unknown, path: string | undefined): LSPAny =>
|
||||
(path === undefined
|
||||
? settings
|
||||
: path
|
||||
.split(".")
|
||||
.reduce<unknown>(
|
||||
(value, key) => (value as Record<string, unknown> | null)?.[key],
|
||||
settings,
|
||||
)) as LSPAny;
|
||||
|
||||
/**
|
||||
* What we tell the server we can do. Deliberately narrow: no dynamic
|
||||
* registration, no snippets, no watched files (servers fall back to their
|
||||
* own watchers), UTF-16 positions only.
|
||||
*/
|
||||
const clientCapabilities: ClientCapabilities = {
|
||||
general: {
|
||||
positionEncodings: ["utf-16"],
|
||||
markdown: { parser: "marked", version: "1.1.0" },
|
||||
},
|
||||
workspace: {
|
||||
applyEdit: true,
|
||||
workspaceEdit: {
|
||||
documentChanges: true,
|
||||
resourceOperations: ["create", "rename", "delete"],
|
||||
failureHandling: "abort",
|
||||
},
|
||||
configuration: true,
|
||||
workspaceFolders: true,
|
||||
symbol: { symbolKind: { valueSet: allSymbolKinds() } },
|
||||
didChangeConfiguration: { dynamicRegistration: false },
|
||||
didChangeWatchedFiles: { dynamicRegistration: false },
|
||||
},
|
||||
window: {
|
||||
workDoneProgress: true,
|
||||
showMessage: {},
|
||||
showDocument: { support: false },
|
||||
},
|
||||
textDocument: {
|
||||
synchronization: {
|
||||
didSave: true,
|
||||
willSave: false,
|
||||
willSaveWaitUntil: false,
|
||||
},
|
||||
publishDiagnostics: {
|
||||
relatedInformation: true,
|
||||
versionSupport: true,
|
||||
codeDescriptionSupport: true,
|
||||
dataSupport: true,
|
||||
},
|
||||
diagnostic: { dynamicRegistration: false, relatedDocumentSupport: false },
|
||||
hover: { contentFormat: ["markdown", "plaintext"] },
|
||||
completion: {
|
||||
completionItem: {
|
||||
snippetSupport: false,
|
||||
documentationFormat: ["markdown", "plaintext"],
|
||||
deprecatedSupport: true,
|
||||
},
|
||||
completionItemKind: {
|
||||
valueSet: Array.from({ length: 25 }, (_, i) => (i + 1) as never),
|
||||
},
|
||||
contextSupport: true,
|
||||
},
|
||||
signatureHelp: {
|
||||
signatureInformation: {
|
||||
documentationFormat: ["markdown", "plaintext"],
|
||||
parameterInformation: { labelOffsetSupport: true },
|
||||
activeParameterSupport: true,
|
||||
},
|
||||
},
|
||||
definition: { linkSupport: true },
|
||||
typeDefinition: { linkSupport: true },
|
||||
implementation: { linkSupport: true },
|
||||
declaration: { linkSupport: true },
|
||||
references: {},
|
||||
documentSymbol: {
|
||||
hierarchicalDocumentSymbolSupport: true,
|
||||
symbolKind: { valueSet: allSymbolKinds() },
|
||||
},
|
||||
codeAction: {
|
||||
codeActionLiteralSupport: {
|
||||
codeActionKind: {
|
||||
valueSet: [
|
||||
"",
|
||||
"quickfix",
|
||||
"refactor",
|
||||
"refactor.extract",
|
||||
"refactor.inline",
|
||||
"refactor.rewrite",
|
||||
"source",
|
||||
"source.organizeImports",
|
||||
"source.fixAll",
|
||||
],
|
||||
},
|
||||
},
|
||||
isPreferredSupport: true,
|
||||
dataSupport: true,
|
||||
resolveSupport: { properties: ["edit"] },
|
||||
},
|
||||
rename: { prepareSupport: true },
|
||||
formatting: {},
|
||||
callHierarchy: {},
|
||||
},
|
||||
};
|
||||
|
||||
function allSymbolKinds() {
|
||||
return Array.from({ length: 26 }, (_, i) => (i + 1) as never);
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* CLI entry point.
|
||||
*
|
||||
* lsp-mcp [--stdio | --http <port>] [--root <dir>] -- <server> [args...]
|
||||
*/
|
||||
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
||||
import { Cause, Effect, Layer, Option, Path, References, Schema } from "effect";
|
||||
import { Argument, Command, Flag } from "effect/unstable/cli";
|
||||
import * as Server from "./Server.ts";
|
||||
|
||||
const Json = Flag.withSchema(Schema.fromJsonString(Schema.Json));
|
||||
|
||||
const command = Command.make(
|
||||
"lsp-mcp",
|
||||
{
|
||||
transport: Flag.Int("http").pipe(
|
||||
Flag.withDescription(
|
||||
"Serve MCP over Streamable HTTP at http://localhost:<port>/mcp",
|
||||
),
|
||||
Flag.map((port) => ({ _tag: "http", port }) as const),
|
||||
Flag.orElse(() =>
|
||||
Flag.Boolean("stdio").pipe(
|
||||
Flag.withDescription("Serve MCP over stdio (the default)"),
|
||||
Flag.withDefault(false),
|
||||
Flag.map(() => ({ _tag: "stdio" }) as const),
|
||||
),
|
||||
),
|
||||
),
|
||||
root: Flag.Directory("root", { mustExist: true }).pipe(
|
||||
Flag.withAlias("r"),
|
||||
Flag.withDescription("Workspace root handed to the language server"),
|
||||
Flag.withDefault("."),
|
||||
),
|
||||
initOptions: Flag.String("init-options").pipe(
|
||||
Json,
|
||||
Flag.withDescription(
|
||||
"JSON passed to the language server as initializationOptions",
|
||||
),
|
||||
Flag.optional,
|
||||
),
|
||||
settings: Flag.String("settings").pipe(
|
||||
Json,
|
||||
Flag.withDescription(
|
||||
"JSON served as workspace/configuration and sent as didChangeConfiguration",
|
||||
),
|
||||
Flag.optional,
|
||||
),
|
||||
languages: Flag.KeyValuePair("language").pipe(
|
||||
Flag.withDescription(
|
||||
"Extra file extension to languageId mapping, e.g. --language vue=vue",
|
||||
),
|
||||
Flag.withDefault({}),
|
||||
),
|
||||
capacity: Flag.Int("open-documents").pipe(
|
||||
Flag.withDescription(
|
||||
"Documents kept open in the language server before the least recently used is closed",
|
||||
),
|
||||
Flag.withDefault(32),
|
||||
),
|
||||
command: Argument.String("server").pipe(
|
||||
Argument.withDescription("Language server executable"),
|
||||
),
|
||||
args: Argument.String("args").pipe(
|
||||
Argument.withDescription(
|
||||
"Arguments for the language server; put `--` before them",
|
||||
),
|
||||
Argument.variadic(),
|
||||
),
|
||||
},
|
||||
Effect.fn(function* ({
|
||||
transport,
|
||||
root,
|
||||
initOptions,
|
||||
settings,
|
||||
languages,
|
||||
capacity,
|
||||
command,
|
||||
args,
|
||||
}) {
|
||||
const path = yield* Path.Path;
|
||||
return yield* Layer.launch(
|
||||
Server.layer({
|
||||
transport,
|
||||
server: {
|
||||
// a relative executable path is relative to where lsp-mcp was started, not to the root
|
||||
command: command.includes("/") ? path.resolve(command) : command,
|
||||
args,
|
||||
root: path.resolve(root),
|
||||
initializationOptions: Option.getOrUndefined(initOptions),
|
||||
settings: Option.getOrUndefined(settings),
|
||||
},
|
||||
documents: { capacity, languages },
|
||||
}),
|
||||
);
|
||||
}),
|
||||
).pipe(
|
||||
Command.withDescription(
|
||||
"Expose a Language Server to MCP clients as a headless editor",
|
||||
),
|
||||
Command.withExamples([
|
||||
{
|
||||
command: "lsp-mcp -- typescript-language-server --stdio",
|
||||
description: "TypeScript over stdio",
|
||||
},
|
||||
{
|
||||
command: "lsp-mcp --http 3000 --root ./crate -- rust-analyzer",
|
||||
description: "Rust over HTTP",
|
||||
},
|
||||
{
|
||||
command: `lsp-mcp --settings '{"gopls":{"staticcheck":true}}' -- gopls`,
|
||||
description: "Go with workspace settings",
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
command.pipe(
|
||||
Command.run({ version: "0.1.0" }),
|
||||
Effect.tapCause((cause) =>
|
||||
Cause.hasInterruptsOnly(cause) ? Effect.void : Effect.logError(cause),
|
||||
),
|
||||
// stdout may be the MCP channel, so every log line goes to stderr
|
||||
Effect.provideService(References.LogToStderr, true),
|
||||
Effect.provide(NodeServices.layer),
|
||||
NodeRuntime.runMain({ disableErrorReporting: true }),
|
||||
);
|
||||
@@ -0,0 +1,171 @@
|
||||
import { NodeServices } from "@effect/platform-node";
|
||||
import { assert, describe, it } from "@effect/vitest";
|
||||
import { Effect, FileSystem, Layer } from "effect";
|
||||
import { RequestType } from "vscode-languageserver-protocol";
|
||||
import { Diagnostics } from "../src/lsp/Diagnostics.ts";
|
||||
import { Documents } from "../src/lsp/Documents.ts";
|
||||
import * as Editor from "../src/lsp/Editor.ts";
|
||||
import { LanguageServer } from "../src/lsp/LanguageServer.ts";
|
||||
import { workspace } from "./fixtures/workspace.ts";
|
||||
|
||||
const State = new RequestType<null, { open: number; closes: number }, void>(
|
||||
"fixture/state",
|
||||
);
|
||||
const Progress = new RequestType<number, string, void>("fixture/progress");
|
||||
|
||||
const TestLayer = Layer.mergeAll(
|
||||
Documents.layer({ capacity: 2, languages: {} }),
|
||||
Diagnostics.layer,
|
||||
).pipe(
|
||||
Layer.provideMerge(
|
||||
workspace({
|
||||
"a.ts": "const alpha = 1\nexport const beta = alpha + alpha\n",
|
||||
"b.ts": "// TODO fix\n",
|
||||
"c.ts": "",
|
||||
}),
|
||||
),
|
||||
Layer.provideMerge(NodeServices.layer),
|
||||
);
|
||||
|
||||
describe("Editor", () => {
|
||||
it.layer(TestLayer, { excludeTestServices: true })(
|
||||
"with the fixture server",
|
||||
(it) => {
|
||||
it.effect("addresses positions by 1-based line and symbol name", () =>
|
||||
Effect.gen(function* () {
|
||||
const byColumn = yield* Editor.hover({
|
||||
file: "a.ts",
|
||||
line: 2,
|
||||
column: 22,
|
||||
});
|
||||
const bySymbol = yield* Editor.hover({
|
||||
file: "a.ts",
|
||||
line: 2,
|
||||
symbol: "alpha",
|
||||
});
|
||||
assert.strictEqual(byColumn?.contents, "word **alpha**");
|
||||
assert.strictEqual(bySymbol?.contents, "word **alpha**");
|
||||
|
||||
const refs = yield* Editor.references({
|
||||
file: "a.ts",
|
||||
line: 1,
|
||||
symbol: "alpha",
|
||||
});
|
||||
assert.deepStrictEqual(
|
||||
refs.map((r) => [r.line, r.column, r.preview]),
|
||||
[
|
||||
[1, 7, "const alpha = 1"],
|
||||
[2, 21, "export const beta = alpha + alpha"],
|
||||
[2, 29, "export const beta = alpha + alpha"],
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
it.effect("sees edits made on disk without being told", () =>
|
||||
Effect.gen(function* () {
|
||||
const fs = yield* FileSystem.FileSystem;
|
||||
const docs = yield* Documents;
|
||||
const lsp = yield* LanguageServer;
|
||||
const before = yield* Editor.diagnostics({ file: "b.ts" });
|
||||
assert.deepStrictEqual(
|
||||
before.map((d) => [d.severity, d.line]),
|
||||
[["warning", 1]],
|
||||
);
|
||||
|
||||
yield* fs.writeFileString(
|
||||
docs.uri("b.ts").replace("file://", ""),
|
||||
"// done\n// TODO more\n",
|
||||
);
|
||||
const after = yield* Editor.diagnostics({ file: "b.ts" });
|
||||
assert.deepStrictEqual(
|
||||
after.map((d) => [d.severity, d.line]),
|
||||
[["warning", 2]],
|
||||
);
|
||||
assert.strictEqual((yield* lsp.request(State, null)).open, 2);
|
||||
}),
|
||||
);
|
||||
|
||||
it.effect("closes the least recently used document beyond capacity", () =>
|
||||
Effect.gen(function* () {
|
||||
const lsp = yield* LanguageServer;
|
||||
const docs = yield* Documents;
|
||||
yield* docs.open("a.ts");
|
||||
yield* docs.open("b.ts");
|
||||
yield* docs.open("c.ts");
|
||||
yield* Effect.sleep("50 millis");
|
||||
const state = yield* lsp.request(State, null);
|
||||
assert.strictEqual(state.open, 2);
|
||||
assert.isAtLeast(state.closes, 1);
|
||||
assert.deepStrictEqual((yield* docs.opened).map(docs.file).sort(), [
|
||||
"b.ts",
|
||||
"c.ts",
|
||||
]);
|
||||
}),
|
||||
);
|
||||
|
||||
it.effect("previews a rename, and applies it only when asked", () =>
|
||||
Effect.gen(function* () {
|
||||
const docs = yield* Documents;
|
||||
const preview = yield* Editor.rename({
|
||||
file: "a.ts",
|
||||
line: 1,
|
||||
symbol: "alpha",
|
||||
newName: "first",
|
||||
});
|
||||
assert.isFalse(preview.applied);
|
||||
assert.strictEqual(preview.files[0]?.edits.length, 3);
|
||||
assert.include((yield* docs.open("a.ts")).getText(), "alpha");
|
||||
|
||||
const applied = yield* Editor.rename({
|
||||
file: "a.ts",
|
||||
line: 1,
|
||||
symbol: "alpha",
|
||||
newName: "first",
|
||||
apply: true,
|
||||
});
|
||||
assert.isTrue(applied.applied);
|
||||
const text = (yield* docs.peek(docs.uri("a.ts"))).getText();
|
||||
assert.strictEqual(
|
||||
text,
|
||||
"const first = 1\nexport const beta = first + first\n",
|
||||
);
|
||||
assert.strictEqual(
|
||||
(yield* Editor.hover({ file: "a.ts", line: 1, symbol: "first" }))
|
||||
?.contents,
|
||||
"word **first**",
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
it.effect("waits for the server's background work before asking", () =>
|
||||
Effect.gen(function* () {
|
||||
const lsp = yield* LanguageServer;
|
||||
yield* lsp.request(Progress, 300);
|
||||
const started = Date.now();
|
||||
const symbols = yield* Editor.documentSymbols({ file: "c.ts" });
|
||||
assert.isAtLeast(Date.now() - started, 250);
|
||||
assert.deepStrictEqual(symbols, []);
|
||||
}),
|
||||
);
|
||||
|
||||
it.effect("explains what the server cannot do", () =>
|
||||
Effect.gen(function* () {
|
||||
const error = yield* Effect.flip(
|
||||
Editor.definition({
|
||||
file: "a.ts",
|
||||
line: 1,
|
||||
symbol: "alpha",
|
||||
kind: "implementation",
|
||||
}),
|
||||
);
|
||||
assert.strictEqual(error._tag, "LspError");
|
||||
assert.match(
|
||||
error.message,
|
||||
/does not support implementationProvider/,
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,144 @@
|
||||
import { NodeServices } from "@effect/platform-node";
|
||||
import { assert, describe, it } from "@effect/vitest";
|
||||
import { Effect, Layer } from "effect";
|
||||
import { McpProtocol, McpSchema, McpServer } from "effect/unstable/ai";
|
||||
import {
|
||||
FetchHttpClient,
|
||||
HttpClient,
|
||||
HttpClientRequest,
|
||||
HttpRouter,
|
||||
} from "effect/unstable/http";
|
||||
import { RpcClient, RpcSerialization } from "effect/unstable/rpc";
|
||||
import { Diagnostics } from "../src/lsp/Diagnostics.ts";
|
||||
import { Documents } from "../src/lsp/Documents.ts";
|
||||
import * as Resources from "../src/Resources.ts";
|
||||
import * as Server from "../src/Server.ts";
|
||||
import { workspace } from "./fixtures/workspace.ts";
|
||||
|
||||
const mcp = McpServer.layerHttp({
|
||||
name: "test",
|
||||
version: "0.0.0",
|
||||
path: "/mcp",
|
||||
protocols: [McpProtocol.v2025_06_18],
|
||||
});
|
||||
|
||||
const app = Layer.mergeAll(Server.tools, Resources.layer).pipe(
|
||||
Layer.provide(mcp),
|
||||
Layer.provide(
|
||||
Layer.mergeAll(
|
||||
Documents.layer({ capacity: 4, languages: {} }),
|
||||
Diagnostics.layer,
|
||||
),
|
||||
),
|
||||
Layer.provide(workspace({ "a.ts": "const alpha = 1\n" })),
|
||||
Layer.provide(NodeServices.layer),
|
||||
);
|
||||
|
||||
/** An MCP client talking to the app over in-memory HTTP. */
|
||||
const client = Effect.gen(function* () {
|
||||
const { dispose, handler } = HttpRouter.toWebHandler(app, {
|
||||
disableLogger: true,
|
||||
});
|
||||
yield* Effect.addFinalizer(() => Effect.promise(dispose));
|
||||
const headers = new Map<string, string>();
|
||||
const fetch: typeof globalThis.fetch = Object.assign(
|
||||
async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
const request = new Request(input, init);
|
||||
for (const [name, value] of headers) request.headers.set(name, value);
|
||||
const response = await handler(request);
|
||||
for (const name of ["Mcp-Session-Id", "Mcp-Protocol-Version"]) {
|
||||
const value = response.headers.get(name);
|
||||
if (value !== null) headers.set(name, value);
|
||||
}
|
||||
return response;
|
||||
},
|
||||
{ preconnect() {} },
|
||||
);
|
||||
const transport = RpcClient.layerProtocolHttp({
|
||||
url: "http://localhost/mcp",
|
||||
transformClient: HttpClient.mapRequest(
|
||||
HttpClientRequest.setHeader(
|
||||
"accept",
|
||||
"application/json, text/event-stream",
|
||||
),
|
||||
),
|
||||
}).pipe(
|
||||
Layer.provideMerge([
|
||||
FetchHttpClient.layer,
|
||||
RpcSerialization.layerJsonRpc(),
|
||||
]),
|
||||
Layer.provide(Layer.succeed(FetchHttpClient.Fetch, fetch)),
|
||||
);
|
||||
const client = yield* RpcClient.make(McpSchema.ClientRpcs).pipe(
|
||||
Effect.provide(transport),
|
||||
);
|
||||
yield* client.initialize({
|
||||
protocolVersion: "2025-06-18",
|
||||
capabilities: {},
|
||||
clientInfo: { name: "test", version: "0" },
|
||||
});
|
||||
return client;
|
||||
});
|
||||
|
||||
describe("MCP server", () => {
|
||||
it.live(
|
||||
"offers only the tools the language server supports, and serves them",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const mcp = yield* client;
|
||||
const { tools } = yield* mcp["tools/list"]({});
|
||||
assert.deepStrictEqual(tools.map((t) => t.name).sort(), [
|
||||
"definition",
|
||||
"diagnostics",
|
||||
"document_symbols",
|
||||
"hover",
|
||||
"references",
|
||||
"rename",
|
||||
]);
|
||||
assert.isTrue(
|
||||
tools.find((t) => t.name === "hover")?.annotations?.readOnlyHint,
|
||||
);
|
||||
assert.isFalse(
|
||||
tools.find((t) => t.name === "rename")?.annotations?.readOnlyHint,
|
||||
);
|
||||
|
||||
const result = yield* mcp["tools/call"]({
|
||||
name: "hover",
|
||||
arguments: { file: "a.ts", line: 1, symbol: "alpha" },
|
||||
});
|
||||
assert.deepStrictEqual(result.structuredContent, {
|
||||
contents: "word **alpha**",
|
||||
});
|
||||
|
||||
const failure = yield* mcp["tools/call"]({
|
||||
name: "hover",
|
||||
arguments: { file: "missing.ts", line: 1 },
|
||||
});
|
||||
assert.isTrue(failure.isError);
|
||||
assert.match(JSON.stringify(failure.content), /missing\.ts/);
|
||||
}).pipe(Effect.scoped),
|
||||
);
|
||||
|
||||
it.live("exposes the server and its diagnostics as resources", () =>
|
||||
Effect.gen(function* () {
|
||||
const mcp = yield* client;
|
||||
const { resources } = yield* mcp["resources/list"]({});
|
||||
assert.deepStrictEqual(resources.map((r) => r.uri).sort(), [
|
||||
"lsp://diagnostics",
|
||||
"lsp://server",
|
||||
]);
|
||||
const server = yield* mcp["resources/read"]({ uri: "lsp://server" });
|
||||
const contents = server.contents[0];
|
||||
assert.isTrue(
|
||||
contents !== undefined &&
|
||||
"text" in contents &&
|
||||
JSON.parse(contents.text).name === "fixture",
|
||||
);
|
||||
const { resourceTemplates } = yield* mcp["resources/templates/list"]({});
|
||||
assert.deepStrictEqual(
|
||||
resourceTemplates.map((t) => t.uriTemplate),
|
||||
["lsp://diagnostics/{param0}"],
|
||||
);
|
||||
}).pipe(Effect.scoped),
|
||||
);
|
||||
});
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* A miniature language server used by the tests. Words are symbols: hover
|
||||
* describes the word under the cursor, definition is its first occurrence,
|
||||
* references and rename cover every occurrence, and each line containing
|
||||
* "TODO" yields a warning. `fixture/state` reports open/close counts.
|
||||
*/
|
||||
import {
|
||||
createConnection,
|
||||
DiagnosticSeverity,
|
||||
type Position,
|
||||
TextDocumentSyncKind,
|
||||
TextDocuments,
|
||||
WorkDoneProgress,
|
||||
} from "vscode-languageserver/node";
|
||||
import { TextDocument } from "vscode-languageserver-textdocument";
|
||||
|
||||
const connection = createConnection(process.stdin, process.stdout);
|
||||
const documents = new TextDocuments(TextDocument);
|
||||
let closes = 0;
|
||||
let progressToken = 0;
|
||||
|
||||
const wordAt = (doc: TextDocument, position: Position) => {
|
||||
const text = doc.getText();
|
||||
const offset = doc.offsetAt(position);
|
||||
let start = offset;
|
||||
let end = offset;
|
||||
while (start > 0 && /\w/.test(text.charAt(start - 1))) start--;
|
||||
while (end < text.length && /\w/.test(text.charAt(end))) end++;
|
||||
return start === end ? undefined : text.slice(start, end);
|
||||
};
|
||||
|
||||
const occurrences = (doc: TextDocument, word: string) => {
|
||||
const text = doc.getText();
|
||||
const ranges = [];
|
||||
const pattern = new RegExp(`\\b${word}\\b`, "g");
|
||||
for (const match of text.matchAll(pattern)) {
|
||||
ranges.push({
|
||||
start: doc.positionAt(match.index),
|
||||
end: doc.positionAt(match.index + word.length),
|
||||
});
|
||||
}
|
||||
return ranges;
|
||||
};
|
||||
|
||||
documents.onDidClose(() => closes++);
|
||||
documents.onDidChangeContent(({ document }) => {
|
||||
const diagnostics = document
|
||||
.getText()
|
||||
.split("\n")
|
||||
.flatMap((line, i) =>
|
||||
line.includes("TODO")
|
||||
? [
|
||||
{
|
||||
range: {
|
||||
start: { line: i, character: 0 },
|
||||
end: { line: i, character: line.length },
|
||||
},
|
||||
severity: DiagnosticSeverity.Warning,
|
||||
message: "unresolved TODO",
|
||||
source: "fixture",
|
||||
},
|
||||
]
|
||||
: [],
|
||||
);
|
||||
void connection.sendDiagnostics({
|
||||
uri: document.uri,
|
||||
version: document.version,
|
||||
diagnostics,
|
||||
});
|
||||
});
|
||||
|
||||
connection.onInitialize(() => ({
|
||||
serverInfo: { name: "fixture", version: "1.0.0" },
|
||||
capabilities: {
|
||||
textDocumentSync: {
|
||||
openClose: true,
|
||||
change: TextDocumentSyncKind.Full,
|
||||
save: { includeText: true },
|
||||
},
|
||||
hoverProvider: true,
|
||||
definitionProvider: true,
|
||||
referencesProvider: true,
|
||||
renameProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
},
|
||||
}));
|
||||
|
||||
connection.onHover(({ textDocument, position }) => {
|
||||
const doc = documents.get(textDocument.uri);
|
||||
const word = doc && wordAt(doc, position);
|
||||
return word
|
||||
? { contents: { kind: "markdown", value: `word **${word}**` } }
|
||||
: null;
|
||||
});
|
||||
|
||||
connection.onDefinition(({ textDocument, position }) => {
|
||||
const doc = documents.get(textDocument.uri);
|
||||
const word = doc && wordAt(doc, position);
|
||||
const range = word && occurrences(doc, word)[0];
|
||||
return range ? { uri: textDocument.uri, range } : null;
|
||||
});
|
||||
|
||||
connection.onReferences(({ textDocument, position }) => {
|
||||
const doc = documents.get(textDocument.uri);
|
||||
const word = doc && wordAt(doc, position);
|
||||
return word
|
||||
? occurrences(doc, word).map((range) => ({ uri: textDocument.uri, range }))
|
||||
: [];
|
||||
});
|
||||
|
||||
connection.onRenameRequest(({ textDocument, position, newName }) => {
|
||||
const doc = documents.get(textDocument.uri);
|
||||
const word = doc && wordAt(doc, position);
|
||||
if (!word) return null;
|
||||
return {
|
||||
documentChanges: [
|
||||
{
|
||||
textDocument: { uri: textDocument.uri, version: doc.version },
|
||||
edits: occurrences(doc, word).map((range) => ({
|
||||
range,
|
||||
newText: newName,
|
||||
})),
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
connection.onDocumentSymbol(({ textDocument }) => {
|
||||
const doc = documents.get(textDocument.uri);
|
||||
if (!doc) return [];
|
||||
const words = new Set(doc.getText().match(/\b[A-Za-z_]\w*\b/g) ?? []);
|
||||
return [...words].flatMap((name) =>
|
||||
occurrences(doc, name)
|
||||
.slice(0, 1)
|
||||
.map((range) => ({ name, kind: 13, range, selectionRange: range })),
|
||||
);
|
||||
});
|
||||
|
||||
connection.onRequest("fixture/state", () => ({
|
||||
open: documents.all().length,
|
||||
closes,
|
||||
}));
|
||||
connection.onRequest("fixture/progress", async (ms: number) => {
|
||||
const token = `work-${progressToken++}`;
|
||||
void connection.sendProgress(WorkDoneProgress.type, token, {
|
||||
kind: "begin",
|
||||
title: "indexing",
|
||||
});
|
||||
setTimeout(
|
||||
() =>
|
||||
void connection.sendProgress(WorkDoneProgress.type, token, {
|
||||
kind: "end",
|
||||
}),
|
||||
ms,
|
||||
);
|
||||
return token;
|
||||
});
|
||||
|
||||
documents.listen(connection);
|
||||
connection.listen();
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { Effect, FileSystem, Layer, Path } from "effect";
|
||||
import { LanguageServer } from "../../src/lsp/LanguageServer.ts";
|
||||
|
||||
const server = fileURLToPath(new URL("./server.ts", import.meta.url));
|
||||
|
||||
/** A temporary workspace with the given files, served by the fixture language server. */
|
||||
export const workspace = (files: Record<string, string>) =>
|
||||
Layer.unwrap(
|
||||
Effect.gen(function* () {
|
||||
const fs = yield* FileSystem.FileSystem;
|
||||
const path = yield* Path.Path;
|
||||
const root = yield* fs.makeTempDirectoryScoped({ prefix: "lsp-mcp-" });
|
||||
for (const [name, content] of Object.entries(files)) {
|
||||
yield* fs.writeFileString(path.join(root, name), content);
|
||||
}
|
||||
return LanguageServer.layer({
|
||||
command: process.execPath,
|
||||
args: [server],
|
||||
root,
|
||||
});
|
||||
}),
|
||||
);
|
||||
+5
-28
@@ -2,50 +2,27 @@
|
||||
"$schema": "./node_modules/@effect/tsgo/schema.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
// File Layout
|
||||
// "rootDir": "./src",
|
||||
// "outDir": "./dist",
|
||||
|
||||
// Environment Settings
|
||||
// See also https://aka.ms/tsconfig/module
|
||||
"module": "nodenext",
|
||||
"target": "esnext",
|
||||
"types": [],
|
||||
// For nodejs:
|
||||
// "lib": ["esnext"],
|
||||
// "types": ["node"],
|
||||
// and npm install -D @types/node
|
||||
|
||||
// Other Outputs
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
|
||||
// Stricter Typechecking Options
|
||||
"types": ["node"],
|
||||
"allowImportingTsExtensions": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
|
||||
// Style Options
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitOverride": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
|
||||
// Recommended Options
|
||||
"strict": true,
|
||||
"jsx": "react-jsx",
|
||||
"verbatimModuleSyntax": true,
|
||||
"isolatedModules": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"moduleDetection": "force",
|
||||
"skipLibCheck": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "@effect/language-service"
|
||||
}
|
||||
]
|
||||
"plugins": [{ "name": "@effect/language-service" }]
|
||||
},
|
||||
"include": ["src", "test", "vitest.config.ts"],
|
||||
"exclude": ["node_modules", "repos"]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
include: ["test/**/*.test.ts"],
|
||||
testTimeout: 20_000,
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user