typeflake 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hauke Schnau
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,167 @@
1
+ # Typeflake
2
+
3
+ Typeflake is an experiment in writing Nix flakes, NixOS systems, Home Manager
4
+ profiles, and dev shells with TypeScript and Effect while keeping Nix as the
5
+ execution truth.
6
+
7
+ The source of intent is `flake.ts`. Typeflake evaluates that TypeScript program,
8
+ validates it, and emits ordinary, inspectable Nix artifacts such as `flake.nix`
9
+ and generated modules. Nix still evaluates, builds, and checks the result.
10
+
11
+ ## Product Thesis
12
+
13
+ Nix the ecosystem is excellent. Nix the language and tooling can be hard to
14
+ write at scale. Typeflake keeps the ecosystem and execution model, but adds:
15
+
16
+ - TypeScript-native authoring ergonomics.
17
+ - project-local types generated from the pinned flake/module universe.
18
+ - explicit typed escape hatches for raw Nix.
19
+ - Effect-powered validation, diagnostics, and command orchestration.
20
+ - taint tracking for generation-time effects such as environment, filesystem,
21
+ process, network, time, and host state.
22
+
23
+ ## Initial Scope
24
+
25
+ The first milestone focuses on:
26
+
27
+ - `flake.ts` as the primary entrypoint.
28
+ - generated `flake.nix`.
29
+ - NixOS configurations.
30
+ - Home Manager configurations.
31
+ - dev shells.
32
+ - option extraction from the real pinned Nix module graph.
33
+ - a tiny CLI with `sync` and `check`.
34
+
35
+ ## Current Shape
36
+
37
+ TypeScript remains the composition system. Typeflake provides typed boundaries
38
+ for Nix concepts and generates ordinary Nix artifacts:
39
+
40
+ ```ts
41
+ import { Flake, Home, NixOS, pkgs } from "typeflake";
42
+
43
+ const systemConfig = NixOS.config({
44
+ services: {
45
+ openssh: {
46
+ enable: true,
47
+ },
48
+ },
49
+ environment: {
50
+ systemPackages: [pkgs.git, pkgs.neovim],
51
+ },
52
+ system: {
53
+ stateVersion: "25.11",
54
+ },
55
+ });
56
+
57
+ const homeConfig = {
58
+ home: {
59
+ stateVersion: "25.11",
60
+ },
61
+ programs: {
62
+ git: {
63
+ enable: true,
64
+ },
65
+ },
66
+ } satisfies Home.Config;
67
+
68
+ export default Flake.make({
69
+ inputs: Flake.inputs({
70
+ nixpkgs: Flake.input("nixpkgs", "github:NixOS/nixpkgs/nixos-unstable"),
71
+ homeManager: Flake.input("homeManager", "github:nix-community/home-manager"),
72
+ }),
73
+ outputs: ({ homeManager }) => ({
74
+ nixosConfigurations: {
75
+ framework: NixOS.configuration({
76
+ system: "x86_64-linux",
77
+ modules: [
78
+ NixOS.module(systemConfig),
79
+ Home.nixosModule(homeManager, {
80
+ users: {
81
+ hauke: homeConfig,
82
+ },
83
+ }),
84
+ ],
85
+ }),
86
+ },
87
+ }),
88
+ });
89
+ ```
90
+
91
+ The option bridge now has a narrow working vertical slice:
92
+
93
+ - a Nix-side probe that evaluates pinned NixOS and Home Manager option metadata,
94
+ - project-local `typeflake options probe` and `typeflake options generate`
95
+ commands,
96
+ - generated fixture types for a small but broader option subset,
97
+ - Attest-backed type assertions for the generated config surface,
98
+ - and a golden test that compares real `nix eval --json` output to the committed
99
+ option fixture.
100
+
101
+ Deployment and broader orchestration are intentionally later milestones. The
102
+ first bet to prove is the type model.
103
+
104
+ ## Install
105
+
106
+ This is a very early alpha. The package is published for experimentation and
107
+ name reservation, not for production use yet.
108
+
109
+ ```sh
110
+ npm install --save-dev typeflake@next
111
+ ```
112
+
113
+ Typeflake currently expects Node.js 22 or newer. It also ships with
114
+ TypeScript-Go Native Preview and the Effect TSGO plugin so the CLI can run its
115
+ own authoring checks after installation.
116
+
117
+ For consumer projects on this alpha, use ESM/NodeNext TypeScript settings. While
118
+ Effect v4 and TypeScript-Go are both still moving, `skipLibCheck` may be needed
119
+ in downstream projects that import Typeflake's declarations.
120
+
121
+ ## Generated Type Lifecycle
122
+
123
+ Generated option types belong to the consuming project. Typeflake reads that
124
+ project's locked flake inputs, asks Nix to evaluate the real option graph, and
125
+ then emits TypeScript declarations from the resulting metadata.
126
+
127
+ ```sh
128
+ typeflake options probe \
129
+ --flake . \
130
+ --system x86_64-linux \
131
+ --scope nixos \
132
+ --scope home-manager \
133
+ --output .typeflake/options.json
134
+
135
+ typeflake options generate \
136
+ --input .typeflake/options.json \
137
+ --output .typeflake/options.ts
138
+ ```
139
+
140
+ Use `--nixpkgs-input` and `--home-manager-input` when a project uses different
141
+ flake input names. After changing `flake.lock`, rerun both commands and then run
142
+ the normal checks.
143
+
144
+ The trust boundary is intentionally simple:
145
+
146
+ - `flake.lock` pins the Nix universe.
147
+ - Nix evaluates the real NixOS/Home Manager module options.
148
+ - Typeflake parses that metadata into a typed IR.
149
+ - TypeScript checks authoring against generated declarations.
150
+ - Nix remains the execution truth for evaluation, checks, and builds.
151
+
152
+ Unsupported option shapes are never erased into `any`. The generator keeps them
153
+ explicit with `UnsupportedNixOption<...>` escape hatches, and
154
+ `typeflake options generate --strict` fails if any remain.
155
+
156
+ ## Documents
157
+
158
+ - [Vision](docs/VISION.md)
159
+ - [Architecture](docs/ARCHITECTURE.md)
160
+ - [First Spike](docs/SPIKE.md)
161
+ - [Prior Art](docs/PRIOR_ART.md)
162
+
163
+ ## Status
164
+
165
+ Implementation spike in progress. The repository can render and check a small
166
+ flake, run Effect-native CLI commands, and validate a first generated option
167
+ type subset.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "../dist/cli.mjs";
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.mjs ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ import { C as sync, M as DoctorFailed, S as check, b as doctor, n as generateProjectOptionTypes, r as probeProjectOptions, t as defaultOptionScopes, x as renderDoctorReport } from "./options-CE3YO7EL.mjs";
3
+ import * as Effect from "effect/Effect";
4
+ import { NodeRuntime, NodeServices } from "@effect/platform-node";
5
+ import * as Console from "effect/Console";
6
+ import { Command, Flag } from "effect/unstable/cli";
7
+ //#endregion
8
+ //#region src/cli.ts
9
+ const { version } = {
10
+ name: "typeflake",
11
+ version: "0.0.1-alpha.0",
12
+ description: "TypeScript and Effect authoring for real Nix flakes.",
13
+ keywords: [
14
+ "effect",
15
+ "flakes",
16
+ "nix",
17
+ "nixos",
18
+ "typescript"
19
+ ],
20
+ homepage: "https://git.schnau.dev/schnau/typeflake",
21
+ bugs: { "url": "https://git.schnau.dev/schnau/typeflake/issues" },
22
+ license: "MIT",
23
+ author: "Hauke Schnau <hauke@schnau.dev>",
24
+ repository: {
25
+ "type": "git",
26
+ "url": "git+ssh://git@git.schnau.dev/schnau/typeflake.git"
27
+ },
28
+ bin: { "typeflake": "bin/typeflake.js" },
29
+ files: [
30
+ "bin",
31
+ "dist",
32
+ "LICENSE",
33
+ "README.md"
34
+ ],
35
+ type: "module",
36
+ types: "./dist/index.d.mts",
37
+ exports: { ".": {
38
+ "types": "./dist/index.d.mts",
39
+ "import": "./dist/index.mjs"
40
+ } },
41
+ publishConfig: { "access": "public" },
42
+ scripts: {
43
+ "build": "tsdown src/index.ts src/cli.ts --format esm --dts --out-dir dist --clean --target node22 --platform node",
44
+ "check": "nub run check:types && nub run check:effect && nub run lint && nub run test && nub run format:check",
45
+ "check:effect": "tsgo --noEmit --project tsconfig.json",
46
+ "check:types": "oxlint . --type-aware --type-check --deny-warnings",
47
+ "format": "oxfmt .",
48
+ "format:check": "oxfmt . --check",
49
+ "lint": "oxlint . --type-aware --deny-warnings --report-unused-disable-directives",
50
+ "pack:dry": "npm pack --dry-run",
51
+ "prepack": "nub run build",
52
+ "prepublishOnly": "nub run check",
53
+ "test": "vitest run",
54
+ "tsgo:patch": "effect-tsgo patch",
55
+ "typeflake": "nub src/cli.ts"
56
+ },
57
+ dependencies: {
58
+ "@effect/platform-node": "4.0.0-beta.93",
59
+ "@effect/tsgo": "0.16.0",
60
+ "@typescript/native-preview": "7.0.0-dev.20260703.1",
61
+ "effect": "4.0.0-beta.93"
62
+ },
63
+ devDependencies: {
64
+ "@arktype/attest": "0.56.2",
65
+ "@effect/vitest": "4.0.0-beta.93",
66
+ "@types/node": "24.10.0",
67
+ "@vitest/runner": "4.1.4",
68
+ "oxfmt": "0.57.0",
69
+ "oxlint": "1.72.0",
70
+ "oxlint-tsgolint": "0.24.0",
71
+ "tsdown": "0.22.3",
72
+ "typescript": "5.9.3",
73
+ "vitest": "4.1.4"
74
+ },
75
+ engines: { "node": ">=22" },
76
+ packageManager: "pnpm@11.9.0"
77
+ };
78
+ const flakeFileFlags = {
79
+ input: Flag.string("input").pipe(Flag.withAlias("i"), Flag.withDescription("TypeScript flake entrypoint"), Flag.withDefault("flake.ts")),
80
+ output: Flag.string("output").pipe(Flag.withAlias("o"), Flag.withDescription("Generated Nix flake path"), Flag.withDefault("flake.nix"))
81
+ };
82
+ const syncCommand = Command.make("sync", flakeFileFlags, (options) => sync(options).pipe(Effect.flatMap(() => Console.log(`Generated ${options.output}`)))).pipe(Command.withDescription("Generate a Nix flake from flake.ts"));
83
+ const checkCommand = Command.make("check", flakeFileFlags, (options) => check(options)).pipe(Command.withDescription("Generate a Nix flake and run nix flake check"));
84
+ const optionScopeFlag = Flag.choice("scope", ["nixos", "home-manager"]).pipe(Flag.atLeast(0), Flag.withDescription("Option scope to probe; repeat for multiple scopes"));
85
+ const optionsProbeCommand = Command.make("probe", {
86
+ flake: Flag.string("flake").pipe(Flag.withDescription("Project flake root used for locked option metadata"), Flag.withDefault(".")),
87
+ homeManagerInput: Flag.string("home-manager-input").pipe(Flag.withDescription("Home Manager input name in the project flake"), Flag.withDefault("home-manager")),
88
+ nixpkgsInput: Flag.string("nixpkgs-input").pipe(Flag.withDescription("nixpkgs input name in the project flake"), Flag.withDefault("nixpkgs")),
89
+ output: Flag.string("output").pipe(Flag.withAlias("o"), Flag.withDescription("Stable option metadata JSON output path"), Flag.withDefault(".typeflake/options.json")),
90
+ scope: optionScopeFlag,
91
+ system: Flag.string("system").pipe(Flag.withDescription("Nix system used while evaluating option metadata"), Flag.withDefault("x86_64-linux"))
92
+ }, (options) => probeProjectOptions({
93
+ flake: options.flake,
94
+ homeManagerInput: options.homeManagerInput,
95
+ nixpkgsInput: options.nixpkgsInput,
96
+ output: options.output,
97
+ scopes: normalizeCliScopes(options.scope),
98
+ system: options.system
99
+ }).pipe(Effect.flatMap((document) => Console.log(`Wrote ${document.options.length} option records to ${options.output}`)))).pipe(Command.withDescription("Probe project-local pinned Nix option metadata"));
100
+ const optionsGenerateCommand = Command.make("generate", {
101
+ input: Flag.string("input").pipe(Flag.withAlias("i"), Flag.withDescription("Stable option metadata JSON input path"), Flag.withDefault(".typeflake/options.json")),
102
+ output: Flag.string("output").pipe(Flag.withAlias("o"), Flag.withDescription("Generated TypeScript option type output path"), Flag.withDefault(".typeflake/options.ts")),
103
+ strict: Flag.boolean("strict").pipe(Flag.withDescription("Fail when generated types contain unsupported option shapes"))
104
+ }, (options) => generateProjectOptionTypes(options).pipe(Effect.flatMap(({ document, unsupported }) => Console.log(`Wrote ${document.options.length} option types to ${options.output}` + renderUnsupportedSummary(unsupported.length))))).pipe(Command.withDescription("Generate TypeScript option types from probed metadata"));
105
+ const optionsCommand = Command.make("options").pipe(Command.withDescription("Probe and generate project-local option types"), Command.withSubcommands([optionsProbeCommand, optionsGenerateCommand]));
106
+ const doctorCommand = Command.make("doctor", { project: Flag.string("project").pipe(Flag.withDescription("TypeScript project checked before loading flake.ts"), Flag.withDefault("tsconfig.json")) }, (options) => Effect.gen(function* () {
107
+ const report = yield* doctor(options);
108
+ yield* Console.log(renderDoctorReport(report));
109
+ if (!report.ok) return yield* new DoctorFailed({ failedChecks: report.checks.filter((doctorCheck) => !doctorCheck.ok).map((doctorCheck) => doctorCheck.name) });
110
+ })).pipe(Command.withDescription("Check local Typeflake tooling and compiler health"));
111
+ const command = Command.make("typeflake").pipe(Command.withDescription("TypeScript and Effect authoring for real Nix flakes"), Command.withSubcommands([
112
+ syncCommand,
113
+ checkCommand,
114
+ doctorCommand,
115
+ optionsCommand
116
+ ]));
117
+ const normalizeCliScopes = (scopes) => scopes.length === 0 ? defaultOptionScopes : scopes;
118
+ const renderUnsupportedSummary = (count) => count === 0 ? "" : ` (${count} unsupported option shapes kept explicit)`;
119
+ Command.run(command, { version }).pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
120
+ //#endregion
121
+ export {};
122
+
123
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.mjs","names":["packageJson"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["","#!/usr/bin/env node\n\nimport { NodeRuntime, NodeServices } from \"@effect/platform-node\";\nimport * as Console from \"effect/Console\";\nimport * as Effect from \"effect/Effect\";\nimport { Command, Flag } from \"effect/unstable/cli\";\nimport { check } from \"./check.ts\";\nimport { doctor, renderDoctorReport } from \"./doctor.ts\";\nimport { DoctorFailed } from \"./errors.ts\";\nimport {\n defaultOptionScopes,\n generateProjectOptionTypes,\n probeProjectOptions,\n type OptionScope,\n} from \"./options.ts\";\nimport { sync } from \"./sync.ts\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\n\nconst { version } = packageJson;\n\nconst flakeFileFlags = {\n input: Flag.string(\"input\").pipe(\n Flag.withAlias(\"i\"),\n Flag.withDescription(\"TypeScript flake entrypoint\"),\n Flag.withDefault(\"flake.ts\"),\n ),\n output: Flag.string(\"output\").pipe(\n Flag.withAlias(\"o\"),\n Flag.withDescription(\"Generated Nix flake path\"),\n Flag.withDefault(\"flake.nix\"),\n ),\n};\n\nconst syncCommand = Command.make(\"sync\", flakeFileFlags, (options) =>\n sync(options).pipe(Effect.flatMap(() => Console.log(`Generated ${options.output}`))),\n).pipe(Command.withDescription(\"Generate a Nix flake from flake.ts\"));\n\nconst checkCommand = Command.make(\"check\", flakeFileFlags, (options) => check(options)).pipe(\n Command.withDescription(\"Generate a Nix flake and run nix flake check\"),\n);\n\nconst optionScopeFlag = Flag.choice(\"scope\", [\"nixos\", \"home-manager\"]).pipe(\n Flag.atLeast(0),\n Flag.withDescription(\"Option scope to probe; repeat for multiple scopes\"),\n);\n\nconst optionsProbeCommand = Command.make(\n \"probe\",\n {\n flake: Flag.string(\"flake\").pipe(\n Flag.withDescription(\"Project flake root used for locked option metadata\"),\n Flag.withDefault(\".\"),\n ),\n homeManagerInput: Flag.string(\"home-manager-input\").pipe(\n Flag.withDescription(\"Home Manager input name in the project flake\"),\n Flag.withDefault(\"home-manager\"),\n ),\n nixpkgsInput: Flag.string(\"nixpkgs-input\").pipe(\n Flag.withDescription(\"nixpkgs input name in the project flake\"),\n Flag.withDefault(\"nixpkgs\"),\n ),\n output: Flag.string(\"output\").pipe(\n Flag.withAlias(\"o\"),\n Flag.withDescription(\"Stable option metadata JSON output path\"),\n Flag.withDefault(\".typeflake/options.json\"),\n ),\n scope: optionScopeFlag,\n system: Flag.string(\"system\").pipe(\n Flag.withDescription(\"Nix system used while evaluating option metadata\"),\n Flag.withDefault(\"x86_64-linux\"),\n ),\n },\n (options) =>\n probeProjectOptions({\n flake: options.flake,\n homeManagerInput: options.homeManagerInput,\n nixpkgsInput: options.nixpkgsInput,\n output: options.output,\n scopes: normalizeCliScopes(options.scope),\n system: options.system,\n }).pipe(\n Effect.flatMap((document) =>\n Console.log(`Wrote ${document.options.length} option records to ${options.output}`),\n ),\n ),\n).pipe(Command.withDescription(\"Probe project-local pinned Nix option metadata\"));\n\nconst optionsGenerateCommand = Command.make(\n \"generate\",\n {\n input: Flag.string(\"input\").pipe(\n Flag.withAlias(\"i\"),\n Flag.withDescription(\"Stable option metadata JSON input path\"),\n Flag.withDefault(\".typeflake/options.json\"),\n ),\n output: Flag.string(\"output\").pipe(\n Flag.withAlias(\"o\"),\n Flag.withDescription(\"Generated TypeScript option type output path\"),\n Flag.withDefault(\".typeflake/options.ts\"),\n ),\n strict: Flag.boolean(\"strict\").pipe(\n Flag.withDescription(\"Fail when generated types contain unsupported option shapes\"),\n ),\n },\n (options) =>\n generateProjectOptionTypes(options).pipe(\n Effect.flatMap(({ document, unsupported }) =>\n Console.log(\n `Wrote ${document.options.length} option types to ${options.output}` +\n renderUnsupportedSummary(unsupported.length),\n ),\n ),\n ),\n).pipe(Command.withDescription(\"Generate TypeScript option types from probed metadata\"));\n\nconst optionsCommand = Command.make(\"options\").pipe(\n Command.withDescription(\"Probe and generate project-local option types\"),\n Command.withSubcommands([optionsProbeCommand, optionsGenerateCommand]),\n);\n\nconst doctorCommand = Command.make(\n \"doctor\",\n {\n project: Flag.string(\"project\").pipe(\n Flag.withDescription(\"TypeScript project checked before loading flake.ts\"),\n Flag.withDefault(\"tsconfig.json\"),\n ),\n },\n (options) =>\n Effect.gen(function* () {\n const report = yield* doctor(options);\n yield* Console.log(renderDoctorReport(report));\n\n if (!report.ok) {\n return yield* new DoctorFailed({\n failedChecks: report.checks\n .filter((doctorCheck) => !doctorCheck.ok)\n .map((doctorCheck) => doctorCheck.name),\n });\n }\n\n return undefined;\n }),\n).pipe(Command.withDescription(\"Check local Typeflake tooling and compiler health\"));\n\nconst command = Command.make(\"typeflake\").pipe(\n Command.withDescription(\"TypeScript and Effect authoring for real Nix flakes\"),\n Command.withSubcommands([syncCommand, checkCommand, doctorCommand, optionsCommand]),\n);\n\nconst normalizeCliScopes = (scopes: readonly OptionScope[]): readonly OptionScope[] =>\n scopes.length === 0 ? defaultOptionScopes : scopes;\n\nconst renderUnsupportedSummary = (count: number): string =>\n count === 0 ? \"\" : ` (${count} unsupported option shapes kept explicit)`;\n\nCommand.run(command, { version }).pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);\n"],"mappings":"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"}