@swiftuijs/twill 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/bin/twill.mjs +12 -0
  4. package/dist/branches.d.ts +12 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +128 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/compiler-Bi9TNOhX.js +1127 -0
  9. package/dist/compiler-Bi9TNOhX.js.map +1 -0
  10. package/dist/compiler.d.ts +50 -0
  11. package/dist/config.d.ts +6 -0
  12. package/dist/config.js +55 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/declarations.d.ts +14 -0
  15. package/dist/declarations.js +132 -0
  16. package/dist/declarations.js.map +1 -0
  17. package/dist/defer.d.ts +17 -0
  18. package/dist/doctor.d.ts +20 -0
  19. package/dist/doctor.js +198 -0
  20. package/dist/doctor.js.map +1 -0
  21. package/dist/editor.d.ts +53 -0
  22. package/dist/editor.js +261 -0
  23. package/dist/editor.js.map +1 -0
  24. package/dist/esbuild.d.ts +3 -0
  25. package/dist/esbuild.js +7 -0
  26. package/dist/esbuild.js.map +1 -0
  27. package/dist/files-D1mERoxc.js +46 -0
  28. package/dist/files-D1mERoxc.js.map +1 -0
  29. package/dist/files.d.ts +5 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +2 -0
  32. package/dist/loader.d.ts +3 -0
  33. package/dist/loader.js +54 -0
  34. package/dist/loader.js.map +1 -0
  35. package/dist/parser.d.ts +9 -0
  36. package/dist/plugin-BGabvyT6.js +112 -0
  37. package/dist/plugin-BGabvyT6.js.map +1 -0
  38. package/dist/plugin.d.ts +9 -0
  39. package/dist/project.d.ts +62 -0
  40. package/dist/project.js +416 -0
  41. package/dist/project.js.map +1 -0
  42. package/dist/recovery.d.ts +3 -0
  43. package/dist/register.d.ts +1 -0
  44. package/dist/register.js +7 -0
  45. package/dist/register.js.map +1 -0
  46. package/dist/rollup.d.ts +3 -0
  47. package/dist/rollup.js +7 -0
  48. package/dist/rollup.js.map +1 -0
  49. package/dist/rspack.d.ts +3 -0
  50. package/dist/rspack.js +7 -0
  51. package/dist/rspack.js.map +1 -0
  52. package/dist/syntax.d.ts +11 -0
  53. package/dist/syntax.js +10 -0
  54. package/dist/syntax.js.map +1 -0
  55. package/dist/transpile-DwVekVFM.js +51 -0
  56. package/dist/transpile-DwVekVFM.js.map +1 -0
  57. package/dist/transpile.d.ts +11 -0
  58. package/dist/typescript-plugin.LICENSE.txt +375 -0
  59. package/dist/typescript-plugin.cjs +17741 -0
  60. package/dist/typescript-plugin.cjs.map +1 -0
  61. package/dist/typescript-plugin.d.ts +5 -0
  62. package/dist/vite-react.d.ts +10 -0
  63. package/dist/vite-react.js +22 -0
  64. package/dist/vite-react.js.map +1 -0
  65. package/dist/vite.d.ts +3 -0
  66. package/dist/vite.js +7 -0
  67. package/dist/vite.js.map +1 -0
  68. package/dist/webpack.d.ts +3 -0
  69. package/dist/webpack.js +7 -0
  70. package/dist/webpack.js.map +1 -0
  71. package/package.json +180 -0
  72. package/schemas/twill.schema.json +16 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Saiya and twill contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # Twill
2
+
3
+ **Clearer flow. Same TypeScript.**
4
+
5
+ Twill is a small syntax-sugar language for JavaScript and TypeScript, built by [forth.ink](https://forth.ink). Make validation, cleanup and business states explicit with guards, `defer`, trailing closures and checked switch expressions. Compile to ordinary JavaScript, keep TS types and mix Twill with your existing code.
6
+
7
+ [Documentation](https://swiftuijs.github.io/twill/) · [Why Twill?](https://swiftuijs.github.io/twill/why-twill) · [Playground](https://swiftuijs.github.io/twill/playground) · [Getting started](https://swiftuijs.github.io/twill/getting-started) · [Support](https://swiftuijs.github.io/twill/readiness)
8
+
9
+ ```twill
10
+ async function readOwned(acquire: () => Promise<TextDocument>) {
11
+ const document = await acquire();
12
+ defer {
13
+ await document.close();
14
+ }
15
+
16
+ guard const text = await document.readText() else {
17
+ return 'Missing';
18
+ }
19
+ return text.toUpperCase();
20
+ }
21
+ ```
22
+
23
+ The successful path stays in view; release sits next to acquisition. Registration is block-scoped, cleanup is awaited explicitly, and `return await` keeps an owned resource alive until its work finishes. The output uses ordinary JS control flow.
24
+
25
+ **Release line:** 0.1. Twill is an experimental language with a tested compiler, editor and build workflow. Start with one module and evaluate it against your application’s requirements. See [support and compatibility](https://swiftuijs.github.io/twill/readiness).
26
+
27
+ ## Why use Twill?
28
+
29
+ - **Make early exits explicit.** `guard … else` requires an exiting failure path. `guard const` evaluates once, preserves zero and false, and keeps native TS narrowing.
30
+ - **Keep cleanup beside ownership.** Register `defer` immediately after acquisition; reached registrations run on scope exit in reverse order, including failures.
31
+ - **Catch omitted business states.** Match ordinary TS discriminated unions and bind their payloads. `twill check` verifies expression exhaustiveness when a variant is added.
32
+ - **Keep callbacks and composition readable.** Trailing closures work with normal callback APIs. In UI files, component closures become native JSX children or lazy Vue slots.
33
+ - **Adopt one module at a time.** Two-way TS/JS imports, standard framework APIs, generated declarations and optional native source export keep the integration incremental.
34
+
35
+ TypeScript already expresses these behaviors with branches, `try/finally`, arrows and unions. Twill supplies a more explicit syntax for recurring tasks; it earns its place when review clarity outweighs an additional compiler integration. Read the [code comparisons and tradeoffs](https://swiftuijs.github.io/twill/why-twill).
36
+
37
+ ## Small syntax, existing semantics
38
+
39
+ ```twill
40
+ const names = users.filter {
41
+ .active;
42
+ }.map {
43
+ .name;
44
+ };
45
+
46
+ type Outcome = { kind: 'ok'; value: number } | { kind: 'error'; message: string };
47
+ function describe(outcome: Outcome): string {
48
+ return switch (outcome) {
49
+ case { kind: 'ok', value }: value.toFixed(2);
50
+ case { kind: 'error', message }: message;
51
+ };
52
+ }
53
+ ```
54
+
55
+ Ordinary closures become arrows; guards become branches. Direct-return switch expressions become native switches; other expression positions use an IIFE. No language runtime library is introduced. `defer` allocates callbacks and dynamic registrations use a local stack; general component child collection uses arrays. These costs are [documented and measured](https://swiftuijs.github.io/twill/performance).
56
+
57
+ | File | Use |
58
+ | ---------------------------- | ----------------------------------------------------------- |
59
+ | `.twill` | TypeScript, including JavaScript syntax with optional types |
60
+ | `.twillx` | TSX, native JSX and component closures |
61
+ | `.ts`, `.tsx`, `.js`, `.jsx` | Ordinary source files, retaining their native syntax |
62
+
63
+ Twill and native files can import each other through the build adapters, virtual checker and Node ESM loader. Your normal `tsconfig.json` supplies types and JSX settings. No `twill.config.json` is required. Native `tsc` cannot parse dialect source; use `twill check` and [standard declaration output](https://swiftuijs.github.io/twill/libraries).
64
+
65
+ ## Try it
66
+
67
+ The [playground](https://swiftuijs.github.io/twill/playground) runs the actual compiler locally, with live highlighting and generated-source inspection. It does not execute your code or type-check project imports.
68
+
69
+ Install the compiler as a development dependency in your application. It supports Node 20.19+ or 22.12+ and introduces no language runtime dependency into your application bundle.
70
+
71
+ ```sh
72
+ pnpm add -D @swiftuijs/twill
73
+ # npm install --save-dev @swiftuijs/twill
74
+ ```
75
+
76
+ Add the Vite adapter to your existing configuration:
77
+
78
+ ```ts
79
+ import { defineConfig } from 'vite';
80
+ import twill from '@swiftuijs/twill/vite';
81
+
82
+ export default defineConfig({ plugins: [twill()] });
83
+ ```
84
+
85
+ Rename one module to `.twill`, update its imports, include it in your usual tsconfig and run:
86
+
87
+ ```sh
88
+ pnpm exec twill check -p tsconfig.json
89
+ ```
90
+
91
+ Follow [getting started](https://swiftuijs.github.io/twill/getting-started) to complete the editor, formatter and linter setup. For React, use the [React Vite adapter](https://swiftuijs.github.io/twill/frameworks#react-with-vite-8) to keep Fast Refresh working.
92
+
93
+ ## A complete working loop
94
+
95
+ | Tool | What it provides |
96
+ | -------------------- | ---------------------------------------------------------------------------------------------------------- |
97
+ | Compiler and checker | Syntax lowering, original-source diagnostics, native TS types and generated declarations |
98
+ | VS Code extension | Completion, signatures, hover, definitions, references, mixed-file rename, safe quick fixes and formatting |
99
+ | Formatter and linter | Independent Prettier and ESLint packages, including optional type-aware exhaustive linting |
100
+ | Build and execution | Vite, Rollup, esbuild, webpack and Rspack adapters; an opt-in Node ESM loader |
101
+ | Debugging | Source maps, generated-source viewer, project diagnostics and original-source Node breakpoints |
102
+ | Web highlighting | `@swiftuijs/twill-highlight`: browser/SSR Shiki integration and portable TextMate grammars |
103
+ | Source export | `twill export`: optional checked source export to formatted native TS/TSX |
104
+
105
+ React children, render props, Vue slots and component libraries use native framework contracts. There are no component registries or Twill-specific wrapping APIs; `@swiftuijs/ui` is one example consumer. Independent [examples](https://github.com/swiftuijs/twill/blob/main/examples/README.md) cover ordinary workflows, mixed sources, cleanup, React, Vue and library output. The [React framework source study](https://swiftuijs.github.io/twill/react-source) also compares a pinned client-core rewrite with native JavaScript.
106
+
107
+ ## Packages
108
+
109
+ Install only the tools your project needs. Keep Twill packages on the same release version.
110
+
111
+ | Package | Purpose |
112
+ | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
113
+ | [`@swiftuijs/twill`](https://www.npmjs.com/package/@swiftuijs/twill) | Compiler, `twill` CLI, checker, build adapters and Node loader |
114
+ | [`@swiftuijs/twill-formatter`](https://www.npmjs.com/package/@swiftuijs/twill-formatter) | Prettier plugin and browser-compatible formatting API |
115
+ | [`@swiftuijs/twill-linter`](https://www.npmjs.com/package/@swiftuijs/twill-linter) | ESLint flat configurations and source-mapped fixes |
116
+ | [`@swiftuijs/twill-export`](https://www.npmjs.com/package/@swiftuijs/twill-export) | Optional `twill export` command for native TS/TSX output |
117
+ | [`@swiftuijs/twill-highlight`](https://www.npmjs.com/package/@swiftuijs/twill-highlight) | Browser/SSR Shiki integration and TextMate grammars |
118
+
119
+ The VS Code extension bundles its editing tools. Your application installs the compiler for builds and whole-project checks. See the [editor guide](https://swiftuijs.github.io/twill/tooling) for installation.
120
+
121
+ ## Choosing it responsibly
122
+
123
+ Twill is a useful candidate for nullable workflows, owned resources, typed state handling and callback-heavy code. It is still an experimental dialect. Parser coverage follows a tested TS 5.9 contract; arbitrary workspace TS versions, general editor refactoring, native incremental `tsc --build`, a CommonJS Twill loader and every SSR framework are outside its current guarantees.
124
+
125
+ Representative native/dialect bundles are compared for behavior and byte size; release artifacts have enforced size budgets. Synthetic benchmarks do not establish whole-application speed or team productivity. Profile your actual workload and exercise failure paths. See [support](https://swiftuijs.github.io/twill/readiness), [performance](https://swiftuijs.github.io/twill/performance) and [gradual adoption](https://swiftuijs.github.io/twill/adoption).
126
+
127
+ ## Contributing
128
+
129
+ The repository is a pnpm workspace with Vite builds. See the [development guide](https://github.com/swiftuijs/twill/blob/main/docs/contributing/tooling.md) for checkout, dependency and build commands. Compiler, formatter, linter, export and highlight packages, editor packages, examples and the English documentation site own their code and tests.
130
+
131
+ ```sh
132
+ pnpm check
133
+ pnpm editor:test # requires a graphical host; use xvfb-run -a on headless Linux
134
+ pnpm test:browser # requires Playwright Chromium
135
+ pnpm docs:dev
136
+ ```
137
+
138
+ See [contributing](https://github.com/swiftuijs/twill/blob/main/CONTRIBUTING.md), [architecture](https://github.com/swiftuijs/twill/blob/main/docs/contributing/architecture.md), [language design](https://swiftuijs.github.io/twill/language) and [release instructions](https://github.com/swiftuijs/twill/blob/main/docs/contributing/releasing.md). MIT licensed.
package/bin/twill.mjs ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../dist/cli.js';
3
+
4
+ main()
5
+ .then((code) => {
6
+ process.exitCode = code;
7
+ })
8
+ .catch((error) => {
9
+ console.error(error.message);
10
+ if (error.frame) console.error(error.frame);
11
+ process.exitCode = 1;
12
+ });
@@ -0,0 +1,12 @@
1
+ import { default as MagicString } from 'magic-string';
2
+ import { Language } from './compiler.js';
3
+ type Node = {
4
+ type: string;
5
+ start: number;
6
+ end: number;
7
+ [key: string]: any;
8
+ };
9
+ /** Native switches with per-arm scopes; expression contexts use a synchronous
10
+ * lexical IIFE. Direct returns need no extra function or scheduling. */
11
+ export declare function lowerSwitchExpressions(source: string, ast: Node, switches: Node[], code: MagicString, language: Language, usedNames: Set<string>, fail: (node: Node, message: string) => never): void;
12
+ export {};
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function main(args?: string[]): Promise<number>;
package/dist/cli.js ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ import { s as transform } from "./compiler-Bi9TNOhX.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { TwillProject } from "./project.js";
5
+ import { inspectProject } from "./doctor.js";
6
+ import { emitDeclarations } from "./declarations.js";
7
+ import { t as transpile } from "./transpile-DwVekVFM.js";
8
+ import { createRequire } from "node:module";
9
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { dirname, resolve } from "node:path";
11
+ import { parseArgs } from "node:util";
12
+ import { pathToFileURL } from "node:url";
13
+ //#region src/cli.ts
14
+ async function main(args = process.argv.slice(2)) {
15
+ const { values, positionals, tokens } = parseArgs({
16
+ args,
17
+ allowPositionals: true,
18
+ tokens: true,
19
+ options: {
20
+ out: {
21
+ type: "string",
22
+ short: "o"
23
+ },
24
+ project: {
25
+ type: "string",
26
+ short: "p"
27
+ },
28
+ js: {
29
+ type: "boolean",
30
+ default: false
31
+ },
32
+ help: {
33
+ type: "boolean",
34
+ short: "h"
35
+ },
36
+ json: {
37
+ type: "boolean",
38
+ default: false
39
+ },
40
+ build: {
41
+ type: "boolean",
42
+ default: false
43
+ },
44
+ "dry-run": {
45
+ type: "boolean",
46
+ default: false
47
+ }
48
+ }
49
+ });
50
+ const [command, input, ...extra] = positionals;
51
+ if (command === "export") {
52
+ let entry;
53
+ try {
54
+ entry = createRequire(resolve(values.project ?? "package.json")).resolve("@swiftuijs/twill-export/cli");
55
+ } catch (error) {
56
+ if (error.code !== "MODULE_NOT_FOUND") throw error;
57
+ throw new Error("twill export requires @swiftuijs/twill-export in your project. Install it with pnpm add -D @swiftuijs/twill-export.", { cause: error });
58
+ }
59
+ const exporter = await import(pathToFileURL(entry).href);
60
+ const index = tokens.find((token) => token.kind === "positional").index;
61
+ return exporter.main(args.filter((_, position) => position !== index));
62
+ }
63
+ if (values["dry-run"]) throw new Error("--dry-run is only supported by twill export");
64
+ if (values.help || !command) {
65
+ console.log("twill compile <file> [-o output.ts] [--js]\ntwill check [-p tsconfig.json] [--json]\ntwill doctor [-p tsconfig.json] [--json]\ntwill declarations [-p tsconfig.json] [-o dist] [--build] [--json]\ntwill export [-p tsconfig.json] -o ../native-project [--dry-run] [--json]\n\ncompile keeps TypeScript types by default; --js erases types and lowers JSX.\nexport requires the optional @swiftuijs/twill-export package.\nCommands use the optional twill.config.json from the project root.");
66
+ return 0;
67
+ }
68
+ if (extra.length) throw new Error("Unexpected arguments: " + extra.join(" "));
69
+ if (command === "declarations") {
70
+ if (input) throw new Error("Use --project <tsconfig.json> with declarations");
71
+ const result = emitDeclarations(resolve(values.project ?? "tsconfig.json"), {
72
+ outDir: values.out,
73
+ build: values.build
74
+ });
75
+ if (values.json) console.log(JSON.stringify(result, null, 2));
76
+ else {
77
+ for (const diagnostic of result.diagnostics) console.error(`${diagnostic.filename ?? "tsconfig"}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`);
78
+ if (!result.diagnostics.some((item) => item.category === "error")) console.log(`Emitted ${result.files.length} declaration/map files from ${result.projects.length} projects.`);
79
+ }
80
+ return result.diagnostics.some((item) => item.category === "error") ? 1 : 0;
81
+ }
82
+ if (command === "check" || command === "doctor") {
83
+ if (input) throw new Error("Use --project <tsconfig.json> with " + command);
84
+ const project = new TwillProject(resolve(values.project ?? "tsconfig.json"));
85
+ try {
86
+ if (command === "doctor") {
87
+ const report = inspectProject(project);
88
+ if (values.json) console.log(JSON.stringify(report, null, 2));
89
+ else {
90
+ console.log(`Twill ${report.twillVersion} / TypeScript ${report.typescriptVersion} / Node ${report.nodeVersion}`);
91
+ console.log(`Project: ${report.root}\nSources: ${report.files.twill} Twill, ${report.files.native} native\nDiagnostics: ${report.diagnostics.length} (${report.diagnosticTimeMs.toFixed(1)} ms)`);
92
+ for (const diagnostic of report.diagnostics) console.log(`${diagnostic.filename ?? "tsconfig"}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`);
93
+ console.log("Use --json to save the complete project report.");
94
+ }
95
+ return report.ok ? 0 : 1;
96
+ }
97
+ const diagnostics = project.diagnostics();
98
+ if (values.json) console.log(JSON.stringify(diagnostics, null, 2));
99
+ else for (const diagnostic of diagnostics) console.error(`${diagnostic.filename ?? "tsconfig"}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`);
100
+ return diagnostics.some((diagnostic) => diagnostic.category === "error") ? 1 : 0;
101
+ } finally {
102
+ project.dispose();
103
+ }
104
+ }
105
+ if (command !== "compile" || !input) throw new Error("Expected compile <file> or check. Use --help for usage.");
106
+ const filename = resolve(input);
107
+ const root = values.project ? dirname(resolve(values.project)) : process.cwd();
108
+ const options = {
109
+ ...loadConfig(root, values.project ? resolve(values.project) : void 0),
110
+ filename
111
+ };
112
+ const source = readFileSync(filename, "utf8");
113
+ const result = values.js ? transpile(source, options) : transform(source, options);
114
+ if (values.out) {
115
+ const output = resolve(values.out);
116
+ if (output === filename) throw new Error("Output must differ from input");
117
+ mkdirSync(dirname(output), { recursive: true });
118
+ writeFileSync(output, result.code + `\n//# sourceMappingURL=${output.split(/[\\/]/).at(-1)}.map\n`);
119
+ const map = JSON.parse(result.map.toString());
120
+ map.file = output.split(/[\\/]/).at(-1);
121
+ writeFileSync(output + ".map", JSON.stringify(map));
122
+ } else process.stdout.write(result.code + "\n");
123
+ return 0;
124
+ }
125
+ //#endregion
126
+ export { main };
127
+
128
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["import { readFileSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport { transform } from './compiler.js';\nimport { transpile } from './transpile.js';\nimport { loadConfig } from './config.js';\nimport { TwillProject } from './project.js';\nimport { inspectProject } from './doctor.js';\nimport { emitDeclarations } from './declarations.js';\n\nexport async function main(args = process.argv.slice(2)): Promise<number> {\n const { values, positionals, tokens } = parseArgs({\n args,\n allowPositionals: true,\n tokens: true,\n options: {\n out: { type: 'string', short: 'o' },\n project: { type: 'string', short: 'p' },\n js: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h' },\n json: { type: 'boolean', default: false },\n build: { type: 'boolean', default: false },\n 'dry-run': { type: 'boolean', default: false },\n },\n });\n const [command, input, ...extra] = positionals;\n if (command === 'export') {\n // Resolve from the selected project, including under pnpm's isolated\n // dependency layout. Core does not depend on the optional export tool.\n let entry: string;\n try {\n entry = createRequire(resolve(values.project ?? 'package.json')).resolve(\n '@swiftuijs/twill-export/cli',\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') throw error;\n throw new Error(\n 'twill export requires @swiftuijs/twill-export in your project. Install it with pnpm add -D @swiftuijs/twill-export.',\n { cause: error },\n );\n }\n const exporter = await import(pathToFileURL(entry).href);\n const index = tokens.find((token) => token.kind === 'positional')!.index;\n return exporter.main(args.filter((_, position) => position !== index));\n }\n if (values['dry-run']) throw new Error('--dry-run is only supported by twill export');\n if (values.help || !command) {\n console.log(\n 'twill compile <file> [-o output.ts] [--js]\\ntwill check [-p tsconfig.json] [--json]\\ntwill doctor [-p tsconfig.json] [--json]\\ntwill declarations [-p tsconfig.json] [-o dist] [--build] [--json]\\ntwill export [-p tsconfig.json] -o ../native-project [--dry-run] [--json]\\n\\ncompile keeps TypeScript types by default; --js erases types and lowers JSX.\\nexport requires the optional @swiftuijs/twill-export package.\\nCommands use the optional twill.config.json from the project root.',\n );\n return 0;\n }\n if (extra.length) throw new Error('Unexpected arguments: ' + extra.join(' '));\n if (command === 'declarations') {\n if (input) throw new Error('Use --project <tsconfig.json> with declarations');\n const result = emitDeclarations(resolve(values.project ?? 'tsconfig.json'), {\n outDir: values.out,\n build: values.build,\n });\n if (values.json) console.log(JSON.stringify(result, null, 2));\n else {\n for (const diagnostic of result.diagnostics)\n console.error(\n `${diagnostic.filename ?? 'tsconfig'}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`,\n );\n if (!result.diagnostics.some((item) => item.category === 'error'))\n console.log(\n `Emitted ${result.files.length} declaration/map files from ${result.projects.length} projects.`,\n );\n }\n return result.diagnostics.some((item) => item.category === 'error') ? 1 : 0;\n }\n if (command === 'check' || command === 'doctor') {\n if (input) throw new Error('Use --project <tsconfig.json> with ' + command);\n const project = new TwillProject(resolve(values.project ?? 'tsconfig.json'));\n try {\n if (command === 'doctor') {\n const report = inspectProject(project);\n if (values.json) console.log(JSON.stringify(report, null, 2));\n else {\n console.log(\n `Twill ${report.twillVersion} / TypeScript ${report.typescriptVersion} / Node ${report.nodeVersion}`,\n );\n console.log(\n `Project: ${report.root}\\nSources: ${report.files.twill} Twill, ${report.files.native} native\\nDiagnostics: ${report.diagnostics.length} (${report.diagnosticTimeMs.toFixed(1)} ms)`,\n );\n for (const diagnostic of report.diagnostics)\n console.log(\n `${diagnostic.filename ?? 'tsconfig'}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`,\n );\n console.log('Use --json to save the complete project report.');\n }\n return report.ok ? 0 : 1;\n }\n const diagnostics = project.diagnostics();\n if (values.json) console.log(JSON.stringify(diagnostics, null, 2));\n else\n for (const diagnostic of diagnostics)\n console.error(\n `${diagnostic.filename ?? 'tsconfig'}:${diagnostic.line}:${diagnostic.column + 1} TS${diagnostic.code}: ${diagnostic.message}`,\n );\n return diagnostics.some((diagnostic) => diagnostic.category === 'error') ? 1 : 0;\n } finally {\n project.dispose();\n }\n }\n if (command !== 'compile' || !input)\n throw new Error('Expected compile <file> or check. Use --help for usage.');\n const filename = resolve(input);\n const root = values.project ? dirname(resolve(values.project)) : process.cwd();\n const options = {\n ...loadConfig(root, values.project ? resolve(values.project) : undefined),\n filename,\n };\n const source = readFileSync(filename, 'utf8');\n const result = values.js ? transpile(source, options) : transform(source, options);\n if (values.out) {\n const output = resolve(values.out);\n if (output === filename) throw new Error('Output must differ from input');\n mkdirSync(dirname(output), { recursive: true });\n writeFileSync(\n output,\n result.code + `\\n//# sourceMappingURL=${output.split(/[\\\\/]/).at(-1)}.map\\n`,\n );\n const map = JSON.parse(result.map.toString());\n map.file = output.split(/[\\\\/]/).at(-1);\n writeFileSync(output + '.map', JSON.stringify(map));\n } else process.stdout.write(result.code + '\\n');\n return 0;\n}\n"],"mappings":"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"}