@directive-run/mcp 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# `@directive-run/mcp`
|
|
2
2
|
|
|
3
|
-
Run a Model Context Protocol (MCP) server that lets AI assistants
|
|
3
|
+
Run a Model Context Protocol (MCP) server that lets AI assistants – Claude Desktop, Cursor, Windsurf, or any MCP client – query Directive's knowledge base, code examples, lint rules, and scaffolding tools live. No pre-bundling, no stale snapshots: the assistant asks, the server answers from the current package contents.
|
|
4
4
|
|
|
5
|
-
Most readers want this package. Install it if you use Claude Desktop, Cursor, or another MCP-speaking client
|
|
5
|
+
Most readers want this package. Install it if you use Claude Desktop, Cursor, or another MCP-speaking client – or if you're hosting Directive's knowledge as a service for your team's agents.
|
|
6
6
|
|
|
7
7
|
> **Which side are you on?** This package is the **server**: it exposes Directive's knowledge so AI clients can read it. If instead you're building a Directive AI agent that needs to *call* external MCP servers (filesystem, GitHub, Slack), use [`@directive-run/ai/mcp`](../ai) and its `createMCPAdapter`.
|
|
8
8
|
|
|
@@ -39,7 +39,7 @@ directive-mcp --help
|
|
|
39
39
|
|
|
40
40
|
```text
|
|
41
41
|
2. Verify the server is loaded.
|
|
42
|
-
Claude Desktop: click the tools/hammer icon
|
|
42
|
+
Claude Desktop: click the tools/hammer icon – you should see `directive`
|
|
43
43
|
with 22 tools. Or ask Claude:
|
|
44
44
|
"Use the directive MCP server's get_server_info tool."
|
|
45
45
|
Cursor: open Settings → MCP → look for `directive` (status: connected).
|
|
@@ -61,7 +61,7 @@ directive-mcp --help
|
|
|
61
61
|
|
|
62
62
|
## How it works
|
|
63
63
|
|
|
64
|
-
Every Directive MCP request follows the same shape: an AI client (Claude Desktop, Cursor, your own agent) speaks JSON-RPC to one of two transports
|
|
64
|
+
Every Directive MCP request follows the same shape: an AI client (Claude Desktop, Cursor, your own agent) speaks JSON-RPC to one of two transports – `stdio` for local subprocess clients, `SSE` for the hosted gateway. The server dispatches to a tool handler, which reads from one of three in-process data sources: the bundled `@directive-run/knowledge` package (markdown + extracted examples), the lazy-loaded `@directive-run/lint` registry (ts-morph rules, loaded on first call so the ~25 MB ts-morph cost only hits when `review_source` or `fix_code` actually runs), or the pure-string `@directive-run/scaffold` generators. Nothing touches disk; nothing calls out over the network – except `get_package_info`, which fetches `latest` from npm with a 1-hour cache.
|
|
65
65
|
|
|
66
66
|
```
|
|
67
67
|
┌────────────────────────────────────────────────────────────────────────────────┐
|
|
@@ -149,10 +149,10 @@ npx @modelcontextprotocol/inspector npx -y @directive-run/mcp
|
|
|
149
149
|
## SSE transport (hosted)
|
|
150
150
|
|
|
151
151
|
```bash
|
|
152
|
-
# Loopback (local dev)
|
|
152
|
+
# Loopback (local dev) – no token required
|
|
153
153
|
directive-mcp --sse --port 3000
|
|
154
154
|
|
|
155
|
-
# Public host
|
|
155
|
+
# Public host – token is mandatory
|
|
156
156
|
directive-mcp --sse --port 3000 --host 0.0.0.0 \
|
|
157
157
|
--token "$DIRECTIVE_MCP_TOKEN" \
|
|
158
158
|
--allow-origin https://app.example.com
|
|
@@ -162,9 +162,9 @@ directive-mcp --sse --port 3000 --host 0.0.0.0 \
|
|
|
162
162
|
|
|
163
163
|
Endpoints:
|
|
164
164
|
|
|
165
|
-
- `GET /sse`
|
|
166
|
-
- `POST /messages?sessionId=…`
|
|
167
|
-
- `GET /healthz`
|
|
165
|
+
- `GET /sse` – establish the SSE stream.
|
|
166
|
+
- `POST /messages?sessionId=…` – client→server JSON-RPC messages.
|
|
167
|
+
- `GET /healthz` – liveness probe.
|
|
168
168
|
|
|
169
169
|
## Tools (22)
|
|
170
170
|
|
|
@@ -192,7 +192,7 @@ Endpoints:
|
|
|
192
192
|
| Tool | Purpose |
|
|
193
193
|
|---|---|
|
|
194
194
|
| `generate_module` | Generate NEW Directive module or AI orchestrator source. Returns the source string + suggested filenames + required-packages list; the caller writes to disk via its own file tool. |
|
|
195
|
-
| `list_module_sections` | Enumerate the valid `sections` values for `generate_module` (autodiscovery
|
|
195
|
+
| `list_module_sections` | Enumerate the valid `sections` values for `generate_module` (autodiscovery – no hallucinated enum values). |
|
|
196
196
|
|
|
197
197
|
### Review
|
|
198
198
|
|
|
@@ -227,10 +227,10 @@ Endpoints:
|
|
|
227
227
|
|
|
228
228
|
| Tool | Purpose |
|
|
229
229
|
|---|---|
|
|
230
|
-
| `playground_link` | Turn TypeScript source into a clickable URL that boots a real Directive project in StackBlitz. Two shapes: pass `source` (single string) for already-runnable snippets from `get_example` / `fix_code`, OR pass `files: [{path, source}, …]` for the paired library + runner output from `generate_module`. Optional `mode: "preview" \| "instant"`
|
|
231
|
-
| `run_in_sandbox` | Execute a Directive snippet inside a bounded worker_threads sandbox and return its observed behavior
|
|
230
|
+
| `playground_link` | Turn TypeScript source into a clickable URL that boots a real Directive project in StackBlitz. Two shapes: pass `source` (single string) for already-runnable snippets from `get_example` / `fix_code`, OR pass `files: [{path, source}, …]` for the paired library + runner output from `generate_module`. Optional `mode: "preview" \| "instant"` – `"preview"` (default) lands on `directive.run/playground` with code + Open-in-StackBlitz button; `"instant"` lands on `directive.run/run` which auto-submits the StackBlitz form (no preview UI). 8 KB cap on raw input. Payload travels in the URL hash so it never reaches server logs. |
|
|
231
|
+
| `run_in_sandbox` | Execute a Directive snippet inside a bounded worker_threads sandbox and return its observed behavior – captured `console.log/warn/error` lines, the post-`settle()` facts snapshot, structured errors, plus a `playgroundUrl` for click-through editing in StackBlitz. Pair with `generate_module` to show the user what the generated module ACTUALLY DID when it ran. **v0.3.0 boundary:** AST allowlist permits `@directive-run/{core, ai, query, react, vue, svelte, solid, lit, el, optimistic, timeline, mutator, knowledge, scaffold, claude-plugin, lint}` + relative `./*.js`; rejects FS/network/eval identifier references AND their property-access bypass chains (`globalThis.process`, `Reflect.get(globalThis, …)`, `.constructor`, `Function(...)`). 5-second wall-clock budget (clamped to [100ms, 10s]), 32 MB heap. Note: `react/vue/svelte/solid/lit` import OK but their runtime hooks throw in Node – use `playground_link` for UI demos. |
|
|
232
232
|
|
|
233
|
-
**Composition for a "try it now" link:** `generate_module` returns paired `{moduleSource, runnerSource, suggestedFilenames}`
|
|
233
|
+
**Composition for a "try it now" link:** `generate_module` returns paired `{moduleSource, runnerSource, suggestedFilenames}` – pass both to `playground_link` as a `files` array (the runner is the entry point at `src/main.ts`) and the user clicks ONE URL that boots a project where `tsx src/main.ts` actually logs Directive facts to the StackBlitz terminal. For `get_example` / `fix_code` output (already runnable), pass the single `source` string instead.
|
|
234
234
|
|
|
235
235
|
## Troubleshooting
|
|
236
236
|
|
|
@@ -239,7 +239,7 @@ The four most common first-time failures:
|
|
|
239
239
|
| Symptom | What's happening | Fix |
|
|
240
240
|
|---|---|---|
|
|
241
241
|
| Claude Desktop shows no `directive` server in the hammer/tools menu. | Config file wasn't read, or `npx` failed to install. | Fully quit Claude Desktop (Cmd-Q, not just close the window) and relaunch. Then check the log: `~/Library/Logs/Claude/mcp-server-directive.log` (macOS), `%APPDATA%\Claude\logs\mcp-server-directive.log` (Windows). |
|
|
242
|
-
| `review_source` returns `review_source failed
|
|
242
|
+
| `review_source` returns `review_source failed – worker-error: ts-morph is not installed`. | npm install ran with `--no-optional`, or your package manager skipped `optionalDependencies`. | `npm install -g ts-morph` once. ts-morph (~25 MB) is loaded only when `review_source` / `fix_code` fires. |
|
|
243
243
|
| `--sse --host 0.0.0.0` exits with `--token is required`. | Public bind needs auth. | Pass `--token <secret>` or set `DIRECTIVE_MCP_TOKEN` in the environment. Loopback binds (the default `127.0.0.1`) don't need a token. |
|
|
244
244
|
| `npx -y @directive-run/mcp` is slow on first launch. | `npx` is downloading + installing the package + ts-morph (~25 MB). | First launch is ~10-20 s on a cold npm cache. Subsequent launches use the cached tarball. To pre-warm: `npm install -g @directive-run/mcp` and use `"command": "directive-mcp"` in the config. |
|
|
245
245
|
|
|
@@ -261,26 +261,26 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
261
261
|
const server = createDirectiveServer();
|
|
262
262
|
await server.connect(new StdioServerTransport());
|
|
263
263
|
|
|
264
|
-
// SSE
|
|
264
|
+
// SSE – returns the underlying http.Server
|
|
265
265
|
const httpServer = await startSseServer({ port: 3000, host: "0.0.0.0" });
|
|
266
266
|
```
|
|
267
267
|
|
|
268
268
|
### Tuning the lint worker pool
|
|
269
269
|
|
|
270
|
-
`review_source` and `fix_code` each spawn a ts-morph worker thread to parse the input. A multi-client burst
|
|
270
|
+
`review_source` and `fix_code` each spawn a ts-morph worker thread to parse the input. A multi-client burst – Cursor + Claude + IDE all calling these tools in parallel – could amplify into a thread-spawn storm. `setMaxConcurrentLintWorkers(n)` caps the simultaneously-running lint workers. Calls beyond the cap queue FIFO; abandoned callers (signal-aborted or dropped promises) deregister cleanly. Defaults to `navigator.hardwareConcurrency` (falls back to 4); pass `Infinity` to disable.
|
|
271
271
|
|
|
272
272
|
```ts
|
|
273
273
|
import { setMaxConcurrentLintWorkers } from "@directive-run/mcp";
|
|
274
|
-
// At server boot
|
|
274
|
+
// At server boot – runs once per process.
|
|
275
275
|
setMaxConcurrentLintWorkers(4);
|
|
276
276
|
```
|
|
277
277
|
|
|
278
278
|
## See also
|
|
279
279
|
|
|
280
|
-
- [`@directive-run/ai/mcp`](../ai)
|
|
281
|
-
- [`@directive-run/knowledge`](../knowledge)
|
|
282
|
-
- [`@directive-run/lint`](../lint)
|
|
283
|
-
- [`@directive-run/scaffold`](../scaffold)
|
|
284
|
-
- [`@directive-run/claude-plugin`](../claude-plugin)
|
|
285
|
-
- [`@directive-run/cli`](../cli)
|
|
286
|
-
- [directive.run/docs/ide-integration](https://directive.run/docs/ide-integration)
|
|
280
|
+
- [`@directive-run/ai/mcp`](../ai) – adapts external MCP servers as Directive resolvers (the *client* side; opposite arrow from this package).
|
|
281
|
+
- [`@directive-run/knowledge`](../knowledge) – markdown + JSON sources this server fronts.
|
|
282
|
+
- [`@directive-run/lint`](../lint) – the ts-morph rule registry behind `review_source` and `fix_code`.
|
|
283
|
+
- [`@directive-run/scaffold`](../scaffold) – the pure-function generators behind `generate_module`.
|
|
284
|
+
- [`@directive-run/claude-plugin`](../claude-plugin) – the Claude Code skill bundles also exposed via `get_skill`.
|
|
285
|
+
- [`@directive-run/cli`](../cli) – generates static `.cursorrules` / `CLAUDE.md` / `.windsurfrules` files for assistants that don't speak MCP.
|
|
286
|
+
- [directive.run/docs/ide-integration](https://directive.run/docs/ide-integration) – the cross-editor decision tree.
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {createHash}from'crypto';import {getAllSkills,getSkill}from'@directive-run/claude-plugin';import {getAllKnowledge,getKnowledge,getAllExamples,getExample,getCompositionsFor,getReverseCompositionsFor,getAntiPatterns,getAntiPatternById,MIGRATION_SOURCES,getMigrationPattern}from'@directive-run/knowledge';import {MODULE_SECTIONS,validateModuleName,generateOrchestrator,generateModule,suggestFileNames,requiredPackages}from'@directive-run/scaffold';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {z as z$1}from'zod';import {fileURLToPath}from'url';import {Worker}from'worker_threads';import {runRules,applyFix}from'@directive-run/lint';import {runInSandbox}from'@directive-run/sandbox';import {createServer}from'http';import {SSEServerTransport}from'@modelcontextprotocol/sdk/server/sse.js';var $e=Object.create;var Z=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,Le=Object.prototype.hasOwnProperty;var Oe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Me=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Pe(t))!Le.call(e,i)&&i!==r&&Z(e,i,{get:()=>t[i],enumerable:!(n=Ie(t,i))||n.enumerable});return e};var Ce=(e,t,r)=>(r=e!=null?$e(Ae(e)):{},Me(Z(r,"default",{value:e,enumerable:true}),e));var de=Oe((qt,A)=>{var W=(function(){var e=String.fromCharCode,t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",n={};function i(o,s){if(!n[o]){n[o]={};for(var u=0;u<o.length;u++)n[o][o.charAt(u)]=u;}return n[o][s]}var a={compressToBase64:function(o){if(o==null)return "";var s=a._compress(o,6,function(u){return t.charAt(u)});switch(s.length%4){default:case 0:return s;case 1:return s+"===";case 2:return s+"==";case 3:return s+"="}},decompressFromBase64:function(o){return o==null?"":o==""?null:a._decompress(o.length,32,function(s){return i(t,o.charAt(s))})},compressToUTF16:function(o){return o==null?"":a._compress(o,15,function(s){return e(s+32)})+" "},decompressFromUTF16:function(o){return o==null?"":o==""?null:a._decompress(o.length,16384,function(s){return o.charCodeAt(s)-32})},compressToUint8Array:function(o){for(var s=a.compress(o),u=new Uint8Array(s.length*2),d=0,p=s.length;d<p;d++){var y=s.charCodeAt(d);u[d*2]=y>>>8,u[d*2+1]=y%256;}return u},decompressFromUint8Array:function(o){if(o==null)return a.decompress(o);for(var s=new Array(o.length/2),u=0,d=s.length;u<d;u++)s[u]=o[u*2]*256+o[u*2+1];var p=[];return s.forEach(function(y){p.push(e(y));}),a.decompress(p.join(""))},compressToEncodedURIComponent:function(o){return o==null?"":a._compress(o,6,function(s){return r.charAt(s)})},decompressFromEncodedURIComponent:function(o){return o==null?"":o==""?null:(o=o.replace(/ /g,"+"),a._decompress(o.length,32,function(s){return i(r,o.charAt(s))}))},compress:function(o){return a._compress(o,16,function(s){return e(s)})},_compress:function(o,s,u){if(o==null)return "";var d,p,y={},x={},k="",T="",v="",w=2,R=3,f=2,h=[],c=0,l=0,b;for(b=0;b<o.length;b+=1)if(k=o.charAt(b),Object.prototype.hasOwnProperty.call(y,k)||(y[k]=R++,x[k]=true),T=v+k,Object.prototype.hasOwnProperty.call(y,T))v=T;else {if(Object.prototype.hasOwnProperty.call(x,v)){if(v.charCodeAt(0)<256){for(d=0;d<f;d++)c=c<<1,l==s-1?(l=0,h.push(u(c)),c=0):l++;for(p=v.charCodeAt(0),d=0;d<8;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}else {for(p=1,d=0;d<f;d++)c=c<<1|p,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=0;for(p=v.charCodeAt(0),d=0;d<16;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}w--,w==0&&(w=Math.pow(2,f),f++),delete x[v];}else for(p=y[v],d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;w--,w==0&&(w=Math.pow(2,f),f++),y[T]=R++,v=String(k);}if(v!==""){if(Object.prototype.hasOwnProperty.call(x,v)){if(v.charCodeAt(0)<256){for(d=0;d<f;d++)c=c<<1,l==s-1?(l=0,h.push(u(c)),c=0):l++;for(p=v.charCodeAt(0),d=0;d<8;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}else {for(p=1,d=0;d<f;d++)c=c<<1|p,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=0;for(p=v.charCodeAt(0),d=0;d<16;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}w--,w==0&&(w=Math.pow(2,f),f++),delete x[v];}else for(p=y[v],d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;w--,w==0&&(w=Math.pow(2,f),f++);}for(p=2,d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;for(;;)if(c=c<<1,l==s-1){h.push(u(c));break}else l++;return h.join("")},decompress:function(o){return o==null?"":o==""?null:a._decompress(o.length,32768,function(s){return o.charCodeAt(s)})},_decompress:function(o,s,u){var d=[],y=4,x=4,k=3,T="",v=[],w,R,f,h,c,l,b,m={val:u(0),position:s,index:1};for(w=0;w<3;w+=1)d[w]=w;for(f=0,c=Math.pow(2,2),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;switch(f){case 0:for(f=0,c=Math.pow(2,8),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;b=e(f);break;case 1:for(f=0,c=Math.pow(2,16),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;b=e(f);break;case 2:return ""}for(d[3]=b,R=b,v.push(b);;){if(m.index>o)return "";for(f=0,c=Math.pow(2,k),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;switch(b=f){case 0:for(f=0,c=Math.pow(2,8),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;d[x++]=e(f),b=x-1,y--;break;case 1:for(f=0,c=Math.pow(2,16),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;d[x++]=e(f),b=x-1,y--;break;case 2:return v.join("")}if(y==0&&(y=Math.pow(2,k),k++),d[b])T=d[b];else if(b===x)T=R+R.charAt(0);else return null;v.push(T),d[x++]=R+T.charAt(0),y--,R=T,y==0&&(y=Math.pow(2,k),k++);}}};return a})();typeof define=="function"&&define.amd?define(function(){return W}):typeof A<"u"&&A!=null?A.exports=W:typeof angular<"u"&&angular!=null&&angular.module("LZString",[]).factory("LZString",function(){return W});});var F=[{name:"@directive-run/ai",version:"1.21.0",description:"AI guardrails and orchestration for Directive. Prompt injection, PII detection, cost tracking, multi-agent patterns.",homepage:"https://directive.run",keywords:["directive","ai","agents","guardrails","orchestration","llm","constraint-driven","ai-safety","prompt-injection","pii-detection","cost-tracking","multi-agent","openai","anthropic","ollama","gemini"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:[".","./anthropic","./devtools","./evals","./gemini","./guardrails","./mcp","./multi-agent","./ollama","./openai","./predicate","./testing"],directory:"ai",published:true},{name:"@directive-run/claude-plugin",version:"1.21.0",description:"Claude Code plugin for Directive \u2014 12 skills covering modules, constraints, resolvers, derivations, AI orchestration, and adapters. Installable via Claude Code's plugin marketplace or consumable programmatically as an npm package.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","claude","claude-code","skills","ai-rules","plugin","agents","knowledge"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"claude-plugin",published:true},{name:"@directive-run/cli",version:"1.21.0",description:"CLI tools for Directive \u2014 AI coding rules, scaffolding, and more.",homepage:"https://directive.run",keywords:["directive","cli","ai-rules","cursor","copilot","claude","windsurf","cline","llms-txt"],dependencies:["@clack/prompts","@directive-run/knowledge","@directive-run/scaffold","picocolors"],peerDependencies:["@directive-run/timeline"],optionalDependencies:[],exports:[".","./llms.txt"],directory:"cli",published:true},{name:"@directive-run/core",version:"1.21.0",description:"The constraint-driven runtime for TypeScript. Declare what must be true \u2014 the runtime makes it happen.",homepage:"https://directive.run",keywords:["directive","constraint-driven","state-management","constraints","reactive","runtime","typescript","ai-guardrails","zero-dependencies","auto-tracking","framework-agnostic","declarative"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:[".","./adapter-utils","./internals","./migration","./plugins","./testing","./worker"],directory:"core",published:true},{name:"@directive-run/el",version:"1.1.1",description:"Vanilla DOM adapter for Directive. Typed element creation + reactive bindings + JSX runtime.",homepage:"https://directive.run",keywords:["directive","vanilla","dom","elements","jsx","htm","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","htm"],optionalDependencies:[],exports:[".","./htm","./jsx-dev-runtime","./jsx-runtime"],directory:"el",published:true},{name:"@directive-run/knowledge",version:"1.21.0",description:"Knowledge files, examples, and validation for Directive \u2014 the constraint-driven TypeScript runtime.",homepage:"https://directive.run",keywords:["directive","knowledge","ai-rules","examples"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"knowledge",published:true},{name:"@directive-run/lint",version:"0.1.2",description:"ts-morph-based static analysis for Directive code. Rule registry + executable checks + autofixes. Consumed by @directive-run/mcp (review_source, fix_code tools) and the future `directive doctor lint` CLI command. Anti-pattern data sourced from @directive-run/knowledge so rule IDs stay in lock-step.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","lint","ast","ts-morph","review","anti-patterns"],dependencies:[],peerDependencies:[],optionalDependencies:["ts-morph"],exports:[".","./executable","./worker"],directory:"lint",published:true},{name:"@directive-run/lit",version:"1.21.0",description:"Lit web components adapter for Directive.",homepage:"https://directive.run",keywords:["directive","lit","web-components","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","lit"],optionalDependencies:[],exports:["."],directory:"lit",published:true},{name:"@directive-run/mcp",version:"0.6.0",description:"Model Context Protocol server that exposes Directive to AI clients \u2014 knowledge files, code examples, and Claude Code skill bundles today, with room to grow into runtime introspection and tooling. stdio for local clients (Claude Desktop, Cursor, MCP Inspector), SSE for hosted deployments at mcp.directive.run.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","mcp","model-context-protocol","knowledge","ai-rules","sse","stdio"],dependencies:["@directive-run/claude-plugin","@directive-run/knowledge","@directive-run/lint","@directive-run/sandbox","@directive-run/scaffold","@modelcontextprotocol/sdk","lz-string","zod"],peerDependencies:[],optionalDependencies:["ts-morph"],exports:["."],directory:"mcp",published:true},{name:"@directive-run/mutator",version:"0.4.0",description:"Discriminated mutation helper for Directive \u2014 collapse the pendingAction ceremony to a typed handler map.",homepage:"https://directive.run",keywords:["directive","mutator","state-management","discriminated-union","optimistic-update"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"mutator",published:true},{name:"@directive-run/optimistic",version:"0.2.1",description:"Resolver-scope optimistic update + automatic rollback for Directive.",homepage:"https://directive.run",keywords:["directive","optimistic","rollback","snapshot","state-management"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"optimistic",published:true},{name:"@directive-run/query",version:"1.2.0",description:"Declarative data fetching for Directive. Constraint-driven queries with causal cache invalidation.",homepage:"https://directive.run",keywords:["directive","data-fetching","query","cache","stale-while-revalidate","constraint-driven","reactive","typescript"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"query",published:true},{name:"@directive-run/react",version:"1.21.0",description:"React hooks and components for Directive.",homepage:"https://directive.run",keywords:["directive","react","hooks","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","react"],optionalDependencies:[],exports:["."],directory:"react",published:true},{name:"@directive-run/sandbox",version:"0.4.0",description:"Execute Directive snippets server-side and return a structured transcript (logs + facts + errors). Consumed by @directive-run/mcp's run_in_sandbox tool and directive.run/playground's live DevTools panel. Uses worker_threads + esbuild bundling + an AST allowlist validator so user-supplied TypeScript runs with a bounded surface (allowlisted imports, allowlisted API calls, 5s wall clock, 32 MB heap).",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","sandbox","worker-threads","execute","transcript"],dependencies:["@directive-run/core"],peerDependencies:[],optionalDependencies:["esbuild","ts-morph"],exports:[".","./worker"],directory:"sandbox",published:true},{name:"@directive-run/scaffold",version:"0.2.1",description:"Pure source-string generators for Directive modules and orchestrators. Shared substrate consumed by @directive-run/cli (its `directive new` command) and @directive-run/mcp (its `generate_module` tool). Zero runtime dependencies.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","scaffold","codegen","module-generator"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"scaffold",published:true},{name:"@directive-run/solid",version:"1.21.0",description:"Solid.js signals adapter for Directive.",homepage:"https://directive.run",keywords:["directive","solid","solidjs","signals","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","solid-js"],optionalDependencies:[],exports:["."],directory:"solid",published:true},{name:"@directive-run/sources",version:"0.3.1",description:"Source adapters for Directive \u2014 wrap Supabase realtime, Cloudflare DO alarms, WebSocket, Sentry, etc. as typed `source` primitives. One package, one install, subpath exports per vendor.",homepage:"https://directive.run",keywords:["directive","source","supabase","cloudflare","realtime","websocket","state-management"],dependencies:[],peerDependencies:["@cloudflare/workers-types","@directive-run/core","@supabase/supabase-js"],optionalDependencies:[],exports:[".","./cloudflare","./supabase"],directory:"sources",published:true},{name:"@directive-run/svelte",version:"1.21.0",description:"Svelte stores adapter for Directive.",homepage:"https://directive.run",keywords:["directive","svelte","stores","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","svelte"],optionalDependencies:[],exports:["."],directory:"svelte",published:true},{name:"@directive-run/timeline",version:"0.3.3",description:"Time-travel test REPL for Directive. Auto-renders the causal-graph timeline of any failing test.",homepage:"https://directive.run",keywords:["directive","time-travel","test-debugging","vitest","causal-graph","state-management"],dependencies:[],peerDependencies:["@directive-run/core","vitest"],optionalDependencies:[],exports:[".","./matchers","./reporter"],directory:"timeline",published:true},{name:"@directive-run/vite-plugin-api-proxy",version:"0.1.1",description:"",keywords:[],dependencies:[],peerDependencies:["vite"],optionalDependencies:[],exports:["."],directory:"vite-plugin-api-proxy",published:false},{name:"@directive-run/vue",version:"1.21.0",description:"Vue composition API adapter for Directive.",homepage:"https://directive.run",keywords:["directive","vue","composition-api","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","vue"],optionalDependencies:[],exports:["."],directory:"vue",published:true}],Q="2026-06-14T06:48:37.121Z";var ee=2e5,te=5e3,je=/^[\w./-]{1,128}$/,Ve=Math.max(1,globalThis.navigator?.hardwareConcurrency??4),V=Ve,I=0,j=[];function Ge(){for(;j.length>0&&I<V;){let e=j.shift();if(!(!e||e.aborted)){I++,e.resolve();return}}}function We(e){return e?.aborted?Promise.reject(e.reason instanceof Error?e.reason:new Error("lint-runner: acquireLintSlot aborted")):I<V?(I++,Promise.resolve()):new Promise((t,r)=>{let n={resolve:t,reject:r,aborted:false};if(j.push(n),e);})}function re(){I=Math.max(0,I-1),I<V&&Ge();}var S=class extends Error{constructor(r,n){super(r);this.code=n;}};function ne(e){let t=Buffer.byteLength(e.source,"utf8");if(t>ee)throw new S(`source is ${t} bytes (max ${ee})`,"source-too-large");let r="fileName"in e?e.fileName:void 0;if(r!==void 0&&!je.test(r))throw new S("invalid fileName","bad-filename")}async function He(){let e=await import.meta.resolve("@directive-run/lint/worker");return fileURLToPath(e)}async function ie(e){await We();let t;try{t=await He();}catch(i){throw re(),i}let r=new Worker(t,{stderr:false}),n=null;try{return await new Promise((i,a)=>{let o=!1;r.once("message",s=>{o=!0,s.ok&&s.result!==void 0?i(s.result):a(new S(s.error??"worker returned without result","worker-error"));}),r.once("error",s=>{o=!0,a(new S(s.message,"worker-error"));}),r.once("exit",s=>{!o&&s!==0&&s!==null&&a(new S(`worker exited with code ${s} before responding`,"worker-error"));}),n=setTimeout(()=>{r.terminate(),a(new S(`parse exceeded ${te}ms budget`,"timeout"));},te),r.postMessage(e);})}finally{n&&clearTimeout(n),await r.terminate().catch(()=>{}),re();}}function oe(){return !(process.env.DIRECTIVE_MCP_USE_LINT_WORKER==="0"||process.env.VITEST==="true")}async function se(e){return ne(e),oe()?ie({kind:"run",source:e.source,options:{fileName:e.fileName,ruleFilter:e.ruleFilter}}):runRules(e.source,{fileName:e.fileName,ruleFilter:e.ruleFilter})}async function ae(e){return ne(e),oe()?ie({kind:"fix",source:e.source,finding:e.finding}):applyFix(e.source,e.finding)}var ze=3600*1e3,Ke=3e3,ce=new Map;function G(){return F.map(e=>({name:e.name,summary:e.description,published:e.published}))}async function le(e){let t=F.find(i=>i.name===e);if(!t)return;let{liveVersion:r,stale:n}=await Xe(t);return Ye(t,r,n)}function Ye(e,t,r){return {name:e.name,description:e.description,homepage:e.homepage,keywords:e.keywords,dependencies:e.dependencies,peerDependencies:e.peerDependencies,optionalDependencies:e.optionalDependencies,exports:e.exports,published:e.published,npmUrl:e.published?`https://www.npmjs.com/package/${e.name}`:void 0,bakedVersion:e.version,liveVersion:t,stale:r}}async function Xe(e){if(!e.published)return {stale:true};let t=ce.get(e.name);if(t&&Date.now()-t.fetchedAt<ze)return {liveVersion:t.liveVersion,stale:t.liveVersion===void 0};let r=await qe(e.name);return ce.set(e.name,{fetchedAt:Date.now(),liveVersion:r.liveVersion,latest:r.liveVersion,error:r.error}),{liveVersion:r.liveVersion,stale:r.liveVersion===void 0}}async function qe(e){let t=`https://registry.npmjs.org/${encodeURIComponent(e).replace(/%2F/g,"/")}/latest`,r=new AbortController,n=setTimeout(()=>r.abort(),Ke);try{let i=await fetch(t,{signal:r.signal});if(!i.ok)return {error:`HTTP ${i.status}`};let a=await i.json();return typeof a.version=="string"?{liveVersion:a.version}:{error:"no version field"}}catch(i){return {error:i.message}}finally{clearTimeout(n);}}var H=Ce(de()),D=8e3,Je="https://directive.run/playground",Ze="https://directive.run/run",_=class extends Error{constructor(r,n){super(r);this.code=n;}};function ue(e){if(e>D)throw new _(`payload is ${e} bytes (max ${D}). Payloads larger than ${D} bytes don't fit reliably in a URL \u2014 copy the source into a fresh Stackblitz project instead.`,"source-too-large")}function pe(e){return encodeURIComponent(e)}function me(e){return e==="instant"?Ze:Je}function Qe(e,t,r){if(e.length===0)throw new _("source is empty","source-empty");let n=Buffer.byteLength(e,"utf8");ue(n);let a=[`src=${(0, H.compressToEncodedURIComponent)(e)}`];t&&a.push(`t=${pe(t)}`);let o=`${me(r)}#${a.join("&")}`;return {url:o,sizeBytes:n,urlBytes:Buffer.byteLength(o,"utf8"),fileCount:1,mode:r,title:t}}function et(e,t,r){if(e.length===0)throw new _("files array is empty","source-empty");for(let u of e){if(typeof u.path!="string"||u.path.length===0)throw new _("every file must have a non-empty path","invalid-file");if(typeof u.source!="string"||u.source.length===0)throw new _(`file '${u.path}' has empty source`,"invalid-file")}let n=JSON.stringify(e),i=Buffer.byteLength(n,"utf8");ue(i);let o=[`files=${(0, H.compressToEncodedURIComponent)(n)}`];t&&o.push(`t=${pe(t)}`);let s=`${me(r)}#${o.join("&")}`;return {url:s,sizeBytes:i,urlBytes:Buffer.byteLength(s,"utf8"),fileCount:e.length,mode:r,title:t}}function z(e){let t=e.mode??"preview",r=typeof e.source=="string",n=Array.isArray(e.files);if(r&&n)throw new _("pass either `source` or `files`, not both","both-source-and-files");if(!r&&!n)throw new _("pass either `source` (single file) or `files` (multi-file array)","no-input");return n?et(e.files,e.title,t):Qe(e.source,e.title,t)}var L=2e5,ge=10,rt=/^[\w./-]{1,128}$/,$=class extends Error{constructor(r,n){super(r);this.code=n;}};function nt(e){if(e.files){if(e.files.length>ge)throw new $(`payload exceeds ${ge} files`,"input-invalid");let t=0;for(let r of e.files){if(!rt.test(r.path))throw new $(`invalid file path: '${r.path}'`,"input-invalid");t+=Buffer.byteLength(r.source,"utf8");}if(t>L)throw new $(`payload is ${t} bytes (max ${L})`,"input-too-large")}else if(e.source){let t=Buffer.byteLength(e.source,"utf8");if(t>L)throw new $(`source is ${t} bytes (max ${L})`,"input-too-large")}}async function fe(e){return nt(e),runInSandbox(e)}var ve="0.6.0",ke=50,ye=200,we=512;function bt(e){return e.length>ye?`${e.slice(0,ye)}\u2026`:e}function be(e,t,r){let n=e.toLowerCase(),i=[];for(let[a,o]of t){let s=o.split(`
|
|
2
|
+
import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {createHash}from'crypto';import {getAllSkills,getSkill}from'@directive-run/claude-plugin';import {getAllKnowledge,getKnowledge,getAllExamples,getExample,getCompositionsFor,getReverseCompositionsFor,getAntiPatterns,getAntiPatternById,MIGRATION_SOURCES,getMigrationPattern}from'@directive-run/knowledge';import {MODULE_SECTIONS,validateModuleName,generateOrchestrator,generateModule,suggestFileNames,requiredPackages}from'@directive-run/scaffold';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {z as z$1}from'zod';import {fileURLToPath}from'url';import {Worker}from'worker_threads';import {runRules,applyFix}from'@directive-run/lint';import {runInSandbox}from'@directive-run/sandbox';import {createServer}from'http';import {SSEServerTransport}from'@modelcontextprotocol/sdk/server/sse.js';var $e=Object.create;var Z=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,Le=Object.prototype.hasOwnProperty;var Oe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Me=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Pe(t))!Le.call(e,i)&&i!==r&&Z(e,i,{get:()=>t[i],enumerable:!(n=Ie(t,i))||n.enumerable});return e};var Ce=(e,t,r)=>(r=e!=null?$e(Ae(e)):{},Me(Z(r,"default",{value:e,enumerable:true}),e));var de=Oe((qt,A)=>{var W=(function(){var e=String.fromCharCode,t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",n={};function i(o,s){if(!n[o]){n[o]={};for(var u=0;u<o.length;u++)n[o][o.charAt(u)]=u;}return n[o][s]}var a={compressToBase64:function(o){if(o==null)return "";var s=a._compress(o,6,function(u){return t.charAt(u)});switch(s.length%4){default:case 0:return s;case 1:return s+"===";case 2:return s+"==";case 3:return s+"="}},decompressFromBase64:function(o){return o==null?"":o==""?null:a._decompress(o.length,32,function(s){return i(t,o.charAt(s))})},compressToUTF16:function(o){return o==null?"":a._compress(o,15,function(s){return e(s+32)})+" "},decompressFromUTF16:function(o){return o==null?"":o==""?null:a._decompress(o.length,16384,function(s){return o.charCodeAt(s)-32})},compressToUint8Array:function(o){for(var s=a.compress(o),u=new Uint8Array(s.length*2),d=0,p=s.length;d<p;d++){var y=s.charCodeAt(d);u[d*2]=y>>>8,u[d*2+1]=y%256;}return u},decompressFromUint8Array:function(o){if(o==null)return a.decompress(o);for(var s=new Array(o.length/2),u=0,d=s.length;u<d;u++)s[u]=o[u*2]*256+o[u*2+1];var p=[];return s.forEach(function(y){p.push(e(y));}),a.decompress(p.join(""))},compressToEncodedURIComponent:function(o){return o==null?"":a._compress(o,6,function(s){return r.charAt(s)})},decompressFromEncodedURIComponent:function(o){return o==null?"":o==""?null:(o=o.replace(/ /g,"+"),a._decompress(o.length,32,function(s){return i(r,o.charAt(s))}))},compress:function(o){return a._compress(o,16,function(s){return e(s)})},_compress:function(o,s,u){if(o==null)return "";var d,p,y={},x={},k="",T="",v="",w=2,R=3,f=2,h=[],c=0,l=0,b;for(b=0;b<o.length;b+=1)if(k=o.charAt(b),Object.prototype.hasOwnProperty.call(y,k)||(y[k]=R++,x[k]=true),T=v+k,Object.prototype.hasOwnProperty.call(y,T))v=T;else {if(Object.prototype.hasOwnProperty.call(x,v)){if(v.charCodeAt(0)<256){for(d=0;d<f;d++)c=c<<1,l==s-1?(l=0,h.push(u(c)),c=0):l++;for(p=v.charCodeAt(0),d=0;d<8;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}else {for(p=1,d=0;d<f;d++)c=c<<1|p,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=0;for(p=v.charCodeAt(0),d=0;d<16;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}w--,w==0&&(w=Math.pow(2,f),f++),delete x[v];}else for(p=y[v],d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;w--,w==0&&(w=Math.pow(2,f),f++),y[T]=R++,v=String(k);}if(v!==""){if(Object.prototype.hasOwnProperty.call(x,v)){if(v.charCodeAt(0)<256){for(d=0;d<f;d++)c=c<<1,l==s-1?(l=0,h.push(u(c)),c=0):l++;for(p=v.charCodeAt(0),d=0;d<8;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}else {for(p=1,d=0;d<f;d++)c=c<<1|p,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=0;for(p=v.charCodeAt(0),d=0;d<16;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;}w--,w==0&&(w=Math.pow(2,f),f++),delete x[v];}else for(p=y[v],d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;w--,w==0&&(w=Math.pow(2,f),f++);}for(p=2,d=0;d<f;d++)c=c<<1|p&1,l==s-1?(l=0,h.push(u(c)),c=0):l++,p=p>>1;for(;;)if(c=c<<1,l==s-1){h.push(u(c));break}else l++;return h.join("")},decompress:function(o){return o==null?"":o==""?null:a._decompress(o.length,32768,function(s){return o.charCodeAt(s)})},_decompress:function(o,s,u){var d=[],y=4,x=4,k=3,T="",v=[],w,R,f,h,c,l,b,m={val:u(0),position:s,index:1};for(w=0;w<3;w+=1)d[w]=w;for(f=0,c=Math.pow(2,2),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;switch(f){case 0:for(f=0,c=Math.pow(2,8),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;b=e(f);break;case 1:for(f=0,c=Math.pow(2,16),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;b=e(f);break;case 2:return ""}for(d[3]=b,R=b,v.push(b);;){if(m.index>o)return "";for(f=0,c=Math.pow(2,k),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;switch(b=f){case 0:for(f=0,c=Math.pow(2,8),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;d[x++]=e(f),b=x-1,y--;break;case 1:for(f=0,c=Math.pow(2,16),l=1;l!=c;)h=m.val&m.position,m.position>>=1,m.position==0&&(m.position=s,m.val=u(m.index++)),f|=(h>0?1:0)*l,l<<=1;d[x++]=e(f),b=x-1,y--;break;case 2:return v.join("")}if(y==0&&(y=Math.pow(2,k),k++),d[b])T=d[b];else if(b===x)T=R+R.charAt(0);else return null;v.push(T),d[x++]=R+T.charAt(0),y--,R=T,y==0&&(y=Math.pow(2,k),k++);}}};return a})();typeof define=="function"&&define.amd?define(function(){return W}):typeof A<"u"&&A!=null?A.exports=W:typeof angular<"u"&&angular!=null&&angular.module("LZString",[]).factory("LZString",function(){return W});});var F=[{name:"@directive-run/ai",version:"1.23.0",description:"AI guardrails and orchestration for Directive. Prompt injection, PII detection, cost tracking, multi-agent patterns.",homepage:"https://directive.run",keywords:["directive","ai","agents","guardrails","orchestration","llm","constraint-driven","ai-safety","prompt-injection","pii-detection","cost-tracking","multi-agent","openai","anthropic","ollama","gemini"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:[".","./anthropic","./devtools","./evals","./gemini","./guardrails","./mcp","./multi-agent","./ollama","./openai","./predicate","./testing"],directory:"ai",published:true},{name:"@directive-run/claude-plugin",version:"1.23.0",description:"Claude Code plugin for Directive \u2014 12 skills covering modules, constraints, resolvers, derivations, AI orchestration, and adapters. Installable via Claude Code's plugin marketplace or consumable programmatically as an npm package.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","claude","claude-code","skills","ai-rules","plugin","agents","knowledge"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"claude-plugin",published:true},{name:"@directive-run/cli",version:"1.23.0",description:"CLI tools for Directive \u2014 AI coding rules, scaffolding, and more.",homepage:"https://directive.run",keywords:["directive","cli","ai-rules","cursor","copilot","claude","windsurf","cline","llms-txt"],dependencies:["@clack/prompts","@directive-run/knowledge","@directive-run/scaffold","picocolors"],peerDependencies:["@directive-run/timeline"],optionalDependencies:[],exports:[".","./llms.txt"],directory:"cli",published:true},{name:"@directive-run/core",version:"1.23.0",description:"The constraint-driven runtime for TypeScript. Declare what must be true \u2014 the runtime makes it happen.",homepage:"https://directive.run",keywords:["directive","constraint-driven","state-management","constraints","reactive","runtime","typescript","ai-guardrails","zero-dependencies","auto-tracking","framework-agnostic","declarative"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:[".","./adapter-utils","./internals","./migration","./plugins","./testing","./worker"],directory:"core",published:true},{name:"@directive-run/el",version:"1.1.1",description:"Vanilla DOM adapter for Directive. Typed element creation + reactive bindings + JSX runtime.",homepage:"https://directive.run",keywords:["directive","vanilla","dom","elements","jsx","htm","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","htm"],optionalDependencies:[],exports:[".","./htm","./jsx-dev-runtime","./jsx-runtime"],directory:"el",published:true},{name:"@directive-run/knowledge",version:"1.23.0",description:"Knowledge files, examples, and validation for Directive \u2014 the constraint-driven TypeScript runtime.",homepage:"https://directive.run",keywords:["directive","knowledge","ai-rules","examples"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"knowledge",published:true},{name:"@directive-run/lint",version:"0.1.2",description:"ts-morph-based static analysis for Directive code. Rule registry + executable checks + autofixes. Consumed by @directive-run/mcp (review_source, fix_code tools) and the future `directive doctor lint` CLI command. Anti-pattern data sourced from @directive-run/knowledge so rule IDs stay in lock-step.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","lint","ast","ts-morph","review","anti-patterns"],dependencies:[],peerDependencies:[],optionalDependencies:["ts-morph"],exports:[".","./executable","./worker"],directory:"lint",published:true},{name:"@directive-run/lit",version:"1.23.0",description:"Lit web components adapter for Directive.",homepage:"https://directive.run",keywords:["directive","lit","web-components","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","lit"],optionalDependencies:[],exports:["."],directory:"lit",published:true},{name:"@directive-run/mcp",version:"0.6.2",description:"Model Context Protocol server that exposes Directive to AI clients \u2014 knowledge files, code examples, and Claude Code skill bundles today, with room to grow into runtime introspection and tooling. stdio for local clients (Claude Desktop, Cursor, MCP Inspector), SSE for hosted deployments at mcp.directive.run.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","mcp","model-context-protocol","knowledge","ai-rules","sse","stdio"],dependencies:["@directive-run/claude-plugin","@directive-run/knowledge","@directive-run/lint","@directive-run/sandbox","@directive-run/scaffold","@modelcontextprotocol/sdk","lz-string","zod"],peerDependencies:[],optionalDependencies:["ts-morph"],exports:["."],directory:"mcp",published:true},{name:"@directive-run/mutator",version:"0.4.0",description:"Discriminated mutation helper for Directive \u2014 collapse the pendingAction ceremony to a typed handler map.",homepage:"https://directive.run",keywords:["directive","mutator","state-management","discriminated-union","optimistic-update"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"mutator",published:true},{name:"@directive-run/optimistic",version:"0.2.1",description:"Resolver-scope optimistic update + automatic rollback for Directive.",homepage:"https://directive.run",keywords:["directive","optimistic","rollback","snapshot","state-management"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"optimistic",published:true},{name:"@directive-run/query",version:"1.2.0",description:"Declarative data fetching for Directive. Constraint-driven queries with causal cache invalidation.",homepage:"https://directive.run",keywords:["directive","data-fetching","query","cache","stale-while-revalidate","constraint-driven","reactive","typescript"],dependencies:[],peerDependencies:["@directive-run/core"],optionalDependencies:[],exports:["."],directory:"query",published:true},{name:"@directive-run/react",version:"1.23.0",description:"React hooks and components for Directive.",homepage:"https://directive.run",keywords:["directive","react","hooks","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","react"],optionalDependencies:[],exports:["."],directory:"react",published:true},{name:"@directive-run/sandbox",version:"0.4.2",description:"Execute Directive snippets server-side and return a structured transcript (logs + facts + errors). Consumed by @directive-run/mcp's run_in_sandbox tool and directive.run/playground's live DevTools panel. Uses worker_threads + esbuild bundling + an AST allowlist validator so user-supplied TypeScript runs with a bounded surface (allowlisted imports, allowlisted API calls, 5s wall clock, 32 MB heap).",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","sandbox","worker-threads","execute","transcript"],dependencies:["@directive-run/core"],peerDependencies:[],optionalDependencies:["esbuild","ts-morph"],exports:[".","./worker"],directory:"sandbox",published:true},{name:"@directive-run/scaffold",version:"0.2.1",description:"Pure source-string generators for Directive modules and orchestrators. Shared substrate consumed by @directive-run/cli (its `directive new` command) and @directive-run/mcp (its `generate_module` tool). Zero runtime dependencies.",homepage:"https://directive.run/docs/ide-integration",keywords:["directive","scaffold","codegen","module-generator"],dependencies:[],peerDependencies:[],optionalDependencies:[],exports:["."],directory:"scaffold",published:true},{name:"@directive-run/solid",version:"1.23.0",description:"Solid.js signals adapter for Directive.",homepage:"https://directive.run",keywords:["directive","solid","solidjs","signals","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","solid-js"],optionalDependencies:[],exports:["."],directory:"solid",published:true},{name:"@directive-run/sources",version:"0.3.1",description:"Source adapters for Directive \u2014 wrap Supabase realtime, Cloudflare DO alarms, WebSocket, Sentry, etc. as typed `source` primitives. One package, one install, subpath exports per vendor.",homepage:"https://directive.run",keywords:["directive","source","supabase","cloudflare","realtime","websocket","state-management"],dependencies:[],peerDependencies:["@cloudflare/workers-types","@directive-run/core","@supabase/supabase-js"],optionalDependencies:[],exports:[".","./cloudflare","./supabase"],directory:"sources",published:true},{name:"@directive-run/svelte",version:"1.23.0",description:"Svelte stores adapter for Directive.",homepage:"https://directive.run",keywords:["directive","svelte","stores","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","svelte"],optionalDependencies:[],exports:["."],directory:"svelte",published:true},{name:"@directive-run/timeline",version:"0.3.3",description:"Time-travel test REPL for Directive. Auto-renders the causal-graph timeline of any failing test.",homepage:"https://directive.run",keywords:["directive","time-travel","test-debugging","vitest","causal-graph","state-management"],dependencies:[],peerDependencies:["@directive-run/core","vitest"],optionalDependencies:[],exports:[".","./matchers","./reporter"],directory:"timeline",published:true},{name:"@directive-run/vite-plugin-api-proxy",version:"0.1.1",description:"",keywords:[],dependencies:[],peerDependencies:["vite"],optionalDependencies:[],exports:["."],directory:"vite-plugin-api-proxy",published:false},{name:"@directive-run/vue",version:"1.23.0",description:"Vue composition API adapter for Directive.",homepage:"https://directive.run",keywords:["directive","vue","composition-api","state-management","reactive","constraint-driven"],dependencies:[],peerDependencies:["@directive-run/core","@directive-run/query","vue"],optionalDependencies:[],exports:["."],directory:"vue",published:true}],Q="2026-06-19T15:08:54.220Z";var ee=2e5,te=5e3,je=/^[\w./-]{1,128}$/,Ve=Math.max(1,globalThis.navigator?.hardwareConcurrency??4),V=Ve,I=0,j=[];function Ge(){for(;j.length>0&&I<V;){let e=j.shift();if(!(!e||e.aborted)){I++,e.resolve();return}}}function We(e){return e?.aborted?Promise.reject(e.reason instanceof Error?e.reason:new Error("lint-runner: acquireLintSlot aborted")):I<V?(I++,Promise.resolve()):new Promise((t,r)=>{let n={resolve:t,reject:r,aborted:false};if(j.push(n),e);})}function re(){I=Math.max(0,I-1),I<V&&Ge();}var S=class extends Error{constructor(r,n){super(r);this.code=n;}};function ne(e){let t=Buffer.byteLength(e.source,"utf8");if(t>ee)throw new S(`source is ${t} bytes (max ${ee})`,"source-too-large");let r="fileName"in e?e.fileName:void 0;if(r!==void 0&&!je.test(r))throw new S("invalid fileName","bad-filename")}async function He(){let e=await import.meta.resolve("@directive-run/lint/worker");return fileURLToPath(e)}async function ie(e){await We();let t;try{t=await He();}catch(i){throw re(),i}let r=new Worker(t,{stderr:false}),n=null;try{return await new Promise((i,a)=>{let o=!1;r.once("message",s=>{o=!0,s.ok&&s.result!==void 0?i(s.result):a(new S(s.error??"worker returned without result","worker-error"));}),r.once("error",s=>{o=!0,a(new S(s.message,"worker-error"));}),r.once("exit",s=>{!o&&s!==0&&s!==null&&a(new S(`worker exited with code ${s} before responding`,"worker-error"));}),n=setTimeout(()=>{r.terminate(),a(new S(`parse exceeded ${te}ms budget`,"timeout"));},te),r.postMessage(e);})}finally{n&&clearTimeout(n),await r.terminate().catch(()=>{}),re();}}function oe(){return !(process.env.DIRECTIVE_MCP_USE_LINT_WORKER==="0"||process.env.VITEST==="true")}async function se(e){return ne(e),oe()?ie({kind:"run",source:e.source,options:{fileName:e.fileName,ruleFilter:e.ruleFilter}}):runRules(e.source,{fileName:e.fileName,ruleFilter:e.ruleFilter})}async function ae(e){return ne(e),oe()?ie({kind:"fix",source:e.source,finding:e.finding}):applyFix(e.source,e.finding)}var ze=3600*1e3,Ke=3e3,ce=new Map;function G(){return F.map(e=>({name:e.name,summary:e.description,published:e.published}))}async function le(e){let t=F.find(i=>i.name===e);if(!t)return;let{liveVersion:r,stale:n}=await Xe(t);return Ye(t,r,n)}function Ye(e,t,r){return {name:e.name,description:e.description,homepage:e.homepage,keywords:e.keywords,dependencies:e.dependencies,peerDependencies:e.peerDependencies,optionalDependencies:e.optionalDependencies,exports:e.exports,published:e.published,npmUrl:e.published?`https://www.npmjs.com/package/${e.name}`:void 0,bakedVersion:e.version,liveVersion:t,stale:r}}async function Xe(e){if(!e.published)return {stale:true};let t=ce.get(e.name);if(t&&Date.now()-t.fetchedAt<ze)return {liveVersion:t.liveVersion,stale:t.liveVersion===void 0};let r=await qe(e.name);return ce.set(e.name,{fetchedAt:Date.now(),liveVersion:r.liveVersion,latest:r.liveVersion,error:r.error}),{liveVersion:r.liveVersion,stale:r.liveVersion===void 0}}async function qe(e){let t=`https://registry.npmjs.org/${encodeURIComponent(e).replace(/%2F/g,"/")}/latest`,r=new AbortController,n=setTimeout(()=>r.abort(),Ke);try{let i=await fetch(t,{signal:r.signal});if(!i.ok)return {error:`HTTP ${i.status}`};let a=await i.json();return typeof a.version=="string"?{liveVersion:a.version}:{error:"no version field"}}catch(i){return {error:i.message}}finally{clearTimeout(n);}}var H=Ce(de()),D=8e3,Je="https://directive.run/playground",Ze="https://directive.run/run",_=class extends Error{constructor(r,n){super(r);this.code=n;}};function ue(e){if(e>D)throw new _(`payload is ${e} bytes (max ${D}). Payloads larger than ${D} bytes don't fit reliably in a URL \u2014 copy the source into a fresh Stackblitz project instead.`,"source-too-large")}function pe(e){return encodeURIComponent(e)}function me(e){return e==="instant"?Ze:Je}function Qe(e,t,r){if(e.length===0)throw new _("source is empty","source-empty");let n=Buffer.byteLength(e,"utf8");ue(n);let a=[`src=${(0, H.compressToEncodedURIComponent)(e)}`];t&&a.push(`t=${pe(t)}`);let o=`${me(r)}#${a.join("&")}`;return {url:o,sizeBytes:n,urlBytes:Buffer.byteLength(o,"utf8"),fileCount:1,mode:r,title:t}}function et(e,t,r){if(e.length===0)throw new _("files array is empty","source-empty");for(let u of e){if(typeof u.path!="string"||u.path.length===0)throw new _("every file must have a non-empty path","invalid-file");if(typeof u.source!="string"||u.source.length===0)throw new _(`file '${u.path}' has empty source`,"invalid-file")}let n=JSON.stringify(e),i=Buffer.byteLength(n,"utf8");ue(i);let o=[`files=${(0, H.compressToEncodedURIComponent)(n)}`];t&&o.push(`t=${pe(t)}`);let s=`${me(r)}#${o.join("&")}`;return {url:s,sizeBytes:i,urlBytes:Buffer.byteLength(s,"utf8"),fileCount:e.length,mode:r,title:t}}function z(e){let t=e.mode??"preview",r=typeof e.source=="string",n=Array.isArray(e.files);if(r&&n)throw new _("pass either `source` or `files`, not both","both-source-and-files");if(!r&&!n)throw new _("pass either `source` (single file) or `files` (multi-file array)","no-input");return n?et(e.files,e.title,t):Qe(e.source,e.title,t)}var L=2e5,ge=10,rt=/^[\w./-]{1,128}$/,$=class extends Error{constructor(r,n){super(r);this.code=n;}};function nt(e){if(e.files){if(e.files.length>ge)throw new $(`payload exceeds ${ge} files`,"input-invalid");let t=0;for(let r of e.files){if(!rt.test(r.path))throw new $(`invalid file path: '${r.path}'`,"input-invalid");t+=Buffer.byteLength(r.source,"utf8");}if(t>L)throw new $(`payload is ${t} bytes (max ${L})`,"input-too-large")}else if(e.source){let t=Buffer.byteLength(e.source,"utf8");if(t>L)throw new $(`source is ${t} bytes (max ${L})`,"input-too-large")}}async function fe(e){return nt(e),runInSandbox(e)}var ve="0.6.2",ke=50,ye=200,we=512;function bt(e){return e.length>ye?`${e.slice(0,ye)}\u2026`:e}function be(e,t,r){let n=e.toLowerCase(),i=[];for(let[a,o]of t){let s=o.split(`
|
|
3
3
|
`);for(let u=0;u<s.length;u++){let d=s[u];if(d.toLowerCase().includes(n)&&(i.push(`${a}${r}:${u+1}: ${bt(d)}`),i.length>=ke))return i}}return i}function xe(e,t){return t.length===0?`No matches for '${e}'.`:`${t.length===ke?`${t.length}+ matches (truncated):`:`${t.length} matches:`}
|
|
4
4
|
${t.join(`
|
|
5
5
|
`)}`}var M=null;function xt(){if(M)return M;let e=createHash("sha256");for(let[t,r]of Array.from(getAllKnowledge()).sort(([n],[i])=>n.localeCompare(i)))e.update(t),e.update("\0"),e.update(r),e.update("\0");return M=e.digest("hex").slice(0,16),M}var P={transport:"stdio",authEnabled:false};function U(e){P=e;}function C(e,t,r){r.length!==0&&e.push("",`**${t}:**`,...r.map(n=>`- ${n}`));}function kt(e){let t=[`# ${e.name}`,e.description,"",`**Version (live):** ${e.liveVersion??"unknown"}`,`**Version (baked):** ${e.bakedVersion}${e.stale?" (live fetch failed; using baked)":""}`,`**Published to npm:** ${e.published?"yes":"no (private workspace package)"}`];return e.homepage&&t.push(`**Homepage:** ${e.homepage}`),e.npmUrl&&t.push(`**npm:** ${e.npmUrl}`),C(t,"Dependencies",e.dependencies),C(t,"Peer dependencies",e.peerDependencies),C(t,"Optional dependencies",e.optionalDependencies),C(t,"Exports",e.exports),t.join(`
|
|
@@ -48,7 +48,7 @@ ${a}`);return {content:[{type:"text",text:n.join(`
|
|
|
48
48
|
${JSON.stringify(o,null,2)}
|
|
49
49
|
</directive-data>`}]}}catch(a){return {isError:true,content:[{type:"text",text:`playground_link failed \u2014 ${a instanceof _?`${a.code}: ${a.message}`:a.message}`}]}}}),e.registerTool("run_in_sandbox",{title:"Execute a Directive snippet and return its observed behavior",description:"Execute a Directive snippet and return its observed behavior. Use `run_in_sandbox` when you want the transcript IN-CHAT (so you or your next reasoning step can see what happened). Use `playground_link` instead when you want to hand the USER an interactive URL. Both accept identical `source` / `files` shapes \u2014 copy the same payload across if you want both.\n\nResponse payload: `logs[]` (captured console.log/warn/error), `facts` (post-settle snapshot), `errors[]` (validation/bundle/runtime/timeout messages), `durationMs`, `timedOut`, and `playgroundUrl` (click-through to StackBlitz for the same snippet).\n\nDecoding errors:\n\u2022 `'<path>:<line>:<col> \u2014 <reason>'` \u2192 validation rejection (snippet hit the AST allowlist). REWRITE the snippet; re-running with the same input will reject again.\n\u2022 `'wall-clock budget of Nms elapsed'` plus `timedOut: true` \u2192 likely infinite loop or unawaited promise. Don't retry; surface to user.\n\u2022 `'cannot resolve \"./X\" from \"./Y\"'` or any `esbuild ...` \u2192 bundle failure; check file paths and imports.\n\u2022 Any other string \u2192 runtime throw (may be intentional from the module's logic; check `facts` to confirm).\n\nSandbox boundary (v0.3.0): the AST allowlist validator rejects (a) imports outside `@directive-run/{core, ai, query, react, vue, svelte, solid, lit, el, optimistic, timeline, mutator, knowledge, scaffold, claude-plugin, lint}` plus relative `./*.js` paths inside the payload, (b) free-identifier references to FS / network / eval surfaces (`process`, `require`, `fetch`, `eval`, `Buffer`, `setTimeout`, etc.), (c) `globalThis.process` / `Reflect.get(globalThis, ...)` / `.constructor` / `Function(...)` and other property-access bypass chains, (d) `@directive-run/{cli, mcp, sandbox, vite-plugin-api-proxy}` (build/CLI/sandbox tooling). The worker has a 5-second wall-clock budget (clamped to [100ms, 10s]) and a 32 MB heap ceiling.\n\nNote: `react/vue/svelte/solid/lit` import OK, but their runtime hooks (`useState`, etc.) need a DOM and throw in this Node sandbox. For UI demos, prefer `playground_link` (StackBlitz has a DOM).\n\nValidator rejection, bundle failure, runtime error, and timeout all return structured results in `errors` rather than throwing.",inputSchema:{source:z$1.string().min(1).max(D).optional().describe(`Single-file source (mutually exclusive with \`files\`). Use for already-runnable code. Max ${D} bytes.`),files:z$1.array(z$1.object({path:z$1.string().min(1).max(120).describe("Relative path inside the sandbox, e.g. 'src/counter.ts'. One file MUST be 'src/main.ts' \u2014 that's the entry point the worker imports."),source:z$1.string().min(1).describe("File contents.")})).min(1).max(10).optional().describe("Multi-file payload (mutually exclusive with `source`). Use for `generate_module` paired output."),timeoutMs:z$1.number().int().min(100).max(1e4).optional().describe("Wall-clock execution budget in milliseconds. Default 5000. Clamped to [100, 10000].")}},async({source:t,files:r,timeoutMs:n})=>{try{let i=await fe({source:t,files:r,timeoutMs:n}),a=null;try{a=z({source:t,files:r}).url;}catch{}let o={logs:i.logs,facts:i.facts,errors:i.errors,durationMs:i.durationMs,timedOut:i.timedOut,playgroundUrl:a};return {content:[{type:"text",text:`<directive-data>
|
|
50
50
|
${JSON.stringify(o,null,2)}
|
|
51
|
-
</directive-data>`}]}}catch(i){return {isError:true,content:[{type:"text",text:`run_in_sandbox failed \u2014 ${i instanceof $?`${i.code}: ${i.message}`:i.message}`}]}}}),e}var Se="/messages",_e="/sse",Tt="/healthz",Et=1e6,Dt=64,Rt=300*1e3,$t=3e4,It=new Set(["127.0.0.1","localhost","::1","0:0:0:0:0:0:0:1"]),q=class extends Error{};function Pt(e){return It.has(e.toLowerCase())}function At(e){let t=e.port??3e3,r=e.host??"127.0.0.1",n=e.logger??console,i=e.token??process.env.DIRECTIVE_MCP_TOKEN??void 0;if(!Pt(r)&&!i)throw new q("Public hosts require a token. Pass --token <value> or set DIRECTIVE_MCP_TOKEN, or bind to 127.0.0.1 for local dev.");return {port:t,host:r,logger:n,token:i,allowOrigins:e.allowOrigins??[],bodyLimitBytes:e.bodyLimitBytes??Et,maxSessions:e.maxSessions??Dt,idleTimeoutMs:e.idleTimeoutMs??Rt}}function Te(e,t){if(!t)return true;let r=e.headers.authorization;return typeof r!="string"?false:/^Bearer\s+(.+)$/i.exec(r)?.[1]?.trim()===t}function Ee(e,t){if(t.length===0)return true;let r=e.headers.origin;return typeof r!="string"?false:t.includes(r)}function E(e,t,r,n={}){e.writeHead(t,{"Content-Type":"text/plain",...n}),e.end(r);}function J(e,t){U({transport:"sse",authEnabled:t,sessionCount:e.size});}var X=0;async function Lt(e,t,r,n){if(!Te(e,n.token)){E(t,401,"unauthorized");return}if(!Ee(e,n.allowOrigins)){E(t,403,"origin not allowed");return}if(r.size+X>=n.maxSessions){E(t,429,"session cap reached",{"Retry-After":"60"});return}X+=1;let i=false;try{let a=new SSEServerTransport(Se,t),o=N();r.set(a.sessionId,{transport:a,lastActivity:Date.now()}),i=!0,J(r,!!n.token);let s=()=>{r.delete(a.sessionId),J(r,!!n.token);};t.on("close",s),a.onclose=s,await o.connect(a),n.logger.log(`[directive-mcp] sse session opened: ${a.sessionId}`);}finally{X-=1;}}async function Ot(e,t,r,n,i){if(!Te(e,i.token)){E(t,401,"unauthorized");return}if(!Ee(e,i.allowOrigins)){E(t,403,"origin not allowed");return}let a=Number(e.headers["content-length"]??"0");if(Number.isFinite(a)&&a>i.bodyLimitBytes){E(t,413,`body exceeds ${i.bodyLimitBytes} bytes`);return}let o=r.searchParams.get("sessionId");if(!o){E(t,400,"missing sessionId query parameter");return}let s=n.get(o);if(!s){E(t,404,`unknown session: ${o}`);return}s.lastActivity=Date.now();let u=0,d=false;e.on("data",p=>{u+=Buffer.byteLength(p),u>i.bodyLimitBytes&&!d&&(d=true,E(t,413,`body exceeds ${i.bodyLimitBytes} bytes`),e.destroy());}),!d&&await s.transport.handlePostMessage(e,t);}async function Mt(e,t,r,n){let i=new URL(e.url??"/",`http://${e.headers.host??n.host}`);if(e.method==="GET"&&i.pathname===Tt){t.writeHead(200,{"Content-Type":"text/plain"}),t.end("ok");return}if(e.method==="GET"&&i.pathname===_e){await Lt(e,t,r,n);return}if(e.method==="POST"&&i.pathname===Se){await Ot(e,t,i,r,n);return}E(t,404,"not found");}function Ct(e,t){return setInterval(()=>{let r=Date.now();for(let[n,i]of e)r-i.lastActivity>t.idleTimeoutMs&&(e.delete(n),i.transport.close().catch(()=>{}),J(e,!!t.token),t.logger.log(`[directive-mcp] pruned idle session: ${n}`));},$t).unref()}async function De(e={}){let t=At(e),r=new Map,n=createServer(async(a,o)=>{try{await Mt(a,o,r,t);}catch(s){t.logger.error("[directive-mcp] request error:",s),o.headersSent||o.writeHead(500,{"Content-Type":"text/plain"}),o.end("internal server error");}}),i=Ct(r,t);return n.on("close",()=>{clearInterval(i);}),await new Promise(a=>{n.listen(t.port,t.host,()=>{t.logger.log(`[directive-mcp] sse server listening at http://${t.host}:${t.port}${_e}${t.token?" (auth: bearer-token)":" (auth: none, loopback only)"}`),a();});}),n}var Nt="0.6.
|
|
51
|
+
</directive-data>`}]}}catch(i){return {isError:true,content:[{type:"text",text:`run_in_sandbox failed \u2014 ${i instanceof $?`${i.code}: ${i.message}`:i.message}`}]}}}),e}var Se="/messages",_e="/sse",Tt="/healthz",Et=1e6,Dt=64,Rt=300*1e3,$t=3e4,It=new Set(["127.0.0.1","localhost","::1","0:0:0:0:0:0:0:1"]),q=class extends Error{};function Pt(e){return It.has(e.toLowerCase())}function At(e){let t=e.port??3e3,r=e.host??"127.0.0.1",n=e.logger??console,i=e.token??process.env.DIRECTIVE_MCP_TOKEN??void 0;if(!Pt(r)&&!i)throw new q("Public hosts require a token. Pass --token <value> or set DIRECTIVE_MCP_TOKEN, or bind to 127.0.0.1 for local dev.");return {port:t,host:r,logger:n,token:i,allowOrigins:e.allowOrigins??[],bodyLimitBytes:e.bodyLimitBytes??Et,maxSessions:e.maxSessions??Dt,idleTimeoutMs:e.idleTimeoutMs??Rt}}function Te(e,t){if(!t)return true;let r=e.headers.authorization;return typeof r!="string"?false:/^Bearer\s+(.+)$/i.exec(r)?.[1]?.trim()===t}function Ee(e,t){if(t.length===0)return true;let r=e.headers.origin;return typeof r!="string"?false:t.includes(r)}function E(e,t,r,n={}){e.writeHead(t,{"Content-Type":"text/plain",...n}),e.end(r);}function J(e,t){U({transport:"sse",authEnabled:t,sessionCount:e.size});}var X=0;async function Lt(e,t,r,n){if(!Te(e,n.token)){E(t,401,"unauthorized");return}if(!Ee(e,n.allowOrigins)){E(t,403,"origin not allowed");return}if(r.size+X>=n.maxSessions){E(t,429,"session cap reached",{"Retry-After":"60"});return}X+=1;let i=false;try{let a=new SSEServerTransport(Se,t),o=N();r.set(a.sessionId,{transport:a,lastActivity:Date.now()}),i=!0,J(r,!!n.token);let s=()=>{r.delete(a.sessionId),J(r,!!n.token);};t.on("close",s),a.onclose=s,await o.connect(a),n.logger.log(`[directive-mcp] sse session opened: ${a.sessionId}`);}finally{X-=1;}}async function Ot(e,t,r,n,i){if(!Te(e,i.token)){E(t,401,"unauthorized");return}if(!Ee(e,i.allowOrigins)){E(t,403,"origin not allowed");return}let a=Number(e.headers["content-length"]??"0");if(Number.isFinite(a)&&a>i.bodyLimitBytes){E(t,413,`body exceeds ${i.bodyLimitBytes} bytes`);return}let o=r.searchParams.get("sessionId");if(!o){E(t,400,"missing sessionId query parameter");return}let s=n.get(o);if(!s){E(t,404,`unknown session: ${o}`);return}s.lastActivity=Date.now();let u=0,d=false;e.on("data",p=>{u+=Buffer.byteLength(p),u>i.bodyLimitBytes&&!d&&(d=true,E(t,413,`body exceeds ${i.bodyLimitBytes} bytes`),e.destroy());}),!d&&await s.transport.handlePostMessage(e,t);}async function Mt(e,t,r,n){let i=new URL(e.url??"/",`http://${e.headers.host??n.host}`);if(e.method==="GET"&&i.pathname===Tt){t.writeHead(200,{"Content-Type":"text/plain"}),t.end("ok");return}if(e.method==="GET"&&i.pathname===_e){await Lt(e,t,r,n);return}if(e.method==="POST"&&i.pathname===Se){await Ot(e,t,i,r,n);return}E(t,404,"not found");}function Ct(e,t){return setInterval(()=>{let r=Date.now();for(let[n,i]of e)r-i.lastActivity>t.idleTimeoutMs&&(e.delete(n),i.transport.close().catch(()=>{}),J(e,!!t.token),t.logger.log(`[directive-mcp] pruned idle session: ${n}`));},$t).unref()}async function De(e={}){let t=At(e),r=new Map,n=createServer(async(a,o)=>{try{await Mt(a,o,r,t);}catch(s){t.logger.error("[directive-mcp] request error:",s),o.headersSent||o.writeHead(500,{"Content-Type":"text/plain"}),o.end("internal server error");}}),i=Ct(r,t);return n.on("close",()=>{clearInterval(i);}),await new Promise(a=>{n.listen(t.port,t.host,()=>{t.logger.log(`[directive-mcp] sse server listening at http://${t.host}:${t.port}${_e}${t.token?" (auth: bearer-token)":" (auth: none, loopback only)"}`),a();});}),n}var Nt="0.6.2",Re=`directive-mcp \u2014 MCP server exposing Directive to AI clients
|
|
52
52
|
|
|
53
53
|
Usage:
|
|
54
54
|
directive-mcp Run stdio transport (default)
|