@hyperfixi/mcp-server 2.8.0 → 2.9.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,156 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@hyperfixi/mcp-server` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Fixed
11
+
12
+ - **Dispatch:** `execute_lse`, `validate_lse`, and `translate_lse` were advertised
13
+ in `ListTools` and implemented in `handleLsePipelineTool`, but the `CallTool`
14
+ router only forwarded two of the five LSE-pipeline tools — the three LSE 2.0
15
+ tools returned `Unknown tool` when called. All five now route.
16
+ - **Server version:** the MCP `serverInfo.version` was hardcoded to `1.0.0` for
17
+ the entire 2.x line; it now reads from `package.json`, so it can't drift on
18
+ release bumps.
19
+
20
+ ### Changed
21
+
22
+ - README refreshed to match the implementation: tool count 80 → **107**,
23
+ resources 5 → **9**, prompts 3 → **9**, domains 8 → **9** (adds `learn`),
24
+ corrected per-domain language tiers, and documented previously-omitted tool
25
+ families (debug, inventory, training-data, feedback, LSE pipeline/correction,
26
+ and the three additional IR/envelope tools).
27
+
28
+ ## [2.7.2] - 2026-07-08
29
+
30
+ Consolidated summary of the 2.x line (2.0.0 shipped 2026-02-11). Patch releases
31
+ tracked the monorepo-wide version; the highlights relevant to this package:
32
+
33
+ ### Added
34
+
35
+ - **GRAIL workflow tools (5)** — `grail_check` / `grail_plan` / `grail_run` /
36
+ `grail_info` / `grail_list` for Claude-native workflow orchestration.
37
+ - **LSE round-trip pipeline** — `lse_from_hyperscript`, `lse_to_hyperscript`,
38
+ plus the LSE 2.0 LLM-native tools `execute_lse` / `validate_lse` /
39
+ `translate_lse` (#624).
40
+ - **`learn` domain** — 9th domain DSL (language-learning sentence patterns),
41
+ bringing generated domain tools to 36.
42
+ - **Cross-domain dispatch** — `detect_domain`, `compile_auto`, `parse_composite`,
43
+ `compile_composite`.
44
+ - **AI-assisted debugging** (`debug_*`), **template inventory**
45
+ (`scan_inventory` / `query_inventory`), and **training-data** / **feedback-loop**
46
+ tools.
47
+ - IR/envelope tools `validate_protocol`, `to_envelope`, `from_envelope`.
48
+
49
+ ### Changed
50
+
51
+ - Domain language coverage widened to the 11-language "bridge" set for
52
+ sql/jsx/todo/llm/flow/voice (bdd/behaviorspec remain 8, learn is 10) via the
53
+ bridge arc (#615).
54
+ - Domain registration extracted to the shared `@lokascript/domain-config`
55
+ package; `domain-registry-setup.ts` is now a re-export shim.
56
+ - Package scope settled as `@hyperfixi/mcp-server` (engine packages publish under
57
+ `@hyperfixi/*`, multilingual packages under `@lokascript/*`).
58
+
59
+ Tool count grew from 22 (1.0.0) to **107** across this line.
60
+
61
+ ## [1.0.0] - 2025-01-19
62
+
63
+ ### Added
64
+
65
+ - Model Context Protocol server for LLM integration
66
+ - 22 tools for hyperscript development assistance
67
+ - 5 resources for documentation and examples
68
+ - Full multilingual support (23 languages)
69
+ - LSP-compatible features (diagnostics, completions, hover info)
70
+ - Code analysis and complexity metrics
71
+ - Pattern database search and lookup
72
+ - Semantic parsing and translation
73
+ - Schema validation for command designs
74
+ - Language profile management
75
+ - Expression documentation
76
+ - Command documentation with usage examples
77
+ - Keyword translation lookup across languages
78
+ - Auto-fix suggestions for common errors
79
+ - Best practices recommendations
80
+ - Natural language intent recognition
81
+
82
+ ### Tools Provided
83
+
84
+ 1. `analyze_complexity` - Calculate cyclomatic, cognitive, Halstead metrics
85
+ 2. `analyze_metrics` - Comprehensive code quality analysis
86
+ 3. `explain_code` - Natural language explanations (beginner/intermediate/expert)
87
+ 4. `recognize_intent` - Understand code purpose and classify patterns
88
+ 5. `get_examples` - Few-shot learning examples for tasks
89
+ 6. `search_patterns` - Pattern database queries
90
+ 7. `translate_hyperscript` - Between-language translation
91
+ 8. `get_pattern_stats` - Database statistics
92
+ 9. `validate_hyperscript` - Syntax validation
93
+ 10. `validate_schema` - Command schema validation
94
+ 11. `suggest_command` - Best command recommendations
95
+ 12. `get_bundle_config` - vite-plugin configuration
96
+ 13. `parse_multilingual` - Parse any supported language
97
+ 14. `translate_to_english` - Essential for LLM understanding
98
+ 15. `explain_in_language` - Detailed explanations in target language
99
+ 16. `get_code_fixes` - Auto-fix suggestions
100
+ 17. `get_diagnostics` - LSP-compatible diagnostics
101
+ 18. `get_completions` - Context-aware code completions
102
+ 19. `get_hover_info` - Hover documentation
103
+ 20. `get_document_symbols` - Extract symbols for outline view
104
+ 21. `get_command_docs` - Command documentation
105
+ 22. `get_expression_docs` - Expression documentation
106
+
107
+ ### Resources Provided
108
+
109
+ 1. Command registry - All available commands
110
+ 2. Expression types - All expression types
111
+ 3. Language elements - Searchable language features
112
+ 4. Language profiles - Complete grammar rules
113
+ 5. Supported languages - Metadata for 23 languages
114
+
115
+ ### Usage
116
+
117
+ ```bash
118
+ # Start server
119
+ npx @lokascript/mcp-server
120
+
121
+ # Configure in Claude Desktop
122
+ {
123
+ "mcpServers": {
124
+ "lokascript": {
125
+ "command": "npx",
126
+ "args": ["@lokascript/mcp-server"]
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Features
133
+
134
+ - Fully typed with TypeScript
135
+ - Comprehensive error handling
136
+ - Detailed logging for debugging
137
+ - LaunchAgent support for macOS
138
+ - Works with Claude Desktop, VSCode, and other MCP clients
139
+
140
+ ### Performance
141
+
142
+ - Fast response times (< 100ms for most operations)
143
+ - In-memory pattern database for quick lookup
144
+ - Efficient semantic parsing with caching
145
+
146
+ ### Compatibility
147
+
148
+ - MCP SDK 1.25+
149
+ - Node.js 18+
150
+ - Works with all MCP-compatible clients
151
+
152
+ ### Notes
153
+
154
+ - This is the first stable 1.0 release
155
+ - API is stable and production-ready
156
+ - Used extensively in LokaScript development workflow
@@ -68,6 +68,7 @@ var closePattern = /\\}/g;
68
68
  var commaPattern = /\\,/g;
69
69
  var periodPattern = /\\\./g;
70
70
  var EXPANSION_MAX = 1e5;
71
+ var EXPANSION_MAX_LENGTH = 4e6;
71
72
  function numeric(str) {
72
73
  return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
73
74
  }
@@ -102,11 +103,11 @@ function expand(str, options = {}) {
102
103
  if (!str) {
103
104
  return [];
104
105
  }
105
- const { max = EXPANSION_MAX } = options;
106
+ const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
106
107
  if (str.slice(0, 2) === "{}") {
107
108
  str = "\\{\\}" + str.slice(2);
108
109
  }
109
- return expand_(escapeBraces(str), max, true).map(unescapeBraces);
110
+ return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
110
111
  }
111
112
  function embrace(str) {
112
113
  return "{" + str + "}";
@@ -120,20 +121,83 @@ function lte(i, y) {
120
121
  function gte(i, y) {
121
122
  return i >= y;
122
123
  }
123
- function expand_(str, max, isTop) {
124
- const expansions = [];
124
+ function combine(acc, pre, values, max, maxLength, dropEmpties) {
125
+ const out = [];
126
+ let length = 0;
127
+ for (let a = 0; a < acc.length; a++) {
128
+ for (let v = 0; v < values.length; v++) {
129
+ if (out.length >= max)
130
+ return out;
131
+ const expansion = acc[a] + pre + values[v];
132
+ if (dropEmpties && !expansion)
133
+ continue;
134
+ if (length + expansion.length > maxLength)
135
+ return out;
136
+ out.push(expansion);
137
+ length += expansion.length;
138
+ }
139
+ }
140
+ return out;
141
+ }
142
+ function expandSequence(body, isAlphaSequence, max) {
143
+ const n = body.split(/\.\./);
144
+ const N = [];
145
+ if (n[0] === void 0 || n[1] === void 0) {
146
+ return N;
147
+ }
148
+ const x = numeric(n[0]);
149
+ const y = numeric(n[1]);
150
+ const width = Math.max(n[0].length, n[1].length);
151
+ let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
152
+ let test = lte;
153
+ const reverse = y < x;
154
+ if (reverse) {
155
+ incr *= -1;
156
+ test = gte;
157
+ }
158
+ const pad = n.some(isPadded);
159
+ for (let i = x; test(i, y) && N.length < max; i += incr) {
160
+ let c;
161
+ if (isAlphaSequence) {
162
+ c = String.fromCharCode(i);
163
+ if (c === "\\") {
164
+ c = "";
165
+ }
166
+ } else {
167
+ c = String(i);
168
+ if (pad) {
169
+ const need = width - c.length;
170
+ if (need > 0) {
171
+ const z = new Array(need + 1).join("0");
172
+ if (i < 0) {
173
+ c = "-" + z + c.slice(1);
174
+ } else {
175
+ c = z + c;
176
+ }
177
+ }
178
+ }
179
+ }
180
+ N.push(c);
181
+ }
182
+ return N;
183
+ }
184
+ function expand_(str, max, maxLength, isTop) {
185
+ let acc = [""];
186
+ let dropEmpties = false;
187
+ let firstGroup = true;
125
188
  for (; ; ) {
126
189
  const m = balanced("{", "}", str);
127
- if (!m)
128
- return [str];
190
+ if (!m) {
191
+ return combine(acc, str, [""], max, maxLength, dropEmpties);
192
+ }
129
193
  const pre = m.pre;
130
- if (/\$$/.test(m.pre)) {
131
- const post2 = m.post.length ? expand_(m.post, max, false) : [""];
132
- for (let k = 0; k < post2.length && k < max; k++) {
133
- const expansion = pre + "{" + m.body + "}" + post2[k];
134
- expansions.push(expansion);
135
- }
136
- return expansions;
194
+ if (/\$$/.test(pre)) {
195
+ acc = combine(acc, pre + "{" + m.body + "}", [""], max, maxLength, dropEmpties && !m.post.length);
196
+ firstGroup = false;
197
+ if (!m.post.length)
198
+ break;
199
+ str = m.post;
200
+ continue;
137
201
  }
138
202
  const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
139
203
  const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
@@ -145,74 +209,38 @@ function expand_(str, max, isTop) {
145
209
  isTop = true;
146
210
  continue;
147
211
  }
148
- return [str];
212
+ return combine(acc, pre + "{" + m.body + "}" + m.post, [""], max, maxLength, dropEmpties);
149
213
  }
150
- const post = m.post.length ? expand_(m.post, max, false) : [""];
151
- let n;
214
+ if (firstGroup) {
215
+ dropEmpties = isTop && !isSequence;
216
+ firstGroup = false;
217
+ }
218
+ let values;
152
219
  if (isSequence) {
153
- n = m.body.split(/\.\./);
220
+ values = expandSequence(m.body, isAlphaSequence, max);
154
221
  } else {
155
- n = parseCommaParts(m.body);
222
+ let n = parseCommaParts(m.body);
156
223
  if (n.length === 1 && n[0] !== void 0) {
157
- n = expand_(n[0], max, false).map(embrace);
224
+ n = expand_(n[0], max, maxLength, false).map(embrace);
158
225
  if (n.length === 1) {
159
- return post.map((p) => m.pre + n[0] + p);
160
- }
161
- }
162
- }
163
- let N;
164
- if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
165
- const x = numeric(n[0]);
166
- const y = numeric(n[1]);
167
- const width = Math.max(n[0].length, n[1].length);
168
- let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
169
- let test = lte;
170
- const reverse = y < x;
171
- if (reverse) {
172
- incr *= -1;
173
- test = gte;
174
- }
175
- const pad = n.some(isPadded);
176
- N = [];
177
- for (let i = x; test(i, y) && N.length < max; i += incr) {
178
- let c;
179
- if (isAlphaSequence) {
180
- c = String.fromCharCode(i);
181
- if (c === "\\") {
182
- c = "";
183
- }
184
- } else {
185
- c = String(i);
186
- if (pad) {
187
- const need = width - c.length;
188
- if (need > 0) {
189
- const z = new Array(need + 1).join("0");
190
- if (i < 0) {
191
- c = "-" + z + c.slice(1);
192
- } else {
193
- c = z + c;
194
- }
195
- }
196
- }
226
+ acc = combine(acc, pre + n[0], [""], max, maxLength, dropEmpties && !m.post.length);
227
+ if (!m.post.length)
228
+ break;
229
+ str = m.post;
230
+ continue;
197
231
  }
198
- N.push(c);
199
232
  }
200
- } else {
201
- N = [];
233
+ values = [];
202
234
  for (let j2 = 0; j2 < n.length; j2++) {
203
- N.push.apply(N, expand_(n[j2], max, false));
235
+ values.push.apply(values, expand_(n[j2], max, maxLength, false));
204
236
  }
205
237
  }
206
- for (let j2 = 0; j2 < N.length; j2++) {
207
- for (let k = 0; k < post.length && expansions.length < max; k++) {
208
- const expansion = pre + N[j2] + post[k];
209
- if (!isTop || isSequence || expansion) {
210
- expansions.push(expansion);
211
- }
212
- }
213
- }
214
- return expansions;
238
+ acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
239
+ if (!m.post.length)
240
+ break;
241
+ str = m.post;
215
242
  }
243
+ return acc;
216
244
  }
217
245
 
218
246
  // ../../node_modules/minimatch/dist/esm/assert-valid-pattern.js
package/dist/index.js CHANGED
@@ -5978,7 +5978,7 @@ async function handleBDDMultiStep(name, args) {
5978
5978
  let rendered = null;
5979
5979
  if (renderer) {
5980
5980
  const renderedSteps = result.steps.map((step) => renderer(step, to));
5981
- rendered = renderedSteps.join("\n");
5981
+ rendered = renderedSteps.every((step) => step != null) ? renderedSteps.join("\n") : null;
5982
5982
  }
5983
5983
  return jsonResponse({
5984
5984
  input: { scenario, language: from },
@@ -6077,23 +6077,32 @@ async function handleBehaviorSpecMultiLine(name, args) {
6077
6077
  if (!from || !to) return errorResponse("Missing required parameter: from, to");
6078
6078
  const result = parseSpec(scenario, from);
6079
6079
  const renderedTests = [];
6080
+ let complete = true;
6081
+ const renderLine = (node, indent) => {
6082
+ const line = render(node, to);
6083
+ if (line == null) {
6084
+ complete = false;
6085
+ return;
6086
+ }
6087
+ lines.push(`${indent}${line}`);
6088
+ };
6089
+ let lines = [];
6080
6090
  for (const test of result.tests) {
6081
- const lines = [];
6082
- lines.push(`test "${test.name}"`);
6091
+ lines = [`test "${test.name}"`];
6083
6092
  for (const given of test.givens) {
6084
- lines.push(` ${render(given, to)}`);
6093
+ renderLine(given, " ");
6085
6094
  }
6086
6095
  for (const interaction of test.interactions) {
6087
- lines.push(` ${render(interaction.when, to)}`);
6096
+ renderLine(interaction.when, " ");
6088
6097
  for (const exp of interaction.expectations) {
6089
- lines.push(` ${render(exp.node, to)}`);
6098
+ renderLine(exp.node, " ");
6090
6099
  }
6091
6100
  }
6092
6101
  renderedTests.push(lines.join("\n"));
6093
6102
  }
6094
6103
  return jsonResponse({
6095
6104
  input: { scenario, language: from },
6096
- translated: renderedTests.join("\n\n"),
6105
+ translated: complete ? renderedTests.join("\n\n") : null,
6097
6106
  playwright: compile(scenario, from),
6098
6107
  errors: result.errors
6099
6108
  });
@@ -8078,7 +8087,7 @@ function createInlineExtractor() {
8078
8087
  const fs = await import("fs");
8079
8088
  const path = await import("path");
8080
8089
  const crypto = await import("crypto");
8081
- const { glob } = await import("./esm-65HZKQ6R.js");
8090
+ const { glob } = await import("./esm-7SV6EOOG.js");
8082
8091
  const globs = [
8083
8092
  "**/*.html",
8084
8093
  "**/*.htm",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperfixi/mcp-server",
3
- "version": "2.8.0",
3
+ "version": "2.9.1",
4
4
  "description": "Model Context Protocol server for HyperFixi hyperscript development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,31 +37,31 @@
37
37
  "author": "LokaScript Contributors",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "@hyperfixi/patterns-reference": "^2.8.0",
41
- "@lokascript/compilation-service": "^2.8.0",
42
- "@lokascript/domain-config": "^2.8.0",
43
- "@lokascript/framework": "^2.8.0",
44
- "@lokascript/planner": "^2.8.0",
45
- "@lokascript/semantic": "^2.8.0",
40
+ "@hyperfixi/patterns-reference": "^2.9.1",
41
+ "@lokascript/compilation-service": "^2.9.1",
42
+ "@lokascript/domain-config": "^2.9.1",
43
+ "@lokascript/framework": "^2.9.1",
44
+ "@lokascript/planner": "^2.9.1",
45
+ "@lokascript/semantic": "^2.9.1",
46
46
  "@modelcontextprotocol/sdk": "^1.25.0",
47
47
  "yaml": "^2.8.3"
48
48
  },
49
49
  "peerDependencies": {
50
- "@hyperfixi/core": "^2.8.0",
51
- "@hyperfixi/patterns-reference": "^2.8.0",
52
- "@hyperfixi/server-bridge": "^2.8.0",
53
- "@lokascript/compilation-service": "^2.8.0",
54
- "@lokascript/domain-bdd": "^2.8.0",
55
- "@lokascript/domain-behaviorspec": "^2.8.0",
56
- "@lokascript/domain-flow": "^2.8.0",
57
- "@lokascript/domain-jsx": "^2.8.0",
58
- "@lokascript/domain-learn": "^2.8.0",
59
- "@lokascript/domain-llm": "^2.8.0",
60
- "@lokascript/domain-sql": "^2.8.0",
61
- "@lokascript/domain-todo": "^2.8.0",
62
- "@lokascript/domain-voice": "^2.8.0",
63
- "@lokascript/framework": "^2.8.0",
64
- "@lokascript/semantic": "^2.8.0"
50
+ "@hyperfixi/core": "^2.9.1",
51
+ "@hyperfixi/patterns-reference": "^2.9.1",
52
+ "@hyperfixi/server-bridge": "^2.9.1",
53
+ "@lokascript/compilation-service": "^2.9.1",
54
+ "@lokascript/domain-bdd": "^2.9.1",
55
+ "@lokascript/domain-behaviorspec": "^2.9.1",
56
+ "@lokascript/domain-flow": "^2.9.1",
57
+ "@lokascript/domain-jsx": "^2.9.1",
58
+ "@lokascript/domain-learn": "^2.9.1",
59
+ "@lokascript/domain-llm": "^2.9.1",
60
+ "@lokascript/domain-sql": "^2.9.1",
61
+ "@lokascript/domain-todo": "^2.9.1",
62
+ "@lokascript/domain-voice": "^2.9.1",
63
+ "@lokascript/framework": "^2.9.1",
64
+ "@lokascript/semantic": "^2.9.1"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "@lokascript/compilation-service": {
@@ -111,21 +111,21 @@
111
111
  }
112
112
  },
113
113
  "devDependencies": {
114
- "@hyperfixi/core": "^2.8.0",
115
- "@hyperfixi/patterns-reference": "^2.8.0",
116
- "@hyperfixi/server-bridge": "^2.8.0",
117
- "@lokascript/compilation-service": "^2.8.0",
118
- "@lokascript/domain-bdd": "^2.8.0",
119
- "@lokascript/domain-behaviorspec": "^2.8.0",
120
- "@lokascript/domain-flow": "^2.8.0",
121
- "@lokascript/domain-jsx": "^2.8.0",
122
- "@lokascript/domain-learn": "^2.8.0",
123
- "@lokascript/domain-llm": "^2.8.0",
124
- "@lokascript/domain-sql": "^2.8.0",
125
- "@lokascript/domain-todo": "^2.8.0",
126
- "@lokascript/domain-voice": "^2.8.0",
127
- "@lokascript/framework": "^2.8.0",
128
- "@lokascript/semantic": "^2.8.0",
114
+ "@hyperfixi/core": "^2.9.1",
115
+ "@hyperfixi/patterns-reference": "^2.9.1",
116
+ "@hyperfixi/server-bridge": "^2.9.1",
117
+ "@lokascript/compilation-service": "^2.9.1",
118
+ "@lokascript/domain-bdd": "^2.9.1",
119
+ "@lokascript/domain-behaviorspec": "^2.9.1",
120
+ "@lokascript/domain-flow": "^2.9.1",
121
+ "@lokascript/domain-jsx": "^2.9.1",
122
+ "@lokascript/domain-learn": "^2.9.1",
123
+ "@lokascript/domain-llm": "^2.9.1",
124
+ "@lokascript/domain-sql": "^2.9.1",
125
+ "@lokascript/domain-todo": "^2.9.1",
126
+ "@lokascript/domain-voice": "^2.9.1",
127
+ "@lokascript/framework": "^2.9.1",
128
+ "@lokascript/semantic": "^2.9.1",
129
129
  "@types/node": "^20.0.0",
130
130
  "tsup": "^8.0.0",
131
131
  "tsx": "^4.23.1",
@@ -133,7 +133,8 @@
133
133
  "vitest": "^4.1.5"
134
134
  },
135
135
  "files": [
136
- "dist"
136
+ "dist",
137
+ "CHANGELOG.md"
137
138
  ],
138
139
  "publishConfig": {
139
140
  "access": "public"