@aihu/css-engine 0.1.0 → 0.2.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/README.md CHANGED
@@ -9,19 +9,30 @@ Part of the **compiler + toolchain** layer of Aihu. Build-time only — does not
9
9
  <!-- BEGIN_HANDWRITTEN: prose -->
10
10
  > aihu CSS engine — a hard fork of Tailwind v4 with Web-Component-native scoped output, AST-aware scanning, and progressive feature emission.
11
11
 
12
- **Status:** v0bootstrap. The fork's identity, perf optimizations, and scoped emitter are all under construction. See [`docs/superpowers/specs/2026-05-10-aihu-css-engine-and-primitives-design.md`](../../docs/superpowers/specs/2026-05-10-aihu-css-engine-and-primitives-design.md) for the full design.
12
+ **Status:** v1shipped. The fork identity, AST scanner, scoped emitter, WC-native
13
+ variants, progressive features, both style packs, and the `cn()` runtime helper
14
+ are all landed. See [`docs/superpowers/specs/2026-05-10-aihu-css-engine-and-primitives-design.md`](../../docs/superpowers/specs/2026-05-10-aihu-css-engine-and-primitives-design.md) for the full design.
13
15
 
14
- ### Status by capability (Plan 1 bootstrap)
16
+ ### Status by capability
15
17
 
16
- | Capability | Plan that lands it |
18
+ | Capability | Status |
17
19
  |---|---|
18
- | Package builds; compile pipeline scaffolded | **Plan 1 (this one)** |
19
- | AST scanner consuming `@aihu/compiler` | Plan 2 |
20
- | Scoped-output mode (`:host` embedding) | Plan 2 |
21
- | WC-native variants (`host:`, `slotted:`, `part-*:`) | Plan 2 |
22
- | Progressive features (`view-transition:`, `anchor:`, etc.) | Plan 3 |
23
- | Style packs (`aihu-default`, `aihu-graphite`) | Plan 3 |
24
- | `cn()` runtime helper | Plan 3 |
20
+ | Package builds; `compile()` / `compileSfc()` pipeline | shipped |
21
+ | AST scanner consuming `@aihu/compiler` (`compileSfc`) | shipped |
22
+ | Scoped-output mode (`:host` embedding) | shipped |
23
+ | WC-native variants (`host:`, `slotted:`, `part-*:`) | shipped |
24
+ | Progressive features (`view-transition:`, `anchor:`, etc.) — `@aihu/css-engine/runtime/progressive` | shipped |
25
+ | Style packs (`aihu-default`, `aihu-graphite`) — `defineStylePack()`, `./packs`, `./styles/*.css` | shipped |
26
+ | `cn()` runtime helper — `@aihu/css-engine/runtime/cn` | shipped |
27
+
28
+ ### Native binary distribution
29
+
30
+ `compile()` / `compileSfc()` shell out to the prebuilt `aihu-css-compile`
31
+ executable (the `aihu-css-core` Rust crate). For npm consumers the binary ships
32
+ as a per-platform `optionalDependencies` package
33
+ (`@aihu/css-engine-{darwin-arm64,darwin-x64,linux-x64-gnu,win32-x64-msvc}`),
34
+ resolved automatically at build time — no Rust toolchain required. In a monorepo
35
+ dev clone the engine falls back to the workspace `target/release` binary.
25
36
 
26
37
  ### Local development
27
38
 
@@ -49,7 +60,7 @@ npm install @aihu/css-engine
49
60
  bun add @aihu/css-engine
50
61
  ```
51
62
 
52
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
63
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
53
64
 
54
65
  <!-- END_AUTOGEN: install -->
55
66
 
@@ -60,12 +71,12 @@ bun add @aihu/css-engine
60
71
 
61
72
  | | |
62
73
  |---|---|
63
- | **Version** | `0.1.0` |
74
+ | **Version** | `0.2.0` |
64
75
  | **Tier** | D — Compiler — CSS engine (Tailwind v4 hard fork, WC-native scoped output) |
65
76
  | **Published files** | 5 entries |
66
77
  | **License** | MIT |
67
78
 
68
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
79
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
69
80
 
70
81
  <!-- END_AUTOGEN: stats -->
71
82
 
@@ -77,10 +88,14 @@ bun add @aihu/css-engine
77
88
  | Subpath | ESM | CJS |
78
89
  |---|---|---|
79
90
  | `.` | `./dist/index.js` | `—` |
91
+ | `./packs` | `./dist/packs.js` | `—` |
92
+ | `./styles/aihu-default.css` | `./styles/aihu-default.css` | — |
93
+ | `./styles/aihu-graphite.css` | `./styles/aihu-graphite.css` | — |
94
+ | `./styles/*` | `./styles/*` | — |
80
95
  | `./runtime/cn` | `./dist/runtime/cn.js` | `—` |
81
96
  | `./runtime/progressive` | `./dist/runtime/progressive.js` | `—` |
82
97
 
83
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
98
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
84
99
 
85
100
  <!-- END_AUTOGEN: exports -->
86
101
 
@@ -93,7 +108,14 @@ bun add @aihu/css-engine
93
108
 
94
109
  - `@aihu/compiler` — `workspace:*`
95
110
 
96
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
111
+ **Optional dependencies (platform-specific):**
112
+
113
+ - `@aihu/css-engine-darwin-arm64` — `0.1.2`
114
+ - `@aihu/css-engine-darwin-x64` — `0.1.2`
115
+ - `@aihu/css-engine-linux-x64-gnu` — `0.1.2`
116
+ - `@aihu/css-engine-win32-x64-msvc` — `0.1.2`
117
+
118
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
97
119
 
98
120
  <!-- END_AUTOGEN: deps -->
99
121
 
@@ -106,7 +128,7 @@ bun add @aihu/css-engine
106
128
  - [@aihu/compiler](../compiler)
107
129
  - [Aihu framework root](../../README.md)
108
130
 
109
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
131
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
110
132
 
111
133
  <!-- END_AUTOGEN: see-also -->
112
134
 
@@ -117,6 +139,6 @@ bun add @aihu/css-engine
117
139
 
118
140
  MIT — see [LICENSE](../../LICENSE).
119
141
 
120
- <sub><i>Auto-generated against `@aihu/css-engine@0.1.0`.</i></sub>
142
+ <sub><i>Auto-generated against `@aihu/css-engine@0.2.0`.</i></sub>
121
143
 
122
144
  <!-- END_AUTOGEN: license -->
@@ -0,0 +1,39 @@
1
+ //#region src/define-style-pack.ts
2
+ /** Normalize a token name to its `--`-prefixed custom-property form. */
3
+ function asCustomProp(name) {
4
+ return name.startsWith("--") ? name : `--${name}`;
5
+ }
6
+ function emitBlock(selector, tokens) {
7
+ return `${selector} {\n${Object.entries(tokens).map(([name, value]) => ` ${asCustomProp(name)}: ${value};`).join("\n")}\n}\n`;
8
+ }
9
+ /**
10
+ * Define a style pack from a token map.
11
+ *
12
+ * @example
13
+ * const acme = defineStylePack({
14
+ * name: 'acme',
15
+ * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },
16
+ * dark: { 'color-primary': '#3fc' },
17
+ * })
18
+ * acme.toCss() // => ":root { --color-primary: #0a7; … } .dark { … }"
19
+ */
20
+ function defineStylePack(input) {
21
+ if (!input.name) throw new Error("defineStylePack: `name` is required");
22
+ if (!input.tokens || Object.keys(input.tokens).length === 0) throw new Error(`defineStylePack("${input.name}"): tokens must be a non-empty map`);
23
+ const tokens = { ...input.tokens };
24
+ const dark = { ...input.dark ?? {} };
25
+ return {
26
+ name: input.name,
27
+ tokens,
28
+ dark,
29
+ toCss() {
30
+ let css = emitBlock(":root", tokens);
31
+ if (Object.keys(dark).length > 0) css += emitBlock(".dark", dark);
32
+ return css;
33
+ }
34
+ };
35
+ }
36
+ //#endregion
37
+ export { defineStylePack as t };
38
+
39
+ //# sourceMappingURL=define-style-pack--6pevgrd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-style-pack--6pevgrd.js","names":[],"sources":["../src/define-style-pack.ts"],"sourcesContent":["/**\n * `defineStylePack()` — the export hook for external orgs (Plan 3 Task 10).\n *\n * Lets an external org declare its own token bundle against the SAME token-name\n * contract as the built-in `aihu-default` / `aihu-graphite` packs (see\n * `styles/*.css`), so a custom pack slots into the engine exactly like the\n * built-ins. Returns a `StylePack` descriptor the engine can register and emit\n * as `:root` / `.dark` token blocks.\n *\n * The built-in packs are expressible through this same API — `defineStylePack`\n * is just the typed, programmatic form of the shipped CSS bundles.\n */\n\n/** A design-token map: `name` → CSS value. Names omit the leading `--`. */\nexport type TokenMap = Record<string, string>\n\n/** Input to {@link defineStylePack}. */\nexport interface StylePackInput {\n /** Pack name, e.g. `'acme'` (used for registration / debugging). */\n name: string\n /** Light-theme tokens (the `:root` block). Names without the `--` prefix. */\n tokens: TokenMap\n /** Optional dark-theme overrides (the `.dark` block). */\n dark?: TokenMap\n}\n\n/** A registered, validated style-pack descriptor. */\nexport interface StylePack {\n readonly name: string\n readonly tokens: TokenMap\n readonly dark: TokenMap\n /**\n * Serialize the pack to a `:root { … }` (+ `.dark { … }`) CSS string — the\n * same shape as the shipped `styles/*.css` bundles.\n */\n toCss(): string\n}\n\n/** Normalize a token name to its `--`-prefixed custom-property form. */\nfunction asCustomProp(name: string): string {\n return name.startsWith('--') ? name : `--${name}`\n}\n\nfunction emitBlock(selector: string, tokens: TokenMap): string {\n const decls = Object.entries(tokens)\n .map(([name, value]) => ` ${asCustomProp(name)}: ${value};`)\n .join('\\n')\n return `${selector} {\\n${decls}\\n}\\n`\n}\n\n/**\n * Define a style pack from a token map.\n *\n * @example\n * const acme = defineStylePack({\n * name: 'acme',\n * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },\n * dark: { 'color-primary': '#3fc' },\n * })\n * acme.toCss() // => \":root { --color-primary: #0a7; … } .dark { … }\"\n */\nexport function defineStylePack(input: StylePackInput): StylePack {\n if (!input.name) {\n throw new Error('defineStylePack: `name` is required')\n }\n if (!input.tokens || Object.keys(input.tokens).length === 0) {\n throw new Error(`defineStylePack(\"${input.name}\"): tokens must be a non-empty map`)\n }\n\n const tokens = { ...input.tokens }\n const dark = { ...(input.dark ?? {}) }\n\n return {\n name: input.name,\n tokens,\n dark,\n toCss(): string {\n let css = emitBlock(':root', tokens)\n if (Object.keys(dark).length > 0) {\n css += emitBlock('.dark', dark)\n }\n return css\n },\n }\n}\n"],"mappings":";;AAuCA,SAAS,aAAa,MAAsB;CAC1C,OAAO,KAAK,WAAW,KAAK,GAAG,OAAO,KAAK;;AAG7C,SAAS,UAAU,UAAkB,QAA0B;CAI7D,OAAO,GAAG,SAAS,MAHL,OAAO,QAAQ,OAAO,CACjC,KAAK,CAAC,MAAM,WAAW,KAAK,aAAa,KAAK,CAAC,IAAI,MAAM,GAAG,CAC5D,KAAK,KACsB,CAAC;;;;;;;;;;;;;AAcjC,SAAgB,gBAAgB,OAAkC;CAChE,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MAAM,sCAAsC;CAExD,IAAI,CAAC,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,CAAC,WAAW,GACxD,MAAM,IAAI,MAAM,oBAAoB,MAAM,KAAK,oCAAoC;CAGrF,MAAM,SAAS,EAAE,GAAG,MAAM,QAAQ;CAClC,MAAM,OAAO,EAAE,GAAI,MAAM,QAAQ,EAAE,EAAG;CAEtC,OAAO;EACL,MAAM,MAAM;EACZ;EACA;EACA,QAAgB;GACd,IAAI,MAAM,UAAU,SAAS,OAAO;GACpC,IAAI,OAAO,KAAK,KAAK,CAAC,SAAS,GAC7B,OAAO,UAAU,SAAS,KAAK;GAEjC,OAAO;;EAEV"}
@@ -0,0 +1,50 @@
1
+ //#region src/define-style-pack.d.ts
2
+ /**
3
+ * `defineStylePack()` — the export hook for external orgs (Plan 3 Task 10).
4
+ *
5
+ * Lets an external org declare its own token bundle against the SAME token-name
6
+ * contract as the built-in `aihu-default` / `aihu-graphite` packs (see
7
+ * `styles/*.css`), so a custom pack slots into the engine exactly like the
8
+ * built-ins. Returns a `StylePack` descriptor the engine can register and emit
9
+ * as `:root` / `.dark` token blocks.
10
+ *
11
+ * The built-in packs are expressible through this same API — `defineStylePack`
12
+ * is just the typed, programmatic form of the shipped CSS bundles.
13
+ */
14
+ /** A design-token map: `name` → CSS value. Names omit the leading `--`. */
15
+ type TokenMap = Record<string, string>;
16
+ /** Input to {@link defineStylePack}. */
17
+ interface StylePackInput {
18
+ /** Pack name, e.g. `'acme'` (used for registration / debugging). */
19
+ name: string;
20
+ /** Light-theme tokens (the `:root` block). Names without the `--` prefix. */
21
+ tokens: TokenMap;
22
+ /** Optional dark-theme overrides (the `.dark` block). */
23
+ dark?: TokenMap;
24
+ }
25
+ /** A registered, validated style-pack descriptor. */
26
+ interface StylePack {
27
+ readonly name: string;
28
+ readonly tokens: TokenMap;
29
+ readonly dark: TokenMap;
30
+ /**
31
+ * Serialize the pack to a `:root { … }` (+ `.dark { … }`) CSS string — the
32
+ * same shape as the shipped `styles/*.css` bundles.
33
+ */
34
+ toCss(): string;
35
+ }
36
+ /**
37
+ * Define a style pack from a token map.
38
+ *
39
+ * @example
40
+ * const acme = defineStylePack({
41
+ * name: 'acme',
42
+ * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },
43
+ * dark: { 'color-primary': '#3fc' },
44
+ * })
45
+ * acme.toCss() // => ":root { --color-primary: #0a7; … } .dark { … }"
46
+ */
47
+ declare function defineStylePack(input: StylePackInput): StylePack;
48
+ //#endregion
49
+ export { defineStylePack as i, StylePackInput as n, TokenMap as r, StylePack as t };
50
+ //# sourceMappingURL=define-style-pack-DjzHvtf0.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-style-pack-DjzHvtf0.d.ts","names":[],"sources":["../src/define-style-pack.ts"],"mappings":";;AAcA;;;;;AAGA;;;;;;;KAHY,QAAA,GAAW,MAAA;;UAGN,cAAA;EAMA;EAJf,IAAA;EAQwB;EANxB,MAAA,EAAQ,QAAA;EASe;EAPvB,IAAA,GAAO,QAAA;AAAA;;UAIQ,SAAA;EAAA,SACN,IAAA;EAAA,SACA,MAAA,EAAQ,QAAA;EAAA,SACR,IAAA,EAAM,QAAA;EAKV;AA0BP;;;EA1BE,KAAA;AAAA;;;;;;;;;;;;iBA0Bc,eAAA,CAAgB,KAAA,EAAO,cAAA,GAAiB,SAAA"}
package/dist/index.d.ts CHANGED
@@ -1,52 +1,26 @@
1
- //#region src/define-style-pack.d.ts
1
+ import { i as defineStylePack, n as StylePackInput, r as TokenMap, t as StylePack } from "./define-style-pack-DjzHvtf0.js";
2
+
3
+ //#region src/index.d.ts
2
4
  /**
3
- * `defineStylePack()` the export hook for external orgs (Plan 3 Task 10).
5
+ * Whether `candidate` is a usable `aihu-css-compile` executable NOT merely a
6
+ * present file.
4
7
  *
5
- * Lets an external org declare its own token bundle against the SAME token-name
6
- * contract as the built-in `aihu-default` / `aihu-graphite` packs (see
7
- * `styles/*.css`), so a custom pack slots into the engine exactly like the
8
- * built-ins. Returns a `StylePack` descriptor the engine can register and emit
9
- * as `:root` / `.dark` token blocks.
8
+ * The per-platform packages (`@aihu/css-engine-<platform>`) carry a placeholder
9
+ * `aihu-css-compile` in source; the real prebuilt binary is only injected by
10
+ * the release CI. Once those packages become resolvable in the workspace (e.g.
11
+ * after a `bun.lock` refresh that pins them as optionalDependencies), a bare
12
+ * `existsSync` would happily return the non-executable placeholder, which then
13
+ * blows up with EACCES inside `spawnSync`/`execFileSync`. So we must verify the
14
+ * candidate is actually runnable before accepting it.
10
15
  *
11
- * The built-in packs are expressible through this same API — `defineStylePack`
12
- * is just the typed, programmatic form of the shipped CSS bundles.
13
- */
14
- /** A design-token map: `name` → CSS value. Names omit the leading `--`. */
15
- type TokenMap = Record<string, string>;
16
- /** Input to {@link defineStylePack}. */
17
- interface StylePackInput {
18
- /** Pack name, e.g. `'acme'` (used for registration / debugging). */
19
- name: string;
20
- /** Light-theme tokens (the `:root` block). Names without the `--` prefix. */
21
- tokens: TokenMap;
22
- /** Optional dark-theme overrides (the `.dark` block). */
23
- dark?: TokenMap;
24
- }
25
- /** A registered, validated style-pack descriptor. */
26
- interface StylePack {
27
- readonly name: string;
28
- readonly tokens: TokenMap;
29
- readonly dark: TokenMap;
30
- /**
31
- * Serialize the pack to a `:root { … }` (+ `.dark { … }`) CSS string — the
32
- * same shape as the shipped `styles/*.css` bundles.
33
- */
34
- toCss(): string;
35
- }
36
- /**
37
- * Define a style pack from a token map.
16
+ * POSIX: require the execute bit (X_OK). A zero-byte/text placeholder without
17
+ * +x fails here and we fall through to the dev `target/` fallback.
38
18
  *
39
- * @example
40
- * const acme = defineStylePack({
41
- * name: 'acme',
42
- * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },
43
- * dark: { 'color-primary': '#3fc' },
44
- * })
45
- * acme.toCss() // => ":root { --color-primary: #0a7; … } .dark { … }"
19
+ * Windows: there is no execute bit — `accessSync(_, X_OK)` is effectively
20
+ * always true so we additionally require a non-empty regular file, which
21
+ * still rejects a zero-byte placeholder.
46
22
  */
47
- declare function defineStylePack(input: StylePackInput): StylePack;
48
- //#endregion
49
- //#region src/index.d.ts
23
+ declare function isUsableExecutable(candidate: string): boolean;
50
24
  /**
51
25
  * Compile a list of utility class names to CSS.
52
26
  *
@@ -72,5 +46,5 @@ declare function compile(classes: string[]): string;
72
46
  */
73
47
  declare function compileSfc(source: string, id?: string): string;
74
48
  //#endregion
75
- export { type StylePack, type StylePackInput, type TokenMap, compile, compileSfc, defineStylePack };
49
+ export { type StylePack, type StylePackInput, type TokenMap, compile, compileSfc, defineStylePack, isUsableExecutable };
76
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/define-style-pack.ts","../src/index.ts"],"mappings":";;AAcA;;;;;AAGA;;;;;;;KAHY,QAAA,GAAW,MAAA;;UAGN,cAAA;EAMA;EAJf,IAAA;EAQwB;EANxB,MAAA,EAAQ,QAAA;EASe;EAPvB,IAAA,GAAO,QAAA;AAAA;;UAIQ,SAAA;EAAA,SACN,IAAA;EAAA,SACA,MAAA,EAAQ,QAAA;EAAA,SACR,IAAA,EAAM,QAAA;EAKV;AA0BP;;;EA1BE,KAAA;AAAA;;;;;;;;ACUF;;;;iBDgBgB,eAAA,CAAgB,KAAA,EAAO,cAAA,GAAiB,SAAA;;;AA/CxD;;;;;AAGA;;;;AAHA,iBC+BgB,OAAA,CAAQ,OAAA;;;;;;;ADlBxB;;;;;;;iBC4CgB,UAAA,CAAW,MAAA,UAAgB,EAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;AA8FA;;;;;AAgHA;;;;;AA0BA;;;;;;;iBA1IgB,kBAAA,CAAmB,SAAA;;;;;;;;;;iBAgHnB,OAAA,CAAQ,OAAA;;;;;;;;;;;;;;iBA0BR,UAAA,CAAW,MAAA,UAAgB,EAAA"}
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
+ import { t as defineStylePack } from "./define-style-pack--6pevgrd.js";
1
2
  import { execFileSync } from "node:child_process";
2
- import { existsSync } from "node:fs";
3
- import { basename, dirname, resolve } from "node:path";
3
+ import { accessSync, constants, existsSync, statSync } from "node:fs";
4
+ import { createRequire } from "node:module";
5
+ import { basename, dirname, join, resolve } from "node:path";
4
6
  import { fileURLToPath } from "node:url";
5
7
  //#region ../compiler/dist/index.js
6
8
  const a = process.platform === `win32` ? `.exe` : ``, o = process.env.SCRIBE_COMPILE_BIN ?? resolve(dirname(fileURLToPath(import.meta.url)), `../bin/aihu-compile${a}`);
7
- function m(n, r) {
9
+ function g(n, r) {
8
10
  let i = [
9
11
  `--stdin`,
10
12
  `--tag`,
@@ -19,54 +21,105 @@ function m(n, r) {
19
21
  return JSON.parse(a);
20
22
  }
21
23
  //#endregion
22
- //#region src/define-style-pack.ts
23
- /** Normalize a token name to its `--`-prefixed custom-property form. */
24
- function asCustomProp(name) {
25
- return name.startsWith("--") ? name : `--${name}`;
26
- }
27
- function emitBlock(selector, tokens) {
28
- return `${selector} {\n${Object.entries(tokens).map(([name, value]) => ` ${asCustomProp(name)}: ${value};`).join("\n")}\n}\n`;
24
+ //#region src/index.ts
25
+ const __dirname = dirname(fileURLToPath(import.meta.url));
26
+ function detectPlatform() {
27
+ if (typeof process === "undefined" || !process.platform || !process.arch) return null;
28
+ switch (`${process.platform}-${process.arch}`) {
29
+ case "darwin-arm64": return {
30
+ platformId: "darwin-arm64",
31
+ packageName: "@aihu/css-engine-darwin-arm64",
32
+ binFile: "aihu-css-compile"
33
+ };
34
+ case "darwin-x64": return {
35
+ platformId: "darwin-x64",
36
+ packageName: "@aihu/css-engine-darwin-x64",
37
+ binFile: "aihu-css-compile"
38
+ };
39
+ case "linux-x64": return {
40
+ platformId: "linux-x64-gnu",
41
+ packageName: "@aihu/css-engine-linux-x64-gnu",
42
+ binFile: "aihu-css-compile"
43
+ };
44
+ case "win32-x64": return {
45
+ platformId: "win32-x64-msvc",
46
+ packageName: "@aihu/css-engine-win32-x64-msvc",
47
+ binFile: "aihu-css-compile.exe"
48
+ };
49
+ default: return null;
50
+ }
29
51
  }
52
+ let _binPath = null;
30
53
  /**
31
- * Define a style pack from a token map.
54
+ * Whether `candidate` is a usable `aihu-css-compile` executable NOT merely a
55
+ * present file.
32
56
  *
33
- * @example
34
- * const acme = defineStylePack({
35
- * name: 'acme',
36
- * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },
37
- * dark: { 'color-primary': '#3fc' },
38
- * })
39
- * acme.toCss() // => ":root { --color-primary: #0a7; … } .dark { … }"
57
+ * The per-platform packages (`@aihu/css-engine-<platform>`) carry a placeholder
58
+ * `aihu-css-compile` in source; the real prebuilt binary is only injected by
59
+ * the release CI. Once those packages become resolvable in the workspace (e.g.
60
+ * after a `bun.lock` refresh that pins them as optionalDependencies), a bare
61
+ * `existsSync` would happily return the non-executable placeholder, which then
62
+ * blows up with EACCES inside `spawnSync`/`execFileSync`. So we must verify the
63
+ * candidate is actually runnable before accepting it.
64
+ *
65
+ * POSIX: require the execute bit (X_OK). A zero-byte/text placeholder without
66
+ * +x fails here and we fall through to the dev `target/` fallback.
67
+ *
68
+ * Windows: there is no execute bit — `accessSync(_, X_OK)` is effectively
69
+ * always true — so we additionally require a non-empty regular file, which
70
+ * still rejects a zero-byte placeholder.
40
71
  */
41
- function defineStylePack(input) {
42
- if (!input.name) throw new Error("defineStylePack: `name` is required");
43
- if (!input.tokens || Object.keys(input.tokens).length === 0) throw new Error(`defineStylePack("${input.name}"): tokens must be a non-empty map`);
44
- const tokens = { ...input.tokens };
45
- const dark = { ...input.dark ?? {} };
46
- return {
47
- name: input.name,
48
- tokens,
49
- dark,
50
- toCss() {
51
- let css = emitBlock(":root", tokens);
52
- if (Object.keys(dark).length > 0) css += emitBlock(".dark", dark);
53
- return css;
54
- }
55
- };
72
+ function isUsableExecutable(candidate) {
73
+ try {
74
+ const st = statSync(candidate);
75
+ if (!st.isFile() || st.size === 0) return false;
76
+ accessSync(candidate, constants.X_OK);
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
56
81
  }
57
- //#endregion
58
- //#region src/index.ts
59
- const __dirname = dirname(fileURLToPath(import.meta.url));
60
82
  /**
61
- * Resolve the path to the `aihu-css-compile` binary.
62
- * Looks for it relative to the package, then in the workspace target/release.
63
- * Plan 4 will replace this with a prebuilt binary shipped with the package.
83
+ * Resolve the absolute path to the `aihu-css-compile` executable.
84
+ *
85
+ * Resolution order:
86
+ * 1. The per-platform optionalDependency package
87
+ * (`@aihu/css-engine-<platform>`) shipped to npm consumers — resolved via
88
+ * `createRequire(...).resolve('<pkg>/package.json')` so it works in both
89
+ * ESM and CJS and respects the consumer's node_modules layout.
90
+ * 2. Dev fallback: the monorepo workspace `target/release|debug/` — only
91
+ * present in a dev clone with a Rust toolchain (`cargo build --release -p
92
+ * aihu-css-core`). Kept so in-repo builds + tests work without publishing.
93
+ *
94
+ * If the current platform is SUPPORTED but neither path yields a binary, throws
95
+ * a structured error pointing at the missing optionalDependency (mirrors
96
+ * @aihu/server's failure-loud contract). If the platform is UNSUPPORTED, the
97
+ * error lists the dev fallback so source builds still have a clear remedy.
64
98
  */
65
99
  function resolveBinary() {
100
+ if (_binPath !== null) return _binPath;
101
+ const descriptor = detectPlatform();
102
+ if (descriptor) {
103
+ const requireFn = createRequire(import.meta.url);
104
+ try {
105
+ const candidate = join(dirname(requireFn.resolve(`${descriptor.packageName}/package.json`)), descriptor.binFile);
106
+ if (isUsableExecutable(candidate)) {
107
+ _binPath = candidate;
108
+ return _binPath;
109
+ }
110
+ } catch {}
111
+ }
66
112
  const ext = process.platform === "win32" ? ".exe" : "";
67
- const candidates = [resolve(__dirname, "../../../target/release", `aihu-css-compile${ext}`), resolve(__dirname, "../../../target/debug", `aihu-css-compile${ext}`)];
68
- for (const c of candidates) if (existsSync(c)) return c;
69
- throw new Error(`aihu-css-compile binary not found. Run \`cargo build --release -p aihu-css-core\` from the repo root first. Checked: ${candidates.join(", ")}`);
113
+ const devCandidates = [resolve(__dirname, "../../../target/release", `aihu-css-compile${ext}`), resolve(__dirname, "../../../target/debug", `aihu-css-compile${ext}`)];
114
+ for (const c of devCandidates) if (existsSync(c)) {
115
+ _binPath = c;
116
+ return _binPath;
117
+ }
118
+ throw buildMissingBinaryError(descriptor, devCandidates);
119
+ }
120
+ function buildMissingBinaryError(descriptor, devCandidates) {
121
+ if (descriptor === null) return /* @__PURE__ */ new Error(`[@aihu/css-engine] No prebuilt aihu-css-compile binary for this platform.\n\n Platform: ${typeof process !== "undefined" ? `${process.platform}-${process.arch}` : "unknown"}\n\n @aihu/css-engine ships prebuilt binaries for darwin-arm64, darwin-x64,\n linux-x64-gnu (glibc) and win32-x64-msvc. Your platform is not in that set.\n\n To build from source you need a Rust toolchain, then run from the repo root:\n cargo build --release -p aihu-css-core\n\n Checked dev fallback paths: ${devCandidates.join(", ")}`);
122
+ return /* @__PURE__ */ new Error(`[@aihu/css-engine] Native CSS compiler binary not found for this platform.\n\n Platform: ${descriptor.platformId}\n Expected package: ${descriptor.packageName}\n Expected file: ${descriptor.packageName}/${descriptor.binFile}\n\n This binary is distributed as an optionalDependency of @aihu/css-engine.\n Your package manager may have skipped it (optionalDependencies are\n silently dropped on install failure).\n\n To reinstall:\n npm install @aihu/css-engine\n # or: pnpm install or: bun install\n\n If you are working in the aihu monorepo, build from source instead:\n cargo build --release -p aihu-css-core\n Checked dev fallback paths: ${devCandidates.join(", ")}`);
70
123
  }
71
124
  /**
72
125
  * Compile a list of utility class names to CSS.
@@ -103,7 +156,7 @@ function compile(classes) {
103
156
  * @returns the scoped CSS string for the SFC
104
157
  */
105
158
  function compileSfc(source, id) {
106
- const ast = m(source, id);
159
+ const ast = g(source, id);
107
160
  return execFileSync(resolveBinary(), ["--ast-json"], {
108
161
  input: JSON.stringify(ast),
109
162
  encoding: "utf-8",
@@ -115,6 +168,6 @@ function compileSfc(source, id) {
115
168
  });
116
169
  }
117
170
  //#endregion
118
- export { compile, compileSfc, defineStylePack };
171
+ export { compile, compileSfc, defineStylePack, isUsableExecutable };
119
172
 
120
173
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["r","n","i","t","e","compileToAst"],"sources":["../../compiler/dist/index.js","../src/define-style-pack.ts","../src/index.ts"],"sourcesContent":["import{execFileSync as e}from\"node:child_process\";import{basename as t,dirname as n,resolve as r}from\"node:path\";import{fileURLToPath as i}from\"node:url\";const a=process.platform===`win32`?`.exe`:``,o=process.env.SCRIBE_COMPILE_BIN??r(n(i(import.meta.url)),`../bin/aihu-compile${a}`);function s(e,t){return e.replace(/(defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\([^]*\\))\\s*\\)/,(e,n)=>`${n}, { shadowMode: '${t}' })`)}function c(e){return/\\b(?:signal|computed|effect|setSignal|onMount|onCleanup)\\s*\\(/.test(e)?`interactive`:`static`}function l(e){let t=/defineElement\\(\\s*['\"]([^'\"]+)['\"]/m.exec(e);return t?t[1]??null:null}function u(e,t){let n=e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_hmrReplace`)||n.push(`_hmrReplace`),`import { ${n.join(`, `)} } from '@aihu/runtime'`}).replace(/\\bdefineComponent\\(/,`defineComponent(__aihu_setup__ = `),r=`\nexport { __aihu_setup__ as default }\n\nif (typeof __DEV__ !== 'undefined' && __DEV__ && import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (!newModule) return\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const newSetup = (newModule as any)['default']\n if (typeof newSetup !== 'function') return\n document.querySelectorAll(${JSON.stringify(t)}).forEach((el) => {\n _hmrReplace(el as HTMLElement, newSetup)\n })\n })\n}\n`;return`let __aihu_setup__: ((ctx: any) => any) | undefined\n`+n+r}function d(e,t){let n=e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_hydrateOnVisible`)||n.push(`_hydrateOnVisible`),`import { ${n.join(`, `)} } from '@aihu/runtime'`}),r=n.replace(/defineElement\\(\\s*('[^']+'|\"[^\"]+\")\\s*,\\s*defineComponent\\(/,(e,t)=>`defineElement(${t}, __aihu_wrap_defer__(defineComponent(`);if(r===n)return e;let i=r.replace(/\\)\\s*\\)\\s*\\nexport\\s/,`)))\nexport `);return i===r&&(i=r.replace(/\\)\\s*\\)\\s*$/,`)))\n`)),i===r?e:`\n// Plan 3.3 (Islands) — defer attribute support. Wraps the constructor\n// returned by defineComponent so instances bearing the \\`defer\\` attribute\n// hydrate lazily via IntersectionObserver. Bare instances retain the\n// eager Plan 3.2 hydration path.\nfunction __aihu_wrap_defer__<T extends typeof HTMLElement>(Ctor: T): T {\n const orig = (Ctor.prototype as unknown as { connectedCallback?: () => void }).connectedCallback\n if (typeof orig !== 'function') return Ctor\n ;(Ctor.prototype as unknown as { connectedCallback: () => void }).connectedCallback = function (this: HTMLElement) {\n if (this.hasAttribute('defer')) {\n _hydrateOnVisible(this, () => orig.call(this))\n } else {\n orig.call(this)\n }\n }\n return Ctor\n}\n`+i}function f(e,t){if(!/defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\(/.test(e))return e;let n=e.replace(/^\\s*import\\s*\\{[^}]*\\}\\s*from\\s*'@aihu\\/runtime'\\s*;?\\s*$/m,``).replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/arbor'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`mount`)||n.push(`mount`),`import { ${n.join(`, `)} } from '@aihu/arbor'`}),r=JSON.stringify(t);return`// SCRIBE_STATIC_ISLAND — zero @aihu/runtime references\\n${n.replace(/defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\(/,`customElements.define(${r}, class extends HTMLElement {\\n connectedCallback() {\\n const root = this.attachShadow({ mode: 'open' })\\n const __aihu_setup__ = (`).replace(/\\)\\s*\\)\\s*$/,`)\n mount(__aihu_setup__({ host: root, element: this }), root)\n }\n})\n`)}`}function p(n,r,i){let a=[`--stdin`,`--tag`,t(r,`.aihu`),`--path`,r];return i?.sidecarOut&&a.push(`--sidecar-out`,i.sidecarOut),{code:e(o,a,{input:n,encoding:`utf8`}),map:null}}function m(n,r){let i=[`--stdin`,`--tag`,r?t(r,`.aihu`):`Component`,`--ast-json`];r&&i.push(`--path`,r);let a=e(o,i,{input:n,encoding:`utf8`});return JSON.parse(a)}function h(e){let t;t=e.includes(`from '@aihu/arbor'`)?e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/arbor'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`mount`)||n.push(`mount`),`import { ${n.join(`, `)} } from '@aihu/arbor'`}):`import { mount } from '@aihu/arbor'\\n${e}`,/import\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/.test(t)?t=t.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/signals'/,(e,t)=>{if(e.startsWith(`import type`))return e;let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`signal`)||n.push(`signal`),`import { ${n.join(`, `)} } from '@aihu/signals'`}):/import.*from\\s*'@aihu\\/signals'/.test(t)?/import\\s+type\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/.test(t)&&!t.match(/import\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/)&&(t=t.replace(/(import\\s+type\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals')/,(e,t)=>`${t}\\nimport { signal } from '@aihu/signals'`)):t=t.replace(/import\\s*\\{[^}]*\\}\\s*from\\s*'@aihu\\/arbor'/,e=>`${e}\\nimport { signal } from '@aihu/signals'`),t=t.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_setMount`)||n.push(`_setMount`),n.includes(`_setSignal`)||n.push(`_setSignal`),`import { ${n.join(`, `)} } from '@aihu/runtime'`});let n=t.split(`\n`),r=-1;for(let e=n.length-1;e>=0;e--){let t=(n[e]??``).trim();if(t.startsWith(`import `)||t.startsWith(`import{`)){r=e;break}}return r!==-1&&(n.splice(r+1,0,`_setMount(mount)`,`_setSignal(signal)`,``),t=n.join(`\n`)),t}function g(e){let t=e?.islands!==!1,n=e?.shadowMode;return{name:`aihu-compiler`,enforce:`pre`,transform(e,r){let i=r.split(`?`)[0];if(i.endsWith(`.aihu`))return(async()=>{let r=p(e,i,{sidecarOut:`${i}.ts`}),a=n==null?r.code:s(r.code,n),o=l(a),m;t&&o!==null&&c(a)===`static`?m=f(a,o):o===null?(m=a,m=h(m)):(m=u(a,o),m=d(m,o),m=h(m));try{let e=await import(`vite`);return`transformWithEsbuild`in e&&typeof e.transformWithEsbuild==`function`?{code:(await e.transformWithEsbuild(m,`component.ts`,{target:`esnext`,sourcemap:!1})).code,map:null}:{code:m,moduleType:`ts`,map:null}}catch{return{code:m,map:null}}})()}}}export{d as _buildDeferredHydration,f as _buildStaticIsland,c as _classifyIsland,h as _injectAutoWiring,s as _injectShadowMode,g as aihuCompilerPlugin,m as compileToAst,p as transform};\n//# sourceMappingURL=index.js.map","/**\n * `defineStylePack()` — the export hook for external orgs (Plan 3 Task 10).\n *\n * Lets an external org declare its own token bundle against the SAME token-name\n * contract as the built-in `aihu-default` / `aihu-graphite` packs (see\n * `styles/*.css`), so a custom pack slots into the engine exactly like the\n * built-ins. Returns a `StylePack` descriptor the engine can register and emit\n * as `:root` / `.dark` token blocks.\n *\n * The built-in packs are expressible through this same API — `defineStylePack`\n * is just the typed, programmatic form of the shipped CSS bundles.\n */\n\n/** A design-token map: `name` → CSS value. Names omit the leading `--`. */\nexport type TokenMap = Record<string, string>\n\n/** Input to {@link defineStylePack}. */\nexport interface StylePackInput {\n /** Pack name, e.g. `'acme'` (used for registration / debugging). */\n name: string\n /** Light-theme tokens (the `:root` block). Names without the `--` prefix. */\n tokens: TokenMap\n /** Optional dark-theme overrides (the `.dark` block). */\n dark?: TokenMap\n}\n\n/** A registered, validated style-pack descriptor. */\nexport interface StylePack {\n readonly name: string\n readonly tokens: TokenMap\n readonly dark: TokenMap\n /**\n * Serialize the pack to a `:root { … }` (+ `.dark { … }`) CSS string — the\n * same shape as the shipped `styles/*.css` bundles.\n */\n toCss(): string\n}\n\n/** Normalize a token name to its `--`-prefixed custom-property form. */\nfunction asCustomProp(name: string): string {\n return name.startsWith('--') ? name : `--${name}`\n}\n\nfunction emitBlock(selector: string, tokens: TokenMap): string {\n const decls = Object.entries(tokens)\n .map(([name, value]) => ` ${asCustomProp(name)}: ${value};`)\n .join('\\n')\n return `${selector} {\\n${decls}\\n}\\n`\n}\n\n/**\n * Define a style pack from a token map.\n *\n * @example\n * const acme = defineStylePack({\n * name: 'acme',\n * tokens: { 'color-primary': '#0a7', 'radius-md': '6px' },\n * dark: { 'color-primary': '#3fc' },\n * })\n * acme.toCss() // => \":root { --color-primary: #0a7; … } .dark { … }\"\n */\nexport function defineStylePack(input: StylePackInput): StylePack {\n if (!input.name) {\n throw new Error('defineStylePack: `name` is required')\n }\n if (!input.tokens || Object.keys(input.tokens).length === 0) {\n throw new Error(`defineStylePack(\"${input.name}\"): tokens must be a non-empty map`)\n }\n\n const tokens = { ...input.tokens }\n const dark = { ...(input.dark ?? {}) }\n\n return {\n name: input.name,\n tokens,\n dark,\n toCss(): string {\n let css = emitBlock(':root', tokens)\n if (Object.keys(dark).length > 0) {\n css += emitBlock('.dark', dark)\n }\n return css\n },\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { compileToAst } from '@aihu/compiler'\n\nexport {\n defineStylePack,\n type StylePack,\n type StylePackInput,\n type TokenMap,\n} from './define-style-pack.ts'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n/**\n * Resolve the path to the `aihu-css-compile` binary.\n * Looks for it relative to the package, then in the workspace target/release.\n * Plan 4 will replace this with a prebuilt binary shipped with the package.\n */\nfunction resolveBinary(): string {\n const ext = process.platform === 'win32' ? '.exe' : ''\n const candidates = [\n // dev: workspace target/release (most common during development)\n resolve(__dirname, '../../../target/release', `aihu-css-compile${ext}`),\n // ci: same with debug\n resolve(__dirname, '../../../target/debug', `aihu-css-compile${ext}`),\n ]\n for (const c of candidates) {\n if (existsSync(c)) return c\n }\n throw new Error(\n `aihu-css-compile binary not found. Run \\`cargo build --release -p aihu-css-core\\` from the repo root first. Checked: ${candidates.join(', ')}`,\n )\n}\n\n/**\n * Compile a list of utility class names to CSS.\n *\n * Plan 1 bootstrap — supports a hardcoded subset; see crates/aihu-css-core/src/tokens.rs.\n * Plan 2 wires the AST scanner so callers pass `.aihu` SFC ASTs instead of raw class lists.\n *\n * @param classes - utility class names like `['bg-primary', 'p-4']`\n * @returns CSS string with one rule per known class\n */\nexport function compile(classes: string[]): string {\n if (classes.length === 0) return ''\n\n const bin = resolveBinary()\n const input = classes.join('\\n')\n const result = execFileSync(bin, [], {\n input,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'inherit'],\n })\n return result\n}\n\n/**\n * Compile a `.aihu` SFC source string to scoped, shadow-DOM-embedded CSS.\n *\n * Pipeline (Plan 2 Task 9): `compileToAst(source)` (from `@aihu/compiler`)\n * → AST JSON → `aihu-css-compile --ast-json` → scoped CSS. The output is the\n * per-SFC stylesheet the compiler folds into the component's shadow `<style>`:\n * `:host`-level theme tokens, variant-resolved utility rules, and the folded\n * authored `@style` block. There is NO global utility stylesheet.\n *\n * @param source - the `.aihu` SFC source text\n * @param id - optional file path/id (used to derive the tag stem + `@route` checks)\n * @returns the scoped CSS string for the SFC\n */\nexport function compileSfc(source: string, id?: string): string {\n const ast = compileToAst(source, id)\n const bin = resolveBinary()\n return execFileSync(bin, ['--ast-json'], {\n input: JSON.stringify(ast),\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'inherit'],\n })\n}\n"],"mappings":";;;;;AAA0J,MAAM,IAAE,QAAQ,aAAW,UAAQ,SAAO,IAAG,IAAE,QAAQ,IAAI,sBAAoBA,QAAEC,QAAEC,cAAE,OAAO,KAAK,IAAI,CAAC,EAAC,sBAAsB,IAAI;AAsCtG,SAAS,EAAE,GAAE,GAAE;CAAC,IAAI,IAAE;EAAC;EAAU;EAAQ,IAAEC,SAAE,GAAE,QAAQ,GAAC;EAAY;EAAa;CAAC,KAAG,EAAE,KAAK,UAAS,EAAE;CAAC,IAAI,IAAEC,aAAE,GAAE,GAAE;EAAC,OAAM;EAAE,UAAS;EAAO,CAAC;CAAC,OAAO,KAAK,MAAM,EAAE;;;;;ACCxV,SAAS,aAAa,MAAsB;CAC1C,OAAO,KAAK,WAAW,KAAK,GAAG,OAAO,KAAK;;AAG7C,SAAS,UAAU,UAAkB,QAA0B;CAI7D,OAAO,GAAG,SAAS,MAHL,OAAO,QAAQ,OAAO,CACjC,KAAK,CAAC,MAAM,WAAW,KAAK,aAAa,KAAK,CAAC,IAAI,MAAM,GAAG,CAC5D,KAAK,KACsB,CAAC;;;;;;;;;;;;;AAcjC,SAAgB,gBAAgB,OAAkC;CAChE,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MAAM,sCAAsC;CAExD,IAAI,CAAC,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,CAAC,WAAW,GACxD,MAAM,IAAI,MAAM,oBAAoB,MAAM,KAAK,oCAAoC;CAGrF,MAAM,SAAS,EAAE,GAAG,MAAM,QAAQ;CAClC,MAAM,OAAO,EAAE,GAAI,MAAM,QAAQ,EAAE,EAAG;CAEtC,OAAO;EACL,MAAM,MAAM;EACZ;EACA;EACA,QAAgB;GACd,IAAI,MAAM,UAAU,SAAS,OAAO;GACpC,IAAI,OAAO,KAAK,KAAK,CAAC,SAAS,GAC7B,OAAO,UAAU,SAAS,KAAK;GAEjC,OAAO;;EAEV;;;;ACtEH,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;;;;;;AAOzD,SAAS,gBAAwB;CAC/B,MAAM,MAAM,QAAQ,aAAa,UAAU,SAAS;CACpD,MAAM,aAAa,CAEjB,QAAQ,WAAW,2BAA2B,mBAAmB,MAAM,EAEvE,QAAQ,WAAW,yBAAyB,mBAAmB,MAAM,CACtE;CACD,KAAK,MAAM,KAAK,YACd,IAAI,WAAW,EAAE,EAAE,OAAO;CAE5B,MAAM,IAAI,MACR,wHAAwH,WAAW,KAAK,KAAK,GAC9I;;;;;;;;;;;AAYH,SAAgB,QAAQ,SAA2B;CACjD,IAAI,QAAQ,WAAW,GAAG,OAAO;CASjC,OALe,aAFH,eAEmB,EAAE,EAAE,EAAE;EACnC,OAFY,QAAQ,KAAK,KAEpB;EACL,UAAU;EACV,OAAO;GAAC;GAAQ;GAAQ;GAAU;EACnC,CACY;;;;;;;;;;;;;;;AAgBf,SAAgB,WAAW,QAAgB,IAAqB;CAC9D,MAAM,MAAMC,EAAa,QAAQ,GAAG;CAEpC,OAAO,aADK,eACW,EAAE,CAAC,aAAa,EAAE;EACvC,OAAO,KAAK,UAAU,IAAI;EAC1B,UAAU;EACV,OAAO;GAAC;GAAQ;GAAQ;GAAU;EACnC,CAAC"}
1
+ {"version":3,"file":"index.js","names":["r","n","i","t","e","compileToAst"],"sources":["../../compiler/dist/index.js","../src/index.ts"],"sourcesContent":["import{execFileSync as e}from\"node:child_process\";import{basename as t,dirname as n,resolve as r}from\"node:path\";import{fileURLToPath as i}from\"node:url\";const a=process.platform===`win32`?`.exe`:``,o=process.env.SCRIBE_COMPILE_BIN??r(n(i(import.meta.url)),`../bin/aihu-compile${a}`);function s(e,t){return e.replace(/(defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\([^]*\\))\\s*\\)/,(e,n)=>`${n}, { shadowMode: '${t}' })`)}function c(e){return/\\b(?:signal|computed|effect|setSignal|onMount|onCleanup)\\s*\\(/.test(e)?`interactive`:`static`}function l(e){let t=/defineElement\\(\\s*['\"]([^'\"]+)['\"]/m.exec(e);return t?t[1]??null:null}function u(e,t){let n=e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_hmrReplace`)||n.push(`_hmrReplace`),`import { ${n.join(`, `)} } from '@aihu/runtime'`}).replace(/\\bdefineComponent\\(/,`defineComponent(__aihu_setup__ = `),r=`\nexport { __aihu_setup__ as default }\n\nif (typeof __DEV__ !== 'undefined' && __DEV__ && import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (!newModule) return\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const newSetup = (newModule as any)['default']\n if (typeof newSetup !== 'function') return\n document.querySelectorAll(${JSON.stringify(t)}).forEach((el) => {\n _hmrReplace(el as HTMLElement, newSetup)\n })\n })\n}\n`;return`let __aihu_setup__: ((ctx: any) => any) | undefined\n`+n+r}function d(e,t){let n=e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_hydrateOnVisible`)||n.push(`_hydrateOnVisible`),`import { ${n.join(`, `)} } from '@aihu/runtime'`}),r=n.replace(/defineElement\\(\\s*('[^']+'|\"[^\"]+\")\\s*,\\s*defineComponent\\(/,(e,t)=>`defineElement(${t}, __aihu_wrap_defer__(defineComponent(`);if(r===n)return e;let i=r.replace(/\\)\\s*\\)\\s*\\nexport\\s/,`)))\nexport `);return i===r&&(i=r.replace(/\\)\\s*\\)\\s*$/,`)))\n`)),i===r?e:`\n// Plan 3.3 (Islands) — defer attribute support. Wraps the constructor\n// returned by defineComponent so instances bearing the \\`defer\\` attribute\n// hydrate lazily via IntersectionObserver. Bare instances retain the\n// eager Plan 3.2 hydration path.\nfunction __aihu_wrap_defer__<T extends typeof HTMLElement>(Ctor: T): T {\n const orig = (Ctor.prototype as unknown as { connectedCallback?: () => void }).connectedCallback\n if (typeof orig !== 'function') return Ctor\n ;(Ctor.prototype as unknown as { connectedCallback: () => void }).connectedCallback = function (this: HTMLElement) {\n if (this.hasAttribute('defer')) {\n _hydrateOnVisible(this, () => orig.call(this))\n } else {\n orig.call(this)\n }\n }\n return Ctor\n}\n`+i}function f(e,t){if(!/defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\(/.test(e))return e;let n=e.replace(/^\\s*import\\s*\\{[^}]*\\}\\s*from\\s*'@aihu\\/runtime'\\s*;?\\s*$/m,``).replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/arbor'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`mount`)||n.push(`mount`),`import { ${n.join(`, `)} } from '@aihu/arbor'`}),r=JSON.stringify(t);return`// SCRIBE_STATIC_ISLAND — zero @aihu/runtime references\\n${n.replace(/defineElement\\(\\s*['\"][^'\"]+['\"]\\s*,\\s*defineComponent\\(/,`customElements.define(${r}, class extends HTMLElement {\\n connectedCallback() {\\n const root = this.attachShadow({ mode: 'open' })\\n const __aihu_setup__ = (`).replace(/\\)\\s*\\)\\s*$/,`)\n mount(__aihu_setup__({ host: root, element: this }), root)\n }\n})\n`)}`}function p(n,r,i){let a=[`--stdin`,`--tag`,t(r,`.aihu`),`--path`,r];return i?.sidecarOut&&a.push(`--sidecar-out`,i.sidecarOut),{code:e(o,a,{input:n,encoding:`utf8`}),map:null}}function m(e){return e.replace(/\\\\/g,`\\\\\\\\`).replace(/`/g,\"\\\\`\").replace(/\\$\\{/g,\"\\\\${\")}function h(e,t){if(!t.trim())return e;let n=m(t),r=/(__style__\\.replaceSync\\(`)[^]*?(`\\);)/;if(r.test(e))return e.replace(r,(e,t,r)=>`${t}${n}${r}`);if(/defineComponent\\(\\s*\\((_ctx|ctx)\\)\\s*=>\\s*\\{/.exec(e)==null)return e;let i=e.split(`\n`),a=-1;for(let e=i.length-1;e>=0;e--){let t=(i[e]??``).trim();if(t.startsWith(`import `)||t.startsWith(`import{`)){a=e;break}}let o=`const __style__ = new CSSStyleSheet();\\n__style__.replaceSync(\\`${n}\\`);`;a===-1?i.unshift(o):i.splice(a+1,0,o);let s=i.join(`\n`);return s=s.replace(/defineComponent\\(\\s*\\((?:_ctx|ctx)\\)\\s*=>\\s*\\{/,`defineComponent((ctx) => {\n (ctx.host as ShadowRoot).adoptedStyleSheets = [__style__];`),s}function g(n,r){let i=[`--stdin`,`--tag`,r?t(r,`.aihu`):`Component`,`--ast-json`];r&&i.push(`--path`,r);let a=e(o,i,{input:n,encoding:`utf8`});return JSON.parse(a)}function _(e){let t;t=e.includes(`from '@aihu/arbor'`)?e.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/arbor'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`mount`)||n.push(`mount`),`import { ${n.join(`, `)} } from '@aihu/arbor'`}):`import { mount } from '@aihu/arbor'\\n${e}`,/import\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/.test(t)?t=t.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/signals'/,(e,t)=>{if(e.startsWith(`import type`))return e;let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`signal`)||n.push(`signal`),`import { ${n.join(`, `)} } from '@aihu/signals'`}):/import.*from\\s*'@aihu\\/signals'/.test(t)?/import\\s+type\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/.test(t)&&!t.match(/import\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals'/)&&(t=t.replace(/(import\\s+type\\s+\\{[^}]*\\}\\s+from\\s+'@aihu\\/signals')/,(e,t)=>`${t}\\nimport { signal } from '@aihu/signals'`)):t=t.replace(/import\\s*\\{[^}]*\\}\\s*from\\s*'@aihu\\/arbor'/,e=>`${e}\\nimport { signal } from '@aihu/signals'`),t=t.replace(/import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/runtime'/,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.includes(`_setMount`)||n.push(`_setMount`),n.includes(`_setSignal`)||n.push(`_setSignal`),`import { ${n.join(`, `)} } from '@aihu/runtime'`});let n=t.split(`\n`),r=-1;for(let e=n.length-1;e>=0;e--){let t=(n[e]??``).trim();if(t.startsWith(`import `)||t.startsWith(`import{`)){r=e;break}}return r!==-1&&(n.splice(r+1,0,`_setMount(mount)`,`_setSignal(signal)`,``),t=n.join(`\n`)),t}let v;async function y(e,t){if(v===null)return``;if(v===void 0)try{v=await import(`@aihu/css-engine`)}catch{return v=null,``}try{return process.env.SCRIBE_COMPILE_BIN??(process.env.SCRIBE_COMPILE_BIN=o),v.compileSfc(e,t)}catch{return``}}function b(e){let t=e?.islands!==!1,n=e?.shadowMode;return{name:`aihu-compiler`,enforce:`pre`,transform(e,r){let i=r.split(`?`)[0];if(i.endsWith(`.aihu`))return(async()=>{let r=p(e,i,{sidecarOut:`${i}.ts`}),a=n==null?r.code:s(r.code,n),o=await y(e,i);o&&(a=h(a,o));let m=l(a),g;t&&m!==null&&c(a)===`static`?g=f(a,m):m===null?(g=a,g=_(g)):(g=u(a,m),g=d(g,m),g=_(g));try{let e=await import(`vite`);return`transformWithEsbuild`in e&&typeof e.transformWithEsbuild==`function`?{code:(await e.transformWithEsbuild(g,`component.ts`,{target:`esnext`,sourcemap:!1})).code,map:null}:{code:g,moduleType:`ts`,map:null}}catch{return{code:g,map:null}}})()}}}export{d as _buildDeferredHydration,f as _buildStaticIsland,c as _classifyIsland,h as _foldCssEngineStyles,_ as _injectAutoWiring,s as _injectShadowMode,b as aihuCompilerPlugin,g as compileToAst,p as transform};\n//# sourceMappingURL=index.js.map","import { execFileSync } from 'node:child_process'\nimport { accessSync, constants, existsSync, statSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { compileToAst } from '@aihu/compiler'\n\nexport {\n defineStylePack,\n type StylePack,\n type StylePackInput,\n type TokenMap,\n} from './define-style-pack.ts'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n// ---------------------------------------------------------------------------\n// Platform support matrix\n// ---------------------------------------------------------------------------\n//\n// Maps process.platform + process.arch to the per-platform npm package that\n// ships the prebuilt `aihu-css-compile` executable, plus the binary's filename\n// inside that package. Mirrors @aihu/server/src/native.ts detectPlatform() and\n// the package directory names under packages/css-engine/npm/<platform>/.\n//\n// Unlike @aihu/server (a napi `.node` addon loaded via require), the css engine\n// invokes `aihu-css-compile` as a CLI SUBPROCESS (execFileSync against the\n// executable on disk). So the platform package exposes a raw executable file,\n// and we resolve its absolute PATH — we never `require()` the binary itself.\n\ninterface PlatformDescriptor {\n readonly platformId: string\n readonly packageName: string\n /** Executable filename inside the platform package. */\n readonly binFile: string\n}\n\nfunction detectPlatform(): PlatformDescriptor | null {\n if (typeof process === 'undefined' || !process.platform || !process.arch) {\n return null\n }\n const key = `${process.platform}-${process.arch}`\n switch (key) {\n case 'darwin-arm64':\n return {\n platformId: 'darwin-arm64',\n packageName: '@aihu/css-engine-darwin-arm64',\n binFile: 'aihu-css-compile',\n }\n case 'darwin-x64':\n return {\n platformId: 'darwin-x64',\n packageName: '@aihu/css-engine-darwin-x64',\n binFile: 'aihu-css-compile',\n }\n case 'linux-x64':\n // We only ship glibc; musl users fall through to the dev/source path.\n return {\n platformId: 'linux-x64-gnu',\n packageName: '@aihu/css-engine-linux-x64-gnu',\n binFile: 'aihu-css-compile',\n }\n case 'win32-x64':\n return {\n platformId: 'win32-x64-msvc',\n packageName: '@aihu/css-engine-win32-x64-msvc',\n binFile: 'aihu-css-compile.exe',\n }\n default:\n return null\n }\n}\n\nlet _binPath: string | null = null\n\n/**\n * Whether `candidate` is a usable `aihu-css-compile` executable — NOT merely a\n * present file.\n *\n * The per-platform packages (`@aihu/css-engine-<platform>`) carry a placeholder\n * `aihu-css-compile` in source; the real prebuilt binary is only injected by\n * the release CI. Once those packages become resolvable in the workspace (e.g.\n * after a `bun.lock` refresh that pins them as optionalDependencies), a bare\n * `existsSync` would happily return the non-executable placeholder, which then\n * blows up with EACCES inside `spawnSync`/`execFileSync`. So we must verify the\n * candidate is actually runnable before accepting it.\n *\n * POSIX: require the execute bit (X_OK). A zero-byte/text placeholder without\n * +x fails here and we fall through to the dev `target/` fallback.\n *\n * Windows: there is no execute bit — `accessSync(_, X_OK)` is effectively\n * always true — so we additionally require a non-empty regular file, which\n * still rejects a zero-byte placeholder.\n */\nexport function isUsableExecutable(candidate: string): boolean {\n try {\n const st = statSync(candidate)\n if (!st.isFile() || st.size === 0) return false\n accessSync(candidate, constants.X_OK)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Resolve the absolute path to the `aihu-css-compile` executable.\n *\n * Resolution order:\n * 1. The per-platform optionalDependency package\n * (`@aihu/css-engine-<platform>`) shipped to npm consumers — resolved via\n * `createRequire(...).resolve('<pkg>/package.json')` so it works in both\n * ESM and CJS and respects the consumer's node_modules layout.\n * 2. Dev fallback: the monorepo workspace `target/release|debug/` — only\n * present in a dev clone with a Rust toolchain (`cargo build --release -p\n * aihu-css-core`). Kept so in-repo builds + tests work without publishing.\n *\n * If the current platform is SUPPORTED but neither path yields a binary, throws\n * a structured error pointing at the missing optionalDependency (mirrors\n * @aihu/server's failure-loud contract). If the platform is UNSUPPORTED, the\n * error lists the dev fallback so source builds still have a clear remedy.\n */\nfunction resolveBinary(): string {\n if (_binPath !== null) return _binPath\n\n const descriptor = detectPlatform()\n\n // 1. Per-platform optionalDependency package (the published-consumer path).\n //\n // Accept the candidate ONLY if it is a usable executable. A present-but-\n // non-executable placeholder (the in-source stub that becomes resolvable once\n // the per-platform packages are pinned in the lockfile) must NOT be returned —\n // doing so spawns a non-executable file and fails with EACCES. In that case we\n // deliberately fall THROUGH to the dev `target/` fallback below.\n if (descriptor) {\n const requireFn = createRequire(import.meta.url)\n try {\n const pkgJson = requireFn.resolve(`${descriptor.packageName}/package.json`)\n const candidate = join(dirname(pkgJson), descriptor.binFile)\n if (isUsableExecutable(candidate)) {\n _binPath = candidate\n return _binPath\n }\n } catch {\n // Package not installed (optionalDependency skipped for this platform, or\n // a partial install). Fall through to the dev/source path, then error.\n }\n }\n\n // 2. Dev fallback: monorepo workspace target/. Only exists in a dev clone.\n const ext = process.platform === 'win32' ? '.exe' : ''\n const devCandidates = [\n resolve(__dirname, '../../../target/release', `aihu-css-compile${ext}`),\n resolve(__dirname, '../../../target/debug', `aihu-css-compile${ext}`),\n ]\n for (const c of devCandidates) {\n if (existsSync(c)) {\n _binPath = c\n return _binPath\n }\n }\n\n throw buildMissingBinaryError(descriptor, devCandidates)\n}\n\nfunction buildMissingBinaryError(\n descriptor: PlatformDescriptor | null,\n devCandidates: string[],\n): Error {\n if (descriptor === null) {\n return new Error(\n `[@aihu/css-engine] No prebuilt aihu-css-compile binary for this platform.\\n\\n` +\n ` Platform: ${typeof process !== 'undefined' ? `${process.platform}-${process.arch}` : 'unknown'}\\n\\n` +\n ` @aihu/css-engine ships prebuilt binaries for darwin-arm64, darwin-x64,\\n` +\n ` linux-x64-gnu (glibc) and win32-x64-msvc. Your platform is not in that set.\\n\\n` +\n ` To build from source you need a Rust toolchain, then run from the repo root:\\n` +\n ` cargo build --release -p aihu-css-core\\n\\n` +\n ` Checked dev fallback paths: ${devCandidates.join(', ')}`,\n )\n }\n return new Error(\n `[@aihu/css-engine] Native CSS compiler binary not found for this platform.\\n\\n` +\n ` Platform: ${descriptor.platformId}\\n` +\n ` Expected package: ${descriptor.packageName}\\n` +\n ` Expected file: ${descriptor.packageName}/${descriptor.binFile}\\n\\n` +\n ` This binary is distributed as an optionalDependency of @aihu/css-engine.\\n` +\n ` Your package manager may have skipped it (optionalDependencies are\\n` +\n ` silently dropped on install failure).\\n\\n` +\n ` To reinstall:\\n` +\n ` npm install @aihu/css-engine\\n` +\n ` # or: pnpm install or: bun install\\n\\n` +\n ` If you are working in the aihu monorepo, build from source instead:\\n` +\n ` cargo build --release -p aihu-css-core\\n` +\n ` Checked dev fallback paths: ${devCandidates.join(', ')}`,\n )\n}\n\n/**\n * Compile a list of utility class names to CSS.\n *\n * Plan 1 bootstrap — supports a hardcoded subset; see crates/aihu-css-core/src/tokens.rs.\n * Plan 2 wires the AST scanner so callers pass `.aihu` SFC ASTs instead of raw class lists.\n *\n * @param classes - utility class names like `['bg-primary', 'p-4']`\n * @returns CSS string with one rule per known class\n */\nexport function compile(classes: string[]): string {\n if (classes.length === 0) return ''\n\n const bin = resolveBinary()\n const input = classes.join('\\n')\n const result = execFileSync(bin, [], {\n input,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'inherit'],\n })\n return result\n}\n\n/**\n * Compile a `.aihu` SFC source string to scoped, shadow-DOM-embedded CSS.\n *\n * Pipeline (Plan 2 Task 9): `compileToAst(source)` (from `@aihu/compiler`)\n * → AST JSON → `aihu-css-compile --ast-json` → scoped CSS. The output is the\n * per-SFC stylesheet the compiler folds into the component's shadow `<style>`:\n * `:host`-level theme tokens, variant-resolved utility rules, and the folded\n * authored `@style` block. There is NO global utility stylesheet.\n *\n * @param source - the `.aihu` SFC source text\n * @param id - optional file path/id (used to derive the tag stem + `@route` checks)\n * @returns the scoped CSS string for the SFC\n */\nexport function compileSfc(source: string, id?: string): string {\n const ast = compileToAst(source, id)\n const bin = resolveBinary()\n return execFileSync(bin, ['--ast-json'], {\n input: JSON.stringify(ast),\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'inherit'],\n })\n}\n"],"mappings":";;;;;;;AAA0J,MAAM,IAAE,QAAQ,aAAW,UAAQ,SAAO,IAAG,IAAE,QAAQ,IAAI,sBAAoBA,QAAEC,QAAEC,cAAE,OAAO,KAAK,IAAI,CAAC,EAAC,sBAAsB,IAAI;AAyC1N,SAAS,EAAE,GAAE,GAAE;CAAC,IAAI,IAAE;EAAC;EAAU;EAAQ,IAAEC,SAAE,GAAE,QAAQ,GAAC;EAAY;EAAa;CAAC,KAAG,EAAE,KAAK,UAAS,EAAE;CAAC,IAAI,IAAEC,aAAE,GAAE,GAAE;EAAC,OAAM;EAAE,UAAS;EAAO,CAAC;CAAC,OAAO,KAAK,MAAM,EAAE;;;;AC3BpO,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAuBzD,SAAS,iBAA4C;CACnD,IAAI,OAAO,YAAY,eAAe,CAAC,QAAQ,YAAY,CAAC,QAAQ,MAClE,OAAO;CAGT,QAAQ,GADO,QAAQ,SAAS,GAAG,QAAQ,QAC3C;EACE,KAAK,gBACH,OAAO;GACL,YAAY;GACZ,aAAa;GACb,SAAS;GACV;EACH,KAAK,cACH,OAAO;GACL,YAAY;GACZ,aAAa;GACb,SAAS;GACV;EACH,KAAK,aAEH,OAAO;GACL,YAAY;GACZ,aAAa;GACb,SAAS;GACV;EACH,KAAK,aACH,OAAO;GACL,YAAY;GACZ,aAAa;GACb,SAAS;GACV;EACH,SACE,OAAO;;;AAIb,IAAI,WAA0B;;;;;;;;;;;;;;;;;;;;AAqB9B,SAAgB,mBAAmB,WAA4B;CAC7D,IAAI;EACF,MAAM,KAAK,SAAS,UAAU;EAC9B,IAAI,CAAC,GAAG,QAAQ,IAAI,GAAG,SAAS,GAAG,OAAO;EAC1C,WAAW,WAAW,UAAU,KAAK;EACrC,OAAO;SACD;EACN,OAAO;;;;;;;;;;;;;;;;;;;;AAqBX,SAAS,gBAAwB;CAC/B,IAAI,aAAa,MAAM,OAAO;CAE9B,MAAM,aAAa,gBAAgB;CASnC,IAAI,YAAY;EACd,MAAM,YAAY,cAAc,OAAO,KAAK,IAAI;EAChD,IAAI;GAEF,MAAM,YAAY,KAAK,QADP,UAAU,QAAQ,GAAG,WAAW,YAAY,eACtB,CAAC,EAAE,WAAW,QAAQ;GAC5D,IAAI,mBAAmB,UAAU,EAAE;IACjC,WAAW;IACX,OAAO;;UAEH;;CAOV,MAAM,MAAM,QAAQ,aAAa,UAAU,SAAS;CACpD,MAAM,gBAAgB,CACpB,QAAQ,WAAW,2BAA2B,mBAAmB,MAAM,EACvE,QAAQ,WAAW,yBAAyB,mBAAmB,MAAM,CACtE;CACD,KAAK,MAAM,KAAK,eACd,IAAI,WAAW,EAAE,EAAE;EACjB,WAAW;EACX,OAAO;;CAIX,MAAM,wBAAwB,YAAY,cAAc;;AAG1D,SAAS,wBACP,YACA,eACO;CACP,IAAI,eAAe,MACjB,uBAAO,IAAI,MACT,mGACwB,OAAO,YAAY,cAAc,GAAG,QAAQ,SAAS,GAAG,QAAQ,SAAS,UAAU,6TAKxE,cAAc,KAAK,KAAK,GAC5D;CAEH,uBAAO,IAAI,MACT,qGACyB,WAAW,WAAW,wBACtB,WAAW,YAAY,wBACvB,WAAW,YAAY,GAAG,WAAW,QAAQ,mbASnC,cAAc,KAAK,KAAK,GAC5D;;;;;;;;;;;AAYH,SAAgB,QAAQ,SAA2B;CACjD,IAAI,QAAQ,WAAW,GAAG,OAAO;CASjC,OALe,aAFH,eAEmB,EAAE,EAAE,EAAE;EACnC,OAFY,QAAQ,KAAK,KAEpB;EACL,UAAU;EACV,OAAO;GAAC;GAAQ;GAAQ;GAAU;EACnC,CACY;;;;;;;;;;;;;;;AAgBf,SAAgB,WAAW,QAAgB,IAAqB;CAC9D,MAAM,MAAMC,EAAa,QAAQ,GAAG;CAEpC,OAAO,aADK,eACW,EAAE,CAAC,aAAa,EAAE;EACvC,OAAO,KAAK,UAAU,IAAI;EAC1B,UAAU;EACV,OAAO;GAAC;GAAQ;GAAQ;GAAU;EACnC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { t as StylePack } from "./define-style-pack-DjzHvtf0.js";
2
+
3
+ //#region src/packs.d.ts
4
+ /**
5
+ * `aihu-default` — the aihu brand palette (warm paper + ink, accent `#c8543a`),
6
+ * derived from `aihu-logo.html` / `aihu-wordmark.svg`. Light values in `:root`,
7
+ * dark overrides in `.dark`.
8
+ */
9
+ declare const aihuDefault: StylePack;
10
+ /**
11
+ * `aihu-graphite` — a neutral monochrome ramp expressed in `oklch()`
12
+ * (chroma ≈ 0). Mirrors `aihu-default`'s token NAMES exactly so the two packs
13
+ * are interchangeable; only the VALUES differ (desaturated monochrome scale).
14
+ */
15
+ declare const aihuGraphite: StylePack;
16
+ /** All built-in packs, keyed by name — handy for registry/iteration. */
17
+ declare const builtinPacks: Record<string, StylePack>;
18
+ //#endregion
19
+ export { aihuDefault, aihuGraphite, builtinPacks };
20
+ //# sourceMappingURL=packs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packs.d.ts","names":[],"sources":["../src/packs.ts"],"mappings":";;;;;;;;cA8Ba,WAAA,EAAa,SAAA;;;;;;cA+Db,YAAA,EAAc,SAAA;;cA2Dd,YAAA,EAAc,MAAA,SAAe,SAAA"}
package/dist/packs.js ADDED
@@ -0,0 +1,149 @@
1
+ import { t as defineStylePack } from "./define-style-pack--6pevgrd.js";
2
+ //#region src/packs.ts
3
+ /**
4
+ * `@aihu/css-engine/packs` — the two built-in style packs as `StylePack`
5
+ * objects (Plan 3 Task 10 follow-up).
6
+ *
7
+ * These are the **source of truth** for the shipped `styles/aihu-default.css`
8
+ * and `styles/aihu-graphite.css` bundles. The `.css` files are GENERATED from
9
+ * these objects (`bun run gen:style-packs` → `scripts/gen-style-packs.ts`),
10
+ * so the JS pack objects and the CSS files can never drift: each `.css` file
11
+ * is exactly `pack.toCss()`. The `style-pack.test.ts` parity test asserts this
12
+ * byte-for-byte.
13
+ *
14
+ * Both packs are expressed through the public {@link defineStylePack} API — the
15
+ * same one external orgs use — proving the built-ins carry no privileged shape.
16
+ * Token NAMES are the interchange contract: any recipe styled against these
17
+ * names works under either pack with no markup change. Only the VALUES differ.
18
+ *
19
+ * Two access paths ship for each pack:
20
+ * 1. `import { aihuDefault } from '@aihu/css-engine/packs'` → the JS object
21
+ * (`.tokens`, `.dark`, `.toCss()`).
22
+ * 2. `import '@aihu/css-engine/styles/aihu-default.css'` → the generated CSS
23
+ * bundle (Vite/bundlers inline it).
24
+ */
25
+ /**
26
+ * `aihu-default` — the aihu brand palette (warm paper + ink, accent `#c8543a`),
27
+ * derived from `aihu-logo.html` / `aihu-wordmark.svg`. Light values in `:root`,
28
+ * dark overrides in `.dark`.
29
+ */
30
+ const aihuDefault = defineStylePack({
31
+ name: "aihu-default",
32
+ tokens: {
33
+ "color-primary": "#1a1d24",
34
+ "color-primary-foreground": "#faf8f4",
35
+ "color-secondary": "#5a5a55",
36
+ "color-secondary-foreground": "#faf8f4",
37
+ "color-accent": "#c8543a",
38
+ "color-accent-foreground": "#faf8f4",
39
+ "color-surface": "#faf8f4",
40
+ "color-surface-foreground": "#1a1d24",
41
+ "color-background": "#faf8f4",
42
+ "color-foreground": "#1a1d24",
43
+ "color-muted": "#5a5a55",
44
+ "color-muted-foreground": "#8a8880",
45
+ "color-border": "#ddd9d2",
46
+ "color-ring": "#c8543a",
47
+ "color-destructive": "#a8432b",
48
+ "color-destructive-foreground": "#faf8f4",
49
+ "radius-sm": "4px",
50
+ "radius-md": "8px",
51
+ "radius-lg": "12px",
52
+ "radius-pill": "999px",
53
+ "space-1": "0.25rem",
54
+ "space-2": "0.5rem",
55
+ "space-3": "0.75rem",
56
+ "space-4": "1rem",
57
+ "space-6": "1.5rem",
58
+ "space-8": "2rem",
59
+ "space-12": "3rem",
60
+ "space-16": "4rem",
61
+ "font-sans": "\"Inter\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif",
62
+ "font-mono": "\"JetBrains Mono\", ui-monospace, \"Fira Code\", \"Cascadia Code\", monospace"
63
+ },
64
+ dark: {
65
+ "color-primary": "#ede8e0",
66
+ "color-primary-foreground": "#1a1d24",
67
+ "color-secondary": "#9e9890",
68
+ "color-secondary-foreground": "#1a1d24",
69
+ "color-accent": "#e8705a",
70
+ "color-accent-foreground": "#1a1d24",
71
+ "color-surface": "#1a1d24",
72
+ "color-surface-foreground": "#ede8e0",
73
+ "color-background": "#13151b",
74
+ "color-foreground": "#ede8e0",
75
+ "color-muted": "#9e9890",
76
+ "color-muted-foreground": "#6e6860",
77
+ "color-border": "#2e3240",
78
+ "color-ring": "#e8705a",
79
+ "color-destructive": "#f08070",
80
+ "color-destructive-foreground": "#1a1d24"
81
+ }
82
+ });
83
+ /**
84
+ * `aihu-graphite` — a neutral monochrome ramp expressed in `oklch()`
85
+ * (chroma ≈ 0). Mirrors `aihu-default`'s token NAMES exactly so the two packs
86
+ * are interchangeable; only the VALUES differ (desaturated monochrome scale).
87
+ */
88
+ const aihuGraphite = defineStylePack({
89
+ name: "aihu-graphite",
90
+ tokens: {
91
+ "color-primary": "oklch(0.22 0 0)",
92
+ "color-primary-foreground": "oklch(0.98 0 0)",
93
+ "color-secondary": "oklch(0.45 0 0)",
94
+ "color-secondary-foreground": "oklch(0.98 0 0)",
95
+ "color-accent": "oklch(0.35 0 0)",
96
+ "color-accent-foreground": "oklch(0.98 0 0)",
97
+ "color-surface": "oklch(0.99 0 0)",
98
+ "color-surface-foreground": "oklch(0.22 0 0)",
99
+ "color-background": "oklch(0.99 0 0)",
100
+ "color-foreground": "oklch(0.22 0 0)",
101
+ "color-muted": "oklch(0.55 0 0)",
102
+ "color-muted-foreground": "oklch(0.65 0 0)",
103
+ "color-border": "oklch(0.88 0 0)",
104
+ "color-ring": "oklch(0.35 0 0)",
105
+ "color-destructive": "oklch(0.4 0 0)",
106
+ "color-destructive-foreground": "oklch(0.98 0 0)",
107
+ "radius-sm": "4px",
108
+ "radius-md": "8px",
109
+ "radius-lg": "12px",
110
+ "radius-pill": "999px",
111
+ "space-1": "0.25rem",
112
+ "space-2": "0.5rem",
113
+ "space-3": "0.75rem",
114
+ "space-4": "1rem",
115
+ "space-6": "1.5rem",
116
+ "space-8": "2rem",
117
+ "space-12": "3rem",
118
+ "space-16": "4rem",
119
+ "font-sans": "\"Inter\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif",
120
+ "font-mono": "\"JetBrains Mono\", ui-monospace, \"Fira Code\", \"Cascadia Code\", monospace"
121
+ },
122
+ dark: {
123
+ "color-primary": "oklch(0.92 0 0)",
124
+ "color-primary-foreground": "oklch(0.18 0 0)",
125
+ "color-secondary": "oklch(0.68 0 0)",
126
+ "color-secondary-foreground": "oklch(0.18 0 0)",
127
+ "color-accent": "oklch(0.78 0 0)",
128
+ "color-accent-foreground": "oklch(0.18 0 0)",
129
+ "color-surface": "oklch(0.22 0 0)",
130
+ "color-surface-foreground": "oklch(0.92 0 0)",
131
+ "color-background": "oklch(0.16 0 0)",
132
+ "color-foreground": "oklch(0.92 0 0)",
133
+ "color-muted": "oklch(0.62 0 0)",
134
+ "color-muted-foreground": "oklch(0.5 0 0)",
135
+ "color-border": "oklch(0.32 0 0)",
136
+ "color-ring": "oklch(0.78 0 0)",
137
+ "color-destructive": "oklch(0.7 0 0)",
138
+ "color-destructive-foreground": "oklch(0.18 0 0)"
139
+ }
140
+ });
141
+ /** All built-in packs, keyed by name — handy for registry/iteration. */
142
+ const builtinPacks = {
143
+ [aihuDefault.name]: aihuDefault,
144
+ [aihuGraphite.name]: aihuGraphite
145
+ };
146
+ //#endregion
147
+ export { aihuDefault, aihuGraphite, builtinPacks };
148
+
149
+ //# sourceMappingURL=packs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packs.js","names":[],"sources":["../src/packs.ts"],"sourcesContent":["/**\n * `@aihu/css-engine/packs` — the two built-in style packs as `StylePack`\n * objects (Plan 3 Task 10 follow-up).\n *\n * These are the **source of truth** for the shipped `styles/aihu-default.css`\n * and `styles/aihu-graphite.css` bundles. The `.css` files are GENERATED from\n * these objects (`bun run gen:style-packs` → `scripts/gen-style-packs.ts`),\n * so the JS pack objects and the CSS files can never drift: each `.css` file\n * is exactly `pack.toCss()`. The `style-pack.test.ts` parity test asserts this\n * byte-for-byte.\n *\n * Both packs are expressed through the public {@link defineStylePack} API — the\n * same one external orgs use — proving the built-ins carry no privileged shape.\n * Token NAMES are the interchange contract: any recipe styled against these\n * names works under either pack with no markup change. Only the VALUES differ.\n *\n * Two access paths ship for each pack:\n * 1. `import { aihuDefault } from '@aihu/css-engine/packs'` → the JS object\n * (`.tokens`, `.dark`, `.toCss()`).\n * 2. `import '@aihu/css-engine/styles/aihu-default.css'` → the generated CSS\n * bundle (Vite/bundlers inline it).\n */\n\nimport { defineStylePack, type StylePack } from './define-style-pack.ts'\n\n/**\n * `aihu-default` — the aihu brand palette (warm paper + ink, accent `#c8543a`),\n * derived from `aihu-logo.html` / `aihu-wordmark.svg`. Light values in `:root`,\n * dark overrides in `.dark`.\n */\nexport const aihuDefault: StylePack = defineStylePack({\n name: 'aihu-default',\n tokens: {\n // ── Color tokens (the utility-table contract: bg-primary → var(--color-primary)) ──\n 'color-primary': '#1a1d24',\n 'color-primary-foreground': '#faf8f4',\n 'color-secondary': '#5a5a55',\n 'color-secondary-foreground': '#faf8f4',\n 'color-accent': '#c8543a',\n 'color-accent-foreground': '#faf8f4',\n 'color-surface': '#faf8f4',\n 'color-surface-foreground': '#1a1d24',\n 'color-background': '#faf8f4',\n 'color-foreground': '#1a1d24',\n 'color-muted': '#5a5a55',\n 'color-muted-foreground': '#8a8880',\n 'color-border': '#ddd9d2',\n 'color-ring': '#c8543a',\n 'color-destructive': '#a8432b',\n 'color-destructive-foreground': '#faf8f4',\n // ── Radius scale ──\n 'radius-sm': '4px',\n 'radius-md': '8px',\n 'radius-lg': '12px',\n 'radius-pill': '999px',\n // ── Spacing scale ──\n 'space-1': '0.25rem',\n 'space-2': '0.5rem',\n 'space-3': '0.75rem',\n 'space-4': '1rem',\n 'space-6': '1.5rem',\n 'space-8': '2rem',\n 'space-12': '3rem',\n 'space-16': '4rem',\n // ── Typography ──\n 'font-sans': '\"Inter\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n 'font-mono': '\"JetBrains Mono\", ui-monospace, \"Fira Code\", \"Cascadia Code\", monospace',\n },\n dark: {\n 'color-primary': '#ede8e0',\n 'color-primary-foreground': '#1a1d24',\n 'color-secondary': '#9e9890',\n 'color-secondary-foreground': '#1a1d24',\n 'color-accent': '#e8705a',\n 'color-accent-foreground': '#1a1d24',\n 'color-surface': '#1a1d24',\n 'color-surface-foreground': '#ede8e0',\n 'color-background': '#13151b',\n 'color-foreground': '#ede8e0',\n 'color-muted': '#9e9890',\n 'color-muted-foreground': '#6e6860',\n 'color-border': '#2e3240',\n 'color-ring': '#e8705a',\n 'color-destructive': '#f08070',\n 'color-destructive-foreground': '#1a1d24',\n },\n})\n\n/**\n * `aihu-graphite` — a neutral monochrome ramp expressed in `oklch()`\n * (chroma ≈ 0). Mirrors `aihu-default`'s token NAMES exactly so the two packs\n * are interchangeable; only the VALUES differ (desaturated monochrome scale).\n */\nexport const aihuGraphite: StylePack = defineStylePack({\n name: 'aihu-graphite',\n tokens: {\n // ── Color tokens — monochrome oklch ramp (light) ──\n 'color-primary': 'oklch(0.22 0 0)',\n 'color-primary-foreground': 'oklch(0.98 0 0)',\n 'color-secondary': 'oklch(0.45 0 0)',\n 'color-secondary-foreground': 'oklch(0.98 0 0)',\n 'color-accent': 'oklch(0.35 0 0)',\n 'color-accent-foreground': 'oklch(0.98 0 0)',\n 'color-surface': 'oklch(0.99 0 0)',\n 'color-surface-foreground': 'oklch(0.22 0 0)',\n 'color-background': 'oklch(0.99 0 0)',\n 'color-foreground': 'oklch(0.22 0 0)',\n 'color-muted': 'oklch(0.55 0 0)',\n 'color-muted-foreground': 'oklch(0.65 0 0)',\n 'color-border': 'oklch(0.88 0 0)',\n 'color-ring': 'oklch(0.35 0 0)',\n 'color-destructive': 'oklch(0.4 0 0)',\n 'color-destructive-foreground': 'oklch(0.98 0 0)',\n // ── Radius scale (shared contract) ──\n 'radius-sm': '4px',\n 'radius-md': '8px',\n 'radius-lg': '12px',\n 'radius-pill': '999px',\n // ── Spacing scale (shared contract) ──\n 'space-1': '0.25rem',\n 'space-2': '0.5rem',\n 'space-3': '0.75rem',\n 'space-4': '1rem',\n 'space-6': '1.5rem',\n 'space-8': '2rem',\n 'space-12': '3rem',\n 'space-16': '4rem',\n // ── Typography (shared contract) ──\n 'font-sans': '\"Inter\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n 'font-mono': '\"JetBrains Mono\", ui-monospace, \"Fira Code\", \"Cascadia Code\", monospace',\n },\n dark: {\n 'color-primary': 'oklch(0.92 0 0)',\n 'color-primary-foreground': 'oklch(0.18 0 0)',\n 'color-secondary': 'oklch(0.68 0 0)',\n 'color-secondary-foreground': 'oklch(0.18 0 0)',\n 'color-accent': 'oklch(0.78 0 0)',\n 'color-accent-foreground': 'oklch(0.18 0 0)',\n 'color-surface': 'oklch(0.22 0 0)',\n 'color-surface-foreground': 'oklch(0.92 0 0)',\n 'color-background': 'oklch(0.16 0 0)',\n 'color-foreground': 'oklch(0.92 0 0)',\n 'color-muted': 'oklch(0.62 0 0)',\n 'color-muted-foreground': 'oklch(0.5 0 0)',\n 'color-border': 'oklch(0.32 0 0)',\n 'color-ring': 'oklch(0.78 0 0)',\n 'color-destructive': 'oklch(0.7 0 0)',\n 'color-destructive-foreground': 'oklch(0.18 0 0)',\n },\n})\n\n/** All built-in packs, keyed by name — handy for registry/iteration. */\nexport const builtinPacks: Record<string, StylePack> = {\n [aihuDefault.name]: aihuDefault,\n [aihuGraphite.name]: aihuGraphite,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,cAAyB,gBAAgB;CACpD,MAAM;CACN,QAAQ;EAEN,iBAAiB;EACjB,4BAA4B;EAC5B,mBAAmB;EACnB,8BAA8B;EAC9B,gBAAgB;EAChB,2BAA2B;EAC3B,iBAAiB;EACjB,4BAA4B;EAC5B,oBAAoB;EACpB,oBAAoB;EACpB,eAAe;EACf,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc;EACd,qBAAqB;EACrB,gCAAgC;EAEhC,aAAa;EACb,aAAa;EACb,aAAa;EACb,eAAe;EAEf,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,YAAY;EACZ,YAAY;EAEZ,aAAa;EACb,aAAa;EACd;CACD,MAAM;EACJ,iBAAiB;EACjB,4BAA4B;EAC5B,mBAAmB;EACnB,8BAA8B;EAC9B,gBAAgB;EAChB,2BAA2B;EAC3B,iBAAiB;EACjB,4BAA4B;EAC5B,oBAAoB;EACpB,oBAAoB;EACpB,eAAe;EACf,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc;EACd,qBAAqB;EACrB,gCAAgC;EACjC;CACF,CAAC;;;;;;AAOF,MAAa,eAA0B,gBAAgB;CACrD,MAAM;CACN,QAAQ;EAEN,iBAAiB;EACjB,4BAA4B;EAC5B,mBAAmB;EACnB,8BAA8B;EAC9B,gBAAgB;EAChB,2BAA2B;EAC3B,iBAAiB;EACjB,4BAA4B;EAC5B,oBAAoB;EACpB,oBAAoB;EACpB,eAAe;EACf,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc;EACd,qBAAqB;EACrB,gCAAgC;EAEhC,aAAa;EACb,aAAa;EACb,aAAa;EACb,eAAe;EAEf,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,YAAY;EACZ,YAAY;EAEZ,aAAa;EACb,aAAa;EACd;CACD,MAAM;EACJ,iBAAiB;EACjB,4BAA4B;EAC5B,mBAAmB;EACnB,8BAA8B;EAC9B,gBAAgB;EAChB,2BAA2B;EAC3B,iBAAiB;EACjB,4BAA4B;EAC5B,oBAAoB;EACpB,oBAAoB;EACpB,eAAe;EACf,0BAA0B;EAC1B,gBAAgB;EAChB,cAAc;EACd,qBAAqB;EACrB,gCAAgC;EACjC;CACF,CAAC;;AAGF,MAAa,eAA0C;EACpD,YAAY,OAAO;EACnB,aAAa,OAAO;CACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aihu/css-engine",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -11,6 +11,14 @@
11
11
  "types": "./dist/index.d.ts",
12
12
  "import": "./dist/index.js"
13
13
  },
14
+ "./packs": {
15
+ "types": "./dist/packs.d.ts",
16
+ "import": "./dist/packs.js",
17
+ "default": "./dist/packs.js"
18
+ },
19
+ "./styles/aihu-default.css": "./styles/aihu-default.css",
20
+ "./styles/aihu-graphite.css": "./styles/aihu-graphite.css",
21
+ "./styles/*": "./styles/*",
14
22
  "./runtime/cn": {
15
23
  "types": "./dist/runtime/cn.d.ts",
16
24
  "import": "./dist/runtime/cn.js"
@@ -29,16 +37,23 @@
29
37
  ],
30
38
  "sideEffects": false,
31
39
  "dependencies": {
32
- "@aihu/compiler": "0.4.0"
40
+ "@aihu/compiler": "0.5.0"
41
+ },
42
+ "optionalDependencies": {
43
+ "@aihu/css-engine-darwin-arm64": "0.1.2",
44
+ "@aihu/css-engine-darwin-x64": "0.1.2",
45
+ "@aihu/css-engine-linux-x64-gnu": "0.1.2",
46
+ "@aihu/css-engine-win32-x64-msvc": "0.1.2"
33
47
  },
34
48
  "scripts": {
35
- "build": "rolldown -c",
49
+ "build": "bun run gen:style-packs && rolldown -c",
36
50
  "build:rust": "cargo build --release -p aihu-css-core",
37
51
  "gen:cn-map": "bun scripts/gen-cn-conflict-map.ts",
52
+ "gen:style-packs": "bun scripts/gen-style-packs.ts",
38
53
  "test": "vitest run",
39
54
  "test:rust": "cargo test -p aihu-css-core",
40
55
  "typecheck": "tsc --noEmit",
41
- "prepublishOnly": "bun run build:rust && bun run gen:cn-map && bun run build"
56
+ "prepublishOnly": "bun run build:rust && bun run gen:cn-map && bun run gen:style-packs && bun run build"
42
57
  },
43
58
  "description": "aihu CSS engine — Tailwind v4 hard fork with WC-native scoped output.",
44
59
  "repository": {
@@ -1,19 +1,4 @@
1
- /* ═══════════════════════════════════════════════════════════════════
2
- aihu-default — style pack (brand token CSS bundle)
3
- ───────────────────────────────────────────────────────────────────
4
- The consumer-shippable CSS form of the aihu brand defaults that the
5
- engine's theme registry (crates/aihu-css-core/src/theme.rs) bakes in.
6
- Token NAMES here are the contract: any recipe styled against these
7
- names works under any interchangeable style pack (e.g. aihu-graphite)
8
- with no markup change.
9
-
10
- Extracted from apps/docs/style.css (the canonical brand palette,
11
- derived from aihu-logo.html / aihu-wordmark.svg). Light values live in
12
- :root; dark overrides in .dark.
13
- ═══════════════════════════════════════════════════════════════════ */
14
-
15
1
  :root {
16
- /* ── Color tokens (the utility-table contract: bg-primary → var(--color-primary)) ── */
17
2
  --color-primary: #1a1d24;
18
3
  --color-primary-foreground: #faf8f4;
19
4
  --color-secondary: #5a5a55;
@@ -30,14 +15,10 @@
30
15
  --color-ring: #c8543a;
31
16
  --color-destructive: #a8432b;
32
17
  --color-destructive-foreground: #faf8f4;
33
-
34
- /* ── Radius scale ── */
35
18
  --radius-sm: 4px;
36
19
  --radius-md: 8px;
37
20
  --radius-lg: 12px;
38
21
  --radius-pill: 999px;
39
-
40
- /* ── Spacing scale ── */
41
22
  --space-1: 0.25rem;
42
23
  --space-2: 0.5rem;
43
24
  --space-3: 0.75rem;
@@ -46,13 +27,9 @@
46
27
  --space-8: 2rem;
47
28
  --space-12: 3rem;
48
29
  --space-16: 4rem;
49
-
50
- /* ── Typography ── */
51
30
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
52
31
  --font-mono: "JetBrains Mono", ui-monospace, "Fira Code", "Cascadia Code", monospace;
53
32
  }
54
-
55
- /* ── Dark theme — same token names, dark values (consumer toggles .dark) ── */
56
33
  .dark {
57
34
  --color-primary: #ede8e0;
58
35
  --color-primary-foreground: #1a1d24;
@@ -1,17 +1,4 @@
1
- /* ═══════════════════════════════════════════════════════════════════
2
- aihu-graphite — style pack (monochrome variant)
3
- ───────────────────────────────────────────────────────────────────
4
- A neutral graphite ramp expressed in oklch(). Mirrors aihu-default.css's
5
- token NAMES exactly so the two packs are interchangeable: any recipe
6
- styled against `--color-*` / `--radius-*` / `--space-*` works under
7
- either pack with no markup change. Only the VALUES differ — graphite is
8
- a desaturated (chroma ≈ 0) monochrome scale.
9
-
10
- Same :root (light) + .dark structure as aihu-default.
11
- ═══════════════════════════════════════════════════════════════════ */
12
-
13
1
  :root {
14
- /* ── Color tokens — monochrome oklch ramp (light) ── */
15
2
  --color-primary: oklch(0.22 0 0);
16
3
  --color-primary-foreground: oklch(0.98 0 0);
17
4
  --color-secondary: oklch(0.45 0 0);
@@ -28,14 +15,10 @@
28
15
  --color-ring: oklch(0.35 0 0);
29
16
  --color-destructive: oklch(0.4 0 0);
30
17
  --color-destructive-foreground: oklch(0.98 0 0);
31
-
32
- /* ── Radius scale (shared contract) ── */
33
18
  --radius-sm: 4px;
34
19
  --radius-md: 8px;
35
20
  --radius-lg: 12px;
36
21
  --radius-pill: 999px;
37
-
38
- /* ── Spacing scale (shared contract) ── */
39
22
  --space-1: 0.25rem;
40
23
  --space-2: 0.5rem;
41
24
  --space-3: 0.75rem;
@@ -44,13 +27,9 @@
44
27
  --space-8: 2rem;
45
28
  --space-12: 3rem;
46
29
  --space-16: 4rem;
47
-
48
- /* ── Typography (shared contract) ── */
49
30
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
50
31
  --font-mono: "JetBrains Mono", ui-monospace, "Fira Code", "Cascadia Code", monospace;
51
32
  }
52
-
53
- /* ── Dark theme — same token names, inverted monochrome ramp ── */
54
33
  .dark {
55
34
  --color-primary: oklch(0.92 0 0);
56
35
  --color-primary-foreground: oklch(0.18 0 0);