@nativele/ts-dom 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,29 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version
10
10
  - Adding a lint rule is a minor change; lint rules are warnings or opt-in and do not count as breaking.
11
11
  - Before every release run `npm run verify:pack` (`publint` and `attw`), `tsc`, the unit tests, the browser tests, `npm run smoke` and `npm run smoke:no-bundler`; all of them run in `.github/workflows/ci.yml`.
12
12
 
13
+ ## 0.5.1
14
+
15
+ Nativele components now have a Skill for each major framework, every Skill is accepted only after a fresh agent has done real work with it, and the checks that those trials found wrong in real framework projects are fixed.
16
+
17
+ ### Skills
18
+
19
+ - New `nativele-vue` (Official): Nativele components in an existing Vue 3 app. It covers an `isCustomElement` predicate that matches only the Nativele tags, so kebab-case Vue components such as `<router-link>` keep resolving; object props as properties, and `.prop` for an element that is not defined yet; prop plus event in place of `v-model`; exact event names; `<KeepAlive>` and `bind`; and a template type declaration built from `ts-dom-tags.ts`. Its example project runs in CI.
20
+ - New `nativele-vite` (Official): Nativele in an existing Vite app without a framework. It covers `tsDom({ dirs })` relative to Vite's `root`, multi-page builds, and a build script that runs `ts-dom check` before `vite build` so a clean checkout builds. It also says which edits reload the page during `vite dev`, and covers Vite+. Its example project, a multi-page app with `root` in a sub-folder, runs in CI.
21
+ - New `nativele-svelte` (Experimental): Nativele components in Svelte 5. It covers props as properties, `onitem-select` event attributes, `{#if}` and keyed `{#each}` children in slots, `bind:this`, and a `svelte/elements` type declaration.
22
+ - New `nativele-angular` (Experimental): Nativele components in Angular. It covers `CUSTOM_ELEMENTS_SCHEMA`, `[prop]` and `(item-select)` bindings, and zoneless change detection. Because the Angular builder takes no Vite plugins, `ts-dom gen` runs in npm `pre*` scripts. It also covers content projection and unit tests.
23
+ - New `nativele-integration` (Experimental): Nativele components in a framework without a Skill of its own, such as Preact or Solid. It covers the four questions to answer from the framework's documentation, defining components before mount, and the limits every framework shares.
24
+ - `nativele-core` and `nativele-react` were filled in where trial agents had to guess:
25
+ - the core Skill gains a complete example, the no-bundler page set-up, plain-element lists and event data;
26
+ - the React Skill starts from an existing React app, adds the `strict` and oxlint steps Vite's template needs, and type-checks with `tsc -p`, because a references-only root tsconfig checks nothing.
27
+ - The React, Vue and Svelte Skills start the template's type-check script with `ts-dom gen src/nv &&`. The generated files are not committed, so on a clean checkout that script otherwise fails with `TS2307`.
28
+ - Skill pull requests are accepted through an agent trial. A fresh agent gets only the packed package and the Skill, and does a task the Skill claims to cover. The result is checked independently, and every guess or error the Skill does not cover is sent back. Integration Skills start from the tool's own starter project and cover only what Nativele adds.
29
+
30
+ ### Tooling
31
+
32
+ - `ts-dom check` runs `vue-tsc` instead of `tsc` when the project's `package.json` lists it: `vue-tsc` takes the same arguments, prints the same errors and reads `.vue` files, which plain `tsc` reports as `TS2307: Cannot find module './App.vue'`. When the checker cannot run, the message names it.
33
+ - `ts-dom doctor` checks `strict`, `lib` and `moduleResolution` only in the tsconfig files that cover the component folders, when there are any. Vite's templates no longer get `tsconfig-no-dom-lib` and `tsconfig-not-strict` for `tsconfig.node.json`, which covers only `vite.config.ts`, whether it lists it in `include` or in `files`.
34
+ - The generated `ts-dom-tags.ts` no longer ends with `export {}`, which linters reported as a useless empty export.
35
+
13
36
  ## 0.5.0
14
37
 
15
38
  Nativele is a light, composable UI layer that grows its integrations through Skills instead of through the library. This version ships the first Skills and the command that delivers them, types `changed` and list event handlers more precisely, and adds recipes for common screens.
package/README.md CHANGED
@@ -62,6 +62,11 @@ npx ts-dom skills add nativele-core # copy it into .claude/skills/ (when the
62
62
  |---|---|
63
63
  | `nativele-core` | building components: the `ts-dom check` loop, templates, state, lists, data flow |
64
64
  | `nativele-react` | Nativele components in React 19: props, events, children and slots, lifecycle, TSX types |
65
+ | `nativele-vue` | Nativele components in Vue 3: props, events, `v-model`, slots, `<KeepAlive>`, template types |
66
+ | `nativele-svelte` | Nativele components in Svelte 5: props, events, slots, template types (Experimental) |
67
+ | `nativele-angular` | Nativele components in Angular: bindings, change detection, the build, content projection (Experimental) |
68
+ | `nativele-vite` | Nativele in a Vite app: the plugin and `root`, multi-page builds, hot updates |
69
+ | `nativele-integration` | Nativele components in a framework without its own Skill (Preact, Solid, ...): properties, events, slots, lifecycle, template types (Experimental) |
65
70
 
66
71
  Tiers: Official Skills are verified by the maintainers against an example project in CI; Community Skills are contributed and show their author and last verified versions; Experimental Skills are not fully verified yet. `ts-dom skills` marks a Skill as stale when its verification is more than six months old or does not cover the installed version.
67
72
 
package/README.zh-TW.md CHANGED
@@ -62,6 +62,11 @@ npx ts-dom skills add nativele-core # 複製到 .claude/skills/(專案有 .
62
62
  |---|---|
63
63
  | `nativele-core` | 開發元件:`ts-dom check` 循環、範本、state、清單、資料流 |
64
64
  | `nativele-react` | 在 React 19 中使用 Nativele 元件:props、事件、子元素與 slot、生命週期、TSX 型別 |
65
+ | `nativele-vue` | 在 Vue 3 中使用 Nativele 元件:props、事件、`v-model`、slot、`<KeepAlive>`、範本型別 |
66
+ | `nativele-svelte` | 在 Svelte 5 中使用 Nativele 元件:props、事件、slot、範本型別(Experimental) |
67
+ | `nativele-angular` | 在 Angular 中使用 Nativele 元件:綁定、變更偵測、建置流程、內容投影(Experimental) |
68
+ | `nativele-vite` | 在 Vite 應用中使用 Nativele:外掛與 `root`、多頁建置、熱更新 |
69
+ | `nativele-integration` | 在沒有專屬 Skill 的框架(Preact、Solid 等)中使用 Nativele 元件:property、事件、slot、生命週期、範本型別(Experimental) |
65
70
 
66
71
  等級:Official 由維護者以 CI 中的範例專案驗證;Community 由社群貢獻,標示作者與最後驗證版本;Experimental 尚未充分驗證。驗證超過六個月,或不涵蓋已安裝的版本時,`ts-dom skills` 會標示為可能過期。
67
72
 
@@ -482,7 +482,7 @@ function renderTags(dir) {
482
482
  const entries = [...seen.values()].map((d) => ` ${JSON.stringify(d.tag)}: ${alias(d)};`);
483
483
  return {
484
484
  out,
485
- next: `${TAGS_HEADER}\n${imports.join("\n")}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n${entries.join("\n")}\n }\n}\n\nexport {};\n`
485
+ next: `${TAGS_HEADER}\n${imports.join("\n")}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n${entries.join("\n")}\n }\n}\n`
486
486
  };
487
487
  }
488
488
  /**
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { _ as watchAll, a as analyze, c as generateAll, d as isSelected, f as listHtml, g as staleGenerated, i as CodegenError, m as renderTags, n as checkA11y, o as checkGenerated, p as listTs, r as CODEGEN_RULES, t as A11Y_RULES } from "./a11y-wWL9rie7.mjs";
3
- import { c as lintUsage, n as UNUSED_MARKUP_RULES, o as formatIssue, s as lintDataFlow, t as DATA_FLOW_RULES } from "./lint-5vo_ifIc.mjs";
2
+ import { _ as watchAll, a as analyze, c as generateAll, d as isSelected, f as listHtml, g as staleGenerated, i as CodegenError, m as renderTags, n as checkA11y, o as checkGenerated, p as listTs, r as CODEGEN_RULES, t as A11Y_RULES } from "./a11y-CV3nBgBn.mjs";
3
+ import { c as lintUsage, n as UNUSED_MARKUP_RULES, o as formatIssue, s as lintDataFlow, t as DATA_FLOW_RULES } from "./lint-DfUAh7t3.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { cpSync, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
6
6
  import { dirname, join, relative, resolve } from "node:path";
@@ -46,7 +46,7 @@ function readTsConfig(file, depth = 0) {
46
46
  };
47
47
  }
48
48
  const own = json.include;
49
- const include = own ? own.map((p) => resolve(dirname(file), p).split("\\").join("/")) : merged.include;
49
+ const include = own ? own.map((p) => resolve(dirname(file), p).split("\\").join("/")) : merged.include ?? (Array.isArray(json.files) ? [] : void 0);
50
50
  return {
51
51
  compilerOptions: {
52
52
  ...merged.compilerOptions,
@@ -213,13 +213,25 @@ function mapTscErrors(errors, cwd) {
213
213
  return out.filter((i) => i.rule !== "tsc" || !followsBroken(i.message));
214
214
  }
215
215
  function findTsc(cwd) {
216
+ const req = createRequire(join(cwd, "package.json"));
217
+ let deps = {};
216
218
  try {
217
- const pkgPath = createRequire(join(cwd, "package.json")).resolve("typescript/package.json");
218
- const bin = JSON.parse(readFileSync(pkgPath, "utf8")).bin?.tsc;
219
- return bin ? resolve(dirname(pkgPath), bin) : null;
220
- } catch {
221
- return null;
222
- }
219
+ const json = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
220
+ deps = {
221
+ ...json.dependencies,
222
+ ...json.devDependencies
223
+ };
224
+ } catch {}
225
+ const candidates = "vue-tsc" in deps ? [["vue-tsc", "vue-tsc"], ["typescript", "tsc"]] : [["typescript", "tsc"]];
226
+ for (const [pkg, name] of candidates) try {
227
+ const pkgPath = req.resolve(`${pkg}/package.json`);
228
+ const bin = JSON.parse(readFileSync(pkgPath, "utf8")).bin?.[name];
229
+ if (bin) return {
230
+ name,
231
+ bin: resolve(dirname(pkgPath), bin)
232
+ };
233
+ } catch {}
234
+ return null;
223
235
  }
224
236
  /**
225
237
  * Everything an agent needs in one pass: template diagnostics, generated files, TypeScript errors mapped back to the templates, and the lint rules.
@@ -288,7 +300,7 @@ function runCheck(options) {
288
300
  const parsed = [];
289
301
  for (const extra of runs) {
290
302
  const run = spawnSync(process.execPath, [
291
- tsc,
303
+ tsc.bin,
292
304
  "--noEmit",
293
305
  "--pretty",
294
306
  "false",
@@ -309,7 +321,7 @@ function runCheck(options) {
309
321
  col: 1,
310
322
  rule: "tsc-failed",
311
323
  severity: "error",
312
- message: `tsc did not check the types: ${detail} Fix: make \`npx tsc --noEmit\` run in this folder (a tsconfig.json, or --project=<path>).`
324
+ message: `${tsc.name} did not check the types: ${detail} Fix: make \`npx ${tsc.name} --noEmit\` run in this folder (a tsconfig.json, or --project=<path>).`
313
325
  });
314
326
  }
315
327
  }
@@ -472,24 +484,34 @@ function runDoctor(options) {
472
484
  if (!configs.length) add("no-tsconfig", "error", "There is no tsconfig.json. Fix: add one with \"strict\": true, \"lib\": [\"ES2022\", \"DOM\"] and \"moduleResolution\": \"bundler\" (or \"NodeNext\").");
473
485
  const includes = [];
474
486
  let everyConfigIncludes = true;
475
- for (const configPath of configs) {
476
- const config = readTsConfig(configPath);
487
+ const scanned = dirs.map((dir) => ({
488
+ dir,
489
+ folders: templateFolders(dir)
490
+ }));
491
+ const targets = scanned.flatMap(({ dir, folders }) => folders.length ? folders : [dir]);
492
+ const read = configs.map((path) => ({
493
+ path,
494
+ config: readTsConfig(path)
495
+ }));
496
+ const covering = read.filter(({ config: { include } }) => !include || targets.some((t) => include.some((p) => covers(p, t))));
497
+ for (const { path: configPath, config } of read) {
477
498
  const o = config.compilerOptions;
478
499
  const file = rel(configPath);
479
500
  paths = {
480
501
  ...paths,
481
502
  ...o.paths
482
503
  };
504
+ if (config.include) includes.push(...config.include);
505
+ else everyConfigIncludes = false;
506
+ if (covering.length && !covering.some((r) => r.path === configPath)) continue;
483
507
  if (o.strict !== true) add("tsconfig-not-strict", "warning", "compilerOptions.strict is not true, so tsc lets wrong names and null values through. Fix: set \"strict\": true.", { file });
484
508
  const lib = o.lib;
485
509
  if (lib && !lib.some((l) => l.toLowerCase() === "dom")) add("tsconfig-no-dom-lib", "error", "compilerOptions.lib leaves out DOM, so element types such as HTMLButtonElement are missing. Fix: add \"DOM\" to lib.", { file });
486
510
  if (String(o.moduleResolution ?? "").toLowerCase() === "classic") add("tsconfig-classic-resolution", "error", "moduleResolution \"classic\" cannot resolve ./x.html.js to the generated x.html.ts. Fix: use \"bundler\" or \"NodeNext\".", { file });
487
- if (config.include) includes.push(...config.include);
488
- else everyConfigIncludes = false;
489
511
  }
490
512
  if (configs.length && everyConfigIncludes) {
491
513
  const missed = /* @__PURE__ */ new Set();
492
- for (const d of dirs) for (const folder of templateFolders(d)) if (!includes.some((p) => covers(p, folder))) missed.add(rel(folder));
514
+ for (const folder of scanned.flatMap((s) => s.folders)) if (!includes.some((p) => covers(p, folder))) missed.add(rel(folder));
493
515
  for (const folder of missed) add("tsconfig-misses-templates", "error", `No tsconfig include covers ${folder}, which has templates, so their generated types are never checked. Fix: add "${folder === "." ? "**/*" : `${folder}/**/*`}" to include.`, { file: rel(configs[0]) });
494
516
  }
495
517
  let resolvable = Object.keys(paths).includes(runtime);
@@ -1,4 +1,4 @@
1
- import { a as analyze, f as listHtml, h as scanDefines } from "./a11y-wWL9rie7.mjs";
1
+ import { a as analyze, f as listHtml, h as scanDefines } from "./a11y-CV3nBgBn.mjs";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { basename, dirname, relative } from "node:path";
4
4
  // src/lib/lint.ts
@@ -1,5 +1,5 @@
1
- import { n as checkA11y, t as A11Y_RULES } from "./a11y-wWL9rie7.mjs";
2
- import { a as dataFlow, i as contractsFor, l as templateCode, n as UNUSED_MARKUP_RULES, r as componentClasses, t as DATA_FLOW_RULES, u as unusedMarkup } from "./lint-5vo_ifIc.mjs";
1
+ import { n as checkA11y, t as A11Y_RULES } from "./a11y-CV3nBgBn.mjs";
2
+ import { a as dataFlow, i as contractsFor, l as templateCode, n as UNUSED_MARKUP_RULES, r as componentClasses, t as DATA_FLOW_RULES, u as unusedMarkup } from "./lint-DfUAh7t3.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { dirname, resolve } from "node:path";
5
5
  // src/lib/oxlint-plugin.ts
@@ -1,4 +1,4 @@
1
- import { c as generateAll, d as isSelected, f as listHtml, h as scanDefines, i as CodegenError, l as generateFile, n as checkA11y, s as formatDiagnostics, u as isFullPage } from "./a11y-wWL9rie7.mjs";
1
+ import { c as generateAll, d as isSelected, f as listHtml, h as scanDefines, i as CodegenError, l as generateFile, n as checkA11y, s as formatDiagnostics, u as isFullPage } from "./a11y-CV3nBgBn.mjs";
2
2
  import { existsSync, readFileSync, unlinkSync } from "node:fs";
3
3
  import { resolve, sep } from "node:path";
4
4
  // src/lib/vite-plugin.ts
package/llms.txt CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Designed for AI agents. Driven by TypeScript. Defined in vanilla HTML. A lightweight library for building web components: bind HTML templates to TypeScript custom elements. HTML describes structure and where data goes; TypeScript owns state and behavior; the DOM is the only view. Fully typed by tsc, no virtual DOM, no bundler required.
4
4
 
5
- Workflow: write `x.html` + `x.ts`, run `npx ts-dom check` (regenerates `x.html.ts`, runs tsc and lint, points errors at the template). Import a template as `import tpl from "./x.html.js"` (note the `.js`). Lint with `npx ts-dom lint` (add `--a11y`). `npx ts-dom rules` lists every rule id. Every diagnostic is `file:line:col severity [rule-id] message` and ends with a `Fix:` hint: read the hint and apply it.
5
+ Workflow: write `x.html` + `x.ts`, run `npx ts-dom check` (regenerates `x.html.ts`, runs tsc, or vue-tsc when the project has it, and lint, points errors at the template). Import a template as `import tpl from "./x.html.js"` (note the `.js`). Lint with `npx ts-dom lint` (add `--a11y`). `npx ts-dom rules` lists every rule id. Every diagnostic is `file:line:col severity [rule-id] message` and ends with a `Fix:` hint: read the hint and apply it.
6
6
 
7
7
  ## Template syntax (HTML only names things; no expressions)
8
8
  - `{{ name }}`: text hole, a single identifier only. NOT `{{ a.b }}` / `{{ a + 1 }}`. Not allowed in attributes.
@@ -79,7 +79,7 @@ define("my-counter", MyCounter);
79
79
  - `data-each` is never nested: a list inside an item is the item component's own `data-each`.
80
80
 
81
81
  ## Rules for agents
82
- - Skills: `npx ts-dom skills` lists the task procedures shipped with the package (`nativele-core` for building components, `nativele-react` for React 19, ...), each with verified versions; `npx ts-dom skills <name>` prints one, `npx ts-dom skills add <name>` copies it into `.claude/skills/` or `.agents/skills/`, and `npx ts-dom doctor` suggests the ones that match the project's dependencies.
82
+ - Skills: `npx ts-dom skills` lists the task procedures shipped with the package (`nativele-core` for building components, `nativele-react`, `nativele-vue`, `nativele-svelte` and `nativele-angular` for those frameworks, `nativele-vite` for Vite, `nativele-integration` for other frameworks, ...), each with verified versions; `npx ts-dom skills <name>` prints one, `npx ts-dom skills add <name>` copies it into `.claude/skills/` or `.agents/skills/`, and `npx ts-dom doctor` suggests the ones that match the project's dependencies.
83
83
  - `npx ts-dom rules --explain=<id>` (or `rules --json`) explains any rule id from a diagnostic: why it exists, a wrong example and the fix.
84
84
  - Markup well-formedness is a formatter's job: `oxfmt --check` reports misnested tags that the library's parser would silently repair. Generate with `--whitespace=collapse` when a formatter is used.
85
85
  - If checks behave oddly (no types, a template not found), run `npx ts-dom doctor --json` first: it reports tsconfig, import path, runtime, generated file and plugin problems with a `Fix:` each.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativele/ts-dom",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Designed for AI agents. Driven by TypeScript. Defined in vanilla HTML. A lightweight library for building web components: typed templates, native custom elements, no virtual DOM, no template expressions, no bundler required.",
5
5
  "keywords": [
6
6
  "html",
package/skills/README.md CHANGED
@@ -6,6 +6,8 @@ Skills extend what Nativele can be used with, without growing the library: each
6
6
 
7
7
  A Skill is a task procedure for a coding agent: how to do one integration or one kind of work with Nativele, step by step, with a complete example, the known limitations, and commands that prove it worked. It is not reference documentation: facts about the library's API live in `docs/`, and a Skill links to them instead of restating them.
8
8
 
9
+ An integration Skill (a framework, a build tool, a library) starts from a project that already uses that tool and teaches how to bring Nativele into it: what to add, what to change, and what to watch for. It does not teach how to set the tool itself up from nothing; the tool's own documentation and starter projects cover that.
10
+
9
11
  A Skill never changes the library's runtime and never adds a dependency to the library's core. Third-party packages a Skill uses are dependencies of the user's project, installed by the Skill's own steps.
10
12
 
11
13
  ## Layout
@@ -50,7 +52,7 @@ Required sections, in this order:
50
52
 
51
53
  1. **When to use**: the situation and the signals (dependencies, files) that call for this Skill, and when not to use it.
52
54
  2. **Versions**: a table of every tool and the exact version it was verified with, and the date. If the project uses a different major version of a tool, the Skill says so and stops treating its steps as verified.
53
- 3. **Set-up**: numbered steps with the exact commands and file contents.
55
+ 3. **Set-up**: numbered steps with the exact commands and file contents, starting from a working project of the tool (for an integration Skill) and covering only what Nativele adds or changes.
54
56
  4. **Example**: a complete, minimal working example (every file it needs, short).
55
57
  5. **Known limitations**: what does not work or needs care, each with what to do instead. An agent must never have to guess these.
56
58
  6. **Verify**: the commands that prove the integration works in the user's project (for example `npx ts-dom check`, `npx tsc --noEmit`, the project's build, a test), with the output to expect.
@@ -68,11 +70,11 @@ Rules for the content:
68
70
 
69
71
  | Tier | Who maintains it | Requirements | Shown by `ts-dom skills` |
70
72
  |---|---|---|---|
71
- | Official | the Nativele maintainers | an `example/` project that `npm run verify` checks in CI; verified within the last 6 months | as official |
72
- | Community | its author | the full SKILL.md format, `author` and `verified` filled in, the verification commands run by the author | as community, with the author |
73
+ | Official | the Nativele maintainers | accepted through an agent trial, and an `example/` project that `npm run verify` checks in CI; verified within the last 6 months | as official |
74
+ | Community | its author | the full SKILL.md format, `author` and `verified` filled in, accepted through a maintainer's agent trial | as community, with the author |
73
75
  | Experimental | its author | the SKILL.md format; verification not complete | as experimental, with a warning |
74
76
 
75
- - A new contribution starts as Experimental. It becomes Community when a reviewer has run its verification commands with the stated versions, and Official when the maintainers adopt it with an `example/` project in CI.
77
+ - A new contribution starts as Experimental. It becomes Community when it passes a maintainer's agent trial (see "How a Skill pull request is accepted"), and Official when the maintainers adopt it with an `example/` project in CI.
76
78
  - A Skill whose `verified` date is older than 6 months, or whose `nativele` range does not include the installed version, is shown as stale. A stale Official Skill whose CI check fails is moved to Experimental until fixed.
77
79
 
78
80
  ## Delivering Skills to projects
@@ -90,7 +92,7 @@ None of this adds a runtime dependency: listing and copying read the Markdown fi
90
92
 
91
93
  - `skills/<name>/example/package.json` pins every tool version the Skill names, depends on the library through `file:../../..` (the library in the same repository), and has `npm run verify`, which runs `ts-dom check`, `ts-dom doctor`, `tsc`, the build, and a short real-browser test of what the Skill promises.
92
94
  - `nativele-core` has no example of its own: the library's CI, which checks every example in the repository, verifies it.
93
- - The workflow `.github/workflows/skills.yml` runs `npm run verify` for each Official Skill when anything under that Skill changes, when the library's runtime changes, and once a month, so a third-party release that breaks a Skill is found. It is not a required check for `main`.
95
+ - The workflow `.github/workflows/skills.yml` runs `npm run verify` for each Official Skill when an `example/` changes, when the library's runtime changes, and once a month, so a third-party release that breaks a Skill is found. A change to `SKILL.md` runs only `.github/workflows/skills-format.yml`, which checks every `SKILL.md` against this specification. Neither is a required check for `main`.
94
96
  - The monthly run opens nothing by itself; a failure is reported in the workflow run, and the Skill is fixed or moved to Experimental.
95
97
 
96
98
  ## Contributing a Skill
@@ -98,7 +100,24 @@ None of this adds a runtime dependency: listing and copying read the Markdown fi
98
100
  - Copy `skills/_template/SKILL.md`, fill in every section, set `tier: experimental`.
99
101
  - Run the Skill's verification commands in a fresh project with the versions you list, and paste their output in the PR description.
100
102
  - The PR touches only `skills/<name>/`; a PR that changes the library and adds a Skill is split. Community and Experimental Skills live in this repository, in the same `skills/` folder, so they ship with the package and `ts-dom skills` lists them with their tier.
101
- - Review checklist: frontmatter complete; every step reproducible; limitations listed; verification commands and their output present; no restating of `docs/`; nothing that would add a dependency to the core.
103
+
104
+ ## How a Skill pull request is accepted
105
+
106
+ A Skill is written for agents, so the maintainers accept it by having an agent use it: a fresh agent that knows nothing about the Skill does real work with nothing but the Skill, and the result is checked. Reading the Skill or rerunning its verification commands is not enough, because neither shows what the Skill leaves out.
107
+
108
+ 1. **Check the format**: the frontmatter is complete, every required section is there, the facts link to `docs/` instead of restating them, and nothing would add a dependency to the library's core.
109
+ 2. **Build the package from the PR branch** (`npm run build:lib && npm pack`), so the trial uses the real delivery path.
110
+ 3. **Start a fresh project** in an empty folder outside the repository: for an integration Skill, the tool's own starter project at the versions the Skill lists (for example `create-vite` with the `react-ts` template), built once to confirm it works before Nativele is added. Install the packed library and the exact tool versions the Skill lists, and install the Skill the way users do: `npx ts-dom skills add <name>`.
111
+ 4. **Give a fresh agent a task** that the Skill says it covers, written from its "When to use" and "Example": a small but real piece of work that goes through every set-up step and touches every known limitation. The agent may use the Skill, `npx ts-dom` and the public guides in `docs/`, but not the Nativele source, this repository or the Skill's `example/`. It reports the files it wrote, the output of every Verify command, every point where it had to guess or look elsewhere, and every error it hit and how it fixed it.
112
+ 5. **Check the result independently**, without relying on the agent's report: run the Verify commands again and check the behavior in a real browser or with a test.
113
+
114
+ The Skill is accepted when:
115
+
116
+ - every Verify command gives the expected output, and the work does what the task asked;
117
+ - the agent followed the Skill's steps as written, and no step was wrong for the stated versions;
118
+ - every guess, outside search or unexplained error in the report is already covered by the Skill; a guess about the tool itself (how to configure the framework, the build tool or the test runner beyond what Nativele needs) is not a gap in the Skill.
119
+
120
+ Otherwise the maintainers send the gaps back to the contributor as review comments (a missing step, a limitation to list, a Troubleshooting row to add), and the trial runs again, with a new agent, on the updated Skill. The record of the passing trial (agent and model, date, versions, Verify output) is added to the PR as a review comment.
102
121
 
103
122
  ## Skills
104
123
 
@@ -106,9 +125,11 @@ None of this adds a runtime dependency: listing and copying read the Markdown fi
106
125
  |---|---|---|---|
107
126
  | `nativele-core` | Official | available | building with Nativele itself: the `ts-dom check` loop, components, lists, data flow |
108
127
  | `nativele-react` | Official | available | Nativele components in React 19: props, events, children and slots, lifecycle, TSX types |
109
- | `nativele-integration` | Official | planned | what every framework integration shares: properties and attributes, events, slots, lifecycle, types |
110
- | `nativele-vite` | Official | planned | the Vite plugin, `root`, hot updates |
111
- | `nativele-vue` | Official | planned | Nativele components in Vue |
128
+ | `nativele-integration` | Experimental | available | Nativele components in a framework without its own Skill: defining before render, properties and attributes, events, slots, lifecycle, types |
129
+ | `nativele-vite` | Official | available | Nativele in a Vite app: the plugin and `root`, multi-page builds, the build script, hot updates, Vite+ |
130
+ | `nativele-vue` | Official | available | Nativele components in Vue 3: `isCustomElement`, props, events, `v-model`, slots, `<KeepAlive>`, template types |
131
+ | `nativele-svelte` | Experimental | available | Nativele components in Svelte 5: props, event attributes, slots, `bind:this`, template types |
132
+ | `nativele-angular` | Experimental | available | Nativele components in Angular: `CUSTOM_ELEMENTS_SCHEMA`, bindings, zoneless change detection, `ts-dom gen` in the build, content projection |
112
133
  | `nativele-state-management` | Official | planned | `createStore`, and Zustand or Redux through `bind` |
113
134
  | `nativele-testing` | Official | planned | Vitest and Playwright |
114
- | Svelte, Angular, Tailwind CSS, TanStack Query, Zod | Experimental or Community | open for contributions | |
135
+ | Tailwind CSS, TanStack Query, Zod | Experimental or Community | open for contributions | |