naider 1.18.0 → 1.20.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/bin/naide.js CHANGED
@@ -8,6 +8,42 @@ import { spawn } from 'child_process';
8
8
  import { createRequire } from 'module';
9
9
  const _require = createRequire(import.meta.url);
10
10
 
11
+ const NAIDE_VERSION = '1.20.0';
12
+
13
+ function crashReport(err, context = {}) {
14
+ const info = [
15
+ `NAIDE v${NAIDE_VERSION}`,
16
+ `Node ${process.version}`,
17
+ `${process.platform} ${process.arch}`,
18
+ ];
19
+ if (context.file) info.push(`File: ${context.file}`);
20
+ if (context.target) info.push(`Target: ${context.target}`);
21
+
22
+ console.error(`\n ┌─ NAIDE Internal Error ───────────────────────────`);
23
+ console.error(` │ ${err.message}`);
24
+ console.error(` │`);
25
+ console.error(` │ ${info.join(' | ')}`);
26
+ if (err.stack) {
27
+ const frames = err.stack.split('\n').slice(1, 4).map(l => l.trim());
28
+ for (const f of frames) console.error(` │ ${f}`);
29
+ }
30
+ console.error(` │`);
31
+ console.error(` │ This is a compiler bug, not a syntax error.`);
32
+ console.error(` │ Report: https://github.com/irxk/naide/issues/new`);
33
+ console.error(` │ Include the .naide file and the info above.`);
34
+ console.error(` └──────────────────────────────────────────────────\n`);
35
+ }
36
+
37
+ process.on('uncaughtException', (err) => {
38
+ crashReport(err);
39
+ process.exit(99);
40
+ });
41
+
42
+ process.on('unhandledRejection', (reason) => {
43
+ crashReport(reason instanceof Error ? reason : new Error(String(reason)));
44
+ process.exit(99);
45
+ });
46
+
11
47
  function checkDependencies(jsCode) {
12
48
  const depMap = {
13
49
  "from 'express'": { pkg: 'express', reason: 'server' },
@@ -77,6 +113,7 @@ const flags = {
77
113
  debug: false,
78
114
  check: false,
79
115
  target: 'node',
116
+ expand: false,
80
117
  };
81
118
 
82
119
  const files = [];
@@ -95,10 +132,108 @@ for (let i = 0; i < args.length; i++) {
95
132
  case '--debug': case '-d': flags.debug = true; break;
96
133
  case '--check': flags.check = true; flags.run = false; break;
97
134
  case '--target': case '-t': flags.target = args[++i]; break;
135
+ case '--expand': flags.expand = true; flags.run = false; break;
98
136
  default: files.push(arg);
99
137
  }
100
138
  }
101
139
 
140
+ // ── Code Generator (~~) ──
141
+ if (files[0] === 'gen' || files[0] === '~~') {
142
+ const instruction = files.slice(1).join(' ');
143
+ if (!instruction) {
144
+ console.log(`
145
+ NAIDE Code Generator (~~)
146
+
147
+ Usage:
148
+ naide ~~ "REST API for users with auth"
149
+ naide gen "todo app with database"
150
+ naide gen "Discord bot with hello command"
151
+
152
+ Generates valid NAIDE code from natural language instructions.
153
+ No AI, no network — pure pattern matching with self-healing validation.
154
+
155
+ Examples:
156
+ naide ~~ "REST API for products with name price stock"
157
+ naide ~~ "blog app with auth and database"
158
+ naide ~~ "Discord bot with hello and help commands"
159
+ naide ~~ "CLI tool"
160
+ naide ~~ "chat app with websocket"
161
+ naide ~~ "user management fullstack app"
162
+ naide ~~ "ユーザー管理APIを認証付きで"
163
+ naide ~~ "掲示板アプリ"
164
+
165
+ In .naide files:
166
+ ~~ "REST API for users with auth"
167
+ # Expands at compile time to full NAIDE code
168
+
169
+ Debug:
170
+ naide --expand app.naide Show ~~ expansion results
171
+
172
+ API:
173
+ import { generate } from 'naider';
174
+ const result = generate("REST API for users");
175
+ console.log(result.code);
176
+
177
+ ── Keyword Cheat Sheet ──────────────────────────────────────
178
+
179
+ Intent server, api, rest, bot, cli, page, test, database,
180
+ ai, crud, auth, websocket, mail, graphql
181
+ Composite todo, blog, chat, shop, fullstack, board
182
+ Platform discord, slack, telegram, line
183
+ DB Type sqlite, postgres
184
+ JP Intent サーバー, 認証, ログイン, 会員, CRUD, 管理, データベース,
185
+ ボット, テスト, ページ, メール, リアルタイム
186
+ JP Entity ユーザー, 商品, 記事, タスク, 注文, コメント, イベント,
187
+ 問い合わせ, 通知, カテゴリ, プロジェクト, 掲示板, 決済
188
+ Fields "with name email age" — auto-inferred types & validators
189
+ Field Alias e-mail→email, pwd→password, tel→phone, desc→description
190
+
191
+ ────────────────────────────────────────────────────────────
192
+ `);
193
+ process.exit(0);
194
+ }
195
+
196
+ const { generate } = await import('../src/gen.js');
197
+ const result = generate(instruction);
198
+
199
+ if (flags.output) {
200
+ writeFileSync(flags.output, result.code, 'utf-8');
201
+ console.log(` Generated: ${flags.output} (${result.intents.join(' + ')})`);
202
+ } else {
203
+ console.log(result.code);
204
+ const meta = [`[${result.intents.join(' + ')}]`];
205
+ if (result.schema) meta.push(`→ ${result.schema}`);
206
+ meta.push(`valid: ${result.valid}`);
207
+ if (result.fixed) meta.push('(auto-fixed)');
208
+ process.stderr.write(`\n ── gen ~~ ${meta.join(' ')} ──\n`);
209
+ if (result.repairs.length > 0) {
210
+ process.stderr.write(' Repairs:\n');
211
+ for (const r of result.repairs) process.stderr.write(` - ${r}\n`);
212
+ }
213
+ if (result.suggestion) {
214
+ process.stderr.write(`\n${result.suggestion}\n`);
215
+ }
216
+ }
217
+ process.exit(0);
218
+ }
219
+
220
+ // ── Expand Debug ──
221
+ if (flags.expand && files.length > 0) {
222
+ const { expandDirectives } = await import('../src/gen.js');
223
+ for (const file of files) {
224
+ const filePath = resolve(file);
225
+ const source = readFileSync(filePath, 'utf-8');
226
+ const { source: expanded, expanded: didExpand } = expandDirectives(source);
227
+ if (didExpand) {
228
+ console.log(` ── ${file} (expanded) ──\n`);
229
+ console.log(expanded);
230
+ } else {
231
+ console.log(` ${file}: no ~~ directives found`);
232
+ }
233
+ }
234
+ process.exit(0);
235
+ }
236
+
102
237
  // ── VS Code Extension Install ──
103
238
  if (files[0] === 'vscode') {
104
239
  const os = await import('os');
@@ -357,24 +492,67 @@ if (files[0] === 'build') {
357
492
 
358
493
  console.log(`\n NAIDE build — ${sourceFiles.length} file(s)\n`);
359
494
  let errors = 0;
495
+ const schemaMap = {};
496
+ const routeMap = {};
497
+
360
498
  for (const srcFile of sourceFiles) {
361
499
  const rel = relative(dir, srcFile);
362
500
  const mode = srcFile.endsWith('.nx') ? 'x' : 'naide';
363
501
  try {
364
502
  const source = readFileSync(srcFile, 'utf-8');
365
- const { js } = compile(source, { mode });
503
+ const { js, ast } = compile(source, { mode });
366
504
  const outName = rel.replace(/\.(naide|nx)$/, '.mjs');
367
505
  const outPath = outDir ? join(outDir, outName) : join(dir, outName);
368
506
  const outDirPath = resolve(outPath, '..');
369
507
  if (!existsSync(outDirPath)) mkdirSync(outDirPath, { recursive: true });
370
508
  writeFileSync(outPath, js);
371
509
  console.log(` ${rel} → ${outDir ? join(relative('.', outDir), outName) : outName}`);
510
+
511
+ if (ast && ast.body) {
512
+ for (const node of ast.body) {
513
+ if (node.type === 'SchemaDecl' && node.name) {
514
+ (schemaMap[node.name] = schemaMap[node.name] || []).push(rel);
515
+ }
516
+ if (node.type === 'Server' && node.routes) {
517
+ for (const s of node.routes) {
518
+ if (s.type === 'CrudDecl' && s.path) {
519
+ const key = `CRUD ${s.path.raw || s.path}`;
520
+ (routeMap[key] = routeMap[key] || []).push(rel);
521
+ }
522
+ if (s.type === 'Route' && s.path) {
523
+ const key = `${(s.method || 'get').toUpperCase()} ${s.path.raw || s.path}`;
524
+ (routeMap[key] = routeMap[key] || []).push(rel);
525
+ }
526
+ }
527
+ }
528
+ }
529
+ }
372
530
  } catch (e) {
373
- console.error(` FAIL ${rel}: ${e.message.split('\n')[0]}`);
531
+ const isSyntaxErr = e.message.includes('line ') || e.message.includes('Unexpected') || e.message.includes('Expected');
532
+ if (isSyntaxErr) {
533
+ console.error(` FAIL ${rel}: ${e.message.split('\n')[0]}`);
534
+ } else {
535
+ crashReport(e, { file: rel });
536
+ }
374
537
  errors++;
375
538
  }
376
539
  }
377
- console.log(`\n Done. ${sourceFiles.length - errors} compiled, ${errors} failed.`);
540
+
541
+ let warnings = 0;
542
+ for (const [name, files] of Object.entries(schemaMap)) {
543
+ if (files.length > 1) {
544
+ console.error(` WARN: schema "${name}" defined in ${files.length} files: ${files.join(', ')}`);
545
+ warnings++;
546
+ }
547
+ }
548
+ for (const [route, files] of Object.entries(routeMap)) {
549
+ if (files.length > 1) {
550
+ console.error(` WARN: route ${route} defined in ${files.length} files: ${files.join(', ')}`);
551
+ warnings++;
552
+ }
553
+ }
554
+
555
+ console.log(`\n Done. ${sourceFiles.length - errors} compiled, ${errors} failed${warnings > 0 ? `, ${warnings} warning(s)` : ''}.`);
378
556
  process.exit(errors > 0 ? 1 : 0);
379
557
  }
380
558
 
@@ -664,6 +842,8 @@ if (flags.help) {
664
842
  naide Start interactive REPL
665
843
  naide <file.naide> Run a NAIDE file
666
844
  naide <file.nx> Run a NAIDE-X file (auto-detected)
845
+ naide ~~ "instruction" Generate NAIDE code from instruction (no AI)
846
+ naide gen "instruction" Same as ~~ (alias)
667
847
  naide init [dir] Create a new NAIDE project
668
848
  naide build [dir] [outdir] Transpile all files to JavaScript
669
849
  naide check <files...> Type-check without running
@@ -683,10 +863,28 @@ if (flags.help) {
683
863
  naide -w <file.naide> Watch mode (auto-restart on changes)
684
864
  naide -d <file> Debug mode (Node.js inspector)
685
865
 
686
- Targets:
866
+ Code Generation (~~):
867
+ naide ~~ "instruction" Generate code from instruction (no AI)
868
+ naide gen "instruction" Alias for ~~
869
+ naide --expand <file> Show ~~ directive expansion results
870
+ In .naide files: ~~ "instruction" expands at compile time
871
+
872
+ Targets (15):
687
873
  node Node.js / JavaScript (default)
688
874
  bun Bun-optimized JavaScript
689
- python Python (Flask for servers)
875
+ ts TypeScript
876
+ python Python (Flask)
877
+ go Go (net/http)
878
+ java Java (HttpServer)
879
+ rust Rust (actix-web)
880
+ cpp C++ (cpp-httplib)
881
+ c C (libmicrohttpd)
882
+ csharp C# (ASP.NET)
883
+ kotlin Kotlin (Ktor)
884
+ swift Swift (Vapor)
885
+ dart Dart (shelf)
886
+ php PHP
887
+ ruby Ruby (Sinatra)
690
888
 
691
889
  Modes:
692
890
  .naide Standard NAIDE (~40% fewer tokens than JS)
@@ -701,9 +899,18 @@ if (flags.help) {
701
899
  -t, --target Compile target: node (default), bun, python/py
702
900
  --check Type-check files without running
703
901
  --mid Show intermediate NAIDE v1 (X mode only)
902
+ --expand Show ~~ directive expansion (debug)
704
903
  --ast Print AST
705
904
  --tokens Print tokens
706
905
  -h, --help Show this help
906
+
907
+ ~~ Keyword Cheat Sheet:
908
+ Intent server api rest bot cli page test database ai crud auth ws mail graphql
909
+ Composite todo blog chat shop fullstack board
910
+ Platform discord slack telegram line
911
+ JP Intent サーバー 認証 ログイン 会員 CRUD 管理 データベース ボット テスト ページ
912
+ JP Entity ユーザー 商品 記事 タスク 注文 コメント イベント 問い合わせ 掲示板 決済
913
+ Fields "with name email age done" → auto-inferred types
707
914
  `);
708
915
  process.exit(0);
709
916
  }
@@ -872,7 +1079,12 @@ for (const file of files) {
872
1079
  } catch {}
873
1080
  }
874
1081
  } catch (err) {
875
- console.error(`\n${err.message}`);
1082
+ const isSyntaxErr = err.message.includes('line ') || err.message.includes('Unexpected') || err.message.includes('Expected');
1083
+ if (isSyntaxErr) {
1084
+ console.error(`\n${err.message}`);
1085
+ } else {
1086
+ crashReport(err, { file, target: flags.target });
1087
+ }
876
1088
  if (process.env.NAIDE_DEBUG) console.error(err.stack);
877
1089
  process.exit(1);
878
1090
  }
package/mcp/server.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createInterface } from 'readline';
4
+ import { resolve, dirname } from 'path';
5
+ import { readFileSync } from 'fs';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+
10
+ let compileModule = null;
11
+ async function getCompiler() {
12
+ if (!compileModule) {
13
+ compileModule = await import(resolve(__dirname, '..', 'src', 'index.js'));
14
+ }
15
+ return compileModule;
16
+ }
17
+
18
+ function send(msg) {
19
+ const json = JSON.stringify(msg);
20
+ const buf = Buffer.from(json, 'utf-8');
21
+ process.stdout.write(`Content-Length: ${buf.length}\r\n\r\n`);
22
+ process.stdout.write(buf);
23
+ }
24
+
25
+ function respond(id, result) {
26
+ send({ jsonrpc: '2.0', id, result });
27
+ }
28
+
29
+ function respondError(id, code, message) {
30
+ send({ jsonrpc: '2.0', id, error: { code, message } });
31
+ }
32
+
33
+ const TOOLS = [
34
+ {
35
+ name: 'naide_compile',
36
+ description: 'Compile NAIDE code to a target language. NAIDE is an AI-optimized language that transpiles to 15 targets.',
37
+ inputSchema: {
38
+ type: 'object',
39
+ properties: {
40
+ code: { type: 'string', description: 'NAIDE source code to compile' },
41
+ target: {
42
+ type: 'string',
43
+ description: 'Target language (default: node)',
44
+ enum: ['node', 'python', 'bun', 'typescript', 'go', 'java', 'rust', 'cpp', 'c', 'csharp', 'kotlin', 'swift', 'dart', 'php', 'ruby']
45
+ }
46
+ },
47
+ required: ['code']
48
+ }
49
+ },
50
+ {
51
+ name: 'naide_run',
52
+ description: 'Compile NAIDE code to JavaScript and execute it. Returns stdout output.',
53
+ inputSchema: {
54
+ type: 'object',
55
+ properties: {
56
+ code: { type: 'string', description: 'NAIDE source code to run' }
57
+ },
58
+ required: ['code']
59
+ }
60
+ },
61
+ {
62
+ name: 'naide_targets',
63
+ description: 'List all available NAIDE compilation targets with details.',
64
+ inputSchema: { type: 'object', properties: {} }
65
+ },
66
+ {
67
+ name: 'naide_generate',
68
+ description: 'Generate NAIDE code from a natural language instruction. No AI — uses pattern matching and template composition with self-healing parser validation. Extremely lightweight, runs in microseconds.',
69
+ inputSchema: {
70
+ type: 'object',
71
+ properties: {
72
+ instruction: { type: 'string', description: 'Natural language instruction (e.g. "REST API for users with auth", "Discord bot", "todo app")' },
73
+ port: { type: 'number', description: 'Server port (default: 3000)' },
74
+ schemaName: { type: 'string', description: 'Override schema/entity name' }
75
+ },
76
+ required: ['instruction']
77
+ }
78
+ },
79
+ {
80
+ name: 'naide_spec',
81
+ description: 'Get the NAIDE language specification. Use this to understand NAIDE syntax before writing code.',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ section: {
86
+ type: 'string',
87
+ description: 'Optional section to retrieve (e.g. "variables", "functions", "server"). Omit for full spec.'
88
+ }
89
+ }
90
+ }
91
+ }
92
+ ];
93
+
94
+ const TARGETS_INFO = [
95
+ { name: 'node', language: 'JavaScript (ES Modules)', server: 'Express', flag: 'default' },
96
+ { name: 'python', language: 'Python', server: 'Flask', flag: '--target python' },
97
+ { name: 'bun', language: 'JavaScript (Bun)', server: 'Bun.serve', flag: '--target bun' },
98
+ { name: 'typescript', language: 'TypeScript', server: 'Express', flag: '--target ts' },
99
+ { name: 'go', language: 'Go', server: 'net/http', flag: '--target go' },
100
+ { name: 'java', language: 'Java', server: 'HttpServer', flag: '--target java' },
101
+ { name: 'rust', language: 'Rust', server: 'actix-web', flag: '--target rust' },
102
+ { name: 'cpp', language: 'C++', server: 'cpp-httplib', flag: '--target cpp' },
103
+ { name: 'c', language: 'C', server: 'libmicrohttpd', flag: '--target c' },
104
+ { name: 'csharp', language: 'C#', server: 'ASP.NET', flag: '--target csharp' },
105
+ { name: 'kotlin', language: 'Kotlin', server: 'Ktor', flag: '--target kotlin' },
106
+ { name: 'swift', language: 'Swift', server: 'Vapor', flag: '--target swift' },
107
+ { name: 'dart', language: 'Dart', server: 'shelf', flag: '--target dart' },
108
+ { name: 'php', language: 'PHP', server: 'Built-in / Laravel', flag: '--target php' },
109
+ { name: 'ruby', language: 'Ruby', server: 'Sinatra', flag: '--target ruby' },
110
+ ];
111
+
112
+ async function handleToolCall(name, args) {
113
+ const { compile, compileAsync } = await getCompiler();
114
+
115
+ switch (name) {
116
+ case 'naide_compile': {
117
+ const target = args.target || 'node';
118
+ try {
119
+ if (target === 'node') {
120
+ const result = compile(args.code);
121
+ return { content: [{ type: 'text', text: result.js }] };
122
+ }
123
+ const result = await compileAsync(args.code, { target });
124
+ return { content: [{ type: 'text', text: result.code }] };
125
+ } catch (e) {
126
+ return { content: [{ type: 'text', text: `Compilation error: ${e.message}` }], isError: true };
127
+ }
128
+ }
129
+
130
+ case 'naide_run': {
131
+ try {
132
+ const result = compile(args.code);
133
+ const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
134
+ let output = '';
135
+ const fakeConsole = { log: (...a) => { output += a.map(String).join(' ') + '\n'; }, error: (...a) => { output += a.map(String).join(' ') + '\n'; } };
136
+ const fn = new AsyncFunction('console', result.js);
137
+ await fn(fakeConsole);
138
+ return { content: [{ type: 'text', text: output || '(no output)' }] };
139
+ } catch (e) {
140
+ return { content: [{ type: 'text', text: `Error: ${e.message}` }], isError: true };
141
+ }
142
+ }
143
+
144
+ case 'naide_targets': {
145
+ const text = TARGETS_INFO.map(t => `${t.name.padEnd(12)} ${t.language.padEnd(25)} ${t.server.padEnd(20)} ${t.flag}`).join('\n');
146
+ return { content: [{ type: 'text', text: `NAIDE Compilation Targets (15):\n\n${'Target'.padEnd(12)} ${'Language'.padEnd(25)} ${'Server'.padEnd(20)} Flag\n${'─'.repeat(75)}\n${text}` }] };
147
+ }
148
+
149
+ case 'naide_generate': {
150
+ try {
151
+ const { generate } = await import(resolve(__dirname, '..', 'src', 'gen.js'));
152
+ const opts = {};
153
+ if (args.port) opts.port = args.port;
154
+ if (args.schemaName) opts.schemaName = args.schemaName;
155
+ const result = generate(args.instruction, opts);
156
+ const meta = `[${result.intents.join(' + ')}]${result.schema ? ` → ${result.schema}` : ''} | valid: ${result.valid}${result.fixed ? ' (auto-fixed)' : ''}`;
157
+ return { content: [{ type: 'text', text: `${result.code}\n# ${meta}` }] };
158
+ } catch (e) {
159
+ return { content: [{ type: 'text', text: `Generation error: ${e.message}` }], isError: true };
160
+ }
161
+ }
162
+
163
+ case 'naide_spec': {
164
+ try {
165
+ let spec = readFileSync(resolve(__dirname, '..', 'SPEC.naide'), 'utf-8');
166
+ if (args.section) {
167
+ const s = args.section.toLowerCase();
168
+ const lines = spec.split('\n');
169
+ const chunks = [];
170
+ let capturing = false;
171
+ for (const line of lines) {
172
+ if (line.startsWith('# ---- ') && line.toLowerCase().includes(s)) capturing = true;
173
+ else if (line.startsWith('# ---- ') && capturing) break;
174
+ if (capturing) chunks.push(line);
175
+ }
176
+ if (chunks.length > 0) spec = chunks.join('\n');
177
+ }
178
+ return { content: [{ type: 'text', text: spec }] };
179
+ } catch (e) {
180
+ return { content: [{ type: 'text', text: `Error reading spec: ${e.message}` }], isError: true };
181
+ }
182
+ }
183
+
184
+ default:
185
+ return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
186
+ }
187
+ }
188
+
189
+ async function handleMessage(msg) {
190
+ switch (msg.method) {
191
+ case 'initialize':
192
+ respond(msg.id, {
193
+ protocolVersion: '2024-11-05',
194
+ capabilities: { tools: {} },
195
+ serverInfo: { name: 'naide-mcp', version: '1.20.0' }
196
+ });
197
+ break;
198
+
199
+ case 'notifications/initialized':
200
+ break;
201
+
202
+ case 'tools/list':
203
+ respond(msg.id, { tools: TOOLS });
204
+ break;
205
+
206
+ case 'tools/call':
207
+ try {
208
+ const result = await handleToolCall(msg.params.name, msg.params.arguments || {});
209
+ respond(msg.id, result);
210
+ } catch (e) {
211
+ respondError(msg.id, -32000, e.message);
212
+ }
213
+ break;
214
+
215
+ case 'ping':
216
+ respond(msg.id, {});
217
+ break;
218
+
219
+ default:
220
+ if (msg.id !== undefined) {
221
+ respondError(msg.id, -32601, `Method not found: ${msg.method}`);
222
+ }
223
+ }
224
+ }
225
+
226
+ let buffer = '';
227
+ process.stdin.setEncoding('utf-8');
228
+ process.stdin.on('data', (chunk) => {
229
+ buffer += chunk;
230
+ while (true) {
231
+ const headerEnd = buffer.indexOf('\r\n\r\n');
232
+ if (headerEnd === -1) break;
233
+ const header = buffer.slice(0, headerEnd);
234
+ const match = header.match(/Content-Length:\s*(\d+)/i);
235
+ if (!match) { buffer = buffer.slice(headerEnd + 4); continue; }
236
+ const len = parseInt(match[1], 10);
237
+ const bodyStart = headerEnd + 4;
238
+ if (buffer.length < bodyStart + len) break;
239
+ const body = buffer.slice(bodyStart, bodyStart + len);
240
+ buffer = buffer.slice(bodyStart + len);
241
+ try {
242
+ handleMessage(JSON.parse(body));
243
+ } catch (e) {
244
+ process.stderr.write(`Parse error: ${e.message}\n`);
245
+ }
246
+ }
247
+ });
248
+
249
+ process.stderr.write('NAIDE MCP Server running on stdio\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naider",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "description": "NAIDE - Simpler than Python, compiles to 15 targets. AI-specialized language with 35+ built-in functions, syntax sugar (unless/until/repeat/swap/is/isnt), and 47 features. Targets: Node.js, Python, TypeScript, C, C++, Java, Go, Rust, PHP, Ruby, Kotlin, Swift, Dart, C#, Bun.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -8,13 +8,15 @@
8
8
  "./runtime": "./src/runtime.js"
9
9
  },
10
10
  "bin": {
11
- "naide": "bin/naide.js"
11
+ "naide": "bin/naide.js",
12
+ "naide-mcp": "mcp/server.js"
12
13
  },
13
14
  "type": "module",
14
15
  "files": [
15
16
  "bin/",
16
17
  "src/",
17
18
  "assets/",
19
+ "mcp/",
18
20
  "lsp/",
19
21
  "examples/",
20
22
  "vscode-naide/",