@velarscript/cli 0.19.1 → 0.20.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/dist/application-entry.d.ts +13 -0
- package/dist/application-entry.d.ts.map +1 -0
- package/dist/application-entry.js +14 -0
- package/dist/application-entry.js.map +1 -0
- package/dist/cli.js +15 -41
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -2
- package/dist/config.js.map +1 -1
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +11 -0
- package/dist/dev-server.js.map +1 -1
- package/dist/mechanical-fixer.d.ts +4 -2
- package/dist/mechanical-fixer.d.ts.map +1 -1
- package/dist/mechanical-fixer.js +17 -4
- package/dist/mechanical-fixer.js.map +1 -1
- package/dist/node-application.d.ts +7 -9
- package/dist/node-application.d.ts.map +1 -1
- package/dist/node-application.js +20 -58
- package/dist/node-application.js.map +1 -1
- package/dist/node-production-build.d.ts +4 -4
- package/dist/node-production-build.d.ts.map +1 -1
- package/dist/node-production-build.js +5 -5
- package/dist/node-production-build.js.map +1 -1
- package/dist/node-production-verifier.d.ts.map +1 -1
- package/dist/node-production-verifier.js +8 -5
- package/dist/node-production-verifier.js.map +1 -1
- package/dist/project-check.d.ts +15 -3
- package/dist/project-check.d.ts.map +1 -1
- package/dist/project-check.js +86 -19
- package/dist/project-check.js.map +1 -1
- package/dist/project-format.d.ts +1 -1
- package/dist/project-format.d.ts.map +1 -1
- package/dist/project-format.js +1 -0
- package/dist/project-format.js.map +1 -1
- package/dist/reproduction.js +5 -5
- package/dist/reproduction.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -8
- package/skill/ai-skill-node.md +38 -23
- package/skill/ai-skill-server.md +39 -30
- package/skill/ai-skill-web.md +9 -0
- package/skill/ai-skill.md +3 -1
package/skill/ai-skill-node.md
CHANGED
|
@@ -10,11 +10,12 @@ capabilities, or application configuration.
|
|
|
10
10
|
path-pattern strings, Node modules, HTTP/WebSocket transport, and low-level
|
|
11
11
|
server lifecycle; it does not own convention-based application configuration.
|
|
12
12
|
An ordinary service activates `@velarscript/server` and then loads
|
|
13
|
-
`velar skill server` for
|
|
13
|
+
`velar skill server` for manifest-declared application configuration, assembly, and
|
|
14
14
|
connection lifecycle.
|
|
15
15
|
|
|
16
|
-
A deliberately low-level Node application may activate Node directly
|
|
17
|
-
|
|
16
|
+
A deliberately low-level Node application may activate Node directly. Its
|
|
17
|
+
selected entry source owns startup inside `@main`, exactly like Core, Web, and
|
|
18
|
+
Desktop entries:
|
|
18
19
|
|
|
19
20
|
```json
|
|
20
21
|
{
|
|
@@ -23,42 +24,41 @@ one exported zero-argument async startup function:
|
|
|
23
24
|
"outDir": "dist",
|
|
24
25
|
"publicDir": "public",
|
|
25
26
|
"build": {"mode": "production", "sourceMaps": false},
|
|
26
|
-
"extensions": ["@velarscript/node"]
|
|
27
|
-
"node": {
|
|
28
|
-
"app": "start"
|
|
29
|
-
}
|
|
27
|
+
"extensions": ["@velarscript/node"]
|
|
30
28
|
}
|
|
31
29
|
```
|
|
32
30
|
|
|
33
31
|
The low-level entry owns its own startup arguments in code:
|
|
34
32
|
|
|
35
33
|
```velar fragment
|
|
36
|
-
import {serve} from "velar/serve"
|
|
34
|
+
import {run, serve} from "velar/serve"
|
|
37
35
|
import {app} from "./app.vel"
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
@main:
|
|
38
|
+
const server = await serve(app, port=3000, host="127.0.0.1")
|
|
39
|
+
await run(server)
|
|
41
40
|
```
|
|
42
41
|
|
|
43
|
-
For one shared HTTP/WebSocket application port, the
|
|
44
|
-
|
|
42
|
+
For one shared HTTP/WebSocket application port, use the WebSocket transport's
|
|
43
|
+
matching lifecycle operation:
|
|
45
44
|
|
|
46
45
|
```velar fragment
|
|
47
46
|
import {app as routes} from "./app.vel"
|
|
48
|
-
import {listen} from "velar/websocket"
|
|
47
|
+
import {listen, run} from "velar/websocket"
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
@main:
|
|
50
|
+
const server = await listen({
|
|
52
51
|
host: "127.0.0.1",
|
|
53
52
|
port: 3000,
|
|
54
53
|
http: routes,
|
|
55
54
|
origins: ["https://app.example.com"],
|
|
56
55
|
maxBodyBytes: 16777216,
|
|
57
56
|
})
|
|
57
|
+
await run(server)
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
`run(server)` owns SIGINT/SIGTERM shutdown for either transport. The external
|
|
61
|
+
CLI executes the compiled entry module directly.
|
|
62
62
|
|
|
63
63
|
Use direct Node activation for tools, embedded adapters, and tests. For an
|
|
64
64
|
application service, activate `@velarscript/server`; it provides the same
|
|
@@ -83,14 +83,14 @@ type CreateArticle:
|
|
|
83
83
|
|
|
84
84
|
export server articles:
|
|
85
85
|
/// Reports whether this service is ready.
|
|
86
|
-
@get(p"/health") => {ok: true}
|
|
86
|
+
@get health(p"/health") => {ok: true}
|
|
87
87
|
|
|
88
|
-
@get(p"/articles/{id:number}?{details:bool?}"):
|
|
88
|
+
@get readArticle(p"/articles/{id:number}?{details:bool?}"):
|
|
89
89
|
if id < 1:
|
|
90
90
|
throw HttpProblem({status: 404, code: "article.not_found", title: "Article not found"})
|
|
91
91
|
return {id, details: details ?? false}
|
|
92
92
|
|
|
93
|
-
@post(p"/articles", input: CreateArticle):
|
|
93
|
+
@post createArticle(p"/articles", input: CreateArticle):
|
|
94
94
|
return created({id: 1, title: input.title})
|
|
95
95
|
|
|
96
96
|
```
|
|
@@ -114,6 +114,12 @@ patterns require `as name` so the compiler never injects identifiers that are
|
|
|
114
114
|
hidden inside another declaration. The old `path=` spelling is an error with a
|
|
115
115
|
mechanical fix to the positional form and `as path`.
|
|
116
116
|
|
|
117
|
+
For a public contract, put one stable source identifier between the role and
|
|
118
|
+
the pattern: `@get readArticle(...)` or `@websocket worldRealtime(...)`.
|
|
119
|
+
Operation identities must be unique after composition, survive `prefix`, and
|
|
120
|
+
are emitted verbatim to OpenAPI. Leave the name out only for a local route whose
|
|
121
|
+
method/path-derived OpenAPI identity is sufficient.
|
|
122
|
+
|
|
117
123
|
On `POST`, `PUT`, or `PATCH`, one concrete Data parameter is the
|
|
118
124
|
checked JSON body. A `Request` parameter explicitly requests the complete
|
|
119
125
|
request, including `queryAll` and cooperative `cancellation`. Ambiguous bodies,
|
|
@@ -218,6 +224,12 @@ An app-scoped provider may depend only on other app-scoped providers, may be
|
|
|
218
224
|
eager, and releases during shutdown. Cycles and provider-budget exhaustion fail
|
|
219
225
|
closed. Do not build a controller or container layer around it.
|
|
220
226
|
|
|
227
|
+
When the process has already constructed an application resource, bind it with
|
|
228
|
+
`supply(app, provider, value)`. The provider must be app-scoped, the value is
|
|
229
|
+
checked against that provider's inferred result type, and its `release` callback
|
|
230
|
+
still owns shutdown. The binding follows `prefix`, middleware, docs, lifecycle,
|
|
231
|
+
and server composition; supplying the same provider twice is rejected.
|
|
232
|
+
|
|
221
233
|
## Composition, lifecycle, and middleware
|
|
222
234
|
|
|
223
235
|
Compose route tables as values:
|
|
@@ -282,7 +294,9 @@ task finishes. `setCookie` and
|
|
|
282
294
|
fields. Never start long-lived work by
|
|
283
295
|
dropping a Promise; use an owned lifecycle, background task, Worker, or process.
|
|
284
296
|
|
|
285
|
-
`docs` adds a bundled offline UI and OpenAPI 3.1 JSON.
|
|
297
|
+
`docs` adds a bundled offline UI and OpenAPI 3.1 JSON. HTTP and WebSocket
|
|
298
|
+
operations share its `paths` catalog; WebSocket entries use GET, response 101,
|
|
299
|
+
and `x-velar-transport: websocket`. Compiler route types
|
|
286
300
|
and response helpers supply parameter, body, response, content-type, and static
|
|
287
301
|
success-status schemas. Applicable framework-generated 400, 401, 413, 415, and
|
|
288
302
|
422 responses are included automatically; a preceding `///` comment supplies
|
|
@@ -317,7 +331,7 @@ session belongs in the route table:
|
|
|
317
331
|
import {WebSocketConnection} from "velar/websocket"
|
|
318
332
|
|
|
319
333
|
server realtime:
|
|
320
|
-
@websocket(p"/worlds/{worldId:string}/realtime", connection: WebSocketConnection):
|
|
334
|
+
@websocket worldRealtime(p"/worlds/{worldId:string}/realtime", connection: WebSocketConnection):
|
|
321
335
|
async for message in connection:
|
|
322
336
|
await connection.send(message)
|
|
323
337
|
```
|
|
@@ -331,7 +345,8 @@ contains these routes rejects its legacy single `path` option and does not offer
|
|
|
331
345
|
accepted sessions through `WebSocketServer.next()`.
|
|
332
346
|
|
|
333
347
|
Set
|
|
334
|
-
`maxBodyBytes` to the supplied application value. `
|
|
348
|
+
`maxBodyBytes` to the supplied application value. `host` is non-empty text of
|
|
349
|
+
at most 255 code units without NUL. `origins` contains exact
|
|
335
350
|
canonical HTTP/HTTPS origins. The default rejects any upgrade carrying
|
|
336
351
|
`Origin`; no-Origin non-browser clients remain allowed. Use `["*"]` only for an
|
|
337
352
|
intentional unrestricted policy. A rejected browser origin receives 403 before
|
package/skill/ai-skill-server.md
CHANGED
|
@@ -13,7 +13,7 @@ browser application activates `@velarscript/web`:
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@velarscript/server": "0.
|
|
16
|
+
"@velarscript/server": "0.20.1"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
```
|
|
@@ -24,27 +24,33 @@ browser application activates `@velarscript/web`:
|
|
|
24
24
|
"entry": "src/main.vel",
|
|
25
25
|
"outDir": "dist",
|
|
26
26
|
"publicDir": "public",
|
|
27
|
-
"extensions": ["@velarscript/server"]
|
|
27
|
+
"extensions": ["@velarscript/server"],
|
|
28
|
+
"server": {
|
|
29
|
+
"configuration": "application.yml"
|
|
30
|
+
}
|
|
28
31
|
}
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
The Server application extension composes the Node capability. Do not list both
|
|
32
35
|
extensions. Without `@velarscript/server`, `velar/server` is unavailable and
|
|
33
|
-
|
|
36
|
+
application configuration is not loaded.
|
|
34
37
|
|
|
35
|
-
The
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
The selected entry source must start the application inside `@main`; there is
|
|
39
|
+
no special exported startup binding. Source maps belong to the target-neutral
|
|
40
|
+
top-level `build.sourceMaps` switch. `velar.json` stores only the project-relative
|
|
41
|
+
configuration path. Host, port, request limits, database locations, and other
|
|
42
|
+
runtime values remain in that YAML or JSON file.
|
|
39
43
|
|
|
40
44
|
## Convention-based application configuration
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
`server.configuration` is required and is the single configuration source.
|
|
47
|
+
The CLI's minimal template chooses root `application.yml`, but users may rename
|
|
48
|
+
or move it by editing `velar.json`; the framework never scans conventional
|
|
49
|
+
filenames.
|
|
43
50
|
|
|
44
51
|
YAML and JSON enter the same checked runtime-Type boundary. Files are bounded;
|
|
45
|
-
YAML is strict, rejects duplicate keys, and limits aliases.
|
|
46
|
-
`.yml`, `.yaml`, or `.json
|
|
47
|
-
configuration; other root filenames are never discovered by convention.
|
|
52
|
+
YAML is strict, rejects duplicate keys, and limits aliases. The declared path
|
|
53
|
+
must stay within the project and end in `.yml`, `.yaml`, or `.json`.
|
|
48
54
|
|
|
49
55
|
The framework-owned server section is:
|
|
50
56
|
|
|
@@ -56,22 +62,24 @@ server:
|
|
|
56
62
|
```
|
|
57
63
|
|
|
58
64
|
All three fields are optional. Their defaults are `127.0.0.1`, `3000`, and
|
|
59
|
-
16 MiB. `application(app)` reads this section
|
|
65
|
+
16 MiB. `application(app)` reads this section and creates the server; the
|
|
66
|
+
entry owns its lifetime explicitly:
|
|
60
67
|
|
|
61
68
|
```velar
|
|
62
69
|
import {application} from "velar/server"
|
|
70
|
+
import {run} from "velar/serve"
|
|
63
71
|
|
|
64
72
|
export server routes:
|
|
65
73
|
@get(p"/health") => {status: "ready"}
|
|
66
74
|
|
|
67
|
-
|
|
75
|
+
@main:
|
|
76
|
+
const server = await application(routes)
|
|
77
|
+
await run(server)
|
|
68
78
|
```
|
|
69
79
|
|
|
70
80
|
`velar dev`, `velar serve`, and the standalone `velar build` output use the
|
|
71
|
-
same
|
|
72
|
-
second configuration channel. A missing
|
|
73
|
-
defaults; when application-specific settings are required, load the full file
|
|
74
|
-
with `configuration(Type)`, which requires the file to exist.
|
|
81
|
+
same declared configuration. CLI `--host` and Node `--port` overrides are not
|
|
82
|
+
a second configuration channel. A missing declared file fails closed.
|
|
75
83
|
|
|
76
84
|
## Typed application settings
|
|
77
85
|
|
|
@@ -93,11 +101,12 @@ type ApplicationSettings:
|
|
|
93
101
|
server: ServerSettings
|
|
94
102
|
database: DatabaseSettings
|
|
95
103
|
|
|
96
|
-
export
|
|
104
|
+
export async def loadSettings() -> ApplicationSettings:
|
|
105
|
+
return await configuration(ApplicationSettings)
|
|
97
106
|
```
|
|
98
107
|
|
|
99
|
-
`configuration(Type,
|
|
100
|
-
|
|
108
|
+
`configuration(Type, maxBytes=65536)` returns `Promise<Type>` and always reads
|
|
109
|
+
the manifest-declared path.
|
|
101
110
|
The framework parses syntax; the application Runtime Type owns field names and
|
|
102
111
|
types, and application validation still owns domain ranges and invariants.
|
|
103
112
|
Environment variables may form an explicit deployment override layer, but
|
|
@@ -238,12 +247,12 @@ idempotent handling.
|
|
|
238
247
|
## Custom shared HTTP/WebSocket startup
|
|
239
248
|
|
|
240
249
|
A service whose route table contains `@websocket` declarations may load the
|
|
241
|
-
same typed configuration and
|
|
242
|
-
|
|
250
|
+
same typed configuration and create the shared HTTP/WebSocket listener inside
|
|
251
|
+
`@main`:
|
|
243
252
|
|
|
244
253
|
```velar fragment
|
|
245
254
|
import {configuration} from "velar/server"
|
|
246
|
-
import {listen} from "velar/websocket"
|
|
255
|
+
import {listen, run} from "velar/websocket"
|
|
247
256
|
|
|
248
257
|
type ServerSettings:
|
|
249
258
|
host: string
|
|
@@ -253,21 +262,21 @@ type ServerSettings:
|
|
|
253
262
|
type Settings:
|
|
254
263
|
server: ServerSettings
|
|
255
264
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return await listen({
|
|
265
|
+
@main:
|
|
266
|
+
const settings = await configuration(Settings)
|
|
267
|
+
const server = await listen({
|
|
260
268
|
host: settings.server.host,
|
|
261
269
|
port: settings.server.port,
|
|
262
270
|
http: routes,
|
|
263
271
|
origins: ["https://app.example.com"],
|
|
264
272
|
maxBodyBytes: settings.server.maxBodyBytes,
|
|
265
273
|
})
|
|
274
|
+
await run(server)
|
|
266
275
|
```
|
|
267
276
|
|
|
268
|
-
The
|
|
269
|
-
|
|
270
|
-
|
|
277
|
+
The entry module itself is the executable artifact; the declared application
|
|
278
|
+
configuration remains the single runtime authority. Each `@websocket`
|
|
279
|
+
RoutePattern owns its own path,
|
|
271
280
|
typed captures, admission inputs, and session handler, so this declarative mode
|
|
272
281
|
does not accept the listener's legacy single `path` option.
|
|
273
282
|
|
package/skill/ai-skill-web.md
CHANGED
|
@@ -23,6 +23,15 @@ modules, and the `web` manifest key. Without that extension these are not Core
|
|
|
23
23
|
syntax. Web visual builders are named imports from `velar/look`; there is no
|
|
24
24
|
`Look.` namespace.
|
|
25
25
|
|
|
26
|
+
Every word in that list is a contextual keyword that stays available as an
|
|
27
|
+
ordinary name — except five. `mount`, `tick`, `viewport`, `scheme`, and `motion`
|
|
28
|
+
are **reserved bindings**: `mount` and `tick` are real runtime entry points, and
|
|
29
|
+
`viewport`, `scheme`, and `motion` name the Look media subjects, so a local
|
|
30
|
+
binding can never shadow a media condition. A Web module refuses all five as
|
|
31
|
+
binding names with `VEL3007`. Three of them are ordinary words for a Web author,
|
|
32
|
+
so name a scroll container `scroller`, a colour setting `theme`, and an
|
|
33
|
+
animation preference `reducedMotion`.
|
|
34
|
+
|
|
26
35
|
`@` remains the language-wide annotation introducer, and `@name` is a context
|
|
27
36
|
annotation with a compiler-owned compile-time role. Components own `@mounted:`
|
|
28
37
|
and `@cleanup:`; Look owns conditions such as `@hover` and `@before`. They are
|
package/skill/ai-skill.md
CHANGED
|
@@ -75,7 +75,8 @@ considering source fallback. Other templates select their own framework brief. E
|
|
|
75
75
|
`velar.json`, a `package.json` whose scripts are the gates, a `src/` tree, a
|
|
76
76
|
passing test, and an `AGENTS.md`.
|
|
77
77
|
|
|
78
|
-
Writing the manifest yourself: `formatVersion` is required, `
|
|
78
|
+
Writing the manifest yourself: `formatVersion` is required, `kind` may be
|
|
79
|
+
`application` or `library` (and defaults to `application`), `extensions` may be
|
|
79
80
|
omitted by a project that loads none, `entry` defaults to `src/main.vel`,
|
|
80
81
|
`outDir` to `dist`, and `publicDir` to `public`.
|
|
81
82
|
|
|
@@ -84,6 +85,7 @@ A Core project (CLI or library) loads no extensions:
|
|
|
84
85
|
```json
|
|
85
86
|
{
|
|
86
87
|
"formatVersion": 2,
|
|
88
|
+
"kind": "library",
|
|
87
89
|
"entry": "src/main.vel",
|
|
88
90
|
"extensions": []
|
|
89
91
|
}
|