From 0faf7d577df4dd8f6302432feb34600e784a742a Mon Sep 17 00:00:00 2001 From: Error-Zhang Date: Mon, 3 Aug 2026 13:15:02 +0800 Subject: [PATCH 1/3] Build the VelarScript 1.0 Web foundation --- README.md | 63 +- docs/0.3-acceptance.md | 2 +- docs/0.4-acceptance.md | 15 +- docs/0.5-acceptance.md | 4 +- docs/0.7-acceptance.md | 16 +- docs/0.8-acceptance.md | 8 +- docs/0.9-acceptance.md | 8 +- docs/1.0-acceptance.md | 10 +- docs/1.0-readiness-audit.md | 8 +- docs/compiler-architecture.md | 79 +- docs/component-packages.md | 75 + docs/continuous-integration.md | 2 +- docs/implementation-status.md | 53 +- docs/language-charter.md | 59 +- docs/package-distribution.md | 79 +- docs/production-readiness.md | 12 +- docs/project-lifecycle.md | 142 +- docs/release-process.md | 17 +- docs/static-deployment.md | 22 +- docs/web-api.md | 43 +- docs/workbench-integration.md | 21 +- .../api-dashboard/src/app.browser.test.vel | 3 +- examples/api-dashboard/velar.json | 3 +- examples/flow-board/src/app.browser.test.vel | 3 +- examples/flow-board/velar.json | 3 +- .../production-web/src/app.browser.test.vel | 3 +- .../production-web/src/components/metrics.vel | 2 +- .../src/components/web-capabilities.vel | 2 +- examples/production-web/src/pages/home.vel | 2 +- examples/production-web/velar.json | 3 +- examples/production-web/velar.netlify.json | 3 +- .../support-desk/src/app.browser.test.vel | 3 +- examples/support-desk/velar.json | 3 +- examples/todo/velar.json | 11 + package-lock.json | 31 + package.json | 2 +- packages/cli/README.md | 48 +- packages/cli/package.json | 2 + packages/cli/src/browser-test-runner.ts | 49 +- packages/cli/src/cli.ts | 139 +- packages/cli/src/config.ts | 328 ++- packages/cli/src/deployment-verifier.ts | 2 +- packages/cli/src/dev-server.ts | 65 +- packages/cli/src/framework-host.ts | 41 + packages/cli/src/language-server.ts | 66 +- packages/cli/src/module-assets.ts | 67 + packages/cli/src/npm.ts | 6 +- packages/cli/src/package-manager.ts | 303 +++ packages/cli/src/production-build.ts | 44 +- packages/cli/src/production-verifier.ts | 26 +- packages/cli/src/project-lifecycle.ts | 100 - packages/cli/src/project-semantic.ts | 220 +- packages/cli/src/project-session.ts | 17 +- packages/cli/src/project.ts | 50 +- packages/cli/src/standard-modules.ts | 1932 +---------------- packages/cli/src/static-deployment.ts | 54 +- packages/cli/src/test-output.ts | 44 + packages/cli/src/test-runner.ts | 20 +- packages/cli/src/version.ts | 1 - packages/cli/src/web.ts | 177 -- packages/compiler/README.md | 32 +- packages/compiler/package.json | 10 +- packages/compiler/src/analyzer.ts | 886 +------- packages/compiler/src/emitter.ts | 66 +- packages/compiler/src/extension.ts | 175 ++ packages/compiler/src/framework-host.ts | 54 + packages/compiler/src/index.ts | 154 +- packages/compiler/src/lexer.ts | 36 +- packages/compiler/src/parser.ts | 392 +--- packages/compiler/src/semantic.ts | 162 +- packages/compiler/src/token.ts | 21 +- packages/compiler/src/types.ts | 10 +- packages/create/LICENSE | 201 ++ packages/create/README.md | 23 + packages/create/package.json | 37 + packages/create/src/arguments.ts | 48 + packages/create/src/cli.ts | 49 + packages/create/src/index.ts | 64 + packages/create/src/templates.ts | 194 ++ packages/create/src/types.ts | 15 + packages/create/tsconfig.build.json | 14 + packages/web/LICENSE | 201 ++ packages/web/README.md | 39 + packages/web/package.json | 49 + packages/web/src/analyzer.ts | 664 ++++++ packages/web/src/compiler.ts | 453 ++++ packages/web/src/editor.ts | 141 ++ .../src/web-emitter.ts => web/src/emitter.ts} | 72 +- packages/web/src/host.ts | 172 ++ packages/web/src/index.ts | 31 + packages/web/src/inspection.ts | 74 + packages/web/src/parser.ts | 338 +++ packages/web/src/project-config.ts | 166 ++ packages/web/src/runtime.ts | 1773 +++++++++++++++ packages/web/src/semantic.ts | 120 + packages/web/tsconfig.build.json | 14 + scripts/mark-package-bin.mjs | 6 + scripts/release-toolchain.mjs | 19 +- tests/browser.acceptance.ts | 2 +- tests/compiler.test.ts | 763 ++++++- tests/fixtures/upgrades/0.3/main.vel | 4 - tests/fixtures/upgrades/0.3/package.json | 7 - tests/fixtures/upgrades/0.3/velar.json | 8 - tests/fixtures/upgrades/0.4/main.vel | 4 - tests/fixtures/upgrades/0.4/package.json | 7 - tests/fixtures/upgrades/0.4/velar.json | 9 - tests/fixtures/upgrades/0.5/main.vel | 4 - tests/fixtures/upgrades/0.5/package.json | 7 - tests/fixtures/upgrades/0.5/velar.json | 15 - tests/fixtures/upgrades/0.6/main.vel | 4 - tests/fixtures/upgrades/0.6/package.json | 7 - tests/fixtures/upgrades/0.6/velar.json | 16 - tests/installed-browser.acceptance.ts | 62 +- tests/package.acceptance.ts | 86 +- tests/performance.test.ts | 2 +- tests/upgrade.test.ts | 45 - 116 files changed, 8031 insertions(+), 4612 deletions(-) create mode 100644 docs/component-packages.md create mode 100644 examples/todo/velar.json create mode 100644 packages/cli/src/framework-host.ts create mode 100644 packages/cli/src/module-assets.ts create mode 100644 packages/cli/src/package-manager.ts delete mode 100644 packages/cli/src/project-lifecycle.ts create mode 100644 packages/cli/src/test-output.ts delete mode 100644 packages/cli/src/web.ts create mode 100644 packages/compiler/src/extension.ts create mode 100644 packages/compiler/src/framework-host.ts create mode 100644 packages/create/LICENSE create mode 100644 packages/create/README.md create mode 100644 packages/create/package.json create mode 100644 packages/create/src/arguments.ts create mode 100644 packages/create/src/cli.ts create mode 100644 packages/create/src/index.ts create mode 100644 packages/create/src/templates.ts create mode 100644 packages/create/src/types.ts create mode 100644 packages/create/tsconfig.build.json create mode 100644 packages/web/LICENSE create mode 100644 packages/web/README.md create mode 100644 packages/web/package.json create mode 100644 packages/web/src/analyzer.ts create mode 100644 packages/web/src/compiler.ts create mode 100644 packages/web/src/editor.ts rename packages/{compiler/src/web-emitter.ts => web/src/emitter.ts} (92%) create mode 100644 packages/web/src/host.ts create mode 100644 packages/web/src/index.ts create mode 100644 packages/web/src/inspection.ts create mode 100644 packages/web/src/parser.ts create mode 100644 packages/web/src/project-config.ts create mode 100644 packages/web/src/runtime.ts create mode 100644 packages/web/src/semantic.ts create mode 100644 packages/web/tsconfig.build.json create mode 100644 scripts/mark-package-bin.mjs delete mode 100644 tests/fixtures/upgrades/0.3/main.vel delete mode 100644 tests/fixtures/upgrades/0.3/package.json delete mode 100644 tests/fixtures/upgrades/0.3/velar.json delete mode 100644 tests/fixtures/upgrades/0.4/main.vel delete mode 100644 tests/fixtures/upgrades/0.4/package.json delete mode 100644 tests/fixtures/upgrades/0.4/velar.json delete mode 100644 tests/fixtures/upgrades/0.5/main.vel delete mode 100644 tests/fixtures/upgrades/0.5/package.json delete mode 100644 tests/fixtures/upgrades/0.5/velar.json delete mode 100644 tests/fixtures/upgrades/0.6/main.vel delete mode 100644 tests/fixtures/upgrades/0.6/package.json delete mode 100644 tests/fixtures/upgrades/0.6/velar.json delete mode 100644 tests/upgrade.test.ts diff --git a/README.md b/README.md index f436893e..1f2a0e01 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,21 @@ modern JavaScript, CSS, and Web assets. It keeps the JavaScript runtime and replaces the source surface with a smaller Python/JavaScript blend designed for Web applications. +```sh +npm create velar@latest my-app +cd my-app +npm install +npm run dev +``` + +Use `-- --template docs` for a routed documentation site, +`-- --template library` for a Core `.vel` source package, or +`-- --template component` for a reusable Web component package. The same +templates are available through `velar create` once the CLI is installed. +Velar keeps npm as the registry and lockfile authority; after bootstrap, +`velar install`, `velar add`, `velar remove`, and `velar update` provide the +project-aware dependency surface. + This repository was rebuilt from zero. It does not retain source code, Git history, architecture, or language semantics from the former VelarScript project. @@ -362,7 +377,7 @@ configuration, structured leveled logging, lazy root mounting, last-valid-DOM retention, async mounted blocks, and failure-tolerant cleanup. 0.7C adds project-owned `.browser.test.vel` suites through `velar test --browser`, a generated-project test, packed-CLI browser execution, -a root-base Netlify deployment adapter, 0.3–0.6 upgrade fixtures, and repeated +a root-base Netlify deployment adapter, clean format-2 project contracts, and repeated route/cleanup production soak. 0.7D closes the production-artifact loop with strict `velar verify` integrity checks and `velar preview`, which refuses to serve an unverified or modified build. External preview and release authority remain @@ -387,22 +402,28 @@ cross-module inherited-member analysis. 0.6B adds the independently versioned Core Standard API, and 0.6C establishes its initial surface. Standard API 0.4 now contains 133 exports across collections, text, math, JSON, async, URL, time, secure IDs, and structured logging modules. Compiler-owned -lightweight polymorphic inference replaces user-facing generics. The compiler -and CLI build -reproducible, version-locked JavaScript plus `.d.ts` tarballs with SHA-256 and -source identity, while rehearsal and strict candidate modes remain incapable -of silently publishing. GitHub CI covers Node 24 on Linux, macOS, and Windows -plus development and production Web flows in three browser engines. +lightweight polymorphic inference replaces user-facing generics. The compiler, +official `@velarscript/web` framework, project creator, and CLI build reproducible, +version-locked JavaScript plus `.d.ts` tarballs with SHA-256 and source +identity, while rehearsal and strict candidate modes remain incapable of +silently publishing. GitHub CI covers Node 24 on Linux, macOS, and Windows plus +development and production Web flows in three browser engines. Velar source libraries use npm itself: a package publishes `.vel` source with `package.json` `velar.entry`, and the compiler checks and bundles that source as -part of the application graph. Development builds provide compile/runtime +part of the application graph. Compiler/framework packages opt into automatic +project activation through generic `velar.extension` metadata. The CLI passes +registry package operations to npm without a shell, leaves dependency and lock +ownership there, and atomically changes only `velar.json` extension fields. +Development builds provide compile/runtime overlays, `.vel` stack mapping, full-graph hot invalidation, and a machine-readable status endpoint. Production builds use isolated staging, emit hashed assets, strict CSP metadata, static-host fallback/header/cache -contracts, and deterministic format-2 build identity with SHA-256 identities. +contracts, and deterministic format-3 framework build identity with SHA-256 +identities. The manifest records the framework package, capability, target, +host-protocol version, API version, and framework artifact kind. -The stable Web API is independently versioned at 0.6. Ten explicit Web +The stable Web API is independently versioned at 0.8. Ten explicit Web modules provide base-aware routing and metadata, typed HTTP, local/session/ IndexedDB persistence, accessible forms, browser environment helpers, cross-browser files, WebSocket/SSE realtime connections, typed tests, @@ -411,8 +432,8 @@ Implicit browser globals are rejected in ordinary Velar source and diagnostics lead to these modules or an explicit JavaScript boundary. The 15-module Release Studio passes Chromium, Firefox, and WebKit against both the development server and the CSP-enabled static production build. Packed toolchains also run through -the real generic Workbench LSP host. The 0.6 language and API implementation is -the foundation now being hardened toward production use in 0.7. +the real generic Workbench LSP host. The 0.6 language baseline and Web API 0.8 +are the foundation now being hardened toward production use. `velar/game`, SSR/server execution, a custom package registry, and a custom debug protocol remain deferred. @@ -457,17 +478,18 @@ node dist/core.js Run a Web application with live recompilation: ```sh -npm run velar -- dev examples/todo/main.vel +npm run velar -- dev examples/todo ``` A normal project uses `velar.json`, so commands need no entry argument: ```json { - "formatVersion": 1, + "formatVersion": 2, "entry": "src/main.vel", "outDir": "dist", "publicDir": "public", + "extensions": ["@velarscript/web"], "web": { "title": "My Velar App", "base": "/", @@ -491,16 +513,21 @@ npm run velar -- verify-deployment examples/production-web --url https://preview npm run preview:prepare ``` -Create a new project or inspect an older project before upgrading it: +Create and validate a new project: ```sh npm run velar -- create my-app npm run velar -- format my-app --check npm run velar -- test my-app -npm run velar -- upgrade my-app --check -npm run velar -- upgrade my-app ``` +Format 2 is a clean break: Core projects declare `"extensions": []`; Web +projects install and declare `@velarscript/web`. Legacy manifests are rejected +instead of upgraded implicitly or through a compatibility command. +The project loader discovers the package's independent `/compiler` and `/host` +entries. Web owns HTML, CSP, reload, deployment projection, and browser-test +metadata; CLI owns only generic host mechanics. + Build a Web application: ```sh @@ -543,6 +570,8 @@ A reusable Velar package publishes source through ordinary npm metadata: Applications import it normally: `import {Button} from "my-velar-library"`. Package-relative `.vel` imports are confined to the package root. +Reusable Web components follow the same source-package path with an explicit +Web peer contract; see [docs/component-packages.md](docs/component-packages.md). Start the language server used by VelarOS Workbench: diff --git a/docs/0.3-acceptance.md b/docs/0.3-acceptance.md index 38d4c551..9d744995 100644 --- a/docs/0.3-acceptance.md +++ b/docs/0.3-acceptance.md @@ -43,7 +43,7 @@ Packaging: bun run package:app:dir && bun run verify:app:dir ## Next big stage Velar 0.4 is the distribution and broader Web-application stage: publishable -compiler/CLI packages, project creation and upgrade policy, a deliberately +toolchain packages, project creation and version policy, a deliberately limited TypeScript declaration bridge for real npm libraries, broader browser coverage, and deeper routing/forms/head/accessibility APIs. SSR/server, `velar/game`, a custom package registry, a custom debug protocol, and complex diff --git a/docs/0.4-acceptance.md b/docs/0.4-acceptance.md index beeb2480..881cc4b7 100644 --- a/docs/0.4-acceptance.md +++ b/docs/0.4-acceptance.md @@ -1,16 +1,17 @@ # VelarScript 0.4 Acceptance Matrix -Status: distribution and broader Web-application milestone complete +Status: historical milestone; its project-lifecycle contract is superseded by +the format-v2 explicit-extension clean break ## Distribution and projects | Contract | Evidence | | --- | --- | -| Compiler and CLI publish JavaScript plus `.d.ts`, require Node 24, and remain independent from Workbench | Package manifests and build tsconfigs | -| Packed tarballs install and run in a clean consumer | `npm run test:packages`: installed CLI version/build and compiler API probe | -| CLI/compiler versions are exact and package contents exclude repository tests | Tarball contract assertions | -| `velar create` refuses non-empty targets and creates a usable versioned project | Project lifecycle integration test | -| Legacy manifests upgrade explicitly; future versions fail closed | `velar upgrade --check`, write upgrade, and formatVersion 99 rejection | +| Compiler, Web, creator, and CLI publish JavaScript plus `.d.ts`, require Node 24, and remain independent from Workbench | Package manifests and build tsconfigs | +| Packed tarballs install and run in a clean consumer | `npm run test:packages`: installed CLI version/build, Web extension, creator, and compiler API probes | +| Release-set versions are exact and package contents exclude repository tests | Tarball contract assertions | +| `velar create` refuses non-empty targets and creates a usable format-v2 project | Project lifecycle integration test | +| Legacy manifests and unknown future versions fail closed | Format-v1 and formatVersion 99 rejection; there is no compatibility loader or upgrade command | ## JavaScript ecosystem boundary @@ -37,7 +38,7 @@ Status: distribution and broader Web-application milestone complete | Contract | Evidence | | --- | --- | | Workbench remains generic and consumes LSP protocol v1 | Product-boundary and language-support tests | -| Versioned project upgrade check is injected as generic command metadata | Workbench Velar contribution test | +| Project checking is injected as generic command metadata | Workbench Velar contribution test | | Installed toolchain is resolved project-locally | Workbench language-service descriptor and package-consumer gate | ## Acceptance commands diff --git a/docs/0.5-acceptance.md b/docs/0.5-acceptance.md index f8b98c37..419ebb6a 100644 --- a/docs/0.5-acceptance.md +++ b/docs/0.5-acceptance.md @@ -6,7 +6,7 @@ Status: pre-release productization milestone complete | Contract | Evidence | | --- | --- | -| Compiler and CLI tarballs have one exact version and dependency identity | Release rehearsal manifest and package consumer test | +| Compiler, Web, creator, and CLI tarballs have one exact version and dependency identity | Release rehearsal manifest and package consumer test | | Unchanged sources create identical package SHA-256 identities | Repeated rehearsal assertion | | Rehearsal records source/tree/package identity and never publishes | `velar-toolchain-release.json`, workflow/source assertions | | Strict candidates require stable version, clean tagged commit, matching remote, and license | Candidate refusal test | @@ -36,7 +36,7 @@ Status: pre-release productization milestone complete | Contract | Evidence | | --- | --- | -| Workbench installs packed compiler/CLI tarballs into a temporary project | `test:velar:installed` | +| Workbench installs the packed compiler/Web/creator/CLI release set into a temporary project | `test:velar:installed` | | Generic Workbench resolves project-local `node_modules/.bin/velar` | Installed-toolchain LSP acceptance | | Diagnostics and completion come from the installed LSP with protocol v1 | Cross-repository acceptance result | | Workbench contains no compiler dependency or duplicated Velar semantics | Existing product-boundary tests | diff --git a/docs/0.7-acceptance.md b/docs/0.7-acceptance.md index 0d7c5eed..efa1cce7 100644 --- a/docs/0.7-acceptance.md +++ b/docs/0.7-acceptance.md @@ -31,18 +31,18 @@ Status: internal 0.7A–0.7G engineering gate complete; external preview remains | Real Web behavior is cross-browser | Release Studio exercises config, logs, async event failure, failed render retention, mounted work, and cleanup continuation in Chromium, Firefox, and WebKit for development and CSP production | | Editor behavior stays injected | The installed-toolchain Workbench gate requests `velar/app`, `velar/config`, and `velar/log` completion through the generic project-local LSP host | -## 0.7C project testing, deployment, upgrade, and soak +## 0.7C project testing, deployment, extension boundary, and soak | Contract | Evidence | | --- | --- | | Browser tests belong to projects | `.browser.test.vel` and `velar test --browser` are product contracts; Core discovery excludes browser files and generated projects include a passing browser test/script | -| Automation stays small and typed | `velar/test.browser` exposes only navigation, interaction, observation, waiting, path, and viewport methods; raw DOM/Playwright evaluation is not exposed | +| Automation stays small and typed | `velar/web-test.browser` exposes only navigation, interaction, observation, waiting, path, and viewport methods; raw DOM/Playwright evaluation is not exposed | | Tests exercise production reality | The CLI builds an isolated CSP production site, serves the deployment contract, creates a fresh context per test, and fails page/console runtime errors automatically | | The browser matrix is selectable | Chromium is the local default and explicit Chromium, Firefox, WebKit, and `all` modes pass Release Studio recovery and eight-cycle route/cleanup soak scenarios (6/6 project flows) | -| Packed CLI carries the feature | A clean consumer installs packed compiler/CLI tarballs, creates a project, and passes its generated browser test in real Chromium | +| Packed CLI carries the feature | A clean consumer installs packed compiler/Web/creator/CLI tarballs, creates a project, and passes its generated browser test in real Chromium | | One real host adapter exists | Root-base `adapter: "netlify"` translates manifest headers and SPA fallback to official `_headers` and `_redirects`; non-root base fails closed | | Adapter output is release identity | Provider files are compiler-reserved, receive `adapter` asset roles, sizes and SHA-256 values, and participate in `buildId` | -| Previous projects remain usable | Fixed 0.3, 0.4, 0.5, and 0.6 fixtures all pass read-only upgrade inspection, explicit upgrade, current semantic check, and production build | +| The clean break is explicit | Generated projects use format 2 and declare `@velarscript/web`; missing, format-1, and unknown future manifests fail closed without a compatibility loader or rewrite command | | Workbench remains a generic host | Only the injected Velar contribution adds Browser Test command metadata; the shared editor/project-command host remains free of Velar branches | ## 0.7D verified production artifacts @@ -98,10 +98,10 @@ Status: internal 0.7A–0.7G engineering gate complete; external preview remains ## API and format versions -Velar language/toolchain version `0.7.0-dev` uses Standard API `0.3`, Web API -`0.6`, project format `1`, build manifest format `2`, and LSP protocol `1`. -The additive manifest/API work requires neither a project migration nor a -Workbench host protocol branch. +The current `0.9.0-dev` toolchain retains Standard API `0.4`, Web API `0.7`, +build manifest format `2`, and LSP protocol `1`. Project format `2` is a clean +break with explicit extensions; no legacy loader or migration command remains, +and the generic Workbench host protocol is unchanged. ## Remaining production gate diff --git a/docs/0.8-acceptance.md b/docs/0.8-acceptance.md index 96dacba4..91477219 100644 --- a/docs/0.8-acceptance.md +++ b/docs/0.8-acceptance.md @@ -74,10 +74,10 @@ Status: 0.8A–0.8F internal gates implemented; no publication or external deplo ## Compatibility versions -The internal toolchain version is `0.8.0-dev`. Standard API `0.4`, Web API -`0.6`, project format `1`, production build manifest format `2`, and LSP -protocol `1` remain compatible. 0.8A–0.8F is additive and requires no project migration -or generic Workbench host change. +The current internal toolchain is `0.9.0-dev`. Standard API `0.4`, Web API +`0.7`, project format `2`, production build manifest format `2`, and LSP +protocol `1` define the active boundary. The project-format clean break uses +explicit extensions and requires no generic Workbench host change. ## 0.8F real-application language completion diff --git a/docs/0.9-acceptance.md b/docs/0.9-acceptance.md index ad26de8e..5fb83045 100644 --- a/docs/0.9-acceptance.md +++ b/docs/0.9-acceptance.md @@ -334,10 +334,10 @@ Status: 0.9Z internal explicit-structural-equality gate complete; no publication ## Compatibility versions -The internal toolchain is `0.9.0-dev`. Standard API `0.4`, backward-compatible -Web API `0.6`, project format `1`, production build manifest format `2`, and LSP -protocol `1` remain compatible. Existing 0.3 through 0.8 project manifests need -no format migration. Source that used the unpublished development-only +The internal toolchain is `0.9.0-dev`. Standard API `0.4`, Web API `0.7`, +project format `2`, production build manifest format `2`, and LSP protocol `1` +define the active clean-break contract. Older project manifests are rejected +instead of migrated. Source that used the unpublished development-only `List.push(value)` spelling must rename it to `append(value)`; this deliberate language cleanup happens before a stable release rather than preserving two mutation names indefinitely. diff --git a/docs/1.0-acceptance.md b/docs/1.0-acceptance.md index d558e11a..14c36de6 100644 --- a/docs/1.0-acceptance.md +++ b/docs/1.0-acceptance.md @@ -14,12 +14,12 @@ release candidate. | Requirement | Internal evidence | Gate | | --- | --- | --- | -| Language semantics are defined by Velar rather than JavaScript accidents | Compiler execution and diagnostics cover strict values, optionals, control flow, functions, async/await, Promise adoption, arithmetic and power precedence, comparison chains, collections, modules, JSX, runtime Types, classes, inheritance, `init:`, native `private`, and read-only getters. A deterministic malformed-input corpus exercises compile, inspect, and format APIs without allowing internal exceptions to escape. The language charter records the accepted surface. | Passing internally | +| Language semantics are defined by Velar rather than JavaScript accidents | Compiler execution and diagnostics cover strict values, optionals, control flow, functions, defaultable-parameter identity and assignability, async/await, Promise adoption, arithmetic and power precedence, comparison chains, collections, modules, JSX, runtime Types, classes, inheritance, `init:`, native `private`, and read-only getters. Signature labels distinguish omission (`= default`) from nullable input (`?`). A deterministic malformed-input corpus exercises compile, inspect, and format APIs without allowing internal exceptions to escape. The language charter records the accepted surface. | Passing internally | | Source modules and JavaScript interop preserve checked identity | Cross-module source packages, dynamic `.vel` imports, JavaScript npm packages, bounded `.d.ts` graphs, native classes, aliases, inheritance, and nominal identities run through compiler, package, and LSP tests. | Passing internally | | Web applications own failures and cleanup | Release Studio exercises route, event, render, resource, action, HTTP cancellation, logging, and recovery paths. Hostile HTTP, file, realtime, form, route, browser-helper, storage, and IndexedDB values are rejected before unsafe side effects or through their owned asynchronous channel. The development server contains an unexpected watched rebuild failure, retains the last good application, reports the failure through status/SSE, recovers on the next edit, and converges after a 64-write burst. | Passing internally | -| JSX, reactivity, components, and browser output are portable | Development and verified CSP production suites pass Chromium, Firefox, and WebKit. SVG/HTML namespace transitions, accessibility diagnostics, lazy chunks, actions, resources, keyed updates, and cleanup are covered by real applications. | Passing internally | -| Real applications pressure the language instead of serving as syntax demos | FlowBoard covers finite state, collections, persistence, callbacks, lazy analytics, and equality; SupportDesk covers routing, native forms, resources, recovery, persistence, and dialogs; API Dashboard covers typed HTTP, npm interop, classes, getters, SVG, lazy components, and concurrent async work. Their Core and browser suites are part of the root gates. | Passing internally | -| A new team project works from installed packages | `tests/package.acceptance.ts` packs and installs the compiler and CLI, exercises the CLI and compiler API, and checks package contents. `tests/installed-browser.acceptance.ts` creates a fresh project from packed packages and runs its generated format, check, Core test, build, verify, and Chromium browser scripts. | Passing internally | +| JSX, reactivity, components, and browser output are portable | Development and verified CSP production suites pass Chromium, Firefox, and WebKit. SVG/HTML namespace transitions, accessibility diagnostics, stable DOM IDs, native disclosure/dialog behavior, lazy chunks, actions, resources, keyed updates, and cleanup are covered by real applications. | Passing internally | +| Real applications pressure the language instead of serving as syntax demos | FlowBoard covers finite state, collections, persistence, callbacks, lazy analytics, and equality; SupportDesk covers routing, native forms, resources, recovery, persistence, and dialogs; API Dashboard covers typed HTTP, npm interop, classes, getters, SVG, lazy components, and concurrent async work. Their Core and browser suites are part of the root gates. The separate official Website dogfoods three checked source-component package layers plus disclosure, dialog focus return, label/hint/error relationships, and keyboard interaction in all three engines. | Passing internally | +| A new team project works from installed packages | `tests/package.acceptance.ts` packs and installs compiler, Web, creator, and CLI packages, exercises both creation entries, the npm-backed `velar install` path, compiler/framework APIs, Core-library and Web-component package metadata, and tarball contents. `tests/installed-browser.acceptance.ts` creates fresh Web, docs, and component projects from packed packages and runs their generated format, check, Core test, build, verify, and Chromium browser scripts. | Passing internally | | Compiler and editor remain independent | The compiler LSP owns diagnostics, completion, hover, signatures, navigation, references, rename, formatting, type hints, semantic tokens, code actions, and commands. The generic Workbench host consumes the packed toolchain through the injected Velar contribution; the installed gate and 9 focused host tests pass without a Workbench-owned type system. | Passing internally | | Application-scale compilation has an explicit budget | `tests/performance.test.ts` checks a 121-module initial build and an incremental change that recompiles only the 41-module reverse-dependency closure while reusing 80 modules, under the checked time budgets. Project-session tests additionally remove and restore a dependency while preserving an unrelated compiled module. | Passing internally | | Production output is exact and reproducible | Browser-project acceptance builds and verifies production output. Release acceptance checks byte-identical package identities and a reproducible root Netlify preview across separate directories. Manifest tampering, extra files, traversal, unsafe replacement, and mismatched release sets fail closed. | Passing internally | @@ -46,7 +46,7 @@ bun test tests/language-support.test.ts bun scripts/test/verifyInstalledVelarToolchain.ts ``` -The compiler/CLI gate currently contains 190 tests before the three real Core +The compiler/CLI gate currently contains 197 tests before the three real Core application suites. The browser gate separately covers development, verified CSP production, all three real applications, and a freshly generated project. Counts are supporting detail; the commands and named contracts above are the diff --git a/docs/1.0-readiness-audit.md b/docs/1.0-readiness-audit.md index 44b25c43..f2b90309 100644 --- a/docs/1.0-readiness-audit.md +++ b/docs/1.0-readiness-audit.md @@ -11,13 +11,13 @@ repository, tag, npm publication, or hosted deployment. | Area | State | Current evidence or required work | | --- | --- | --- | -| New-project workflow | Passing internally | Packed compiler/CLI tarballs create a project, install into that project, and run its own format check, semantic check, Core test, production build, artifact verification, and Chromium browser test scripts. | +| New-project workflow | Passing internally | Packed compiler/Web/creator/CLI tarballs create default Web, routed docs, and reusable Web component projects, install into those projects, and run their own format check, semantic check, Core test, production build, artifact verification, and Chromium browser test scripts. The component package publishes its checked `velar.entry` plus README and keeps its preview separate. The same creator also checks and tests a framework-free Core source-library template. | | Source maintenance | Passing internally | `velar format [file or project] [--check]` recursively owns manifest source and excludes `.git`, dependencies, public assets, and build output. | | Data integrity | Passing internally | Official JSON, local/session storage, IndexedDB, HTTP JSON bodies, and WebSocket `sendJson` share strict finite primitive/record/dense-List validation. Known Map/Set/class/function values fail checking; dynamic lossy/cyclic values fail before storage, fetch, or socket side effects. | | Standard/Web API parity | Passing internally | Every compiler-declared official module export is imported from its shipped runtime and compared exactly. Full behavioral and browser matrices remain required separately. | -| Language surface | Passing internally | Core boundaries are unified. Runtime Type arguments fail early, async/time inputs are strict, and test matchers are subject-typed. Class constructors contain only caller inputs while typed instance/static fields own internal state; one synchronous `init:` block enforces post-field invariants, typed read-only `get` properties cover derived data without setters, and one native-backed `private` modifier covers constructor/body fields, getters, and concrete sync/async methods without a `public`/`protected` hierarchy. Getter abstract/override contracts, `super.name`, module identity, and property-shaped editor operations remain compiler-owned. Async expressions and block declarations share one resolved-value annotation and native Promise-adoption rule, enforce their own `await` boundary, reject direct `await` in parameter defaults, and fail before Promise values enter JSX. Object-returning arrows are unambiguous, power preserves right association plus predictable unary/await grouping, and strict comparison chains evaluate once while ordered links reject JavaScript bool/object/mixed coercion. Bounded `///` Markdown documents declarations and members across aliases without runtime output or JSDoc types. Multiline imports, parameters, types, constructors, and calls accept final commas without generating indentation tokens. Scope-aware completion, hover, signatures, navigation, visibility, and refactors retain one analyzer/LSP authority. Deterministic malformed inputs are retained across compile, inspect, and format APIs. The retained matrix is recorded in `1.0-acceptance.md`. | -| Web operation and recovery | Passing internally | Route/callback recovery, explicit dialog focus restoration, namespace-correct accessible SVG JSX across ordinary/lazy component and `foreignObject` boundaries, and IndexedDB commit/retry are owned. HTTP, Web component/navigation props, forms, browser helpers, files, and realtime validate hostile dynamic boundaries before native effects. API Dashboard adds typed HTTP, JavaScript-package interop, a class-owned chart scale whose `init:` rejects invalid construction, responsive SVG passed through a lazy component chunk, and two concurrently loaded typed metric feeds using an async arrow, with three-engine evidence. Watched rebuild failures retain the last good application, report through the managed development channel, recover on the next edit, and converge after rapid edits. Development and verified CSP production suites pass Chromium, Firefox, and WebKit; broader workload diversity remains correctly owned by the external-use row. | -| Toolchain delivery | Passing internally | Transactional create, strict config/help/LSP transport, packed consumers, reproducible release sets, safe output replacement, exact candidate verification, and independent Workbench hash checks pass. The current packed release passes the Workbench installed-toolchain gate, including collection/route signatures, HTML/component/SVG completion, typed object keys, recursive-record rename, semantic tokens, safe equality, class-body fields and `init:`, private-member inside/outside completion, a documented getter delivered as an ordinary read-only property, comparison-chain `bool` hover/inlay hints, declaration documentation in completion/hover, an async arrow's contextual parameter hover and Promise signature, and named-function Promise adoption, plus all 9 focused generic-language-host tests without moving language rules into Workbench. | +| Language surface | Passing internally | Core boundaries are unified. Runtime Type arguments fail early, async/time inputs are strict, and test matchers are subject-typed. Class constructors contain only caller inputs while typed instance/static fields own internal state; one synchronous `init:` block enforces post-field invariants, typed read-only `get` properties cover derived data without setters, and one native-backed `private` modifier covers constructor/body fields, getters, and concrete sync/async methods without a `public`/`protected` hierarchy. Getter abstract/override contracts, `super.name`, module identity, and property-shaped editor operations remain compiler-owned. Defaultable parameters participate in function identity and safe assignability, overrides preserve their arity contract, and compiler/LSP labels distinguish omission (`= default`) from nullable input (`?`). Async expressions and block declarations share one resolved-value annotation and native Promise-adoption rule, enforce their own `await` boundary, reject direct `await` in parameter defaults, and fail before Promise values enter JSX. Object-returning arrows are unambiguous, power preserves right association plus predictable unary/await grouping, and strict comparison chains evaluate once while ordered links reject JavaScript bool/object/mixed coercion. Bounded `///` Markdown documents declarations and members across aliases without runtime output or JSDoc types. Multiline imports, parameters, types, constructors, and calls accept final commas without generating indentation tokens. Scope-aware completion, hover, signatures, navigation, visibility, and refactors retain one analyzer/LSP authority. Deterministic malformed inputs are retained across compile, inspect, and format APIs. The retained matrix is recorded in `1.0-acceptance.md`. | +| Web operation and recovery | Passing internally | Web API 0.8 adds bounded application-local `domId` values for accessible label/title/hint relationships without cryptographic UUIDs. Route/callback recovery, explicit dialog focus restoration, namespace-correct accessible SVG JSX across ordinary/lazy component and `foreignObject` boundaries, and IndexedDB commit/retry are owned. HTTP, Web component/navigation props, forms, browser helpers, files, and realtime validate hostile dynamic boundaries before native effects. API Dashboard adds typed HTTP, JavaScript-package interop, a class-owned chart scale whose `init:` rejects invalid construction, responsive SVG passed through a lazy component chunk, and two concurrently loaded typed metric feeds using an async arrow, with three-engine evidence. The official Website separately dogfoods source component packages, native disclosure, modal focus return, form error/hint ownership, and keyboard paths in Chromium, Firefox, and WebKit. Watched rebuild failures retain the last good application, report through the managed development channel, recover on the next edit, and converge after rapid edits. Development and verified CSP production suites pass Chromium, Firefox, and WebKit; broader workload diversity remains correctly owned by the external-use row. | +| Toolchain delivery | Passing internally | Transactional create, strict config/help/LSP transport, packed consumers, reproducible release sets, safe output replacement, exact candidate verification, and independent Workbench hash checks pass. The current packed release passes the Workbench installed-toolchain gate, including exact defaultable/nullable signatures for `domId`, `slice`, and TypeScript-package methods, collection/route signatures, HTML/component/SVG completion, typed object keys, recursive-record rename, semantic tokens, safe equality, class-body fields and `init:`, private-member inside/outside completion, a documented getter delivered as an ordinary read-only property, comparison-chain `bool` hover/inlay hints, declaration documentation in completion/hover, an async arrow's contextual parameter hover and Promise signature, and named-function Promise adoption, plus all 9 focused generic-language-host tests without moving language rules into Workbench. | | External use and release | Requires later authority | Apache-2.0 is applied and retained in both npm tarballs. A real hosted preview, independent users, compatibility feedback, stable clean tag, provenance, and explicit publish authority remain absent. | ## Evidence commands diff --git a/docs/compiler-architecture.md b/docs/compiler-architecture.md index 85411e45..388baa0c 100644 --- a/docs/compiler-architecture.md +++ b/docs/compiler-architecture.md @@ -7,12 +7,11 @@ and incremental pipeline implemented ```text .vel source --> indentation-aware lexer --> source-spanned Core + Web AST --> scope and lightweight type analysis --> Web validation and lowering hints --> readable ESM JavaScript + native DOM operations --> extracted scoped/global CSS + Web assets +-> Core lexer plus an extension-selected parser when a framework owns syntax +-> source-spanned internal syntax carriers +-> extension-selected analysis, semantic indexing, intrinsic typing, dependency inspection, and module-interface contribution +-> extension-selected JavaScript emitter +-> readable ESM JavaScript and optional extension artifacts -> development source maps / explicitly enabled production source maps ``` @@ -87,33 +86,71 @@ replacing JavaScript identity, insertion order, or membership semantics. ## Package ownership -- `packages/compiler` owns source text, diagnostics, AST, parsing, Core/Web - analysis, JavaScript/DOM/CSS emission, formatting, and source maps. -- `packages/cli` owns `velar.json`, commands, filesystem graphs, official - Standard/Web modules, explicit public-config validation, test discovery, +- `packages/compiler` owns the Core language, source text, diagnostics, + extension host, Core analysis, Core JavaScript emission, formatting, and + source maps. Component, JSX, reactivity, lifecycle, CSS, DOM lowering, and + Web types are not active Core language features. Its extension protocol has + explicit parser, analyzer, semantic-index, intrinsic-analysis, + dependency-inspection, public-interface, module, emitter, lexical-editor, and + contextual project-editor seams; + loading lexical keywords alone can never silently activate Web semantics. + Its `framework-host` subpath is a platform-neutral tooling ABI containing + only protocol types and a version constant; it does not implement HTML, + filesystem access, servers, bundling, browser automation, or framework + behavior. +- `packages/web` owns component/JSX syntax activation, reactive and lifecycle + analysis, semantic symbols/references, Web intrinsic typing, project graph + traversal, exported component/reactive interfaces, DOM/CSS emission, Web + type/global guidance, Web standard modules, browser runtime, `web` manifest + validation, JSX/native-element completion and rename protection, and the + separate `@velarscript/web/host` implementation. That host owns application + and compile-error HTML documents, the development reload client, CSP + construction, static-deployment projection, source-map policy, base URL, and + browser-test contract. It + depends on the neutral compiler extension contract, not CLI orchestration or + an editor host. +- `packages/create` owns transactional project creation and the complete + `web`, `docs`, `library`, and `component` template inventory. The component + template is an ordinary Web source package with a separate preview entry, not + a compiler extension. Creator code has no compiler, browser, CLI, or editor + dependency. +- `packages/cli` owns the format-2 manifest shell, extension resolution, + commands, the npm-backed project dependency workflow, filesystem graphs, the + Core Standard modules, test discovery, optimized production bundling, the dev server, hot - replacement, and the language server. + replacement transport, browser driver, verification, and the language + server. For every declared extension it may load an optional `/host` export, + validates framework-host protocol version 1 and matching compiler capability, + and composes at most one application host. CLI source neither identifies the + official Web npm package nor constructs Web HTML/CSP/JSX-editor/lifecycle + behavior. - VelarOS Workbench owns the generic editor and LSP host. Its default Velar contribution owns presentation and connection metadata, but never copies or embeds compiler semantics. -The compiler and CLI build as independent npm packages containing emitted -JavaScript, source maps, and `.d.ts` declarations. The CLI pins the exact -compiler version. Packed tarballs must install and execute in a clean consumer; -Workbench is neither bundled into nor imported by either package. +The compiler, Web framework, creator, and CLI build as independent npm packages +containing emitted JavaScript, source maps, and `.d.ts` declarations. Web pins +the exact compiler version. CLI pins the compiler and creator but neither +depends on nor peers with Web; a Web project installs Web directly. +Packed tarballs must install and +execute in a clean consumer; Workbench is neither bundled into nor imported by +any package. -Project manifests declare `formatVersion: 1`. Creation refuses non-empty -targets, upgrades are explicit and inspectable, and unknown future versions -fail closed before compilation. +Project manifests declare `formatVersion: 2` and a required `extensions` list. +There is no legacy loader or upgrade command; missing, format-1, and unknown +future versions fail closed before compilation. -Production Web builds are assembled in a sibling staging directory. Public +Production framework builds are assembled in a sibling staging directory. Public assets are copied through a confined regular-file walker, bundling and all manifests finish there, and only then does the complete directory replace the previous output. Compiler-owned entry/fallback/manifest names and symbolic links fail closed. The deployment manifest is the provider-neutral authority for CSP, security headers, cache rules, base paths, and SPA fallback. -The production verifier is the read-side authority for format-2 output. It +The production verifier is the read-side authority for format-3 framework +build output and format-2 static-deployment output. Each build records the +framework package, capability, target, host-protocol version, framework API +version, and framework artifact kind. It requires the physical regular-file tree to equal the manifest inventory, recomputes size/SHA-256/build identity, and validates the build/deployment relationship before preview binds a port. Browser-project tests call this same @@ -129,7 +166,7 @@ content hashes and source maps reproducible across output locations. Linked production maps are disabled by default and remain an explicit manifest input. Release packaging is outside compiler semantics. A repository script builds -both npm packages, records source and tarball identities, verifies every +all four npm packages, records source and tarball identities, verifies every SHA-256, and refuses candidate status without a clean exact tag, matching remote, stable version, and publishable license. It contains no publish step. diff --git a/docs/component-packages.md b/docs/component-packages.md new file mode 100644 index 00000000..5c3b49e6 --- /dev/null +++ b/docs/component-packages.md @@ -0,0 +1,75 @@ +# Velar Component Packages + +Status: source-package contract under application dogfood + +A Velar component package is an ordinary npm package whose public implementation +is checked `.vel` source. It is not a compiler extension, does not provide a +framework host, and cannot silently activate language syntax. + +## Package contract + +```json +{ + "name": "example-components", + "version": "1.0.0", + "type": "module", + "files": ["src/index.vel", "README.md"], + "velar": { "entry": "src/index.vel" }, + "peerDependencies": { + "@velarscript/web": "^1.0.0" + } +} +``` + +- `velar.entry` is the one public source entry resolved by the compiler. +- `files` contains the public source and required package documentation. Demo + applications, browser tests, screenshots, and local project manifests remain + outside the published inventory. +- `@velarscript/web` is a peer contract because the consuming application owns + the framework instance and compiler extension. A component library must not + hide a second Web runtime inside itself. +- Runtime JavaScript dependencies remain ordinary npm dependencies. Framework + and toolchain dependencies are not smuggled through Velar metadata. + +`npm create velar@latest components -- --template component` creates this +shape with a local preview application, Core contract test, browser rendering +test, production build, and verification scripts. + +## Layering + +Component systems should grow in three layers: + +1. Theme-neutral primitives own accessible behavior and small layout contracts. +2. A brand/theme package composes primitives with tokens, typography, color, + spacing, and visual identity. +3. Product packages compose both layers into navigation, documentation, forms, + dashboards, or other domain patterns. + +The official website dogfoods this split privately as `@velarscript/ui`, +`@velarscript/site-ui`, and `@velarscript/docs-kit`. Those packages do not enter +the public toolchain release merely because they live under the Velar namespace; +promotion requires a stable API, independent package acceptance, and explicit +release scope. + +## Accessibility boundary + +Primitive components prefer native elements and browser behavior. A wrapper +must preserve the native role, keyboard path, focus target, and accessible name. +ARIA describes behavior that really exists; it is not used to simulate missing +interaction. Skip links require a real focusable target. Reduced-motion rules +belong beside the animation they disable. + +Reusable label, title, hint, and error relationships use +`domId(prefix="velar")` from `velar/web`. Component packages do not require +callers to coordinate global ID strings and do not spend cryptographic UUIDs on +ordinary in-document accessibility relationships. + +Browser tests verify rendered roles/attributes and the user path. Type checking +alone is not accessibility evidence. + +## Versioning + +Component packages version independently from the language and Web API. Their +peer range states which Web contract consumers must provide. Breaking props, +rendered semantics, focus behavior, or published source paths require a major +component-package version even when generated JavaScript would still execute. diff --git a/docs/continuous-integration.md b/docs/continuous-integration.md index 006ed05a..248ed2da 100644 --- a/docs/continuous-integration.md +++ b/docs/continuous-integration.md @@ -9,7 +9,7 @@ The repository defines three GitHub Actions workflows: Chromium, Firefox, and WebKit dependencies and runs both development-server and CSP-enabled production browser matrices, the project-owned `.browser.test.vel` suite in all engines, and the same generated browser test - through packed installed compiler/CLI tarballs. Browser-project execution + through packed installed compiler/Web/creator/CLI tarballs. Browser-project execution first verifies the exact production asset inventory and uses the public preview server. - Hosted-deployment acceptance runs the public remote verifier against root and diff --git a/docs/implementation-status.md b/docs/implementation-status.md index 4e1237b2..d71eb2a9 100644 --- a/docs/implementation-status.md +++ b/docs/implementation-status.md @@ -9,7 +9,7 @@ Workbench consumption, base-aware stable Web APIs, incremental dev compilation, publishable toolchain packages, project lifecycle management, deliberately limited TypeScript declaration consumption, cross-browser automation, reproducible release rehearsal, secure static deployment, and production -observability. The compiler-owned 0.6 language and Web API baseline is complete; +observability. The compiler-owned 0.6 language baseline and Web API 0.8 are complete; 0.7 closed the internal reliability, configuration, testing, and release rehearsal sequence. 0.8A–0.8E added checked dynamic modules, strict block matching, safe multipart uploads, checked rest parameters, and native Set @@ -177,10 +177,20 @@ coordinates, dynamically chunked component-rendered bars, an HTML `foreignObject direct browser namespace assertions. The packed LSP and independently installed Workbench gate also complete `svg`, `foreignObject`, `viewBox`, and `stroke-width` from the analyzer-owned -Web context; the generic editor host contains no SVG- or Velar-specific branch. +Web context. Those JSX tag/attribute contexts and the `children` rename guard +are now supplied by the Web compiler extension; the generic CLI project-semantic +layer and editor host contain no SVG-, JSX-, or Velar-specific branch. ## Complete +- npm-backed project dependency commands cover install, add, remove, and + range-respecting update without introducing a Velar registry. Package and + lockfile changes remain npm-owned; generic `velar.extension` metadata drives + atomic format-2 extension activation and removal, including cleanup of the + extension-owned manifest field. Registry arguments are bounded and passed + after `--` without a shell, invalid activation restores the prior project + manifest, and packed-consumer acceptance performs a real local-file npm + install through the installed CLI. - Indentation-aware lexer/parser, stable `VEL` diagnostics, formatter, source maps, and readable ESM JavaScript generation. - Intentional diagnostics for rejected JavaScript legacy surface, including @@ -303,11 +313,13 @@ Web context; the generic editor host contains no SVG- or Velar-specific branch. unsafe HTML, and basic accessibility contracts. - `velar.json` plus `velar check`, `build`, `verify`, `preview`, `dev`, `test`, `format`, and `lsp`. -- Project format version 1 plus fail-safe `velar create` and explicit - `velar upgrade` / `velar upgrade --check` lifecycle commands. +- Project format version 2 with an explicit `extensions` list, fail-safe + `velar create`, and a clean break that rejects legacy manifests instead of + loading or rewriting them. - Ten explicit Web modules: `velar/app`, `velar/config`, `velar/web`, `velar/http`, `velar/storage`, `velar/forms`, `velar/browser`, `velar/files`, - `velar/realtime`, and `velar/test`. + `velar/realtime`, and `velar/web-test`; Core assertions remain in + `velar/test`. - Independently versioned Standard API 0.4 with 133 exports across `velar/collections`, `velar/text`, `velar/math`, `velar/json`, `velar/async`, `velar/url`, `velar/time`, `velar/id`, and `velar/log`. @@ -380,14 +392,14 @@ Web context; the generic editor host contains no SVG- or Velar-specific branch. document highlights, non-TypeScript inlay hints, structural completion triggers, and safe current-file code actions through generic contracts. Workbench and the compiler remain independent products. -- Versioned Velar Web API 0.6 for application error ownership, explicit public - configuration, routing/navigation, metadata ownership, HTTP, +- Versioned Velar Web API 0.8 for application error ownership, bounded stable + DOM IDs, explicit public configuration, routing/navigation, metadata ownership, HTTP, storage/IndexedDB, forms, browser environment, files, realtime, and tests; compiler interfaces and emitted runtime code share one authority. -- Backward-compatible Web 0.6 route/form completion: runtime-validatable +- Web 0.8 route/form completion: runtime-validatable `RouteContext`, checked route patterns/component props, typed text/number/ checkbox/multi-value form reads, and owned native reset. -- Backward-compatible Web 0.6 navigation/dialog completion: application-relative +- Web 0.8 navigation/dialog completion: application-relative `NavLink` activity with `aria-current`, nominal `DialogElement` refs, and mounted native modal open/close/result helpers without untyped DOM access. - Lazy root mounting surfaces an accessible fatal state; failed dynamic/keyed @@ -411,13 +423,16 @@ Web context; the generic editor host contains no SVG- or Velar-specific branch. recompile only changed modules and reverse dependents. - Dynamic watching for installed and workspace Velar npm package roots. - Machine-readable development status and deterministic production build - identity/module composition/asset roles. + identity/module composition/asset roles, including framework package, + capability, target, host-protocol version, API version, and artifact kind. - Playwright-backed Chromium, Firefox, and WebKit acceptance automation plus a 121-module application-scale incremental budget. - A three-module reusable Velar Web library exercising public data types, functions, nested components, children, and scoped CSS. -- Publishable `@velarscript/compiler` and `@velarscript/cli` JavaScript plus - `.d.ts` packages, verified from packed tarballs in a clean npm consumer. +- Publishable `@velarscript/compiler`, `@velarscript/web`, `create-velar`, and + `@velarscript/cli` JavaScript plus `.d.ts` packages, verified from packed + tarballs in a clean npm consumer. The creator owns checked `web`, `docs`, and + `library` templates shared by npm and CLI entry points. - A deliberately limited `.d.ts` bridge for safe JavaScript package imports; constants/functions, nested callback parameters, and simple object/interface fields, methods, or directly expandable bases map to Velar types. Unsupported @@ -425,13 +440,13 @@ Web context; the generic editor host contains no SVG- or Velar-specific branch. never weakens silently by dropping base fields. - Production dependency summaries that distinguish Velar source packages from JavaScript packages. -- Reproducible compiler/CLI release rehearsal with source-tree identity, +- Reproducible compiler/Web/creator/CLI release rehearsal with source-tree identity, SHA-256 checksums, strict tagged-candidate refusal, and no publication path. - Linux/macOS/Windows Node 24 CI plus Chromium/Firefox/WebKit development and CSP production browser matrices. - Isolated static builds with last-good output preservation, reserved-file and public-symlink rejection, strict default CSP, SPA fallback, header/cache - contract, and format-2 build manifests. + contract, format-3 framework build manifests, and format-2 deployment manifests. - A 15-module Release Studio exercising typed data, async HTTP, routing and metadata, accessible forms/progress, browser state, local/session/IndexedDB persistence, file selection/downloads, explicit watcher cleanup, reusable @@ -452,8 +467,9 @@ Web context; the generic editor host contains no SVG- or Velar-specific branch. - A root-base Netlify adapter emits official `_headers` and `_redirects` files from the neutral deployment manifest; adapter files are reserved and included in build hashes and identity. -- Fixed 0.3 through 0.6 project fixtures pass current-CLI read-only upgrade - checks, explicit upgrade, semantic checking, and production builds. +- Generated Core and Web projects declare their compiler extensions explicitly; + missing, format-1, and unknown future manifests fail closed with no legacy + loader or upgrade command. - Strict application-build verification rejects missing, extra, modified, symlinked, unsafe, duplicated, or structurally inconsistent output while recomputing every SHA-256 and `buildId` and cross-checking deployment state. @@ -616,7 +632,8 @@ current-release gate proves one inferred collection type and one suppressed explicit annotation, resource-handle suppression, and exact same-document highlights. It also proves a narrowed local, component resource/action/prop, checked List members through ordinary completion, a collection-literal -`slice` signature, `route.params` Map completion/signature/hover, and typed +`slice` signature, compiler-owned defaultable/nullable parameter labels, +`route.params` Map completion/signature/hover, and typed record-field definition plus multi-site rename navigation. External LSP acceptance also proves a component prop definition/hover/reference and three-site rename without a Workbench JSX prop table. The packed installed gate @@ -631,7 +648,7 @@ four-method language-path interface without loading the wider Workspace runtime. The bounded-resource audit now passes its complete internal delivery matrix: -190 compiler/CLI tests, FlowBoard, SupportDesk, and API Dashboard Core tests, packed consumer +197 compiler/CLI tests, FlowBoard, SupportDesk, and API Dashboard Core tests, packed consumer installation, reproducible non-publishing rehearsal, installed Workbench toolchain acceptance, the 9 generic-host tests, and Chromium/Firefox/WebKit development plus verified CSP production application suites. The new limits diff --git a/docs/language-charter.md b/docs/language-charter.md index 7d4b35ff..3a98164a 100644 --- a/docs/language-charter.md +++ b/docs/language-charter.md @@ -13,10 +13,18 @@ It compiles to modern JavaScript, CSS, and Web assets and runs on existing brows VelarScript combines: -- JavaScript's expression model, objects, arrays, modules, asynchronous model, and JSX suitability. +- JavaScript's expression model, objects, arrays, modules, and asynchronous model. - Python's readable blocks, named functions, explicit `self`, and approachable control flow. - A small type layer for assistance and boundary validation rather than type-level programming. -- A compiler-owned Web model for components, state, DOM updates, and scoped CSS. +- An official `@velarscript/web` extension for JSX, components, state, DOM + updates, lifecycle, and scoped CSS. + +The Core language and Web framework are separate contracts. Core provides the +neutral compiler-extension host and framework-host ABI but does not activate or document JSX, +components, reactivity, lifecycle, DOM types, or CSS as Core syntax. A format-2 +project opts into those features with `"extensions": ["@velarscript/web"]`. +The Web package's separate host entry owns browser-document, CSP, reload, +deployment, and browser-test policy; the CLI supplies generic host mechanics. ## 2. Non-goals @@ -76,7 +84,7 @@ JavaScript contributes: - `?.` and `??` - inline conditionals with `? :` - collection operations such as `map`, `filter`, and `reduce` -- JSX +- JSX, when contributed by `@velarscript/web` Python contributes: @@ -261,6 +269,11 @@ component Choice(label: string, onChoose: (string) -> none): - Parameter types appear inside parentheses and the result follows `->`. - Parameter names are omitted because they do not change assignability. +- Compiler and LSP display labels append `= default` to a positional parameter + that the caller may omit. This is deliberately distinct from `T?`, which + means the caller may pass `none`; a defaultable `string` parameter does not + become nullable merely because it can be omitted. A parameter that is both + nullable and omittable displays both facts, for example `string? = default`. - A single final rest element uses `...`, for example `(string, ...number) -> bool`. - Callback parameters and results are checked for named functions, contextual @@ -1022,9 +1035,10 @@ VelarScript does not embed arbitrary JavaScript in `.vel` files. Complex compatibility code belongs in a separate `.js` adapter imported through `import js`. -## 14. JSX +## 14. `@velarscript/web`: JSX -JSX is a native VelarScript expression and is not React JSX. +JSX is a native expression contributed by `@velarscript/web`; it is not React +JSX and is rejected by a Core-only project. ```velar return
@@ -1071,7 +1085,7 @@ return
that merely looks like SVG but was created as an HTML unknown element is a compiler defect, not acceptable compatibility behavior. -## 15. Components and state +## 15. `@velarscript/web`: components and state ```velar component Counter(start: number = 0): @@ -1377,10 +1391,11 @@ my-app/ ```json { - "formatVersion": 1, + "formatVersion": 2, "entry": "src/main.vel", "outDir": "dist", "publicDir": "public", + "extensions": ["@velarscript/web"], "web": { "title": "My App", "base": "/", @@ -1405,23 +1420,23 @@ velar test --browser [chromium|firefox|webkit|all] velar format [file.vel | project-directory] [--check] velar lsp velar create -velar upgrade ``` `.test.vel` files are discovered recursively. Top-level functions named `test_*` are tests and do not need to be exported. Assertions come from `velar/test`. `.browser.test.vel` files are excluded from Core tests and run -only through `--browser`; they use the restricted typed `browser` controller, +only through `--browser`; they import the restricted typed `browser` controller +from `velar/web-test`, not raw DOM or Playwright APIs. Each browser test receives a fresh context against a real isolated CSP production build. `velar create` refuses non-empty target directories and creates a minimal -format-version-1 application with a separate application module, entry point, +format-version-2 application with a separate application module, entry point, Core test, browser test, and project-level formatting scripts. Project-format mode recursively owns `.vel` source while excluding `node_modules`, `.git`, the -public directory, and build output. `velar upgrade --check` is read-only; `velar -upgrade` explicitly upgrades legacy manifests. Unknown future project format -versions fail closed. Creation is transactional: all files are completed in a +public directory, and build output. Legacy and unknown future project format +versions fail closed; there is no compatibility loader or upgrade command. +Creation is transactional: all files are completed in a sibling staging directory before an absent or verified-empty target is replaced. Manifest and nested Web objects reject unknown fields, so misspelled settings do not silently fall back; `web.base` is one canonical application pathname. @@ -1431,8 +1446,9 @@ its defaults. Unexpected top-level arguments return a usage error, while unexpected operational failures are normalized without exposing a Node stack as the command-line contract. -Official Web modules are explicit imports. Their stable public API version is -0.6 and is specified in [web-api.md](web-api.md): +Official Web modules are explicit imports contributed by `@velarscript/web`. +Their stable public API version is 0.7 and is specified in +[web-api.md](web-api.md): - `velar/app`: compiler-owned application error reporting, classification, root-mount fallback, last-valid render retention, and explicit handler cleanup. @@ -1470,7 +1486,8 @@ Official Web modules are explicit imports. Their stable public API version is downloads without persistent browser file handles. - `velar/realtime`: explicitly closed WebSocket and server-sent-event wrappers; `sendJson` shares the strict lossless JSON data boundary. -- `velar/test`: typed Core assertions plus a restricted project-level browser +- `velar/test`: typed Core assertions. +- `velar/web-test`: the Web extension's restricted project-level browser controller for production application tests. Ordinary Velar source does not receive untyped `console`, DOM/window, @@ -1542,7 +1559,7 @@ VelarScript 0.9 is validated with: - A production-style, base-routed Web application using reusable Velar source packages, a safely typed JavaScript npm package, Head ownership, accessible forms, persistent state, and scoped CSS in Chromium, Firefox, and WebKit. -- A 121-module incremental compilation budget plus packed compiler/CLI +- A 121-module incremental compilation budget plus packed compiler/Web/creator/CLI installation in a clean npm consumer. - A 15-module Release Studio in development and CSP-enabled production across Chromium, Firefox, and WebKit. @@ -1590,14 +1607,16 @@ VelarScript 0.9 is validated with: - Standard API 0.4 type/runtime acceptance across collections, text, math, JSON, async, URL, time, secure IDs, and structured logging modules, including execution from a clean packed CLI consumer. -- Web API 0.6 type/runtime acceptance across routing, metadata, HTTP, +- Web API 0.8 type/runtime acceptance across routing, metadata, stable DOM IDs, HTTP, storage/IndexedDB, forms, browser helpers, files, WebSocket/SSE, and tests in all six development/production browser flows, including explicit public configuration and mount/render/event/mounted/cleanup error ownership. - Project-level `.browser.test.vel` acceptance through both source and packed CLIs, including three browser engines and repeated route/cleanup failure soak. -- Current-CLI upgrade and production-build acceptance for fixed 0.3, 0.4, 0.5, - and 0.6 project fixtures, plus a root-base Netlify adapter artifact contract. +- Format-v2 Core and Web project acceptance with explicit compiler extensions, + legacy/future-version rejection, plus a root-base Netlify adapter artifact + contract, format-3 framework build identity, and format-2 static-deployment + identity. Canvas game development is not part of this milestone. diff --git a/docs/package-distribution.md b/docs/package-distribution.md index bc75db7d..bb846a8b 100644 --- a/docs/package-distribution.md +++ b/docs/package-distribution.md @@ -2,21 +2,74 @@ Status: pre-release package contract for Velar 0.9; publication deferred -The toolchain is distributed as two independent npm packages: +The toolchain is distributed as four independent npm packages: - `@velarscript/compiler`: compiler, formatter, diagnostics, semantic index, - and Core/Web lowering APIs. + Core lowering APIs, compiler-extension ABI, and neutral framework-host ABI. +- `@velarscript/web`: the official Web framework's versioned module contract + and browser runtime, plus independent compiler and framework-host entries. +- `create-velar`: the lightweight, transactional `npm create velar` entry and + the single authority for `web`, `docs`, `library`, and reusable Web + `component` templates. - `@velarscript/cli`: `velar` CLI, project tooling, development server, test - runners, production builder/local and remote verifiers/preview server, and - LSP server. + runners, npm-backed dependency workflow, production builder/local and remote + verifiers/preview server, and LSP server. -Both packages require Node.js 24 or later, publish JavaScript and `.d.ts` -artifacts from `dist`, and contain no Workbench code. The CLI depends on the -exact matching compiler version. Workbench discovers the project-local +All four packages require Node.js 24 or later, publish JavaScript and `.d.ts` +artifacts from `dist`, and contain no Workbench code. Web pins the exact +matching compiler version. CLI pins compiler and creator but has no Web +dependency: it resolves every compiler/project extension declared by the +application's format-v2 manifest from that project, then discovers and +validates an optional protocol-v1 `/host` entry from the same package. +Workbench discovers the project-local `node_modules/.bin/velar` executable and never embeds the compiler. -`npm run test:packages` is the release boundary. It builds both packages, runs -`npm pack`, checks the tarball contents, installs both tarballs into a clean +## Package model + +Velar does not operate a second registry or invent another dependency graph. +npm remains authoritative for registry resolution, `package.json`, +`package-lock.json`, installation, integrity, audit, and update ranges. The CLI +adds a project-aware layer: + +```sh +velar install +velar add ... [--dev] +velar remove ... +velar update [package...] +``` + +Registry package specifications are passed to npm as argument-array data after +`--`; paths, Git URLs, aliases, and injected npm flags are intentionally left +to direct npm usage. `update` follows the ranges already declared in +`package.json` rather than silently moving every dependency to a new major. + +A reusable Velar source package declares `velar.entry`. A compiler/framework +extension declares `velar.extension`: + +```json +{ + "velar": { + "extension": { "manifestKey": "web" } + } +} +``` + +After npm installs such a package, `velar add` atomically adds its package name +to `velar.json.extensions`. `velar remove` removes the extension and its owned +manifest field. The compiler and optional framework-host exports remain the +runtime authority; metadata only controls project activation and never bypasses +protocol validation. + +The `library` creator template publishes a Core-only source entry. The +`component` template uses the same `velar.entry` mechanism for a Web component, +declares `@velarscript/web` as its peer contract, and keeps its demo application +and tests out of the published `files` inventory. Component packages therefore +remain ordinary source libraries rather than hidden framework extensions. +The complete layering, accessibility, and versioning rules are documented in +[`component-packages.md`](component-packages.md). + +`npm run test:packages` is the release boundary. It builds all four packages, +runs `npm pack`, checks the tarball contents, installs the complete set into a clean temporary consumer, invokes the installed CLI, builds and runs a Velar file that imports the Core Standard API, and imports the public compiler API. The browser package gate additionally creates a project through packed tarballs, @@ -24,20 +77,20 @@ builds and verifies its production output, and runs its browser test. A successful source build without this consumer test is not considered publishable. -`npm run release:rehearse` adds the release-set boundary: both tarballs, +`npm run release:rehearse` adds the release-set boundary: all four tarballs, deterministic SHA-256 values, source identity, npm integrity, and explicit publication blockers. Candidate mode fails closed unless Git/version/remote and license requirements are satisfied. CI may attest and upload these tarballs, but no Velar 0.9 workflow invokes `npm publish`. Release output replacement refuses repository roots/ancestors, symbolic links, -and non-release directories. Verification accepts exactly the sorted compiler -and CLI package identities, canonical tarball names, matching versions/sizes/ +and non-release directories. Verification accepts exactly the sorted compiler, +Web, creator, and CLI package identities, canonical tarball names, matching versions/sizes/ hashes/npm integrity, the declared checksum file, and no undeclared files. Workbench independently checks the same package set and tarball SHA-256 values before installing them; it does not import this repository's verifier. -The workspace, compiler, and CLI use Apache-2.0. Both npm tarballs contain the +The workspace, compiler, Web framework, creator, and CLI use Apache-2.0. Every npm tarball contains the complete license text, and package acceptance verifies the installed metadata and file rather than trusting the source manifest alone. The current rehearsal remains intentionally not publishable because the development version, source diff --git a/docs/production-readiness.md b/docs/production-readiness.md index 9ab53ac9..fd798ca9 100644 --- a/docs/production-readiness.md +++ b/docs/production-readiness.md @@ -2,7 +2,7 @@ Status: internal engineering gate complete; external preview and release evidence pending; do not describe VelarScript as production-ready yet -Production-ready means an ordinary team can create, operate, upgrade, debug, +Production-ready means an ordinary team can create, operate, evolve, debug, test, deploy, and recover a real Velar Web application without depending on repository-internal knowledge or unsafe browser globals. A green compiler suite alone is not sufficient evidence. @@ -19,9 +19,9 @@ alone is not sufficient evidence. | Browser/deployment compatibility | Chromium, Firefox, and WebKit pass development and CSP production flows; deployment manifest has at least one exercised host adapter | Passing internally: browser matrices pass; root-base Netlify files preserve asset 404 before SPA fallback; `verify-deployment` checks real hosted bytes, MIME, headers, and routes; a live provider run remains external-use evidence | | Application artifact integrity | Teams can prove that a production directory exactly matches its build/deployment manifests and run that exact output locally | Passing: `velar verify` checks complete inventory/hash/relationship integrity; hashing and preview delivery stream regular files, production inventory is capped at 100,000 assets, and the same verified server powers browser-project tests | | Reproducibility/source disclosure | Identical production inputs produce identical bytes and source code is not published accidentally | Passing: stable virtual Velar inputs remove random-path hashing; cross-directory builds are byte-identical and linked source maps are explicit/off by default | -| Package/upgrade stability | Packed toolchains install cleanly, exact versions match, compatibility policy is documented, project migrations fail closed, and a previous project upgrades successfully | Passing: packed consumers plus fixed 0.3–0.6 inspect/upgrade/check/build fixtures pass | +| Package/project stability | Packed toolchains install cleanly, exact versions match, and the project-extension boundary is explicit and fail-closed | Passing: packed consumers create format-v2 Core and Web projects; missing, format-1, and unknown future manifests are rejected without a compatibility loader or upgrade command | | Editor independence | Project-local LSP works through the generic Workbench host with diagnostics, completion, navigation, rename, formatting, type hints, occurrence highlights, semantic tokens, code actions, and commands | Current packed-toolchain acceptance and 9/9 focused generic-host tests pass. Completion is lexical/scope-aware and member items come from analyzer-owned signatures rather than a host type table. Selectively indexed checked expressions preserve completion, hover, and active-parameter signatures through collection literals and nested Web chains; JSX tag/attribute and typed object-key positions are context-aware and restore lexical symbols inside values. The installed gate proves collection and route signatures, HTML/component/SVG completion, typed object keys, recursive-record and component-prop refactors, semantic tokens, safe equality fixes, a real npm class, native `ScoreCard` class-body fields plus `init:`, a private history field that appears through `self` but not consumer completion, and a documented read-only `summary` getter delivered as an ordinary property. It also covers comparison-chain `bool` hover/inlay hints, packed `///` documentation in completion/hover, an async arrow with contextual parameter hover plus `Promise` signature help, and a named async function that directly adopts its Promise result. Record/class members navigate across aliases and inheritance, including inherited static declarations; private members instead keep owner-local navigation/refactors. CodeMirror consumes all of this through generic LSP contracts. The host validates tarball hashes independently and injects format/format-check commands without owning language rules. The wider Workbench tree remains mid Platform migration; that unrelated baseline is not Velar evidence. | -| Release integrity | Stable clean tagged source produces verified reproducible tarballs with license, provenance, and explicit publish authority | Partial: Apache-2.0 is applied to the workspace and both package tarballs; rehearsal/candidate refusal exists; the first committed remote source, stable tag, and public release authority remain external decisions | +| Release integrity | Stable clean tagged source produces verified reproducible tarballs with license, provenance, and explicit publish authority | Partial: Apache-2.0 is applied to the workspace and all four package tarballs; rehearsal/candidate refusal exists; the first committed remote source, stable tag, and public release authority remain external decisions | | External use | More than the repository's own examples are built, deployed, and operated; feedback is converted into compatibility tests | Missing: a reproducible root Netlify candidate, remote verifier, signed-report workflow, and Chromium candidate smoke now exist, but no authorized live deployment or external user evidence exists yet | ## Completed internal sequence @@ -30,7 +30,7 @@ alone is not sufficient evidence. 2. 0.7B: complete — application error recovery/reporting, explicit public configuration, and structured logging. 3. 0.7C: complete — browser-project test command, host-adapter acceptance, - upgrade fixtures, and production soak/failure tests. + format-v2 project-boundary checks, and production soak/failure tests. 4. 0.7D: complete — strict application artifact verification and verified production preview. 5. 0.7E: complete — reproducible production bundling and opt-in source maps. @@ -142,7 +142,7 @@ alone is not sufficient evidence. 41. 1.0 audit B: complete — bounded compiler/project inputs, standard/Web runtime resource contracts, streamed production/deployment bytes, realpath-confined npm assets, linear repeated-form accumulation, and - hostile-input and host-result regression coverage; 190 compiler/CLI tests, + hostile-input and host-result regression coverage; 197 compiler/CLI tests, real Core and three-engine application suites, packed installation, non-publishing rehearsal, installed Workbench acceptance, and 9 generic-host tests pass. 42. 1.0 audit C: complete — namespace-correct inline SVG JSX across static, @@ -206,4 +206,4 @@ alone is not sufficient evidence. `velar/game`, SSR/server rendering, WebRTC, WebGPU, service workers/PWA, directory handles, and a custom package registry are not required for the first production-ready static Web release. They remain separate capabilities and must -not destabilize the language or Web 0.6 contracts. +not destabilize the language or Web 0.7 contracts. diff --git a/docs/project-lifecycle.md b/docs/project-lifecycle.md index 7f8143bb..f27c402a 100644 --- a/docs/project-lifecycle.md +++ b/docs/project-lifecycle.md @@ -1,82 +1,96 @@ # Velar Project Lifecycle -Status: format version 1 +Status: project format 2, explicit compiler extensions -New applications are created with: +Projects are created through `npm create velar` or the installed CLI. Both +commands use the same transactional `create-velar` implementation: ```sh +npm create velar@latest my-app +npm create velar@latest product-docs -- --template docs +npm create velar@latest shared-library -- --template library +npm create velar@latest component-library -- --template component + velar create my-app +velar create product-docs --template docs +velar create shared-library --template library +velar create component-library --template component ``` -The command refuses to write into a non-empty directory. It first creates the -complete project in a sibling staging directory, then renames it over only an -absent or verified-empty target; a partial scaffold is never exposed as a -successful project. It creates a minimal -`src/app.vel` module, `src/main.vel` entry, `src/app.test.vel` Core test, -`src/app.browser.test.vel` browser test, versioned `velar.json`, private npm -application manifest, and ignore file. The application name stays an ordinary -Velar string expression, so filesystem characters such as `&` cannot be -misinterpreted as JSX markup. The generated npm package name is normalized to -a valid unscoped form. The generated scripts include project-level `format` / -`format:check`, Core and Chromium browser tests, plus production `build`, `verify`, `preview`, and -`verify:deployment`. The last command reads an explicit `--url` argument passed -through npm or `VELAR_DEPLOYMENT_URL`; no hosting target is embedded in a new -project. It does not install dependencies, browser binaries, or -initialize Git implicitly. - -`velar format` run inside a project recursively formats its `.vel` sources; -`velar format --check` is read-only and exits unsuccessfully after listing -files that differ. A source file or another project directory may be passed -explicitly. Project traversal excludes `.git`, `node_modules`, `publicDir`, and -`outDir`, so public assets, dependencies, and built output are never rewritten. +Creation refuses non-empty targets and assembles the complete project in a +sibling staging directory before the final rename. It does not install +dependencies, browsers, initialize Git, publish, or deploy. -`velar.json` now declares `formatVersion: 1`. Manifests created before 0.4 that -omit the field remain readable and report `needsUpgrade`; they can be checked -or upgraded explicitly: +The first install remains ordinary npm bootstrap because a newly created +project does not yet have its local `velar` executable. After that, dependency +maintenance can stay inside the project-aware CLI: ```sh -velar upgrade --check -velar upgrade +cd my-app +npm install +npm exec velar -- add package-name +npm exec velar -- add test-package --dev +npm exec velar -- update +npm exec velar -- remove package-name ``` -The check form never writes and exits unsuccessfully when an upgrade is needed. -The write form adds the current format version while preserving existing -fields. Unknown future versions fail closed instead of being interpreted by an -older compiler. Single-file builds have no manifest and therefore no project -upgrade operation. Unknown fields at the project, `web`, `build`, `security`, -or `deployment` levels also fail closed, so spelling mistakes cannot silently -select defaults. +These commands do not replace npm. npm owns dependency resolution and the lock; +Velar validates that it is operating inside a format-2 project and synchronizes +only extension activation metadata. An extension package opts in through its +own `package.json` `velar.extension` object, so the CLI has no official Web or +future Game package-name branch. + +Format 2 makes the language/framework boundary explicit: + +```json +{ + "formatVersion": 2, + "entry": "src/main.vel", + "outDir": "dist", + "publicDir": "public", + "extensions": ["@velarscript/web"], + "web": { + "title": "My Velar App", + "base": "/", + "publicConfig": {}, + "build": { "sourceMaps": false }, + "security": { "contentSecurityPolicy": true }, + "deployment": { "spaFallback": true, "adapter": "neutral" } + } +} +``` -A command may receive an explicit manifest file instead of the conventional -project directory. This supports checked-in deployment profiles that share one -source/public root while declaring different base, adapter, source-map, or -public configuration. Release Studio uses `velar.json` for `/app/` -compatibility testing and `velar.netlify.json` for its root external preview; -the profile is explicit input and is never selected from an environment -variable. `web.base` is normalized to one trailing slash and otherwise must be -a canonical pathname without query/hash text, empty/dot segments, backslashes, -malformed percent escapes, or encoded path separators. +`extensions` is required. A Core library uses `"extensions": []` and does not +install `@velarscript/web`. A Web application installs and declares +`@velarscript/web`; that package contributes component/JSX syntax, reactive and +lifecycle semantics, Web types, standard modules, runtime code, manifest +validation, and syntax-aware project-editor behavior. The CLI only resolves and composes those +contributions. Its separate `/host` export also provides the framework-owned +application/error HTML, CSP/reload/deployment/browser-test contract; the CLI validates protocol +version 1 and supplies only generic host mechanics. -Velar 0.5 adds optional `web.security` and `web.deployment` fields without -changing format version 1. Their absence selects the secure CSP and SPA -fallback defaults, so older format-1 projects remain equivalent and need no -mechanical rewrite. Output, public, and entry paths are validated as -non-overlapping before an isolated production build can replace anything. +There is deliberately no legacy manifest loader and no `velar upgrade` +command. Missing, format-1, and unknown future versions fail before source is +compiled. This is a clean architectural break rather than a compatibility +transition. Unknown project fields and unknown extension-owned fields also fail +closed. -Velar 0.7 adds optional `web.publicConfig` without changing format version 1. -It is an explicitly public, build-time JSON object rather than an environment -loader. Values are limited to 64 KiB, dangerous prototype keys and non-JSON -values fail loading, and the emitted object is recursively frozen. Projects -created by the current compiler include an empty object and depend on -`@velarscript/cli` `^0.9.0`; -existing format-1 projects require no migration when they omit it. +The `web`, `docs`, `library`, and `component` templates share the same creator. +Web and docs projects include Core tests plus browser tests. `library` is a +framework-free Core source package. `component` is a Web source package with a +single published `velar.entry`, a local preview application, a Core contract +test, a browser rendering test, and `@velarscript/web` as both a development +dependency and consumer peer contract. Assertions come from `velar/test`. +Browser automation is a Web extension surface imported from `velar/web-test` +and runs only through `velar test --browser`. -The additive `web.build.sourceMaps` boolean also keeps format version 1. Its -safe default is `false`, including generated projects. Setting it to `true` -explicitly publishes linked maps with Velar `sourcesContent`; teams should do -so only when that disclosure is intended. +`velar format` recursively owns project `.vel` files while excluding `.git`, +`node_modules`, `publicDir`, and `outDir`. `velar format --check` is read-only. +Build, verification, preview, and remote-deployment verification continue to +operate on isolated, integrity-checked production output. -The 0.7 compatibility matrix keeps fixed 0.3 through 0.6 project fixtures. The -current CLI runs `upgrade --check`, explicit upgrade, semantic check, and a -production build for every fixture. Additive format-1 fields keep their prior -values; only the pre-0.4 manifest without `formatVersion` is rewritten. +An explicit manifest file may be passed instead of the conventional project +directory. This supports checked-in deployment profiles sharing source and +public roots while declaring different Web base paths, adapters, source-map +policy, or public configuration. Extension selection is always declared in the +selected manifest and is never inferred from source text. diff --git a/docs/release-process.md b/docs/release-process.md index 3176c959..22581cb0 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -2,9 +2,10 @@ Status: Velar 0.9 release contract retained but execution deferred -Velar builds the compiler and CLI into two independently installable npm -packages, but treats them as one version-locked release set. The CLI must pin -the exact compiler version. +Velar builds the compiler, official Web framework, project creator, and CLI into four +independently installable npm packages, but treats them as one version-locked +release set. Web pins the exact compiler version; CLI pins compiler and creator +while loading Web only when a project explicitly declares `@velarscript/web`. ## Rehearsal @@ -13,9 +14,9 @@ npm run release:rehearse npm run release:verify -- release/rehearsal ``` -A rehearsal runs `npm pack` for both workspaces and writes: +A rehearsal runs `npm pack` for all four workspaces and writes: -- the two package tarballs; +- the four package tarballs; - `SHA256SUMS`; - `velar-toolchain-release.json` containing package name, version, filename, byte size, SHA-256, npm integrity, source-tree identity, and publication @@ -38,8 +39,8 @@ Candidate mode fails unless all of these are true: - Git has a committed, clean `HEAD`; - `HEAD` has exactly the `v` tag; - `origin` matches package repository metadata; -- both packages have an explicit publishable license; -- CLI and compiler versions/dependencies match exactly. +- all four packages have an explicit publishable license; +- compiler, Web, creator, and CLI versions/dependencies match exactly. The GitHub rehearsal workflow adds an OIDC artifact attestation to the packed tarballs and uploads them as workflow artifacts. It deliberately contains no @@ -48,7 +49,7 @@ separate, explicit release action. npm trusted publishing/provenance must be configured against the final public repository before that action is added. Application artifacts have a separate integrity boundary. `velar verify` -recomputes the format-2 build inventory and `buildId`, while `velar preview` +recomputes the format-3 framework-build inventory and `buildId`, while `velar preview` serves only a verified directory. This proves local self-consistency, not publisher authenticity; the external release pipeline must sign or attest the application manifest when authenticated application releases are introduced. diff --git a/docs/static-deployment.md b/docs/static-deployment.md index c222b217..5c4c5e02 100644 --- a/docs/static-deployment.md +++ b/docs/static-deployment.md @@ -15,8 +15,8 @@ velar preview --port 4173 velar verify-deployment --url https://preview.example.com ``` -`verify` requires exact equality between the output file tree and the format-2 -asset inventory, rejects symbolic links and unsafe/duplicate paths, checks +`verify` requires exact equality between the output file tree and the format-3 +framework-build asset inventory, rejects symbolic links and unsafe/duplicate paths, checks every size and SHA-256, recomputes `buildId`, and cross-checks entry, stylesheet, deployment, CSP, cache, fallback, and adapter contracts. `preview` always runs this verification first. It applies the declared base and headers, @@ -59,14 +59,14 @@ output directories differ. ## Generated deployment files -- `index.html`: compiler-owned HTML entry with production CSP metadata. +- `index.html`: framework-host-owned HTML entry with production CSP metadata. - `404.html`: optional SPA fallback copy for simple static hosts. -- `velar-deploy.json`: provider-neutral base path, fallback, header, and cache - contract. -- `velar-build.json`: format version 2 build identity and hashes for every - emitted file, including the deployment files. +- `velar-deploy.json`: format version 2 provider-neutral base path, framework + identity, fallback, header, and cache contract. +- `velar-build.json`: format version 3 build identity, framework/host-protocol + identity, and hashes for every emitted file, including deployment files. - `assets/*`: content-hashed JavaScript, CSS, and maps. -- `_headers` and `_redirects`: compiler-owned files when the explicit Netlify +- `_headers` and `_redirects`: CLI deployment-adapter files when the explicit Netlify adapter is selected. `web.publicConfig` is validated and compiled into the content-hashed JavaScript @@ -95,7 +95,7 @@ Root-base applications may select the first concrete adapter: } ``` -The compiler translates every header rule to Netlify's `_headers` syntax. Its +The CLI deployment adapter translates every framework-projected header rule to Netlify's `_headers` syntax. Its redirects first map a nonexistent `/assets/*` request to `404.html` with status 404, then apply `/* /index.html 200` as the SPA rewrite. Netlify's documented shadowing keeps existing assets available while preventing a missing script @@ -141,8 +141,8 @@ Additional origins are configured structurally: Only secure origin values are accepted. Paths, credentials, queries, hashes, and arbitrary CSP fragments fail configuration loading. -The compiler owns `index.html`, `404.html`, `velar-build.json`, -`velar-deploy.json`, `_headers`, and `_redirects`. Files with those names in +The framework/CLI production pipeline reserves `index.html`, `404.html`, +`velar-build.json`, `velar-deploy.json`, `_headers`, and `_redirects`. Files with those names in `publicDir` fail the build rather than overriding the security boundary. Public symbolic links are also rejected so a build cannot copy files outside the declared asset root. diff --git a/docs/web-api.md b/docs/web-api.md index fc6deb36..f9d72c39 100644 --- a/docs/web-api.md +++ b/docs/web-api.md @@ -1,13 +1,15 @@ -# Velar Web API 0.6 +# Velar Web API 0.8 Status: stable for the Velar 0.9 internal line -Runtime: existing browser JavaScript engine; no framework runtime or virtual DOM +Runtime: existing browser JavaScript engine; no virtual DOM -Velar Web applications use explicit compiler-owned modules instead of implicit +Velar Web applications install and declare `@velarscript/web`. The extension +owns JSX, components, reactivity, lifecycle, scoped CSS, Web types, editor +contributions, and explicit Web modules instead of implicit browser globals. The compiler reports `VEL3008` for direct source-level use of `console`, `document`, `window`, `navigator`, `location`, `history`, `fetch`, `JSON`, `Math`, or `Date` and points to the official module or an explicit -JavaScript boundary. Additions within API 0.6 must be backward compatible; +JavaScript boundary. Additions within API 0.8 must be backward compatible; removals or semantic changes require a new Web API version. ## `velar/app` @@ -93,7 +95,7 @@ const config = publicConfig(RuntimeConfig) ## `velar/web` ```velar -import {Head, Link, NavLink, RouteContext, Router, announce, back, currentRoute, forward, lazy, navigate, redirect, reload, route} from "velar/web" +import {Head, Link, NavLink, RouteContext, Router, announce, back, currentRoute, domId, forward, lazy, navigate, redirect, reload, route} from "velar/web" component PageLoading: return
Loading…
@@ -171,6 +173,11 @@ const Reports = lazy(() => import("./pages/reports.vel"), "Reports", PageLoading `themeColor` for its component lifetime and restores prior values on cleanup. - `announce(message, priority="polite")` writes to a compiler-owned live region; priority is `polite` or `assertive`. +- `domId(prefix="velar")` returns an application-local, monotonically unique DOM ID + for component setup. It exists for accessible `aria-labelledby`, + `aria-describedby`, and label/control relationships without requiring a + cryptographic UUID. Prefixes must start with a letter, contain only letters, + numbers, `_`, or `-`, and are limited to 64 characters. Dynamic `Head`, `Router`, `Link`, and `NavLink` prop records accept only their documented enumerable data fields. Accessors, symbols, unknown fields, invalid @@ -457,7 +464,7 @@ created. `readText(file, maxBytes=16777216)` and the explicit ceiling is 64 MiB. One picker result is limited to 10,000 files, and text downloads are likewise limited to 64 MiB. Directory access, persistent file handles, and the File System Access API are deliberately not -part of Web API 0.6. +part of Web API 0.8. Returned file names/MIME types, sizes, and modification times are validated before an opaque record is registered. Invalid native picker results reject @@ -509,7 +516,7 @@ component LiveStatus: from sibling component `cleanup`; the API does not introduce React-style effects or hidden lifecycle behavior. -## `velar/test` +## Core `velar/test` and Web `velar/web-test` `expect(value)` provides typed `toBe`, `toEqual`, `toBeTruthy`, `toBeFalsy`, `toContain`, `toMatch`, `toHaveLength`, `toThrow`, and `toReject` matchers. @@ -528,7 +535,8 @@ Browser application tests use a separate `.browser.test.vel` suffix and run only through `velar test --browser`: ```velar -import {browser, expect} from "velar/test" +import {expect} from "velar/test" +import {browser} from "velar/web-test" async def test_home_page(): await browser.open("/") @@ -550,7 +558,7 @@ install. ## Deliberate boundaries -Web API 0.6 does not define SSR/server execution, workers, service workers/PWA, +Web API 0.8 does not define SSR/server execution, workers, service workers/PWA, WebRTC, WebGPU, directory handles, persistent file handles, or a game runtime. JavaScript packages remain available through checked declarations or an explicit unsafe boundary when an application needs capabilities outside the @@ -559,9 +567,14 @@ this Web platform. ## Compatibility authority -The compiler-owned type interface and emitted runtime source live together in -`packages/cli/src/standard-modules.ts`. `standardModuleApi()` reports Web API -`0.6`, compiler tests protect exact names and types, and the Chromium, Firefox, -and WebKit development/production matrix protects runtime behavior. Workbench -does not copy these rules; completion and diagnostics arrive through the -project's installed `velar lsp`. +The versioned type interface, emitted runtime source, and framework-host +implementation live together in `@velarscript/web`, under `packages/web`. The +CLI dynamically loads the project-declared `/compiler` and optional `/host` +entries. Web owns HTML/CSP/reload/deployment projection and browser-test +metadata; CLI owns generic routing, filesystem, bundling, transport, +verification, and browser-driver mechanics. +`standardModuleApi()` reports Web API `0.7` under the extension ID, and compiler tests protect +exact names and types, and the Chromium, Firefox, and WebKit +development/production matrix protects runtime behavior. Workbench does not +copy these rules; completion and diagnostics arrive through the project's +installed `velar lsp`. diff --git a/docs/workbench-integration.md b/docs/workbench-integration.md index 67ee1f0d..319c0950 100644 --- a/docs/workbench-integration.md +++ b/docs/workbench-integration.md @@ -11,11 +11,15 @@ the compiler and language server remain the semantic authority. Velar protocol. It owns only generic language-contribution and stdio LSP host contracts. - The separately packaged Workbench Velar contribution is injected by the app - and supplies `.vel` association, syntax coloring, indentation presentation, + and supplies `.vel` association, Core syntax coloring, indentation presentation, `velar.json` detection, generic check/format/format-check/dev/Core-test/browser-test/build/verify/ - preview/deployed-site-verification/project-upgrade-check command metadata, + preview/deployed-site-verification/project-check command metadata, the LSP descriptor, and protocol compatibility declaration. +- The Workbench contribution contains no Web keyword, type, JSX directive, or + module table. A format-v2 project that declares `@velarscript/web` receives + those editor semantics from the project-local compiler extension through LSP + completion and semantic tokens. - `velar lsp` owns diagnostics, completion, hover, formatting, definition, references, same-document symbol highlights, safe rename, document symbols, signature help, inferred-type inlay hints, and all future semantic features. @@ -209,27 +213,28 @@ the compiler and language server remain the semantic authority. Workbench refuses an incompatible protocol instead of silently degrading. - Protocol version: `1`. - Standard and Web API versioning are independent of the compiler and LSP - transport versions. Velar `0.9.0-dev` uses Standard API `0.4`, Web API `0.6`, and + transport versions. Velar `0.9.0-dev` uses Standard API `0.4`, Web API `0.7`, and protocol `1`, so Workbench requires no Velar-specific host change; new module names, signatures, and diagnostics flow through the compiler-owned LSP. Workbench first resolves `velar` from the project-local `node_modules/.bin`, then from `PATH`. This keeps every project tied to its own compiler toolchain. -Published compiler/CLI packages contain emitted JavaScript and `.d.ts` files; +Published compiler/Web/creator/CLI packages contain emitted JavaScript and `.d.ts` files; Workbench invokes the local CLI executable and does not depend on its source layout. The editor never imports or embeds `@velarscript/compiler`; the compiler never depends on Workbench. -The cross-repository installed-toolchain gate packs the compiler and CLI, -installs both tarballs into a temporary Velar project, and asks the real generic +The cross-repository installed-toolchain gate packs the compiler, Web framework, creator, and CLI, +installs the complete release set into a temporary Velar project, and asks the real generic Workbench language host for diagnostics, completion, signature help, inferred-type hints, same-document symbol highlights, semantic tokens, and safe code actions. It checks that an inferred `List` is displayed, an explicit `TreeNode` annotation is not duplicated, a resource handle is not mislabeled as a source annotation, and all uses of a local record binding are highlighted, `[1, 2, 3].slice(...)` reports its second active -parameter, and `route.params.get(...)` exposes checked Map members and its +parameter and its compiler-owned `slice(number = default, number = default)` +label, and `route.params.get(...)` exposes checked Map members and its `get(string) -> string?` signature. The installed sample also hovers the nested `params` field and navigates `tree.children` to the local `TreeNode` field declaration, then renames that recursive record field across its declaration, @@ -272,7 +277,7 @@ owning a Velar comment parser or documentation store. Together this proves that local binary discovery, stdio transport, protocol negotiation, and standard semantic mapping work without a source-tree link in either direction. Before installation, Workbench validates -the release format, exact compiler/CLI set, canonical package paths, byte sizes, +the release format, exact compiler/Web/creator/CLI set, canonical package paths, byte sizes, and SHA-256 values itself rather than trusting a shared source checkout. ## Joint delivery gate diff --git a/examples/api-dashboard/src/app.browser.test.vel b/examples/api-dashboard/src/app.browser.test.vel index 6760551a..188e784e 100644 --- a/examples/api-dashboard/src/app.browser.test.vel +++ b/examples/api-dashboard/src/app.browser.test.vel @@ -1,4 +1,5 @@ -import {browser, expect} from "velar/test" +import {expect} from "velar/test" +import {browser} from "velar/web-test" async def test_dashboard_loads_typed_data_and_real_svg(): await browser.open("/") diff --git a/examples/api-dashboard/velar.json b/examples/api-dashboard/velar.json index 438d9d38..a0bfd2ec 100644 --- a/examples/api-dashboard/velar.json +++ b/examples/api-dashboard/velar.json @@ -1,8 +1,9 @@ { - "formatVersion": 1, + "formatVersion": 2, "entry": "src/main.vel", "outDir": "dist", "publicDir": "public", + "extensions": ["@velarscript/web"], "web": { "title": "Velar Metrics", "base": "/", diff --git a/examples/flow-board/src/app.browser.test.vel b/examples/flow-board/src/app.browser.test.vel index 0da2b525..b4013d5b 100644 --- a/examples/flow-board/src/app.browser.test.vel +++ b/examples/flow-board/src/app.browser.test.vel @@ -1,4 +1,5 @@ -import {browser, expect} from "velar/test" +import {expect} from "velar/test" +import {browser} from "velar/web-test" async def reset(): await browser.open("/") diff --git a/examples/flow-board/velar.json b/examples/flow-board/velar.json index 9c987b83..b4f5a82c 100644 --- a/examples/flow-board/velar.json +++ b/examples/flow-board/velar.json @@ -1,8 +1,9 @@ { - "formatVersion": 1, + "formatVersion": 2, "entry": "src/main.vel", "outDir": "dist", "publicDir": "public", + "extensions": ["@velarscript/web"], "web": { "title": "FlowBoard", "base": "/", diff --git a/examples/production-web/src/app.browser.test.vel b/examples/production-web/src/app.browser.test.vel index 1c70c055..24ed4fdf 100644 --- a/examples/production-web/src/app.browser.test.vel +++ b/examples/production-web/src/app.browser.test.vel @@ -1,5 +1,6 @@ import {range} from "velar/collections" -import {browser, expect} from "velar/test" +import {expect} from "velar/test" +import {browser} from "velar/web-test" async def test_release_studio_recovery(): await browser.open("/") diff --git a/examples/production-web/src/components/metrics.vel b/examples/production-web/src/components/metrics.vel index 15c5577a..d36403fc 100644 --- a/examples/production-web/src/components/metrics.vel +++ b/examples/production-web/src/components/metrics.vel @@ -37,5 +37,5 @@ export component Metrics(projects: number): return
- +
diff --git a/examples/production-web/src/components/web-capabilities.vel b/examples/production-web/src/components/web-capabilities.vel index 0ab6179d..1ffdbd51 100644 --- a/examples/production-web/src/components/web-capabilities.vel +++ b/examples/production-web/src/components/web-capabilities.vel @@ -166,7 +166,7 @@ export component WebCapabilities: uploadLabel = f"{uploaded.label}:{uploaded.fileName}:{uploaded.size}" action copyStatus(): - await copyText("Velar Web API 0.6") + await copyText("Velar Web API 0.8") clipboardLabel = "Copied" def saveStatus(): diff --git a/examples/production-web/src/pages/home.vel b/examples/production-web/src/pages/home.vel index e78ed4e2..ce78a225 100644 --- a/examples/production-web/src/pages/home.vel +++ b/examples/production-web/src/pages/home.vel @@ -87,7 +87,7 @@ export component Home:
-

Velar 0.8 · Web API 0.6

+

Velar 0.9 · Web API 0.8

Velar Release Studio