@directive-run/mcp 0.2.2 → 0.3.0

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 CHANGED
@@ -1,25 +1,133 @@
1
1
  # `@directive-run/mcp`
2
2
 
3
- A Model Context Protocol server that exposes Directive to AI clients. Today's tools cover knowledge files, code examples, and Claude Code skill bundles queryable at retrieval time instead of bundled as a static snapshot. The package is the umbrella for "Directive as an MCP server," with room to grow into runtime introspection, system state, and tooling.
3
+ Run a Model Context Protocol (MCP) server that lets AI assistants Claude Desktop, Cursor, Windsurf, or any MCP clientquery 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
- Two transports ship in the same binary:
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
- - **stdio** the canonical MCP local-client pattern. Plugs into Claude Desktop, Cursor MCP, the MCP Inspector, and any other client that spawns an MCP server as a subprocess.
8
- - **SSE (HTTP)** — for hosting at `mcp.directive.run` or a private MCP gateway. Production AI agents query the hosted endpoint at runtime; no embedding pipeline, no bundle bloat.
9
-
10
- > **Client vs. server, two different packages.** This package is the MCP **server** side — it serves Directive to outside clients. If you want the **client** side — Directive AI agents calling out to external MCP servers (filesystem, GitHub, etc.) — that's `@directive-run/ai/mcp` (`createMCPAdapter`). Same protocol, opposite arrows.
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`.
11
8
 
12
9
  ## Install
13
10
 
11
+ The fastest path is zero-install via `npx`. Claude Desktop, Cursor, and other MCP clients will spawn it for you when their config block points here:
12
+
13
+ ```bash
14
+ npx -y @directive-run/mcp --help
15
+ ```
16
+
17
+ For environments that pin binaries, install globally instead:
18
+
14
19
  ```bash
15
20
  npm install -g @directive-run/mcp
16
- # or run directly without installing:
17
- npx @directive-run/mcp --help
21
+ directive-mcp --help
22
+ ```
23
+
24
+ ## Try it (3 steps)
25
+
26
+ ```jsonc
27
+ // 1. Paste into your AI client's MCP config and restart it.
28
+ // Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json
29
+ // Cursor: .cursor/mcp.json
30
+ {
31
+ "mcpServers": {
32
+ "directive": {
33
+ "command": "npx",
34
+ "args": ["-y", "@directive-run/mcp"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ```text
41
+ 2. Verify the server is loaded.
42
+ Claude Desktop: click the tools/hammer icon — you should see `directive`
43
+ with 20 tools. Or ask Claude:
44
+ "Use the directive MCP server's get_server_info tool."
45
+ Cursor: open Settings → MCP → look for `directive` (status: connected).
46
+ MCP Inspector: npx @modelcontextprotocol/inspector npx -y @directive-run/mcp
47
+ → connect → /tools should list 20 entries.
18
48
  ```
19
49
 
50
+ ```text
51
+ 3. Send your first prompt. Any of these will fire a tool round-trip:
52
+
53
+ • "Using the directive MCP server, list the knowledge files,
54
+ then read the one about constraints."
55
+ • "Generate a Directive module named 'cart' with constraints + resolvers
56
+ using the directive MCP server."
57
+ • "Review this code with directive's review_source tool, then call
58
+ fix_code on any fixable findings:
59
+ createModule('Cart', { schema: {} });"
60
+ ```
61
+
62
+ ## How it works
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 — `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
+
66
+ ```
67
+ ┌────────────────────────────────────────────────────────────────────────────────┐
68
+ │ Claude Desktop / Cursor / Windsurf / MCP Inspector │
69
+ │ │
70
+ │ Reads ~/Library/Application Support/Claude/claude_desktop_config.json on │
71
+ │ launch. For each mcpServers entry, spawns the subprocess and pipes JSON-RPC │
72
+ │ over its stdin/stdout. │
73
+ └────────────────────────────┬───────────────────────────────────────────────────┘
74
+ │ stdio (or SSE for hosted)
75
+
76
+ ┌────────────────────────────────────────────────────────────────────────────────┐
77
+ │ @directive-run/mcp@0.2.x (`npx -y @directive-run/mcp` subprocess) │
78
+ │ │
79
+ │ src/cli.ts: │
80
+ │ parseArgs() → { sse: false (default) } │
81
+ │ setServerInfo({ transport: "stdio", authEnabled: false }) │
82
+ │ createDirectiveServer() → McpServer with 20 tools registered │
83
+ │ │
84
+ │ Tool surface (20): │
85
+ │ Knowledge: list_knowledge, get_knowledge, search_knowledge, │
86
+ │ list_examples, get_example, search_examples │
87
+ │ Packages: list_packages, get_package_info, get_composable_packages │
88
+ │ Generate: generate_module, list_module_sections │
89
+ │ Review: list_review_rules, get_review_rule, review_source, fix_code │
90
+ │ Migration: list_migration_sources, get_migration_pattern │
91
+ │ Skills: list_skills, get_skill │
92
+ │ Server: get_server_info │
93
+ └──────┬─────────────────┬──────────────────┬──────────────────┬─────────────────┘
94
+ │ │ │ │
95
+ ▼ ▼ ▼ ▼
96
+ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌───────────────────┐
97
+ │knowledge │ │claude-plug-│ │ scaffold │ │ lint │
98
+ │ │ │ in │ │ │ │ (lazy-loaded │
99
+ │ • core/* │ │ • skills/* │ │ pure │ │ via separate │
100
+ │ • ai/* │ │ bundled │ │ functions│ │ tsup entry) │
101
+ │ • compo- │ │ from │ │ in / │ │ │
102
+ │ sitions│ │ knowledge │ │ strings │ │ • 10 ts-morph │
103
+ │ .json │ │ at build │ │ out │ │ rules │
104
+ │ • migra- │ │ │ │ │ │ • 6 fixable │
105
+ │ tion. │ │ │ │ Zero │ │ • Worker_threads │
106
+ │ json │ │ │ │ runtime │ │ ON by default │
107
+ │ • Lazy + │ │ │ │ deps │ │ • 5-second │
108
+ │ cached │ │ │ │ │ │ parse budget │
109
+ │ parsers│ │ │ │ │ └──────┬────────────┘
110
+ └──────────┘ └────────────┘ └──────────┘ │
111
+
112
+ ┌────────────────────────┐
113
+ │ ts-morph (lazy) │
114
+ │ TypeScript compiler │
115
+ │ API wrapper. Spins up │
116
+ │ in-memory Project, │
117
+ │ parses src → AST. │
118
+ │ Each rule walks the │
119
+ │ AST via │
120
+ │ getDescendantsOfKind │
121
+ └────────────────────────┘
122
+ ```
123
+
124
+ **Caching & limits.** First call to `list_knowledge` warms the knowledge cache (~700 KB markdown). First call to `review_source` spins up a worker thread + the ts-morph project, then keeps both for the process lifetime. Built-in caps: 200 KB max source for `review_source`/`fix_code`, 5-second parse budget, 1 MB body cap on SSE, 64 concurrent SSE sessions, 5-minute idle pruning. See `get_server_info` for the live counts.
125
+
126
+ For the request-flow trace in code, see `src/server.ts` (tool registration) and `src/lint-runner.ts` (worker dispatch).
127
+
20
128
  ## stdio transport (local clients)
21
129
 
22
- Add to your Claude Desktop config (`claude_desktop_config.json`):
130
+ Add to your AI client's MCP config (Claude Desktop's `claude_desktop_config.json`, Cursor's `.cursor/mcp.json`, etc.) and restart it:
23
131
 
24
132
  ```json
25
133
  {
@@ -32,7 +140,7 @@ Add to your Claude Desktop config (`claude_desktop_config.json`):
32
140
  }
33
141
  ```
34
142
 
35
- Or test with the MCP Inspector:
143
+ Or run the MCP Inspector for a browser-based UI:
36
144
 
37
145
  ```bash
38
146
  npx @modelcontextprotocol/inspector npx -y @directive-run/mcp
@@ -50,7 +158,7 @@ directive-mcp --sse --port 3000 --host 0.0.0.0 \
50
158
  --allow-origin https://app.example.com
51
159
  ```
52
160
 
53
- The SSE server **refuses to start** on a non-loopback host without `--token` (or `DIRECTIVE_MCP_TOKEN`). When a token is set, every request to `/sse` and `/messages` must carry `Authorization: Bearer <token>`. Body size is capped at 1 MB; concurrent sessions at 64; idle sessions are pruned at 5 minutes.
161
+ **Security defaults.** A public bind (`--host 0.0.0.0`) without `--token` exits with `error: --token is required when binding to a non-loopback host`. With a token set, every `/sse` and `/messages` request must send `Authorization: Bearer <token>`. Defaults: 1 MB body cap, 64 concurrent sessions, 5-minute idle timeout. Token can also come from the `DIRECTIVE_MCP_TOKEN` environment variable.
54
162
 
55
163
  Endpoints:
56
164
 
@@ -58,7 +166,7 @@ Endpoints:
58
166
  - `POST /messages?sessionId=…` — client→server JSON-RPC messages.
59
167
  - `GET /healthz` — liveness probe.
60
168
 
61
- ## Tools (20)
169
+ ## Tools (21)
62
170
 
63
171
  ### Knowledge
64
172
 
@@ -76,24 +184,24 @@ Endpoints:
76
184
  | Tool | Purpose |
77
185
  |---|---|
78
186
  | `list_packages` | Every `@directive-run/*` package with one-line description. |
79
- | `get_package_info` | Single-package detail (baked metadata + live npm version, 1 h cache). |
80
- | `get_composable_packages` | Outgoing and incoming composition edges for one package. |
187
+ | `get_package_info` | Single-package detail (baked metadata + live npm version, 1 h cache, 3 s timeout, falls back to baked on failure). |
188
+ | `get_composable_packages` | Outgoing and incoming composition edges for one package. Returns `isError: true` with `NOT_FOUND` prefix when the package isn't known. |
81
189
 
82
190
  ### Generate
83
191
 
84
192
  | Tool | Purpose |
85
193
  |---|---|
86
- | `generate_module` | Generate NEW Directive module or AI orchestrator source. Returns the source string; never writes to disk. |
87
- | `list_module_sections` | Enumerate the valid `sections` values for `generate_module`. |
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 — no hallucinated enum values). |
88
196
 
89
197
  ### Review
90
198
 
91
199
  | Tool | Purpose |
92
200
  |---|---|
93
- | `list_review_rules` | Directive anti-patterns and ts-morph rules as structured data. |
201
+ | `list_review_rules` | All 10 ts-morph rules as structured data (id, severity, category, title). |
94
202
  | `get_review_rule` | One rule's full detail: WRONG/CORRECT example pair + explanation. |
95
- | `review_source` | Run the rule registry against a TypeScript source string. Returns structured findings. |
96
- | `fix_code` | Apply a rule's mechanical fix; returns diff + fixed source. |
203
+ | `review_source` | Run the rule registry against a TypeScript source string. Pre-parse 200 KB cap, 5-second budget enforced via `worker.terminate()`. Returns structured findings. |
204
+ | `fix_code` | Apply a rule's mechanical fix; returns diff + fixed source. 6 of 10 rules ship a fix; the rest return `{ ok: false, reason }`. |
97
205
 
98
206
  ### Migration
99
207
 
@@ -113,7 +221,26 @@ Endpoints:
113
221
 
114
222
  | Tool | Purpose |
115
223
  |---|---|
116
- | `get_server_info` | Version + transport + auth state + bundled-knowledge hash + session count. |
224
+ | `get_server_info` | Version + transport + auth state + bundled-knowledge hash + session count + package-registry timestamp. |
225
+
226
+ ### Playground
227
+
228
+ | Tool | Purpose |
229
+ |---|---|
230
+ | `playground_link` | Turn any TypeScript snippet (≤ 8 KB) into a `directive.run/playground` URL. The page decompresses the source from the URL hash, shows it with syntax highlighting, and offers a one-click **Open in StackBlitz** button that boots a real running Directive project with the snippet as `src/main.ts`. Pair it with any tool that returns code — `generate_module`, `get_example`, `fix_code` — to give the user a "try it now" link in chat. |
231
+
232
+ ## Troubleshooting
233
+
234
+ The four most common first-time failures:
235
+
236
+ | Symptom | What's happening | Fix |
237
+ |---|---|---|
238
+ | 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). |
239
+ | `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. |
240
+ | `--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. |
241
+ | `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. |
242
+
243
+ If a tool errors mid-conversation, the fastest recovery is: *"Ask the directive MCP server's `get_server_info` tool to verify connectivity."*
117
244
 
118
245
  ## Programmatic embedding
119
246
 
@@ -133,8 +260,10 @@ const httpServer = await startSseServer({ port: 3000, host: "0.0.0.0" });
133
260
 
134
261
  ## See also
135
262
 
136
- - [`@directive-run/ai/mcp`](../ai) — the MCP **client** side of Directive. Use it inside a Directive AI agent to call out to external MCP servers.
137
- - [`@directive-run/knowledge`](../knowledge) — the knowledge package this server fronts.
138
- - [`@directive-run/claude-plugin`](../claude-plugin) — the Claude Code skill bundles also exposed.
139
- - [`@directive-run/cli`](../cli) — generate static `.cursorrules` / `CLAUDE.md` / `.windsurfrules` files for assistants that don't speak MCP.
140
- - [docs/ide-integration](https://directive.run/docs/ide-integration) — decision tree across every install path.
263
+ - [`@directive-run/ai/mcp`](../ai) — adapts external MCP servers as Directive resolvers (the *client* side; opposite arrow from this package).
264
+ - [`@directive-run/knowledge`](../knowledge) — markdown + JSON sources this server fronts.
265
+ - [`@directive-run/lint`](../lint) — the ts-morph rule registry behind `review_source` and `fix_code`.
266
+ - [`@directive-run/scaffold`](../scaffold) — the pure-function generators behind `generate_module`.
267
+ - [`@directive-run/claude-plugin`](../claude-plugin) — the Claude Code skill bundles also exposed via `get_skill`.
268
+ - [`@directive-run/cli`](../cli) — generates static `.cursorrules` / `CLAUDE.md` / `.windsurfrules` files for assistants that don't speak MCP.
269
+ - [directive.run/docs/ide-integration](https://directive.run/docs/ide-integration) — the cross-editor decision tree.
package/dist/cli.js CHANGED
@@ -1,49 +1,51 @@
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 {createServer}from'http';import {SSEServerTransport}from'@modelcontextprotocol/sdk/server/sse.js';var k=[{name:"@directive-run/ai",version:"1.17.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.17.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.17.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.17.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.0",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.17.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.1",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:[".","./worker"],directory:"lint",published:true},{name:"@directive-run/lit",version:"1.17.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.2.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/scaffold","@modelcontextprotocol/sdk","zod"],peerDependencies:[],optionalDependencies:["ts-morph"],exports:["."],directory:"mcp",published:true},{name:"@directive-run/mutator",version:"0.3.1",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.0",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.17.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/scaffold",version:"0.1.0",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.17.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/svelte",version:"1.17.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.1",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.17.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}],E="2026-06-04T01:56:10.722Z";var T=2e5,D=5e3,ee=/^[\w./-]{1,128}$/,l=class extends Error{constructor(r,i){super(r);this.code=i;}};function I(e){let t=Buffer.byteLength(e.source,"utf8");if(t>T)throw new l(`source is ${t} bytes (max ${T})`,"source-too-large");let r="fileName"in e?e.fileName:void 0;if(r!==void 0&&!ee.test(r))throw new l("invalid fileName","bad-filename")}async function te(){let e=await import.meta.resolve("@directive-run/lint/worker");return fileURLToPath(e)}async function R(e){let t=await te(),r=new Worker(t,{stderr:false}),i=null;try{return await new Promise((n,s)=>{let c=!1;r.once("message",a=>{c=!0,a.ok&&a.result!==void 0?n(a.result):s(new l(a.error??"worker returned without result","worker-error"));}),r.once("error",a=>{c=!0,s(new l(a.message,"worker-error"));}),r.once("exit",a=>{!c&&a!==0&&a!==null&&s(new l(`worker exited with code ${a} before responding`,"worker-error"));}),i=setTimeout(()=>{r.terminate(),s(new l(`parse exceeded ${D}ms budget`,"timeout"));},D),r.postMessage(e);})}finally{i&&clearTimeout(i),await r.terminate().catch(()=>{});}}function $(){return process.env.DIRECTIVE_MCP_USE_LINT_WORKER==="1"}async function C(e){return I(e),$()?R({kind:"run",source:e.source,options:{fileName:e.fileName,ruleFilter:e.ruleFilter}}):runRules(e.source,{fileName:e.fileName,ruleFilter:e.ruleFilter})}async function P(e){return I(e),$()?R({kind:"fix",source:e.source,finding:e.finding}):applyFix(e.source,e.finding)}var re=3600*1e3,ie=3e3,A=new Map;function O(){return k.map(e=>({name:e.name,summary:e.description,published:e.published}))}async function L(e){let t=k.find(n=>n.name===e);if(!t)return;let{liveVersion:r,stale:i}=await se(t);return ne(t,r,i)}function ne(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 se(e){if(!e.published)return {stale:true};let t=A.get(e.name);if(t&&Date.now()-t.fetchedAt<re)return {liveVersion:t.liveVersion,stale:t.liveVersion===void 0};let r=await oe(e.name);return A.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 oe(e){let t=`https://registry.npmjs.org/${encodeURIComponent(e).replace(/%2F/g,"/")}/latest`,r=new AbortController,i=setTimeout(()=>r.abort(),ie);try{let n=await fetch(t,{signal:r.signal});if(!n.ok)return {error:`HTTP ${n.status}`};let s=await n.json();return typeof s.version=="string"?{liveVersion:s.version}:{error:"no version field"}}catch(n){return {error:n.message}}finally{clearTimeout(i);}}var N="0.2.2",j=50,V=200,F=512;function Se(e){return e.length>V?`${e.slice(0,V)}\u2026`:e}function U(e,t,r){let i=e.toLowerCase(),n=[];for(let[s,c]of t){let a=c.split(`
3
- `);for(let d=0;d<a.length;d++){let u=a[d];if(u.toLowerCase().includes(i)&&(n.push(`${s}${r}:${d+1}: ${Se(u)}`),n.length>=j))return n}}return n}function G(e,t){return t.length===0?`No matches for '${e}'.`:`${t.length===j?`${t.length}+ matches (truncated):`:`${t.length} matches:`}
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 {compressToEncodedURIComponent}from'lz-string';import {createServer}from'http';import {SSEServerTransport}from'@modelcontextprotocol/sdk/server/sse.js';var b=[{name:"@directive-run/ai",version:"1.17.1",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.17.1",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.17.1",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.17.1",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.0",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.17.1",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.17.1",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.3.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/scaffold","@modelcontextprotocol/sdk","lz-string","zod"],peerDependencies:[],optionalDependencies:["ts-morph"],exports:["."],directory:"mcp",published:true},{name:"@directive-run/mutator",version:"0.3.1",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.0",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.17.1",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/scaffold",version:"0.1.0",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.17.1",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/svelte",version:"1.17.1",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.1",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.17.1",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}],$="2026-06-04T05:24:29.642Z";var I=2e5,P=5e3,ie=/^[\w./-]{1,128}$/,l=class extends Error{constructor(r,n){super(r);this.code=n;}};function C(e){let t=Buffer.byteLength(e.source,"utf8");if(t>I)throw new l(`source is ${t} bytes (max ${I})`,"source-too-large");let r="fileName"in e?e.fileName:void 0;if(r!==void 0&&!ie.test(r))throw new l("invalid fileName","bad-filename")}async function se(){let e=await import.meta.resolve("@directive-run/lint/worker");return fileURLToPath(e)}async function L(e){let t=await se(),r=new Worker(t,{stderr:false}),n=null;try{return await new Promise((i,s)=>{let c=!1;r.once("message",a=>{c=!0,a.ok&&a.result!==void 0?i(a.result):s(new l(a.error??"worker returned without result","worker-error"));}),r.once("error",a=>{c=!0,s(new l(a.message,"worker-error"));}),r.once("exit",a=>{!c&&a!==0&&a!==null&&s(new l(`worker exited with code ${a} before responding`,"worker-error"));}),n=setTimeout(()=>{r.terminate(),s(new l(`parse exceeded ${P}ms budget`,"timeout"));},P),r.postMessage(e);})}finally{n&&clearTimeout(n),await r.terminate().catch(()=>{});}}function O(){return !(process.env.DIRECTIVE_MCP_USE_LINT_WORKER==="0"||process.env.VITEST==="true")}async function A(e){return C(e),O()?L({kind:"run",source:e.source,options:{fileName:e.fileName,ruleFilter:e.ruleFilter}}):runRules(e.source,{fileName:e.fileName,ruleFilter:e.ruleFilter})}async function M(e){return C(e),O()?L({kind:"fix",source:e.source,finding:e.finding}):applyFix(e.source,e.finding)}var oe=3600*1e3,ae=3e3,N=new Map;function S(){return b.map(e=>({name:e.name,summary:e.description,published:e.published}))}async function U(e){let t=b.find(i=>i.name===e);if(!t)return;let{liveVersion:r,stale:n}=await le(t);return ce(t,r,n)}function ce(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 le(e){if(!e.published)return {stale:true};let t=N.get(e.name);if(t&&Date.now()-t.fetchedAt<oe)return {liveVersion:t.liveVersion,stale:t.liveVersion===void 0};let r=await de(e.name);return N.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 de(e){let t=`https://registry.npmjs.org/${encodeURIComponent(e).replace(/%2F/g,"/")}/latest`,r=new AbortController,n=setTimeout(()=>r.abort(),ae);try{let i=await fetch(t,{signal:r.signal});if(!i.ok)return {error:`HTTP ${i.status}`};let s=await i.json();return typeof s.version=="string"?{liveVersion:s.version}:{error:"no version field"}}catch(i){return {error:i.message}}finally{clearTimeout(n);}}var g=8e3,pe="https://directive.run/playground",m=class extends Error{constructor(r,n){super(r);this.code=n;}};function ge(e){if(e.length===0)throw new m("source is empty","source-empty");let t=Buffer.byteLength(e,"utf8");if(t>g)throw new m(`source is ${t} bytes (max ${g}). Snippets larger than ${g} bytes don't fit reliably in a URL \u2014 copy the source into a fresh Stackblitz project instead.`,"source-too-large")}function me(e){return encodeURIComponent(e)}function V(e){ge(e.source);let r=[`src=${compressToEncodedURIComponent(e.source)}`];e.title&&r.push(`t=${me(e.title)}`);let n=`${pe}#${r.join("&")}`;return {url:n,sizeBytes:Buffer.byteLength(e.source,"utf8"),urlBytes:Buffer.byteLength(n,"utf8"),title:e.title}}var F="0.3.0",W=50,j=200,G=512;function Pe(e){return e.length>j?`${e.slice(0,j)}\u2026`:e}function H(e,t,r){let n=e.toLowerCase(),i=[];for(let[s,c]of t){let a=c.split(`
3
+ `);for(let d=0;d<a.length;d++){let p=a[d];if(p.toLowerCase().includes(n)&&(i.push(`${s}${r}:${d+1}: ${Pe(p)}`),i.length>=W))return i}}return i}function K(e,t){return t.length===0?`No matches for '${e}'.`:`${t.length===W?`${t.length}+ matches (truncated):`:`${t.length} matches:`}
4
4
  ${t.join(`
5
- `)}`}var v=null;function _e(){if(v)return v;let e=createHash("sha256");for(let[t,r]of Array.from(getAllKnowledge()).sort(([i],[n])=>i.localeCompare(n)))e.update(t),e.update("\0"),e.update(r),e.update("\0");return v=e.digest("hex").slice(0,16),v}var g={transport:"stdio",authEnabled:false};function f(e){g=e;}function h(e,t,r){r.length!==0&&e.push("",`**${t}:**`,...r.map(i=>`- ${i}`));}function Ee(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}`),h(t,"Dependencies",e.dependencies),h(t,"Peer dependencies",e.peerDependencies),h(t,"Optional dependencies",e.optionalDependencies),h(t,"Exports",e.exports),t.join(`
6
- `)}function y(){let e=new McpServer({name:"directive",version:N});return e.registerTool("list_knowledge",{title:"List Directive knowledge files",description:"List every knowledge file shipped in @directive-run/knowledge. Returns the file names (without .md) that can be passed to get_knowledge. Covers core docs (engine, facts, constraints, resolvers, derivations, effects, plugins, modules, systems, testing) and AI docs (orchestrator, agents, adapters, guardrails, memory, MCP, RAG, security, evals, budget, multi-agent).",inputSchema:{}},async()=>{let t=getAllKnowledge(),r=Array.from(t.keys()).sort();return {content:[{type:"text",text:`${r.length} knowledge files:
5
+ `)}`}var f=null;function Ce(){if(f)return f;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 f=e.digest("hex").slice(0,16),f}var h={transport:"stdio",authEnabled:false};function k(e){h=e;}function y(e,t,r){r.length!==0&&e.push("",`**${t}:**`,...r.map(n=>`- ${n}`));}function Le(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}`),y(t,"Dependencies",e.dependencies),y(t,"Peer dependencies",e.peerDependencies),y(t,"Optional dependencies",e.optionalDependencies),y(t,"Exports",e.exports),t.join(`
6
+ `)}function w(){let e=new McpServer({name:"directive",version:F});return e.registerTool("list_knowledge",{title:"List Directive knowledge files",description:"List every knowledge file shipped in @directive-run/knowledge. Returns the file names (without .md) that can be passed to get_knowledge. Covers core docs (engine, facts, constraints, resolvers, derivations, effects, plugins, modules, systems, testing) and AI docs (orchestrator, agents, adapters, guardrails, memory, MCP, RAG, security, evals, budget, multi-agent).",inputSchema:{}},async()=>{let t=getAllKnowledge(),r=Array.from(t.keys()).sort();return {content:[{type:"text",text:`${r.length} knowledge files:
7
7
  ${r.join(`
8
8
  `)}`}]}}),e.registerTool("get_knowledge",{title:"Get a Directive knowledge file",description:"Fetch the full Markdown contents of one Directive knowledge file by name. Use list_knowledge first to discover available names. Names match the file stem (e.g. 'constraints', 'ai-orchestrator', 'api-skeleton').",inputSchema:{name:z$1.string().min(1).describe("The knowledge file name (no .md suffix). Example: 'constraints', 'ai-orchestrator', 'api-skeleton'.")}},async({name:t})=>{let r=getKnowledge(t);return r?{content:[{type:"text",text:r}]}:{isError:true,content:[{type:"text",text:`Knowledge file not found: '${t}'. Call list_knowledge to see available names.`}]}}),e.registerTool("list_examples",{title:"List Directive code examples",description:"List every code example shipped in @directive-run/knowledge. Examples are minimal, working TypeScript files demonstrating one concept each. Pass the returned names to get_example.",inputSchema:{}},async()=>{let t=getAllExamples(),r=Array.from(t.keys()).sort();return {content:[{type:"text",text:`${r.length} examples:
9
9
  ${r.join(`
10
10
  `)}`}]}}),e.registerTool("get_example",{title:"Get a Directive code example",description:"Fetch the source of one Directive code example by name. Use list_examples first to discover available names. Returns raw TypeScript.",inputSchema:{name:z$1.string().min(1).describe("The example file name (no .ts suffix). Example: 'basic-module', 'ai-orchestrator'.")}},async({name:t})=>{let r=getExample(t);return r?{content:[{type:"text",text:`\`\`\`typescript
11
11
  ${r}
12
- \`\`\``}]}:{isError:true,content:[{type:"text",text:`Example not found: '${t}'. Call list_examples to see available names.`}]}}),e.registerTool("search_knowledge",{title:"Search Directive knowledge files",description:"Case-insensitive substring search across every knowledge file. Returns existing reference material; does NOT generate code. Use this to find which knowledge file covers a topic before calling get_knowledge for the full document.",inputSchema:{query:z$1.string().min(1).max(F).describe("The search string. Matched case-insensitively against every line of every knowledge file.")}},async({query:t})=>{let r=U(t,getAllKnowledge(),".md");return {content:[{type:"text",text:G(t,r)}]}}),e.registerTool("search_examples",{title:"Search Directive code examples",description:"Case-insensitive substring search across every bundled code example (.ts files in @directive-run/knowledge). Returns existing reference material; does NOT generate code. Use this to find which example demonstrates a concept before calling get_example for the full source.",inputSchema:{query:z$1.string().min(1).max(F).describe("The search string. Matched case-insensitively against every line of every example file.")}},async({query:t})=>{let r=U(t,getAllExamples(),".ts");return {content:[{type:"text",text:G(t,r)}]}}),e.registerTool("list_packages",{title:"List @directive-run/* packages",description:"Enumerate every @directive-run/* package known to this MCP server. Returns name + one-line description. Use this to answer 'what should I install for X?' and to discover names to pass to get_package_info or get_composable_packages. Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>{let t=O(),r=t.map(i=>`${i.name}${i.published?"":" (private)"} \u2014 ${i.summary}`);return {content:[{type:"text",text:`${t.length} packages:
12
+ \`\`\``}]}:{isError:true,content:[{type:"text",text:`Example not found: '${t}'. Call list_examples to see available names.`}]}}),e.registerTool("search_knowledge",{title:"Search Directive knowledge files",description:"Case-insensitive substring search across every knowledge file. Returns existing reference material; does NOT generate code. Use this to find which knowledge file covers a topic before calling get_knowledge for the full document.",inputSchema:{query:z$1.string().min(1).max(G).describe("The search string. Matched case-insensitively against every line of every knowledge file.")}},async({query:t})=>{let r=H(t,getAllKnowledge(),".md");return {content:[{type:"text",text:K(t,r)}]}}),e.registerTool("search_examples",{title:"Search Directive code examples",description:"Case-insensitive substring search across every bundled code example (.ts files in @directive-run/knowledge). Returns existing reference material; does NOT generate code. Use this to find which example demonstrates a concept before calling get_example for the full source.",inputSchema:{query:z$1.string().min(1).max(G).describe("The search string. Matched case-insensitively against every line of every example file.")}},async({query:t})=>{let r=H(t,getAllExamples(),".ts");return {content:[{type:"text",text:K(t,r)}]}}),e.registerTool("list_packages",{title:"List @directive-run/* packages",description:"Enumerate every @directive-run/* package known to this MCP server. Returns name + one-line description. Use this to answer 'what should I install for X?' and to discover names to pass to get_package_info or get_composable_packages. Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>{let t=S(),r=t.map(n=>`${n.name}${n.published?"":" (private)"} \u2014 ${n.summary}`);return {content:[{type:"text",text:`${t.length} packages:
13
13
  ${r.join(`
14
- `)}`}]}}),e.registerTool("get_package_info",{title:"Get @directive-run/* package detail",description:"Fetch detailed info for one @directive-run/* package: description, dependencies, peerDependencies, exports, npm URL. Returns the version baked into this MCP build AND the live-from-npm version when available (1-hour cache, 3-second timeout, falls back to baked version on network failure). Returns existing reference material; does NOT generate code.",inputSchema:{name:z$1.string().min(1).max(128).describe("Package name (e.g. '@directive-run/core'). Call list_packages first to discover valid names.")}},async({name:t})=>{let r=await L(t);return r?{content:[{type:"text",text:Ee(r)}]}:{isError:true,content:[{type:"text",text:`Package not found: '${t}'. Call list_packages to see available names.`}]}}),e.registerTool("get_composable_packages",{title:"Get composition siblings for a package",description:"Given a @directive-run/* package name, return the sibling packages it composes with (outgoing edges) AND the packages that compose with IT (incoming edges). Each edge carries a one-line reason. Returns existing reference material; does NOT generate code. Use this to answer 'what should I pair @directive-run/X with?' or 'who else uses @directive-run/Y?'.",inputSchema:{name:z$1.string().min(1).max(128).describe("Package name (e.g. '@directive-run/query'). Call list_packages first to discover valid names.")}},async({name:t})=>{let r=getCompositionsFor(t),i=getReverseCompositionsFor(t);if(r.length===0&&i.length===0)return {content:[{type:"text",text:`No composition data for '${t}'. Call list_packages to see available names.`}]};let n=[`# ${t}`,""];if(r.length>0){n.push("## Composes with:");for(let s of r)n.push(`- ${s.to} \u2014 ${s.reason}`);n.push("");}if(i.length>0){n.push("## Composed by:");for(let s of i)n.push(`- ${s.from} \u2014 ${s.reason}`);}return {content:[{type:"text",text:`<directive-data>
15
- ${n.join(`
14
+ `)}`}]}}),e.registerTool("get_package_info",{title:"Get @directive-run/* package detail",description:"Fetch detailed info for one @directive-run/* package: description, dependencies, peerDependencies, exports, npm URL. Returns the version baked into this MCP build AND the live-from-npm version when available (1-hour cache, 3-second timeout, falls back to baked version on network failure). Returns existing reference material; does NOT generate code.",inputSchema:{name:z$1.string().min(1).max(128).describe("Package name (e.g. '@directive-run/core'). Call list_packages first to discover valid names.")}},async({name:t})=>{let r=await U(t);return r?{content:[{type:"text",text:Le(r)}]}:{isError:true,content:[{type:"text",text:`Package not found: '${t}'. Call list_packages to see available names.`}]}}),e.registerTool("get_composable_packages",{title:"Get composition siblings for a package",description:"Given a @directive-run/* package name, return the sibling packages it composes with (outgoing edges) AND the packages that compose with IT (incoming edges). Each edge carries a one-line reason. Returns existing reference material; does NOT generate code. Use this to answer 'what should I pair @directive-run/X with?' or 'who else uses @directive-run/Y?'.",inputSchema:{name:z$1.string().min(1).max(128).describe("Package name (e.g. '@directive-run/query'). Call list_packages first to discover valid names.")}},async({name:t})=>{let r=getCompositionsFor(t),n=getReverseCompositionsFor(t);if(r.length===0&&n.length===0)return {isError:true,content:[{type:"text",text:S().some(c=>c.name===t)?`NO_COMPOSITIONS: '${t}' is a known package but has no composition edges yet. This is a coverage gap in compositions.json.`:`NOT_FOUND: '${t}' is not a known @directive-run/* package. Call list_packages to see available names.`}]};let i=[`# ${t}`,""];if(r.length>0){i.push("## Composes with:");for(let s of r)i.push(`- ${s.to} \u2014 ${s.reason}`);i.push("");}if(n.length>0){i.push("## Composed by:");for(let s of n)i.push(`- ${s.from} \u2014 ${s.reason}`);}return {content:[{type:"text",text:`<directive-data>
15
+ ${i.join(`
16
16
  `)}
17
- </directive-data>`}]}}),e.registerTool("get_server_info",{title:"Get directive MCP server info",description:"Return version manifest for this MCP server build \u2014 package version, transport (stdio or SSE), whether auth is enabled, bundled-knowledge hash, package-registry build timestamp, and (for SSE) the current session count. Returns existing reference material; does NOT generate code. Use this to verify the client is talking to the expected build.",inputSchema:{}},async()=>{let t=[`# @directive-run/mcp@${N}`,`**Transport:** ${g.transport}`,`**Auth enabled:** ${g.authEnabled?"yes":"no"}`,`**Bundled knowledge hash:** ${_e()}`,`**Package registry built at:** ${E}`];return g.sessionCount!==void 0&&t.push(`**Active SSE sessions:** ${g.sessionCount}`),{content:[{type:"text",text:t.join(`
17
+ </directive-data>`}]}}),e.registerTool("get_server_info",{title:"Get directive MCP server info",description:"Return version manifest for this MCP server build \u2014 package version, transport (stdio or SSE), whether auth is enabled, bundled-knowledge hash, package-registry build timestamp, and (for SSE) the current session count. Returns existing reference material; does NOT generate code. Use this to verify the client is talking to the expected build.",inputSchema:{}},async()=>{let t=[`# @directive-run/mcp@${F}`,`**Transport:** ${h.transport}`,`**Auth enabled:** ${h.authEnabled?"yes":"no"}`,`**Bundled knowledge hash:** ${Ce()}`,`**Package registry built at:** ${$}`];return h.sessionCount!==void 0&&t.push(`**Active SSE sessions:** ${h.sessionCount}`),{content:[{type:"text",text:t.join(`
18
18
  `)}]}}),e.registerTool("list_module_sections",{title:"List valid module sections for generate_module",description:"Enumerate the valid `sections` values that `generate_module` accepts: derive, events, constraints, resolvers, effects. Call this before generate_module so the section list comes from the server (no hallucination risk). Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>({content:[{type:"text",text:`${MODULE_SECTIONS.length} module sections:
19
19
  ${MODULE_SECTIONS.join(`
20
- `)}`}]})),e.registerTool("generate_module",{title:"Generate NEW Directive module source code",description:'Generate the source string for a new Directive module or AI orchestrator. Use this when the user wants to CREATE a module, not learn about one. Returns the source as text; never writes to disk \u2014 the caller decides where to put it. Strict regex on `name` (kebab-case, \u226464 chars). For `kind: "module"`, optionally pass `sections` to pick which blocks to include (default: every section). Discover valid section values via list_module_sections.',inputSchema:{name:z$1.string().min(1).max(64).describe("Kebab-case identifier (e.g. 'traffic-light'). Must start with a lowercase letter and contain only lowercase letters, digits, and hyphens."),kind:z$1.enum(["module","orchestrator"]).default("module").describe("What to generate. 'module' for a plain Directive module; 'orchestrator' for an AI agent orchestrator module with memory + guardrails scaffolding."),sections:z$1.array(z$1.enum(MODULE_SECTIONS)).optional().describe("Which module sections to include. Defaults to every section. Only honored when kind === 'module'. Discover valid values via list_module_sections.")}},async({name:t,kind:r,sections:i})=>{let n=validateModuleName(t);if(n!==true)return {isError:true,content:[{type:"text",text:`Invalid name '${t}': ${n}`}]};try{let s=r==="orchestrator"?generateOrchestrator(t):generateModule(t,i??MODULE_SECTIONS),{sourceFileName:c,testFileName:a}=suggestFileNames(t,r),d=requiredPackages(r);return {content:[{type:"text",text:[`// Suggested file: src/${c}`,`// Suggested test: src/${a}`,`// Required packages: ${d.join(", ")}`,`// Run: pnpm add ${d.join(" ")}`,"",s].join(`
21
- `)}]}}catch(s){return {isError:true,content:[{type:"text",text:s.message}]}}}),e.registerTool("list_review_rules",{title:"List Directive code-review rules",description:"Enumerate every anti-pattern Directive code can violate, parsed from @directive-run/knowledge. Each entry carries an id, severity, category, title, badExample, goodExample, and explanation. Use this to discover rule ids before calling get_review_rule or before passing ruleFilter to review_source. Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>{let t=getAntiPatterns(),r=t.map(i=>({id:i.id,severity:i.severity,category:i.category,title:i.title}));return {content:[{type:"text",text:`<directive-data>
20
+ `)}`}]})),e.registerTool("generate_module",{title:"Generate NEW Directive module source code",description:'Generate the source string for a new Directive module or AI orchestrator. Use this when the user wants to CREATE a module, not learn about one. Returns the source as text; never writes to disk \u2014 the caller decides where to put it. Strict regex on `name` (kebab-case, \u226464 chars). For `kind: "module"`, optionally pass `sections` to pick which blocks to include (default: every section). Discover valid section values via list_module_sections.',inputSchema:{name:z$1.string().min(1).max(64).describe("Kebab-case identifier (e.g. 'traffic-light'). Must start with a lowercase letter and contain only lowercase letters, digits, and hyphens."),kind:z$1.enum(["module","orchestrator"]).default("module").describe("What to generate. 'module' for a plain Directive module; 'orchestrator' for an AI agent orchestrator module with memory + guardrails scaffolding."),sections:z$1.array(z$1.enum(MODULE_SECTIONS)).optional().describe("Which module sections to include. Defaults to every section. Only honored when kind === 'module'. Discover valid values via list_module_sections.")}},async({name:t,kind:r,sections:n})=>{let i=validateModuleName(t);if(i!==true)return {isError:true,content:[{type:"text",text:`Invalid name '${t}': ${i}`}]};try{let s=r==="orchestrator"?generateOrchestrator(t):generateModule(t,n??MODULE_SECTIONS),{sourceFileName:c,testFileName:a}=suggestFileNames(t,r),d=requiredPackages(r);return {content:[{type:"text",text:[`// Suggested file: src/${c}`,`// Suggested test: src/${a}`,`// Required packages: ${d.join(", ")}`,`// Run: pnpm add ${d.join(" ")}`,"",s].join(`
21
+ `)}]}}catch(s){return {isError:true,content:[{type:"text",text:s.message}]}}}),e.registerTool("list_review_rules",{title:"List Directive code-review rules",description:"Enumerate every anti-pattern Directive code can violate, parsed from @directive-run/knowledge. Each entry carries an id, severity, category, title, badExample, goodExample, and explanation. Use this to discover rule ids before calling get_review_rule or before passing ruleFilter to review_source. Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>{let t=getAntiPatterns(),r=t.map(n=>({id:n.id,severity:n.severity,category:n.category,title:n.title}));return {content:[{type:"text",text:`<directive-data>
22
22
  ${t.length} review rules:
23
23
  ${JSON.stringify(r,null,2)}
24
- </directive-data>`}]}}),e.registerTool("get_review_rule",{title:"Get a Directive code-review rule",description:"Fetch one anti-pattern's full detail: title, severity, category, explanation, and the WRONG/CORRECT code-example pair. Use list_review_rules first to discover valid ids. Returns existing reference material; does NOT generate code.",inputSchema:{id:z$1.string().min(1).max(128).describe("Rule id (a kebab-case slug \u2014 e.g. 'flat-schema-missing-facts-wrapper'). Call list_review_rules first to discover valid ids.")}},async({id:t})=>{let r=getAntiPatternById(t);if(!r)return {isError:true,content:[{type:"text",text:`Rule not found: '${t}'. Call list_review_rules to see available ids.`}]};let i=[`# ${r.title}`,`**id:** ${r.id}`,`**severity:** ${r.severity}`,`**category:** ${r.category}`];return r.explanation&&i.push("",r.explanation),r.badExample&&i.push("","## Wrong","```typescript",r.badExample,"```"),r.goodExample&&i.push("","## Correct","```typescript",r.goodExample,"```"),{content:[{type:"text",text:`<directive-data>
25
- ${i.join(`
24
+ </directive-data>`}]}}),e.registerTool("get_review_rule",{title:"Get a Directive code-review rule",description:"Fetch one anti-pattern's full detail: title, severity, category, explanation, and the WRONG/CORRECT code-example pair. Use list_review_rules first to discover valid ids. Returns existing reference material; does NOT generate code.",inputSchema:{id:z$1.string().min(1).max(128).describe("Rule id (a kebab-case slug \u2014 e.g. 'flat-schema-missing-facts-wrapper'). Call list_review_rules first to discover valid ids.")}},async({id:t})=>{let r=getAntiPatternById(t);if(!r)return {isError:true,content:[{type:"text",text:`Rule not found: '${t}'. Call list_review_rules to see available ids.`}]};let n=[`# ${r.title}`,`**id:** ${r.id}`,`**severity:** ${r.severity}`,`**category:** ${r.category}`];return r.explanation&&n.push("",r.explanation),r.badExample&&n.push("","## Wrong","```typescript",r.badExample,"```"),r.goodExample&&n.push("","## Correct","```typescript",r.goodExample,"```"),{content:[{type:"text",text:`<directive-data>
25
+ ${n.join(`
26
26
  `)}
27
27
  </directive-data>`}]}}),e.registerTool("list_migration_sources",{title:"List supported migration source libraries",description:"Enumerate the source libraries get_migration_pattern accepts: redux, zustand, xstate, mobx, jotai, recoil. Call this before get_migration_pattern so the source list comes from the server (no hallucination risk). Returns existing reference material; does NOT generate code.",inputSchema:{}},async()=>({content:[{type:"text",text:`${MIGRATION_SOURCES.length} sources:
28
28
  ${MIGRATION_SOURCES.join(`
29
29
  `)}`}]})),e.registerTool("get_migration_pattern",{title:"Get migration pattern from a state-management library",description:"Fetch the concept-mapping table + step list + before/after exemplars for migrating from a popular state-management library to Directive. Use this when a user asks 'how do I migrate from Redux / Zustand / XState / MobX / Jotai / Recoil'. Returns existing reference material; does NOT generate code.",inputSchema:{source:z$1.enum(MIGRATION_SOURCES).describe("Source library. Discover valid values via list_migration_sources.")}},async({source:t})=>{let r=getMigrationPattern(t);return r?{content:[{type:"text",text:`<directive-data>
30
- ${[`# Migrating from ${r.name} to Directive`,"","## Concept map","","| From | To | Note |","|---|---|---|",...r.conceptMap.map(n=>`| ${n.from} | ${n.to} | ${n.note} |`),"","## Steps",...r.steps.map((n,s)=>`${s+1}. ${n}`),"","## Before","```typescript",r.before,"```","","## After","```typescript",r.after,"```"].join(`
30
+ ${[`# Migrating from ${r.name} to Directive`,"","## Concept map","","| From | To | Note |","|---|---|---|",...r.conceptMap.map(i=>`| ${i.from} | ${i.to} | ${i.note} |`),"","## Steps",...r.steps.map((i,s)=>`${s+1}. ${i}`),"","## Before","```typescript",r.before,"```","","## After","```typescript",r.after,"```"].join(`
31
31
  `)}
32
- </directive-data>`}]}:{isError:true,content:[{type:"text",text:`Migration pattern not found: '${t}'. Call list_migration_sources to see valid values.`}]}}),e.registerTool("review_source",{title:"Review Directive code with ts-morph rules",description:"Run the @directive-run/lint rule registry against a TypeScript source string. Returns structured findings (line, column, severity, message, fixable) for every match. Use this when the user asks 'review this Directive code' or 'lint this'. Source is parsed in a worker thread with a 5-second budget and 200 KB cap.",inputSchema:{source:z$1.string().min(1).max(2e5).describe("TypeScript source to review. Max 200,000 bytes; longer inputs are rejected pre-parse."),fileName:z$1.string().regex(/^[\w./-]{1,128}$/).optional().describe("Optional file name shown in findings. Must match /^[\\w./-]{1,128}$/."),ruleFilter:z$1.array(z$1.string().max(64)).max(32).optional().describe("Optional whitelist of rule ids to run. Discover valid ids via list_review_rules.")}},async({source:t,fileName:r,ruleFilter:i})=>{try{let n=await C({source:t,fileName:r,ruleFilter:i});return {content:[{type:"text",text:`<directive-data>
33
- ${JSON.stringify(n,null,2)}
34
- </directive-data>`}]}}catch(n){return {isError:true,content:[{type:"text",text:`review_source failed \u2014 ${n instanceof l?`${n.code}: ${n.message}`:n.message}`}]}}}),e.registerTool("fix_code",{title:"Apply a mechanical fix for a Directive review finding",description:"Given a source string and a Finding returned by review_source, run the rule's mechanical fix and return { ok, diff, fixedSource, explanation } \u2014 or { ok: false, reason } when the rule has no fix. Useful for closing the loop: review_source \u2192 user picks \u2192 fix_code. The fixed source is NOT written to disk \u2014 the caller decides.",inputSchema:{source:z$1.string().min(1).max(2e5).describe("The same source you passed to review_source."),finding:z$1.object({ruleId:z$1.string().min(1).max(64),severity:z$1.enum(["error","warning","info"]),line:z$1.number().int().nonnegative(),column:z$1.number().int().nonnegative(),message:z$1.string(),findingId:z$1.string(),suggestion:z$1.string().optional()}).describe("The Finding returned by review_source. Pass the WHOLE object \u2014 the worker uses ruleId + line + column to locate the AST node.")}},async({source:t,finding:r})=>{try{let i=await P({source:t,finding:r});return {content:[{type:"text",text:`<directive-data>
32
+ </directive-data>`}]}:{isError:true,content:[{type:"text",text:`Migration pattern not found: '${t}'. Call list_migration_sources to see valid values.`}]}}),e.registerTool("review_source",{title:"Review Directive code with ts-morph rules",description:"Run the @directive-run/lint rule registry against a TypeScript source string. Returns structured findings (line, column, severity, message, fixable) for every match. Use this when the user asks 'review this Directive code' or 'lint this'. Source is parsed in a worker thread with a 5-second budget and 200 KB cap.",inputSchema:{source:z$1.string().min(1).max(2e5).describe("TypeScript source to review. Max 200,000 bytes; longer inputs are rejected pre-parse."),fileName:z$1.string().regex(/^[\w./-]{1,128}$/).optional().describe("Optional file name shown in findings. Must match /^[\\w./-]{1,128}$/."),ruleFilter:z$1.array(z$1.string().max(64)).max(32).optional().describe("Optional whitelist of rule ids to run. Discover valid ids via list_review_rules.")}},async({source:t,fileName:r,ruleFilter:n})=>{try{let i=await A({source:t,fileName:r,ruleFilter:n});return {content:[{type:"text",text:`<directive-data>
35
33
  ${JSON.stringify(i,null,2)}
36
- </directive-data>`}]}}catch(i){return {isError:true,content:[{type:"text",text:`fix_code failed \u2014 ${i instanceof l?`${i.code}: ${i.message}`:i.message}`}]}}}),e.registerTool("list_skills",{title:"List Directive Claude Code skills",description:"List every skill bundled in @directive-run/claude-plugin. Each skill is a gerund-named bundle of one SKILL.md plus supporting knowledge files. Pass a returned name to get_skill.",inputSchema:{}},async()=>{let t=getAllSkills(),r=Array.from(t.keys()).sort();return {content:[{type:"text",text:`${r.length} skills:
34
+ </directive-data>`}]}}catch(i){return {isError:true,content:[{type:"text",text:`review_source failed \u2014 ${i instanceof l?`${i.code}: ${i.message}`:i.message}`}]}}}),e.registerTool("fix_code",{title:"Apply a mechanical fix for a Directive review finding",description:"Given a source string and a Finding returned by review_source, run the rule's mechanical fix and return { ok, diff, fixedSource, explanation } \u2014 or { ok: false, reason } when the rule has no fix. Useful for closing the loop: review_source \u2192 user picks \u2192 fix_code. The fixed source is NOT written to disk \u2014 the caller decides.",inputSchema:{source:z$1.string().min(1).max(2e5).describe("The same source you passed to review_source."),finding:z$1.object({ruleId:z$1.string().min(1).max(64),severity:z$1.enum(["error","warning","info"]),line:z$1.number().int().nonnegative(),column:z$1.number().int().nonnegative(),message:z$1.string(),findingId:z$1.string(),suggestion:z$1.string().optional()}).describe("The Finding returned by review_source. Pass the WHOLE object \u2014 the worker uses ruleId + line + column to locate the AST node.")}},async({source:t,finding:r})=>{try{let n=await M({source:t,finding:r});return {content:[{type:"text",text:`<directive-data>
35
+ ${JSON.stringify(n,null,2)}
36
+ </directive-data>`}]}}catch(n){return {isError:true,content:[{type:"text",text:`fix_code failed \u2014 ${n instanceof l?`${n.code}: ${n.message}`:n.message}`}]}}}),e.registerTool("list_skills",{title:"List Directive Claude Code skills",description:"List every skill bundled in @directive-run/claude-plugin. Each skill is a gerund-named bundle of one SKILL.md plus supporting knowledge files. Pass a returned name to get_skill.",inputSchema:{}},async()=>{let t=getAllSkills(),r=Array.from(t.keys()).sort();return {content:[{type:"text",text:`${r.length} skills:
37
37
  ${r.join(`
38
- `)}`}]}}),e.registerTool("get_skill",{title:"Get a Directive Claude Code skill",description:"Fetch one skill bundle: the SKILL.md manifest plus every supporting knowledge file concatenated into a single document. Use list_skills to discover names.",inputSchema:{name:z$1.string().min(1).describe("The skill name (e.g. 'building-ai-orchestrators', 'writing-directive-constraints').")}},async({name:t})=>{let r=getSkill(t);if(!r)return {isError:true,content:[{type:"text",text:`Skill not found: '${t}'. Call list_skills to see available names.`}]};let i=[`# Skill: ${r.name}
38
+ `)}`}]}}),e.registerTool("get_skill",{title:"Get a Directive Claude Code skill",description:"Fetch one skill bundle: the SKILL.md manifest plus every supporting knowledge file concatenated into a single document. Use list_skills to discover names.",inputSchema:{name:z$1.string().min(1).describe("The skill name (e.g. 'building-ai-orchestrators', 'writing-directive-constraints').")}},async({name:t})=>{let r=getSkill(t);if(!r)return {isError:true,content:[{type:"text",text:`Skill not found: '${t}'. Call list_skills to see available names.`}]};let n=[`# Skill: ${r.name}
39
39
 
40
- ${r.manifest}`];for(let[n,s]of r.files)i.push(`---
40
+ ${r.manifest}`];for(let[i,s]of r.files)n.push(`---
41
41
 
42
- ## ${n}.md
42
+ ## ${i}.md
43
43
 
44
- ${s}`);return {content:[{type:"text",text:i.join(`
44
+ ${s}`);return {content:[{type:"text",text:n.join(`
45
45
 
46
- `)}]}}),e}var B="/messages",H="/sse",Ie="/healthz",Re=1e6,$e=64,Ce=300*1e3,Pe=3e4,Ae=new Set(["127.0.0.1","localhost","::1","0:0:0:0:0:0:0:1"]),S=class extends Error{};function Oe(e){return Ae.has(e.toLowerCase())}function Le(e){let t=e.port??3e3,r=e.host??"127.0.0.1",i=e.logger??console,n=e.token??process.env.DIRECTIVE_MCP_TOKEN??void 0;if(!Oe(r)&&!n)throw new S("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:i,token:n,allowOrigins:e.allowOrigins??[],bodyLimitBytes:e.bodyLimitBytes??Re,maxSessions:e.maxSessions??$e,idleTimeoutMs:e.idleTimeoutMs??Ce}}function K(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 W(e,t){if(t.length===0)return true;let r=e.headers.origin;return typeof r!="string"?false:t.includes(r)}function p(e,t,r,i={}){e.writeHead(t,{"Content-Type":"text/plain",...i}),e.end(r);}function _(e,t){f({transport:"sse",authEnabled:t,sessionCount:e.size});}async function Me(e,t,r,i){if(!K(e,i.token)){p(t,401,"unauthorized");return}if(!W(e,i.allowOrigins)){p(t,403,"origin not allowed");return}if(r.size>=i.maxSessions){p(t,429,"session cap reached",{"Retry-After":"60"});return}let n=new SSEServerTransport(B,t),s=y();r.set(n.sessionId,{transport:n,lastActivity:Date.now()}),_(r,!!i.token);let c=()=>{r.delete(n.sessionId),_(r,!!i.token);};t.on("close",c),n.onclose=c,await s.connect(n),i.logger.log(`[directive-mcp] sse session opened: ${n.sessionId}`);}async function Ne(e,t,r,i,n){if(!K(e,n.token)){p(t,401,"unauthorized");return}if(!W(e,n.allowOrigins)){p(t,403,"origin not allowed");return}let s=Number(e.headers["content-length"]??"0");if(Number.isFinite(s)&&s>n.bodyLimitBytes){p(t,413,`body exceeds ${n.bodyLimitBytes} bytes`);return}let c=r.searchParams.get("sessionId");if(!c){p(t,400,"missing sessionId query parameter");return}let a=i.get(c);if(!a){p(t,404,`unknown session: ${c}`);return}a.lastActivity=Date.now();let d=0,u=false;e.on("data",Y=>{d+=Buffer.byteLength(Y),d>n.bodyLimitBytes&&!u&&(u=true,p(t,413,`body exceeds ${n.bodyLimitBytes} bytes`),e.destroy());}),!u&&await a.transport.handlePostMessage(e,t);}async function Ve(e,t,r,i){let n=new URL(e.url??"/",`http://${e.headers.host??i.host}`);if(e.method==="GET"&&n.pathname===Ie){t.writeHead(200,{"Content-Type":"text/plain"}),t.end("ok");return}if(e.method==="GET"&&n.pathname===H){await Me(e,t,r,i);return}if(e.method==="POST"&&n.pathname===B){await Ne(e,t,n,r,i);return}p(t,404,"not found");}function Fe(e,t){return setInterval(()=>{let r=Date.now();for(let[i,n]of e)r-n.lastActivity>t.idleTimeoutMs&&(e.delete(i),n.transport.close().catch(()=>{}),_(e,!!t.token),t.logger.log(`[directive-mcp] pruned idle session: ${i}`));},Pe).unref()}async function z(e={}){let t=Le(e),r=new Map,i=createServer(async(s,c)=>{try{await Ve(s,c,r,t);}catch(a){t.logger.error("[directive-mcp] request error:",a),c.headersSent||c.writeHead(500,{"Content-Type":"text/plain"}),c.end("internal server error");}}),n=Fe(r,t);return i.on("close",()=>{clearInterval(n);}),await new Promise(s=>{i.listen(t.port,t.host,()=>{t.logger.log(`[directive-mcp] sse server listening at http://${t.host}:${t.port}${H}${t.token?" (auth: bearer-token)":" (auth: none, loopback only)"}`),s();});}),i}var Ge="0.2.2",X=`directive-mcp \u2014 MCP server exposing Directive to AI clients
46
+ `)}]}}),e.registerTool("playground_link",{title:"Build a shareable playground link for a Directive snippet",description:"Turn a TypeScript snippet (from generate_module, get_example, fix_code, or anywhere) into a directive.run/playground URL. The page decompresses the source, renders it with syntax highlighting, and offers a one-click 'Open in StackBlitz' button that boots a real running Directive project with the snippet as src/main.ts. Hand this URL to the user when you want to say 'try it now'. Source is encoded in the URL hash (not query) so it never hits server logs.",inputSchema:{source:z$1.string().min(1).max(g).describe(`The TypeScript source to embed. Max ${g} bytes \u2014 anything larger should be opened in a real sandbox directly.`),title:z$1.string().min(1).max(120).optional().describe("Optional short label shown as the editor tab title on the playground page. Defaults to 'Untitled snippet'.")}},async({source:t,title:r})=>{try{let n=V({source:t,title:r}),i={url:n.url,sizeBytes:n.sizeBytes,urlBytes:n.urlBytes,title:n.title??null};return {content:[{type:"text",text:`<directive-data>
47
+ ${JSON.stringify(i,null,2)}
48
+ </directive-data>`}]}}catch(n){return {isError:true,content:[{type:"text",text:`playground_link failed \u2014 ${n instanceof m?`${n.code}: ${n.message}`:n.message}`}]}}}),e}var z="/messages",Y="/sse",Me="/healthz",Ne=1e6,Ue=64,Ve=300*1e3,Be=3e4,Fe=new Set(["127.0.0.1","localhost","::1","0:0:0:0:0:0:0:1"]),D=class extends Error{};function je(e){return Fe.has(e.toLowerCase())}function Ge(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(!je(r)&&!i)throw new D("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??Ne,maxSessions:e.maxSessions??Ue,idleTimeoutMs:e.idleTimeoutMs??Ve}}function X(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 q(e,t){if(t.length===0)return true;let r=e.headers.origin;return typeof r!="string"?false:t.includes(r)}function u(e,t,r,n={}){e.writeHead(t,{"Content-Type":"text/plain",...n}),e.end(r);}function R(e,t){k({transport:"sse",authEnabled:t,sessionCount:e.size});}var T=0;async function He(e,t,r,n){if(!X(e,n.token)){u(t,401,"unauthorized");return}if(!q(e,n.allowOrigins)){u(t,403,"origin not allowed");return}if(r.size+T>=n.maxSessions){u(t,429,"session cap reached",{"Retry-After":"60"});return}T+=1;let i=false;try{let s=new SSEServerTransport(z,t),c=w();r.set(s.sessionId,{transport:s,lastActivity:Date.now()}),i=!0,R(r,!!n.token);let a=()=>{r.delete(s.sessionId),R(r,!!n.token);};t.on("close",a),s.onclose=a,await c.connect(s),n.logger.log(`[directive-mcp] sse session opened: ${s.sessionId}`);}finally{T-=1;}}async function Ke(e,t,r,n,i){if(!X(e,i.token)){u(t,401,"unauthorized");return}if(!q(e,i.allowOrigins)){u(t,403,"origin not allowed");return}let s=Number(e.headers["content-length"]??"0");if(Number.isFinite(s)&&s>i.bodyLimitBytes){u(t,413,`body exceeds ${i.bodyLimitBytes} bytes`);return}let c=r.searchParams.get("sessionId");if(!c){u(t,400,"missing sessionId query parameter");return}let a=n.get(c);if(!a){u(t,404,`unknown session: ${c}`);return}a.lastActivity=Date.now();let d=0,p=false;e.on("data",Q=>{d+=Buffer.byteLength(Q),d>i.bodyLimitBytes&&!p&&(p=true,u(t,413,`body exceeds ${i.bodyLimitBytes} bytes`),e.destroy());}),!p&&await a.transport.handlePostMessage(e,t);}async function We(e,t,r,n){let i=new URL(e.url??"/",`http://${e.headers.host??n.host}`);if(e.method==="GET"&&i.pathname===Me){t.writeHead(200,{"Content-Type":"text/plain"}),t.end("ok");return}if(e.method==="GET"&&i.pathname===Y){await He(e,t,r,n);return}if(e.method==="POST"&&i.pathname===z){await Ke(e,t,i,r,n);return}u(t,404,"not found");}function ze(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(()=>{}),R(e,!!t.token),t.logger.log(`[directive-mcp] pruned idle session: ${n}`));},Be).unref()}async function J(e={}){let t=Ge(e),r=new Map,n=createServer(async(s,c)=>{try{await We(s,c,r,t);}catch(a){t.logger.error("[directive-mcp] request error:",a),c.headersSent||c.writeHead(500,{"Content-Type":"text/plain"}),c.end("internal server error");}}),i=ze(r,t);return n.on("close",()=>{clearInterval(i);}),await new Promise(s=>{n.listen(t.port,t.host,()=>{t.logger.log(`[directive-mcp] sse server listening at http://${t.host}:${t.port}${Y}${t.token?" (auth: bearer-token)":" (auth: none, loopback only)"}`),s();});}),n}var Xe="0.3.0",Z=`directive-mcp \u2014 MCP server exposing Directive to AI clients
47
49
 
48
50
  Usage:
49
51
  directive-mcp Run stdio transport (default)
@@ -64,9 +66,9 @@ Options:
64
66
  --version, -v Show package version
65
67
 
66
68
  Docs: https://directive.run/docs/ide-integration
67
- `;function w(e,t,r){let i=e[t];if(!i)throw new Error(`${r} requires a value`);return i}function je(e){let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`invalid --port: ${e}`);return t}function Be(e){let t={sse:false,port:3e3,host:"127.0.0.1",help:false,version:false,allowOrigins:[]};for(let r=0;r<e.length;r++){let i=e[r];switch(i){case "--sse":t.sse=true;break;case "--port":t.port=je(w(e,++r,"--port"));break;case "--host":t.host=w(e,++r,"--host");break;case "--token":t.token=w(e,++r,"--token");break;case "--allow-origin":t.allowOrigins.push(w(e,++r,"--allow-origin"));break;case "--help":case "-h":t.help=true;break;case "--version":case "-v":t.version=true;break;default:throw new Error(`unknown argument: ${i}`)}}return t}async function He(){let e;try{e=Be(process.argv.slice(2));}catch(i){process.stderr.write(`${i.message}
69
+ `;function x(e,t,r){let n=e[t];if(!n)throw new Error(`${r} requires a value`);return n}function qe(e){let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`invalid --port: ${e}`);return t}function Je(e){let t={sse:false,port:3e3,host:"127.0.0.1",help:false,version:false,allowOrigins:[]};for(let r=0;r<e.length;r++){let n=e[r];switch(n){case "--sse":t.sse=true;break;case "--port":t.port=qe(x(e,++r,"--port"));break;case "--host":t.host=x(e,++r,"--host");break;case "--token":t.token=x(e,++r,"--token");break;case "--allow-origin":t.allowOrigins.push(x(e,++r,"--allow-origin"));break;case "--help":case "-h":t.help=true;break;case "--version":case "-v":t.version=true;break;default:throw new Error(`unknown argument: ${n}`)}}return t}async function Ze(){let e;try{e=Je(process.argv.slice(2));}catch(n){process.stderr.write(`${n.message}
68
70
 
69
- ${X}`),process.exit(2);}if(e.help){process.stdout.write(X);return}if(e.version){process.stdout.write(`${Ge}
70
- `);return}if(e.sse){let i=await z({port:e.port,host:e.host,token:e.token,allowOrigins:e.allowOrigins}),n=()=>{i.close(()=>process.exit(0));};process.on("SIGINT",n),process.on("SIGTERM",n);return}f({transport:"stdio",authEnabled:false});let t=y(),r=new StdioServerTransport;await t.connect(r);}He().catch(e=>{process.stderr.write(`[directive-mcp] fatal: ${e.stack??String(e)}
71
+ ${Z}`),process.exit(2);}if(e.help){process.stdout.write(Z);return}if(e.version){process.stdout.write(`${Xe}
72
+ `);return}if(e.sse){let n=await J({port:e.port,host:e.host,token:e.token,allowOrigins:e.allowOrigins}),i=()=>{n.close(()=>process.exit(0));};process.on("SIGINT",i),process.on("SIGTERM",i);return}k({transport:"stdio",authEnabled:false});let t=w(),r=new StdioServerTransport;await t.connect(r);}Ze().catch(e=>{process.stderr.write(`[directive-mcp] fatal: ${e.stack??String(e)}
71
73
  `),process.exit(1);});//# sourceMappingURL=cli.js.map
72
74
  //# sourceMappingURL=cli.js.map