naider 1.24.5 → 2.0.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 +28 -83
- package/SPEC.naide +8 -6
- package/bin/naide.js +41 -102
- package/bin/postinstall.js +5 -15
- package/examples/model.naide +1 -1
- package/lsp/server.js +1 -2
- package/mcp/server.js +2 -2
- package/package.json +2 -4
- package/src/gen.js +853 -324
- package/src/generator.js +5 -1
- package/src/index.js +34 -14
- package/src/parser.js +15 -14
- package/src/typechecker.js +60 -13
- package/vscode-naide/README.md +4 -6
- package/vscode-naide/extension.js +1 -2
- package/vscode-naide/package-lock.json +2 -2
- package/vscode-naide/package.json +3 -15
- package/SPEC-X.nx +0 -276
- package/assets/nx.ico +0 -0
- package/assets/nx_check.png +0 -0
- package/examples/ai-app.nx +0 -21
- package/examples/async.nx +0 -40
- package/examples/crud.nx +0 -64
- package/examples/fullapp.nx +0 -74
- package/examples/hello.nx +0 -29
- package/examples/server.nx +0 -27
- package/examples/sql-app.nx +0 -23
- package/examples/todo-api.nx +0 -31
- package/src/preprocess.js +0 -308
- package/vscode-naide/language-configuration-nx.json +0 -32
- package/vscode-naide/naide-lang-1.1.0.vsix +0 -0
- package/vscode-naide/syntaxes/naidex.tmLanguage.json +0 -287
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# NAIDE
|
|
2
2
|
|
|
3
|
-
**Node AI Development Environment** —
|
|
3
|
+
**Node AI Development Environment** — One readable syntax for building, checking, and running applications, with compiler targets for **15 languages**.
|
|
4
4
|
|
|
5
|
-
NAIDE is
|
|
5
|
+
NAIDE is designed around one canonical syntax shared by people, AI tools, the compiler, editor support, and examples. It combines familiar control flow and types with concise inference, a built-in application toolkit, diagnostics, and a compiler that can emit multiple targets. The goal is not to hide how programs work, but to make common work direct and errors easier to find.
|
|
6
6
|
|
|
7
7
|
### Compilation Targets
|
|
8
8
|
|
|
@@ -24,10 +24,7 @@ NAIDE is built on four principles: simpler than Python (built-in functions, synt
|
|
|
24
24
|
| `php` | `--target php` | PHP | Built-in / Laravel |
|
|
25
25
|
| `ruby` / `rb` | `--target ruby` | Ruby | Sinatra |
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- **NAIDE** (`.naide`) — Human-readable, ~40% fewer tokens than JavaScript
|
|
30
|
-
- **NAIDE-X** (`.nx`) — AI-only readability, ~80% fewer tokens than JavaScript
|
|
27
|
+
NAIDE source files use the `.naide` extension. There is one language syntax; no separate compressed or AI-only dialect.
|
|
31
28
|
|
|
32
29
|
## Install
|
|
33
30
|
|
|
@@ -61,7 +58,7 @@ naide app.naide
|
|
|
61
58
|
## CLI
|
|
62
59
|
|
|
63
60
|
```bash
|
|
64
|
-
naide <file>
|
|
61
|
+
naide <file.naide> # Check and run a NAIDE file
|
|
65
62
|
naide # Start interactive REPL
|
|
66
63
|
naide repl # Start interactive REPL
|
|
67
64
|
naide init [dir] # Scaffold a new project
|
|
@@ -71,7 +68,6 @@ naide fmt <files...> # Format NAIDE files
|
|
|
71
68
|
naide lsp # Start Language Server (LSP)
|
|
72
69
|
naide vscode # Install VS Code extension
|
|
73
70
|
naide deploy [dir] # Generate Dockerfile for deployment
|
|
74
|
-
naide convert <files...> # Convert .nx ↔ .naide (bidirectional)
|
|
75
71
|
naide pkg init # Create naide.pkg.json manifest
|
|
76
72
|
naide pkg install <name> # Install a NAIDE package
|
|
77
73
|
naide pkg publish # Publish package to npm
|
|
@@ -82,7 +78,6 @@ naide gen "instruction" # Same as ~~ (alias)
|
|
|
82
78
|
naide --expand <file> # Show ~~ directive expansion results
|
|
83
79
|
naide --emit <file> # Print generated JavaScript
|
|
84
80
|
naide -o <out.js> <file> # Write JavaScript to file
|
|
85
|
-
naide --mid <file.nx> # Show intermediate NAIDE v1 (debug X mode)
|
|
86
81
|
naide --ast <file> # Print AST
|
|
87
82
|
naide --tokens <file> # Print token stream
|
|
88
83
|
```
|
|
@@ -178,7 +173,7 @@ Type `.eval` to switch to evaluation mode (runs the code instead of showing JS).
|
|
|
178
173
|
|
|
179
174
|
### Playground
|
|
180
175
|
|
|
181
|
-
Open `playground/index.html` in a browser (via a local server) for a live in-browser
|
|
176
|
+
Open `playground/index.html` in a browser (via a local server) for a live in-browser compiler with examples and source-size indicators.
|
|
182
177
|
|
|
183
178
|
### Benchmark
|
|
184
179
|
|
|
@@ -187,12 +182,13 @@ node benchmark/compare.js
|
|
|
187
182
|
```
|
|
188
183
|
|
|
189
184
|
```
|
|
190
|
-
|
|
191
|
-
JavaScript
|
|
192
|
-
NAIDE
|
|
193
|
-
NAIDE-X 39 435 19 -88%
|
|
185
|
+
Source Whitespace units Chars Lines
|
|
186
|
+
JavaScript 330 2590 78
|
|
187
|
+
NAIDE 66 517 19
|
|
194
188
|
```
|
|
195
189
|
|
|
190
|
+
The benchmark's "whitespace units" are a rough source-size comparison, not model-token counts or evidence of faster generation.
|
|
191
|
+
|
|
196
192
|
## Language Reference
|
|
197
193
|
|
|
198
194
|
### Variables
|
|
@@ -1285,7 +1281,7 @@ naide lsp
|
|
|
1285
1281
|
naide vscode
|
|
1286
1282
|
```
|
|
1287
1283
|
|
|
1288
|
-
One command installs the extension — syntax highlighting, LSP diagnostics, autocomplete, and hover docs for `.naide`
|
|
1284
|
+
One command installs the extension — syntax highlighting, LSP diagnostics, autocomplete, and hover docs for `.naide` files. Restart VS Code after install.
|
|
1289
1285
|
|
|
1290
1286
|
## Deploy
|
|
1291
1287
|
|
|
@@ -1321,7 +1317,7 @@ server app port 3000:
|
|
|
1321
1317
|
ret {ok: true}
|
|
1322
1318
|
```
|
|
1323
1319
|
|
|
1324
|
-
Build all files with `naide build`, which compiles every `.naide
|
|
1320
|
+
Build all files with `naide build`, which compiles every `.naide` file to `.mjs`.
|
|
1325
1321
|
|
|
1326
1322
|
## Full Example
|
|
1327
1323
|
|
|
@@ -1414,63 +1410,21 @@ every "30m":
|
|
|
1414
1410
|
|
|
1415
1411
|
This generates a complete production API — SQLite database, AI/LLM integration, auth, password hashing, CORS, sessions, rate limiting, CRUD with pagination/search, WebSocket, SSE, file caching, request validation, background jobs, auto-generated API docs, route middleware, file downloads, redirects with status codes, type checking, error handling with ensure/finally, and event-driven hooks — from ~75 lines.
|
|
1416
1412
|
|
|
1417
|
-
##
|
|
1418
|
-
|
|
1419
|
-
Every keyword is a single character. Line-start symbol = intent.
|
|
1420
|
-
|
|
1421
|
-
```
|
|
1422
|
-
s:name="World" -- str name = "World"
|
|
1423
|
-
i:count=42 -- int count = 42
|
|
1424
|
-
~i:counter=0 -- mut int counter = 0
|
|
1425
|
-
|
|
1426
|
-
f greet(s:who)s -- fn greet(str who) -> str:
|
|
1427
|
-
>"Hello, {who}!" -- ret "Hello, {who}!"
|
|
1413
|
+
## One syntax, end to end
|
|
1428
1414
|
|
|
1429
|
-
|
|
1430
|
-
>~fetch(url) -- ret await fetch(url)
|
|
1415
|
+
NAIDE has one source syntax for people and tools. Type inference and concise built-ins reduce ceremony; ordinary keywords keep control flow explicit:
|
|
1431
1416
|
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|count>2 -- elif count > 2:
|
|
1435
|
-
log"some" -- log "some"
|
|
1436
|
-
: -- else:
|
|
1437
|
-
log"few" -- log "few"
|
|
1417
|
+
```naide
|
|
1418
|
+
auto name = "World"
|
|
1438
1419
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
*active -- while active:
|
|
1420
|
+
fn greet(str who) -> str:
|
|
1421
|
+
ret "Hello, {who}!"
|
|
1442
1422
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
>users -- ret users
|
|
1446
|
-
P"/users"(req,res) -- post "/users" (req, res):
|
|
1447
|
-
>req.body -- ret req.body
|
|
1423
|
+
if name:
|
|
1424
|
+
log greet(name)
|
|
1448
1425
|
```
|
|
1449
1426
|
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
| Symbol | Meaning | Symbol | Meaning |
|
|
1453
|
-
|--------|---------|--------|---------|
|
|
1454
|
-
| `>` | return | `?` | if |
|
|
1455
|
-
| `\|` | elif | `:` | else |
|
|
1456
|
-
| `@` | loop | `*` | while |
|
|
1457
|
-
| `!` | try | `!!` | catch |
|
|
1458
|
-
| `!!!` | ensure/finally | `>.d` | ret.download |
|
|
1459
|
-
| `$` | server | `^` | model |
|
|
1460
|
-
| `<` | import | `%` | match |
|
|
1461
|
-
| `f` | function | `~f` | async function |
|
|
1462
|
-
| `+` | export | `~` | await |
|
|
1463
|
-
| `G` | GET | `P` | POST |
|
|
1464
|
-
| `U` | PUT | `D` | DELETE |
|
|
1465
|
-
| `X` | PATCH | `>.s` | ret.status |
|
|
1466
|
-
| `>.r` | ret.redirect | `>.h` | ret.html |
|
|
1467
|
-
| `>.t` | ret.text | `>.v` | ret.render |
|
|
1468
|
-
|
|
1469
|
-
Types: `s`=str `i`=int `n`=num `b`=bool `l`=list `m`=map `a`=any
|
|
1470
|
-
|
|
1471
|
-
High-level keywords work in both modes: `schema`, `crud`, `auth`, `cors`, `limit`, `env`, `every`, `watch`, `static`, `ws`, `db`, `db.sql`, `group`, `cookie`, `error`, `session`, `upload`, `view`, `sse`, `cache`, `patch`, `validate`, `test`, `assert`, `queue`, `openapi`, `typeof`, `instanceof`, `ensure`, `ai`, `prompt`, `bot`, `slash`.
|
|
1472
|
-
|
|
1473
|
-
NAIDE-X log shorthands: `log.e` = error, `log.w` = warn, `log.i` = info, `log.d` = debug.
|
|
1427
|
+
New projects, generated examples, editor tooling, and compiler input all use `.naide`. There is no separate symbolic or AI-only form to learn.
|
|
1474
1428
|
|
|
1475
1429
|
## Plugin System
|
|
1476
1430
|
|
|
@@ -1489,15 +1443,6 @@ list names = listPlugins()
|
|
|
1489
1443
|
|
|
1490
1444
|
`registerPlugin(name, setup)` — registers a plugin factory. `usePlugin(name, opts?)` — initializes on first call, returns cached exports. `listPlugins()` — returns registered plugin names.
|
|
1491
1445
|
|
|
1492
|
-
## Convert (NX ↔ NAIDE)
|
|
1493
|
-
|
|
1494
|
-
Bidirectional conversion between `.nx` and `.naide`:
|
|
1495
|
-
|
|
1496
|
-
```bash
|
|
1497
|
-
naide convert file.nx # → file.naide (expand to readable syntax)
|
|
1498
|
-
naide convert file.naide # → file.nx (compress to NX syntax)
|
|
1499
|
-
```
|
|
1500
|
-
|
|
1501
1446
|
## Source Maps & Error Remapping
|
|
1502
1447
|
|
|
1503
1448
|
Runtime errors are automatically remapped to source file line numbers:
|
|
@@ -1509,7 +1454,7 @@ Error in app.naide:12
|
|
|
1509
1454
|
>>12 | throw "not found"
|
|
1510
1455
|
```
|
|
1511
1456
|
|
|
1512
|
-
The CLI tracks source-to-output line mappings and shows context from your `.naide
|
|
1457
|
+
The CLI tracks source-to-output line mappings and shows context from your `.naide` file, not the generated JavaScript.
|
|
1513
1458
|
|
|
1514
1459
|
## Native Dependency Detection
|
|
1515
1460
|
|
|
@@ -1648,14 +1593,14 @@ server app port 3000:
|
|
|
1648
1593
|
|
|
1649
1594
|
## Why NAIDE?
|
|
1650
1595
|
|
|
1651
|
-
|
|
1596
|
+
An approachable language should reduce incidental complexity without obscuring program behavior:
|
|
1652
1597
|
|
|
1653
|
-
1. **
|
|
1654
|
-
2. **
|
|
1655
|
-
3. **
|
|
1656
|
-
4. **
|
|
1598
|
+
1. **One syntax** — no human-only and machine-only dialects to keep in sync
|
|
1599
|
+
2. **Direct feedback** — type checks, tests, and source-mapped diagnostics help find mistakes
|
|
1600
|
+
3. **Useful defaults** — common application patterns need less setup
|
|
1601
|
+
4. **Escape hatches** — generated code and ordinary packages remain inspectable and usable
|
|
1657
1602
|
|
|
1658
|
-
NAIDE
|
|
1603
|
+
NAIDE aims to make one readable source representation work well for both people and AI tools. Generated code and compiler diagnostics remain inspectable rather than treating the source as an opaque prompt format.
|
|
1659
1604
|
|
|
1660
1605
|
## License
|
|
1661
1606
|
|
package/SPEC.naide
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
# NAIDE Language Specification
|
|
3
3
|
# Node AI Development Environment
|
|
4
4
|
# ============================================
|
|
5
|
-
# AI
|
|
5
|
+
# 人間とAIが同じ構文を読み書きできる、実用的なプログラミング言語
|
|
6
6
|
#
|
|
7
7
|
# 設計原則:
|
|
8
|
-
# 1.
|
|
9
|
-
# 2.
|
|
10
|
-
# 3.
|
|
11
|
-
# 4.
|
|
12
|
-
# 5.
|
|
8
|
+
# 1. 構文はひとつ。人間・AI・ツールで異なる方言を持たない
|
|
9
|
+
# 2. 短さは記号暗記ではなく、型推論と明快な標準機能で実現する
|
|
10
|
+
# 3. 制御フロー・非同期・失敗の扱いはコードから読み取れる
|
|
11
|
+
# 4. よく使う仕事を支援しつつ、暗黙の副作用を増やさない
|
|
12
|
+
# 5. 型検査・診断・テストで、実行前に誤りを見つけやすくする
|
|
13
|
+
# 6. コンパイラの出力と実行時の挙動を追跡できるようにする
|
|
14
|
+
# 7. 新機能は構文の一貫性、保守性、ターゲット間の意味保存を満たしてから追加
|
|
13
15
|
# ============================================
|
|
14
16
|
|
|
15
17
|
|
package/bin/naide.js
CHANGED
|
@@ -8,7 +8,7 @@ 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 = '
|
|
11
|
+
const NAIDE_VERSION = '2.0.0';
|
|
12
12
|
|
|
13
13
|
function crashReport(err, context = {}) {
|
|
14
14
|
const info = [
|
|
@@ -34,6 +34,10 @@ function crashReport(err, context = {}) {
|
|
|
34
34
|
console.error(` └──────────────────────────────────────────────────\n`);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function reportRetiredNx(file) {
|
|
38
|
+
console.error(` Error: ${file} uses retired NAIDE-X syntax. Use standard NAIDE syntax in a .naide file.`);
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
process.on('uncaughtException', (err) => {
|
|
38
42
|
crashReport(err);
|
|
39
43
|
process.exit(99);
|
|
@@ -107,8 +111,6 @@ const flags = {
|
|
|
107
111
|
tokens: false,
|
|
108
112
|
output: null,
|
|
109
113
|
help: false,
|
|
110
|
-
mode: null,
|
|
111
|
-
mid: false,
|
|
112
114
|
watch: false,
|
|
113
115
|
debug: false,
|
|
114
116
|
check: false,
|
|
@@ -129,8 +131,6 @@ for (let i = 0; i < args.length; i++) {
|
|
|
129
131
|
case '--tokens': flags.tokens = true; flags.run = false; break;
|
|
130
132
|
case '--output': case '-o': flags.output = args[++i]; break;
|
|
131
133
|
case '--help': case '-h': flags.help = true; break;
|
|
132
|
-
case '--x': case '-x': flags.mode = 'x'; break;
|
|
133
|
-
case '--mid': flags.mid = true; flags.run = false; break;
|
|
134
134
|
case '--watch': case '-w': flags.watch = true; break;
|
|
135
135
|
case '--debug': case '-d': flags.debug = true; break;
|
|
136
136
|
case '--check': flags.check = true; flags.run = false; break;
|
|
@@ -221,11 +221,11 @@ if (files[0] === 'gen' || files[0] === '~~') {
|
|
|
221
221
|
|
|
222
222
|
const { generate, generateProject, updateProject, writeToFile } = await import('../src/gen.js');
|
|
223
223
|
|
|
224
|
-
// Write mode: inject into existing .naide
|
|
225
|
-
const targetFile = instruction.match(/\S+\.
|
|
224
|
+
// Write mode: inject into existing .naide file
|
|
225
|
+
const targetFile = instruction.match(/\S+\.naide$/)?.[0];
|
|
226
226
|
if (targetFile || flags.write) {
|
|
227
227
|
const file = flags.write || targetFile;
|
|
228
|
-
const cleanInstruction = targetFile ? instruction.replace(/\s+\S+\.
|
|
228
|
+
const cleanInstruction = targetFile ? instruction.replace(/\s+\S+\.naide$/, '') : instruction;
|
|
229
229
|
const mode = flags.replace ? 'replace' : 'append';
|
|
230
230
|
const result = writeToFile(resolve(file), cleanInstruction, { mode });
|
|
231
231
|
const a = result.analysis;
|
|
@@ -271,8 +271,11 @@ if (files[0] === 'gen' || files[0] === '~~') {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
const isGame = result.analysis && result.analysis.gameType;
|
|
274
|
+
const isApp = result.analysis && result.analysis.appType;
|
|
274
275
|
if (isGame && !flags.output && !isUpdate) {
|
|
275
276
|
dir = result.analysis.gameType + '-game';
|
|
277
|
+
} else if (isApp && !flags.output && !isUpdate) {
|
|
278
|
+
dir = result.analysis.appType + '-app';
|
|
276
279
|
} else {
|
|
277
280
|
const primaryName = (result.entities[0] || 'app').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
278
281
|
if (!flags.output && !isUpdate) dir = primaryName + '-app';
|
|
@@ -424,7 +427,7 @@ if (flags.expand && files.length > 0) {
|
|
|
424
427
|
if (files[0] === 'vscode') {
|
|
425
428
|
const os = await import('os');
|
|
426
429
|
const extSrc = new URL('../vscode-naide', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1');
|
|
427
|
-
const extName = 'irxk.naide-lang-
|
|
430
|
+
const extName = 'irxk.naide-lang-2.0.0';
|
|
428
431
|
const extDir = join(os.homedir(), '.vscode', 'extensions', extName);
|
|
429
432
|
|
|
430
433
|
if (existsSync(extDir)) {
|
|
@@ -457,7 +460,7 @@ if (files[0] === 'vscode') {
|
|
|
457
460
|
`);
|
|
458
461
|
} catch (e) {
|
|
459
462
|
console.error(` Error: ${e.message}`);
|
|
460
|
-
console.log('\n Manual install: copy vscode-naide/ to ~/.vscode/extensions/irxk.naide-lang-
|
|
463
|
+
console.log('\n Manual install: copy vscode-naide/ to ~/.vscode/extensions/irxk.naide-lang-2.0.0/');
|
|
461
464
|
process.exit(1);
|
|
462
465
|
}
|
|
463
466
|
process.exit(0);
|
|
@@ -663,31 +666,34 @@ if (files[0] === 'build') {
|
|
|
663
666
|
if (statSync(full).isDirectory()) {
|
|
664
667
|
if (entry === 'node_modules' || entry === '.git' || entry === 'dist') continue;
|
|
665
668
|
found.push(...walkDir(full));
|
|
666
|
-
} else if (entry.endsWith('.naide')
|
|
669
|
+
} else if (entry.endsWith('.naide')) {
|
|
667
670
|
found.push(full);
|
|
671
|
+
} else if (entry.endsWith('.nx')) {
|
|
672
|
+
retiredFiles.push(full);
|
|
668
673
|
}
|
|
669
674
|
}
|
|
670
675
|
return found;
|
|
671
676
|
}
|
|
672
677
|
|
|
678
|
+
const retiredFiles = [];
|
|
673
679
|
const sourceFiles = walkDir(dir);
|
|
680
|
+
for (const file of retiredFiles) reportRetiredNx(relative(dir, file));
|
|
674
681
|
if (sourceFiles.length === 0) {
|
|
675
|
-
console.log(' No .naide
|
|
676
|
-
process.exit(0);
|
|
682
|
+
console.log(' No .naide files found.');
|
|
683
|
+
process.exit(retiredFiles.length > 0 ? 1 : 0);
|
|
677
684
|
}
|
|
678
685
|
|
|
679
686
|
console.log(`\n NAIDE build — ${sourceFiles.length} file(s)\n`);
|
|
680
|
-
let errors =
|
|
687
|
+
let errors = retiredFiles.length;
|
|
681
688
|
const schemaMap = {};
|
|
682
689
|
const routeMap = {};
|
|
683
690
|
|
|
684
691
|
for (const srcFile of sourceFiles) {
|
|
685
692
|
const rel = relative(dir, srcFile);
|
|
686
|
-
const mode = srcFile.endsWith('.nx') ? 'x' : 'naide';
|
|
687
693
|
try {
|
|
688
694
|
const source = readFileSync(srcFile, 'utf-8');
|
|
689
|
-
const { js, ast } = compile(source
|
|
690
|
-
const outName = rel.replace(/\.
|
|
695
|
+
const { js, ast } = compile(source);
|
|
696
|
+
const outName = rel.replace(/\.naide$/, '.mjs');
|
|
691
697
|
const outPath = outDir ? join(outDir, outName) : join(dir, outName);
|
|
692
698
|
const outDirPath = resolve(outPath, '..');
|
|
693
699
|
if (!existsSync(outDirPath)) mkdirSync(outDirPath, { recursive: true });
|
|
@@ -742,81 +748,26 @@ if (files[0] === 'build') {
|
|
|
742
748
|
process.exit(errors > 0 ? 1 : 0);
|
|
743
749
|
}
|
|
744
750
|
|
|
745
|
-
// ── Convert (NX ↔ NAIDE) ──
|
|
746
|
-
if (files[0] === 'convert') {
|
|
747
|
-
const targets = files.slice(1);
|
|
748
|
-
if (targets.length === 0) {
|
|
749
|
-
console.log(' Usage: naide convert <file.nx|file.naide>');
|
|
750
|
-
console.log(' .nx → .naide Expand NX shorthand to readable NAIDE');
|
|
751
|
-
console.log(' .naide → .nx Compress NAIDE to AI-optimized NX');
|
|
752
|
-
process.exit(0);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
for (const file of targets) {
|
|
756
|
-
const filePath = resolve(file);
|
|
757
|
-
const ext = extname(file);
|
|
758
|
-
try {
|
|
759
|
-
const source = readFileSync(filePath, 'utf-8');
|
|
760
|
-
|
|
761
|
-
if (ext === '.nx') {
|
|
762
|
-
const { preprocess } = await import('../src/preprocess.js');
|
|
763
|
-
const naide = preprocess(source);
|
|
764
|
-
const outPath = filePath.replace(/\.nx$/, '.naide');
|
|
765
|
-
writeFileSync(outPath, naide);
|
|
766
|
-
console.log(` ${file} → ${basename(outPath)}`);
|
|
767
|
-
} else if (ext === '.naide') {
|
|
768
|
-
const lines = source.split('\n');
|
|
769
|
-
const nxLines = [];
|
|
770
|
-
for (const line of lines) {
|
|
771
|
-
let nx = line;
|
|
772
|
-
nx = nx.replace(/^(\s*)#\s?(.*)/, '$1-- $2');
|
|
773
|
-
nx = nx.replace(/^(\s*)fn\.async\s+/, '$1~f ');
|
|
774
|
-
nx = nx.replace(/^(\s*)fn\s+/, '$1f ');
|
|
775
|
-
nx = nx.replace(/^(\s*)use\s+\{(.+?)\}\s+from\s+/, '$1<{$2}');
|
|
776
|
-
nx = nx.replace(/^(\s*)use\s+/, '$1<');
|
|
777
|
-
nx = nx.replace(/\bret\b/, '>');
|
|
778
|
-
nx = nx.replace(/\beach\s+(\w+)\s+in\s+/, '@$1<');
|
|
779
|
-
nx = nx.replace(/\bawait\s+/, '~');
|
|
780
|
-
nx = nx.replace(/\bstr\b/g, 's');
|
|
781
|
-
nx = nx.replace(/\bint\b/g, 'i');
|
|
782
|
-
nx = nx.replace(/\bnum\b/g, 'n');
|
|
783
|
-
nx = nx.replace(/\bbool\b/g, 'b');
|
|
784
|
-
nx = nx.replace(/\blist\b/g, 'l');
|
|
785
|
-
nx = nx.replace(/\bmap\b/g, 'm');
|
|
786
|
-
nx = nx.replace(/\bany\b/g, 'a');
|
|
787
|
-
nx = nx.replace(/\bconsole\.log\b/, 'log');
|
|
788
|
-
nxLines.push(nx);
|
|
789
|
-
}
|
|
790
|
-
const outPath = filePath.replace(/\.naide$/, '.nx');
|
|
791
|
-
writeFileSync(outPath, nxLines.join('\n'));
|
|
792
|
-
console.log(` ${file} → ${basename(outPath)}`);
|
|
793
|
-
} else {
|
|
794
|
-
console.error(` Unsupported: ${file} (use .naide or .nx)`);
|
|
795
|
-
}
|
|
796
|
-
} catch (e) {
|
|
797
|
-
console.error(` Error: ${file} — ${e.message}`);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
process.exit(0);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
751
|
// ── Type Check ──
|
|
804
752
|
if (files[0] === 'check') {
|
|
805
753
|
const targets = files.slice(1);
|
|
806
754
|
if (targets.length === 0) {
|
|
807
|
-
console.log(' Usage: naide check <file.naide
|
|
755
|
+
console.log(' Usage: naide check <file.naide> [files...]');
|
|
808
756
|
process.exit(0);
|
|
809
757
|
}
|
|
810
758
|
|
|
811
759
|
let totalErrors = 0;
|
|
812
760
|
let totalWarnings = 0;
|
|
813
761
|
for (const file of targets) {
|
|
762
|
+
if (extname(file) === '.nx') {
|
|
763
|
+
reportRetiredNx(file);
|
|
764
|
+
totalErrors++;
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
814
767
|
const filePath = resolve(file);
|
|
815
768
|
try {
|
|
816
769
|
const source = readFileSync(filePath, 'utf-8');
|
|
817
|
-
const
|
|
818
|
-
const mode = ext === '.nx' ? 'x' : 'naide';
|
|
819
|
-
const result = compile(source, { mode, typeCheck: true });
|
|
770
|
+
const result = compile(source, { typeCheck: true });
|
|
820
771
|
const { typeErrors } = result;
|
|
821
772
|
|
|
822
773
|
if (typeErrors) {
|
|
@@ -931,7 +882,7 @@ if (files[0] === 'pkg') {
|
|
|
931
882
|
type: 'module',
|
|
932
883
|
main: manifest.main,
|
|
933
884
|
keywords: manifest.keywords,
|
|
934
|
-
files: ['*.naide', '
|
|
885
|
+
files: ['*.naide', 'src/', 'naide.pkg.json'],
|
|
935
886
|
}, null, 2) + '\n');
|
|
936
887
|
}
|
|
937
888
|
|
|
@@ -985,7 +936,6 @@ CMD ["node", "dist/app.mjs"]
|
|
|
985
936
|
const dockerignoreContent = `node_modules
|
|
986
937
|
.git
|
|
987
938
|
*.naide
|
|
988
|
-
*.nx
|
|
989
939
|
.naide_tmp_*
|
|
990
940
|
dist
|
|
991
941
|
`;
|
|
@@ -1022,12 +972,11 @@ dist
|
|
|
1022
972
|
if (flags.help) {
|
|
1023
973
|
console.log(`
|
|
1024
974
|
NAIDE - Node AI Development Environment
|
|
1025
|
-
|
|
975
|
+
One readable syntax for people and tools
|
|
1026
976
|
|
|
1027
977
|
Usage:
|
|
1028
978
|
naide Start interactive REPL
|
|
1029
979
|
naide <file.naide> Run a NAIDE file
|
|
1030
|
-
naide <file.nx> Run a NAIDE-X file (auto-detected)
|
|
1031
980
|
naide ~~ "instruction" Generate NAIDE code from instruction (no AI)
|
|
1032
981
|
naide gen "instruction" Same as ~~ (alias)
|
|
1033
982
|
naide init [dir] Create a new NAIDE project
|
|
@@ -1037,15 +986,12 @@ if (flags.help) {
|
|
|
1037
986
|
naide lsp Start language server (LSP)
|
|
1038
987
|
naide vscode Install VS Code extension
|
|
1039
988
|
naide deploy [dir] Generate Dockerfile for deployment
|
|
1040
|
-
naide convert <files...> Convert between .naide and .nx formats
|
|
1041
989
|
naide fmt <files...> Format NAIDE files
|
|
1042
990
|
naide pkg init Create naide.pkg.json manifest
|
|
1043
991
|
naide pkg install <name> Install a NAIDE package
|
|
1044
992
|
naide pkg publish Publish package to npm
|
|
1045
993
|
naide pkg list List NAIDE dependencies
|
|
1046
994
|
naide --emit <file> Output generated JavaScript
|
|
1047
|
-
naide --mid <file.nx> Output intermediate NAIDE v1 (debug)
|
|
1048
|
-
naide -x <file.naide> Force NAIDE-X mode
|
|
1049
995
|
naide -w <file.naide> Watch mode (auto-restart on changes)
|
|
1050
996
|
naide -d <file> Debug mode (Node.js inspector)
|
|
1051
997
|
|
|
@@ -1072,19 +1018,13 @@ if (flags.help) {
|
|
|
1072
1018
|
php PHP
|
|
1073
1019
|
ruby Ruby (Sinatra)
|
|
1074
1020
|
|
|
1075
|
-
Modes:
|
|
1076
|
-
.naide Standard NAIDE (~40% fewer tokens than JS)
|
|
1077
|
-
.nx NAIDE-X extreme (~80% fewer tokens than JS)
|
|
1078
|
-
|
|
1079
1021
|
Options:
|
|
1080
1022
|
-e, --emit Print generated JavaScript
|
|
1081
1023
|
-o, --output Write generated JavaScript to file
|
|
1082
|
-
-x Force NAIDE-X mode
|
|
1083
1024
|
-w, --watch Watch mode: restart on file changes
|
|
1084
1025
|
-d, --debug Start with Node.js debugger (--inspect-brk)
|
|
1085
1026
|
-t, --target Compile target: node (default), bun, python/py
|
|
1086
1027
|
--check Type-check files without running
|
|
1087
|
-
--mid Show intermediate NAIDE v1 (X mode only)
|
|
1088
1028
|
--expand Show ~~ directive expansion (debug)
|
|
1089
1029
|
--ast Print AST
|
|
1090
1030
|
--tokens Print tokens
|
|
@@ -1094,6 +1034,7 @@ if (flags.help) {
|
|
|
1094
1034
|
Intent server api rest bot cli page test database ai crud auth ws mail graphql game
|
|
1095
1035
|
Composite todo blog chat shop fullstack board
|
|
1096
1036
|
Game tapping quiz memory snake typing reaction breakout dodge color pong
|
|
1037
|
+
App calculator timer counter pomodoro clock drawing notes
|
|
1097
1038
|
Platform discord slack telegram line
|
|
1098
1039
|
JP Intent サーバー 認証 ログイン 会員 CRUD 管理 データベース ボット テスト ページ ゲーム
|
|
1099
1040
|
JP Entity ユーザー 商品 記事 タスク 注文 コメント イベント 問い合わせ 掲示板 決済
|
|
@@ -1115,15 +1056,13 @@ for (const file of files) {
|
|
|
1115
1056
|
}
|
|
1116
1057
|
|
|
1117
1058
|
const ext = extname(file);
|
|
1118
|
-
|
|
1059
|
+
if (ext === '.nx') {
|
|
1060
|
+
reportRetiredNx(file);
|
|
1061
|
+
process.exitCode = 1;
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1119
1064
|
|
|
1120
1065
|
try {
|
|
1121
|
-
if (flags.mid && mode === 'x') {
|
|
1122
|
-
const { preprocess } = await import('../src/preprocess.js');
|
|
1123
|
-
console.log(preprocess(source));
|
|
1124
|
-
continue;
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
1066
|
const runtimePath = flags.emit || flags.output ? 'naider/runtime' : runtimeUrl;
|
|
1128
1067
|
|
|
1129
1068
|
if (flags.watch) {
|
|
@@ -1133,7 +1072,7 @@ for (const file of files) {
|
|
|
1133
1072
|
function start() {
|
|
1134
1073
|
try {
|
|
1135
1074
|
source = readFileSync(filePath, 'utf-8');
|
|
1136
|
-
const result = compile(source, {
|
|
1075
|
+
const result = compile(source, { runtimePath });
|
|
1137
1076
|
writeFileSync(tempFile, result.js, 'utf-8');
|
|
1138
1077
|
child = spawn(process.execPath, [tempFile], { stdio: 'inherit' });
|
|
1139
1078
|
child.on('error', (err) => console.error(`[NAIDE] Process error: ${err.message}`));
|
|
@@ -1176,8 +1115,8 @@ for (const file of files) {
|
|
|
1176
1115
|
|
|
1177
1116
|
const useAsync = flags.target !== 'node';
|
|
1178
1117
|
const result = useAsync
|
|
1179
|
-
? await compileAsync(source, {
|
|
1180
|
-
: compile(source, {
|
|
1118
|
+
? await compileAsync(source, { runtimePath, sourceFile: file, typeCheck: flags.check, target: flags.target })
|
|
1119
|
+
: compile(source, { runtimePath, sourceFile: file, typeCheck: flags.check });
|
|
1181
1120
|
|
|
1182
1121
|
if (flags.check) {
|
|
1183
1122
|
const { typeErrors } = result;
|
package/bin/postinstall.js
CHANGED
|
@@ -32,19 +32,14 @@ function registerWindows() {
|
|
|
32
32
|
const regAdd = (key, value) => run(`reg add "${key}" /ve /d "${value}" /f`);
|
|
33
33
|
|
|
34
34
|
regAdd('HKCU\\Software\\Classes\\.naide', 'NAIDEFile');
|
|
35
|
-
regAdd('HKCU\\Software\\Classes\\.nx', 'NAIDEXFile');
|
|
36
35
|
regAdd('HKCU\\Software\\Classes\\NAIDEFile', 'NAIDE Source File');
|
|
37
|
-
regAdd('HKCU\\Software\\Classes\\NAIDEXFile', 'NAIDE-X Source File');
|
|
38
36
|
regAdd('HKCU\\Software\\Classes\\NAIDEFile\\shell\\open\\command', cmd);
|
|
39
|
-
regAdd('HKCU\\Software\\Classes\\NAIDEXFile\\shell\\open\\command', cmd);
|
|
40
37
|
|
|
41
38
|
const assetsDir = resolve(__dirname, '..', 'assets');
|
|
42
39
|
const naideIco = resolve(assetsDir, 'naide.ico');
|
|
43
|
-
const nxIco = resolve(assetsDir, 'nx.ico');
|
|
44
40
|
regAdd('HKCU\\Software\\Classes\\NAIDEFile\\DefaultIcon', naideIco);
|
|
45
|
-
regAdd('HKCU\\Software\\Classes\\NAIDEXFile\\DefaultIcon', nxIco);
|
|
46
41
|
|
|
47
|
-
console.log(' .naide
|
|
42
|
+
console.log(' .naide file association registered (Windows)');
|
|
48
43
|
}
|
|
49
44
|
|
|
50
45
|
function registerMacOS() {
|
|
@@ -68,7 +63,7 @@ function registerMacOS() {
|
|
|
68
63
|
<key>CFBundleDocumentTypes</key>
|
|
69
64
|
<array>
|
|
70
65
|
<dict>
|
|
71
|
-
<key>CFBundleTypeExtensions</key><array><string>naide</string
|
|
66
|
+
<key>CFBundleTypeExtensions</key><array><string>naide</string></array>
|
|
72
67
|
<key>CFBundleTypeName</key><string>NAIDE Source</string>
|
|
73
68
|
<key>CFBundleTypeRole</key><string>Editor</string>
|
|
74
69
|
</dict>
|
|
@@ -81,7 +76,7 @@ function registerMacOS() {
|
|
|
81
76
|
|
|
82
77
|
run(`/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "${handlerApp}"`);
|
|
83
78
|
|
|
84
|
-
console.log(' .naide
|
|
79
|
+
console.log(' .naide file association registered (macOS)');
|
|
85
80
|
}
|
|
86
81
|
|
|
87
82
|
function registerLinux() {
|
|
@@ -96,26 +91,21 @@ function registerLinux() {
|
|
|
96
91
|
<comment>NAIDE Source File</comment>
|
|
97
92
|
<glob pattern="*.naide"/>
|
|
98
93
|
</mime-type>
|
|
99
|
-
<mime-type type="text/x-naidex">
|
|
100
|
-
<comment>NAIDE-X Source File</comment>
|
|
101
|
-
<glob pattern="*.nx"/>
|
|
102
|
-
</mime-type>
|
|
103
94
|
</mime-info>`);
|
|
104
95
|
|
|
105
96
|
writeFileSync(join(appDir, 'naide.desktop'), `[Desktop Entry]
|
|
106
97
|
Type=Application
|
|
107
98
|
Name=NAIDE
|
|
108
99
|
Exec=node "${naideBin}" %f
|
|
109
|
-
MimeType=text/x-naide;
|
|
100
|
+
MimeType=text/x-naide;
|
|
110
101
|
Terminal=true
|
|
111
102
|
Categories=Development;
|
|
112
103
|
`);
|
|
113
104
|
|
|
114
105
|
run('update-mime-database ~/.local/share/mime');
|
|
115
106
|
run('xdg-mime default naide.desktop text/x-naide');
|
|
116
|
-
run('xdg-mime default naide.desktop text/x-naidex');
|
|
117
107
|
|
|
118
|
-
console.log(' .naide
|
|
108
|
+
console.log(' .naide file association registered (Linux)');
|
|
119
109
|
}
|
|
120
110
|
|
|
121
111
|
console.log('NAIDE: Registering file extensions...');
|
package/examples/model.naide
CHANGED
package/lsp/server.js
CHANGED
|
@@ -96,11 +96,10 @@ function validateDocument(uri) {
|
|
|
96
96
|
const text = documents.get(uri);
|
|
97
97
|
if (!text) return;
|
|
98
98
|
|
|
99
|
-
const mode = uri.endsWith('.nx') ? 'x' : 'naide';
|
|
100
99
|
const diagnostics = [];
|
|
101
100
|
|
|
102
101
|
try {
|
|
103
|
-
const result = compile(text
|
|
102
|
+
const result = compile(text);
|
|
104
103
|
|
|
105
104
|
const lines = text.split('\n');
|
|
106
105
|
for (let i = 0; i < lines.length; i++) {
|
package/mcp/server.js
CHANGED
|
@@ -33,7 +33,7 @@ function respondError(id, code, message) {
|
|
|
33
33
|
const TOOLS = [
|
|
34
34
|
{
|
|
35
35
|
name: 'naide_compile',
|
|
36
|
-
description: 'Compile NAIDE code to a target language.
|
|
36
|
+
description: 'Compile readable NAIDE source code to a target language.',
|
|
37
37
|
inputSchema: {
|
|
38
38
|
type: 'object',
|
|
39
39
|
properties: {
|
|
@@ -192,7 +192,7 @@ async function handleMessage(msg) {
|
|
|
192
192
|
respond(msg.id, {
|
|
193
193
|
protocolVersion: '2024-11-05',
|
|
194
194
|
capabilities: { tools: {} },
|
|
195
|
-
serverInfo: { name: 'naide-mcp', version: '
|
|
195
|
+
serverInfo: { name: 'naide-mcp', version: '2.0.0' }
|
|
196
196
|
});
|
|
197
197
|
break;
|
|
198
198
|
|