@bestagentkits/render 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +21 -0
  3. package/README.md +166 -0
  4. package/dist/cli.d.ts +18 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +336 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/diagnostics.d.ts +45 -0
  9. package/dist/diagnostics.d.ts.map +1 -0
  10. package/dist/diagnostics.js +57 -0
  11. package/dist/diagnostics.js.map +1 -0
  12. package/dist/diagram/adapter.d.ts +71 -0
  13. package/dist/diagram/adapter.d.ts.map +1 -0
  14. package/dist/diagram/adapter.js +87 -0
  15. package/dist/diagram/adapter.js.map +1 -0
  16. package/dist/errors.d.ts +37 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +42 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/hash.d.ts +14 -0
  21. package/dist/hash.d.ts.map +1 -0
  22. package/dist/hash.js +27 -0
  23. package/dist/hash.js.map +1 -0
  24. package/dist/index.d.ts +43 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +25 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/internal/yaml-error.d.ts +14 -0
  29. package/dist/internal/yaml-error.d.ts.map +1 -0
  30. package/dist/internal/yaml-error.js +12 -0
  31. package/dist/internal/yaml-error.js.map +1 -0
  32. package/dist/ir.d.ts +77 -0
  33. package/dist/ir.d.ts.map +1 -0
  34. package/dist/ir.js +20 -0
  35. package/dist/ir.js.map +1 -0
  36. package/dist/json.d.ts +23 -0
  37. package/dist/json.d.ts.map +1 -0
  38. package/dist/json.js +47 -0
  39. package/dist/json.js.map +1 -0
  40. package/dist/registry/actions.d.ts +48 -0
  41. package/dist/registry/actions.d.ts.map +1 -0
  42. package/dist/registry/actions.js +274 -0
  43. package/dist/registry/actions.js.map +1 -0
  44. package/dist/registry/prop-schema.d.ts +108 -0
  45. package/dist/registry/prop-schema.d.ts.map +1 -0
  46. package/dist/registry/prop-schema.js +400 -0
  47. package/dist/registry/prop-schema.js.map +1 -0
  48. package/dist/registry/registry.d.ts +47 -0
  49. package/dist/registry/registry.d.ts.map +1 -0
  50. package/dist/registry/registry.js +201 -0
  51. package/dist/registry/registry.js.map +1 -0
  52. package/dist/registry/roster.d.ts +53 -0
  53. package/dist/registry/roster.d.ts.map +1 -0
  54. package/dist/registry/roster.js +692 -0
  55. package/dist/registry/roster.js.map +1 -0
  56. package/dist/render/blocks.d.ts +41 -0
  57. package/dist/render/blocks.d.ts.map +1 -0
  58. package/dist/render/blocks.js +749 -0
  59. package/dist/render/blocks.js.map +1 -0
  60. package/dist/render/charts.d.ts +29 -0
  61. package/dist/render/charts.d.ts.map +1 -0
  62. package/dist/render/charts.js +235 -0
  63. package/dist/render/charts.js.map +1 -0
  64. package/dist/render/document.d.ts +40 -0
  65. package/dist/render/document.d.ts.map +1 -0
  66. package/dist/render/document.js +90 -0
  67. package/dist/render/document.js.map +1 -0
  68. package/dist/render/escape.d.ts +46 -0
  69. package/dist/render/escape.d.ts.map +1 -0
  70. package/dist/render/escape.js +108 -0
  71. package/dist/render/escape.js.map +1 -0
  72. package/dist/render/render.d.ts +52 -0
  73. package/dist/render/render.d.ts.map +1 -0
  74. package/dist/render/render.js +216 -0
  75. package/dist/render/render.js.map +1 -0
  76. package/dist/render/runtime.d.ts +25 -0
  77. package/dist/render/runtime.d.ts.map +1 -0
  78. package/dist/render/runtime.js +451 -0
  79. package/dist/render/runtime.js.map +1 -0
  80. package/dist/render/styles.d.ts +15 -0
  81. package/dist/render/styles.d.ts.map +1 -0
  82. package/dist/render/styles.js +163 -0
  83. package/dist/render/styles.js.map +1 -0
  84. package/dist/render/verify.d.ts +25 -0
  85. package/dist/render/verify.d.ts.map +1 -0
  86. package/dist/render/verify.js +168 -0
  87. package/dist/render/verify.js.map +1 -0
  88. package/dist/spec/bindings.d.ts +19 -0
  89. package/dist/spec/bindings.d.ts.map +1 -0
  90. package/dist/spec/bindings.js +51 -0
  91. package/dist/spec/bindings.js.map +1 -0
  92. package/dist/spec/bounds.d.ts +43 -0
  93. package/dist/spec/bounds.d.ts.map +1 -0
  94. package/dist/spec/bounds.js +144 -0
  95. package/dist/spec/bounds.js.map +1 -0
  96. package/dist/spec/forbidden.d.ts +27 -0
  97. package/dist/spec/forbidden.d.ts.map +1 -0
  98. package/dist/spec/forbidden.js +91 -0
  99. package/dist/spec/forbidden.js.map +1 -0
  100. package/dist/spec/migrate.d.ts +33 -0
  101. package/dist/spec/migrate.d.ts.map +1 -0
  102. package/dist/spec/migrate.js +113 -0
  103. package/dist/spec/migrate.js.map +1 -0
  104. package/dist/spec/normalize.d.ts +29 -0
  105. package/dist/spec/normalize.d.ts.map +1 -0
  106. package/dist/spec/normalize.js +649 -0
  107. package/dist/spec/normalize.js.map +1 -0
  108. package/dist/spec/parse.d.ts +22 -0
  109. package/dist/spec/parse.d.ts.map +1 -0
  110. package/dist/spec/parse.js +62 -0
  111. package/dist/spec/parse.js.map +1 -0
  112. package/dist/spec/providers.d.ts +30 -0
  113. package/dist/spec/providers.d.ts.map +1 -0
  114. package/dist/spec/providers.js +64 -0
  115. package/dist/spec/providers.js.map +1 -0
  116. package/dist/spec/validate.d.ts +28 -0
  117. package/dist/spec/validate.d.ts.map +1 -0
  118. package/dist/spec/validate.js +68 -0
  119. package/dist/spec/validate.js.map +1 -0
  120. package/dist/theme/load-theme.d.ts +55 -0
  121. package/dist/theme/load-theme.d.ts.map +1 -0
  122. package/dist/theme/load-theme.js +219 -0
  123. package/dist/theme/load-theme.js.map +1 -0
  124. package/dist/theme/presets.d.ts +50 -0
  125. package/dist/theme/presets.d.ts.map +1 -0
  126. package/dist/theme/presets.js +304 -0
  127. package/dist/theme/presets.js.map +1 -0
  128. package/dist/theme/theme-catalog.d.ts +68 -0
  129. package/dist/theme/theme-catalog.d.ts.map +1 -0
  130. package/dist/theme/theme-catalog.js +198 -0
  131. package/dist/theme/theme-catalog.js.map +1 -0
  132. package/dist/theme/tokens.d.ts +38 -0
  133. package/dist/theme/tokens.d.ts.map +1 -0
  134. package/dist/theme/tokens.js +190 -0
  135. package/dist/theme/tokens.js.map +1 -0
  136. package/dist/version.d.ts +12 -0
  137. package/dist/version.d.ts.map +1 -0
  138. package/dist/version.js +12 -0
  139. package/dist/version.js.map +1 -0
  140. package/package.json +80 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
6
+ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ Release mechanics and the compatibility contract live in
8
+ [docs/release-policy.md](./docs/release-policy.md).
9
+
10
+ ## [Unreleased]
11
+
12
+ ### Added
13
+
14
+ - Repository baseline for the public AK Render package: MIT license,
15
+ contribution guide, security policy, release policy, and CI covering lint,
16
+ typecheck, unit tests, browser tests, build, and package smoke.
17
+ - TypeScript ESM package skeleton targeting Node >= 20.11, with a library entry
18
+ point, an `ak-render` CLI bin, and a `pack`/install smoke test that exercises
19
+ both surfaces from a throwaway consumer project.
20
+ - Architecture decision record
21
+ ([ADR 0001](./docs/adr/0001-page-spec-compiler-boundary.md)) fixing the Page
22
+ Spec versus internal IR split, catalog/registry separation, trusted
23
+ interaction runtime, theme trust model, local/cloud boundary, and the
24
+ optional AgentKit adapter model.
25
+ - Fixture corpus representing the plan, explain, recap, diff, dashboard, media,
26
+ and interactive page classes.
27
+ - Reproducible baseline measurement of the legacy HTML presentation guidance
28
+ currently carried in agent model context, with captured results under
29
+ [docs/artifacts/](./docs/artifacts/).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentKit
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,166 @@
1
+ # @bestagentkits/render
2
+
3
+ Declarative page compiler for AgentKit: a constrained JSON/YAML **Page Spec**
4
+ in, a deterministic, self-contained, interactive **standalone HTML** out.
5
+
6
+ Agents describe meaning and composition. The compiler owns HTML, CSS,
7
+ interaction, accessibility, responsive layout, theming, asset bundling, security
8
+ policy, and byte-for-byte determinism.
9
+
10
+ ```bash
11
+ npx @bestagentkits/render page.yaml --out page.html
12
+ ```
13
+
14
+ The emitted file opens directly from disk (`file://`) and makes zero network
15
+ requests by default. The local compiler is canonical: no account, no network, no
16
+ server.
17
+
18
+ > **Status:** pre-1.0, in active construction. This repository is being built in
19
+ > milestones. The package skeleton, ADR, CI, and fixture corpus exist; the
20
+ > schema, compiler, themes, runtime, catalog, and cloud service land in the
21
+ > milestones described in [docs/adr/0001-page-spec-compiler-boundary.md](./docs/adr/0001-page-spec-compiler-boundary.md)
22
+ > and the [changelog](./CHANGELOG.md). Nothing below is advertised as available
23
+ > before it exists.
24
+
25
+ ## Why
26
+
27
+ AgentKit's HTML-producing skills each carried the presentation layer in model
28
+ context: layout, CSS, JavaScript, charts, responsive rules, theming, and
29
+ verification. That costs tokens, adds latency, invites retries after
30
+ HTML/CSS/JS mistakes, and lets skills drift against each other.
31
+
32
+ `ak:diagram` already proved the alternative for diagrams: typed IR, deterministic
33
+ compiler, trusted fragment boundary. AK Render applies the same pattern to whole
34
+ pages.
35
+
36
+ ## Design in one screen
37
+
38
+ ```text
39
+ Page Spec (JSON/YAML, authored by a model)
40
+ | parse -> validate -> normalize
41
+ v
42
+ internal IR (flat nodes, stable content-derived IDs)
43
+ | resolve registry -> resolve theme -> render
44
+ v
45
+ single self-contained HTML document
46
+ | collect used assets/runtime features -> assemble -> verify
47
+ v
48
+ deterministic artifact (opens from file://, zero network by default)
49
+ ```
50
+
51
+ Six decisions define the boundary, argued in
52
+ [ADR 0001](./docs/adr/0001-page-spec-compiler-boundary.md):
53
+
54
+ 1. **Page Spec is authoring; the IR is compiler-internal.** The nested,
55
+ model-friendly spec normalizes into a flat node graph with stable IDs for
56
+ rendering, future diff/patch/editor tooling, and MCP surfaces.
57
+ 2. **Catalog and registry are separate.** `catalog()` is compact and cheap;
58
+ `describe(type)` carries the full contract. Discovery stays out of the token
59
+ budget until a block is actually selected.
60
+ 3. **The interaction runtime is trusted and declarative.** A closed action
61
+ vocabulary, one small event-delegation script, native HTML controls first,
62
+ and only the feature modules a page uses.
63
+ 4. **Themes are typed data, never CSS.** Built-in presets plus user presets that
64
+ `extends` them. No CSS escape hatch, no CDN fonts.
65
+ 5. **Local is canonical; cloud is opt-in.** The hosted renderer reuses the same
66
+ compiler and is never the source of truth.
67
+ 6. **Optional capabilities arrive as adapters.** Diagrams delegate to the
68
+ existing `ak:diagram` compiler where installed; the public package never
69
+ copies paid or Engineer-only implementation.
70
+
71
+ ## Install
72
+
73
+ ```bash
74
+ pnpm add @bestagentkits/render
75
+ # or run without installing
76
+ npx @bestagentkits/render --help
77
+ ```
78
+
79
+ Requires Node.js >= 20.11.
80
+
81
+ ## Library API
82
+
83
+ ```ts
84
+ import {
85
+ render,
86
+ validate,
87
+ normalize,
88
+ catalog,
89
+ describe,
90
+ loadTheme,
91
+ } from '@bestagentkits/render';
92
+ ```
93
+
94
+ | Export | Purpose | Status |
95
+ | --- | --- | --- |
96
+ | `VERSION` | Package version, matching `package.json` | Available |
97
+ | `RenderError`, `isRenderError` | Stable error codes with JSON path and node ID | Available |
98
+ | `render(spec, options)` | Compile a spec to a standalone HTML artifact | Available |
99
+ | `validate(spec)` | Report spec diagnostics without rendering | Available |
100
+ | `normalize(spec)` | Produce the flat internal IR | Available |
101
+ | `catalog()` | Compact list of available blocks and actions | Available |
102
+ | `describe(type)` | Full machine-readable contract for one entry | Available |
103
+ | `loadTheme(input)` | Validate and resolve a theme preset | Available |
104
+ | `buildThemeCatalog(options)` | Discover built-in, user, project, and explicit presets | Available |
105
+
106
+ ## CLI
107
+
108
+ ```bash
109
+ ak-render page.yaml --out page.html
110
+ ak-render validate page.json
111
+ ak-render catalog
112
+ ak-render describe carousel
113
+ ak-render themes
114
+
115
+ ak-render --help
116
+ ak-render --version
117
+ ```
118
+
119
+ The CLI only advertises commands it can actually run; the compiler subcommands
120
+ are registered by the milestones that implement them.
121
+
122
+ ## Fixtures and snapshots
123
+
124
+ `fixtures/pages/` holds the representative corpus the compiler is built
125
+ against: plan, explain, recap, diff, dashboard, media, interactive, and theme
126
+ showcase pages. `fixtures/snapshots/` holds one committed artifact per built-in
127
+ preset. See [fixtures/README.md](./fixtures/README.md) and
128
+ [docs/themes.md](./docs/themes.md). Fixtures are the specification: a new
129
+ capability is not done until a fixture exercises it.
130
+
131
+ ## Repository layout
132
+
133
+ | Path | Contents |
134
+ | --- | --- |
135
+ | `src/` | Library and CLI source |
136
+ | `tests/unit/` | Vitest unit and contract tests |
137
+ | `tests/browser/` | Playwright browser tests, including the zero-network audit |
138
+ | `fixtures/` | Representative Page Spec corpus and committed cross-preset snapshots |
139
+ | `benchmarks/` | Reproducible measurement harnesses |
140
+ | `docs/adr/` | Architecture decision records |
141
+ | `docs/artifacts/` | Captured measurements and evidence |
142
+ | `apps/cloud/` | Opt-in Cloudflare renderer (cloud milestone) |
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ pnpm install
148
+ pnpm verify # lint + typecheck + unit tests + build
149
+ pnpm test:browser # Playwright, after: pnpm exec playwright install chromium
150
+ pnpm test:package # pack, install into a temp project, exercise API and bin
151
+ pnpm bench:baseline # re-run the legacy presentation-context measurement
152
+ ```
153
+
154
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the determinism, trust, and testing
155
+ rules that changes are reviewed against, and
156
+ [docs/release-policy.md](./docs/release-policy.md) for versioning.
157
+
158
+ ## Security
159
+
160
+ Spec input is untrusted. Report vulnerabilities privately through GitHub's
161
+ security advisory flow; see [SECURITY.md](./SECURITY.md) for the threat model and
162
+ the invariants the compiler must hold.
163
+
164
+ ## License
165
+
166
+ MIT — see [LICENSE](./LICENSE).
package/dist/cli.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `ak-render` command-line entry point.
4
+ *
5
+ * Help output is generated from the command table, so a command that is not
6
+ * implemented cannot be advertised. Every command supports `--json` for
7
+ * scripted and CI use, and never prompts.
8
+ *
9
+ * `ak-render <spec> [--out <file>]` is the documented primary surface; naming a
10
+ * known command is optional.
11
+ */
12
+ export interface CliIo {
13
+ stdout: (text: string) => void;
14
+ stderr: (text: string) => void;
15
+ }
16
+ /** Run the CLI. Returns the process exit code. */
17
+ export declare function run(argv: readonly string[], io?: CliIo): number;
18
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAYH,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAsTD,kDAAkD;AAClD,wBAAgB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,GAAE,KAAiB,GAAG,MAAM,CAwC1E"}
package/dist/cli.js ADDED
@@ -0,0 +1,336 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `ak-render` command-line entry point.
4
+ *
5
+ * Help output is generated from the command table, so a command that is not
6
+ * implemented cannot be advertised. Every command supports `--json` for
7
+ * scripted and CI use, and never prompts.
8
+ *
9
+ * `ak-render <spec> [--out <file>]` is the documented primary surface; naming a
10
+ * known command is optional.
11
+ */
12
+ import { readFileSync, realpathSync, writeFileSync } from 'node:fs';
13
+ import { homedir } from 'node:os';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { isRenderError } from './errors.js';
16
+ import { catalog, describe } from './registry/registry.js';
17
+ import { compile } from './render/render.js';
18
+ import { validate } from './spec/validate.js';
19
+ import { buildThemeCatalog } from './theme/theme-catalog.js';
20
+ import { PACKAGE_NAME, VERSION } from './version.js';
21
+ const defaultIo = {
22
+ stdout: (text) => process.stdout.write(text),
23
+ stderr: (text) => process.stderr.write(text),
24
+ };
25
+ function readSpecFile(path, io) {
26
+ try {
27
+ return readFileSync(path, 'utf8');
28
+ }
29
+ catch (error) {
30
+ io.stderr(`ak-render: cannot read ${path}: ${error instanceof Error ? error.message : String(error)}\n`);
31
+ return undefined;
32
+ }
33
+ }
34
+ function reportDiagnostics(io, diagnostics) {
35
+ for (const diagnostic of diagnostics) {
36
+ const location = diagnostic.nodeId === undefined ? '' : ` [${diagnostic.nodeId}]`;
37
+ io.stderr(`${diagnostic.severity}: ${diagnostic.path}${location}: ${diagnostic.message}\n`);
38
+ }
39
+ }
40
+ function compileCommand(args, io, flags) {
41
+ const file = args[0];
42
+ if (file === undefined) {
43
+ io.stderr('ak-render: a spec path is required\n');
44
+ return 2;
45
+ }
46
+ const text = readSpecFile(file, io);
47
+ if (text === undefined)
48
+ return 2;
49
+ try {
50
+ const result = compile(text, {
51
+ source: file,
52
+ themeCatalog: themeCatalogFor(flags, io),
53
+ ...(flags.theme === undefined ? {} : { theme: flags.theme }),
54
+ });
55
+ if (flags.out !== undefined) {
56
+ writeFileSync(flags.out, result.html, 'utf8');
57
+ }
58
+ else {
59
+ io.stdout(result.html);
60
+ // Human-readable summary goes to stderr so stdout stays a clean artifact.
61
+ if (!flags.json) {
62
+ io.stderr(`ak-render: ${result.bytes} bytes, ${result.features.length} runtime features, hash ${result.hash}\n`);
63
+ }
64
+ }
65
+ if (flags.json) {
66
+ io.stdout(`${JSON.stringify({
67
+ source: file,
68
+ out: flags.out ?? null,
69
+ bytes: result.bytes,
70
+ hash: result.hash,
71
+ title: result.ir.meta.title,
72
+ theme: result.theme.name,
73
+ themeBase: result.theme.base,
74
+ themeChain: result.theme.chain,
75
+ features: result.features,
76
+ nodes: result.ir.nodes.length,
77
+ warnings: result.warnings,
78
+ }, null, 2)}\n`);
79
+ }
80
+ else if (flags.out !== undefined) {
81
+ io.stdout(`wrote ${result.bytes} bytes to ${flags.out} (${result.features.length} runtime features, hash ${result.hash})\n`);
82
+ }
83
+ for (const warning of result.warnings) {
84
+ io.stderr(`warning: ${warning.path}: ${warning.message}\n`);
85
+ }
86
+ return 0;
87
+ }
88
+ catch (error) {
89
+ if (isRenderError(error)) {
90
+ const renderError = error;
91
+ io.stderr(`ak-render: ${renderError.message} (${renderError.path ?? '$'})\n`);
92
+ const diagnostics = renderError.details?.diagnostics;
93
+ if (Array.isArray(diagnostics)) {
94
+ reportDiagnostics(io, diagnostics);
95
+ }
96
+ return 1;
97
+ }
98
+ throw error;
99
+ }
100
+ }
101
+ const COMMANDS = {
102
+ compile: {
103
+ summary: 'Compile a Page Spec to a standalone HTML artifact.',
104
+ usage: 'ak-render <spec.yaml|spec.json> [--out <file.html>] [--theme <preset>] [--json]',
105
+ run: compileCommand,
106
+ },
107
+ validate: {
108
+ summary: 'Validate a Page Spec without rendering it.',
109
+ usage: 'ak-render validate <spec.yaml|spec.json> [--json]',
110
+ run: (args, io, flags) => {
111
+ const file = args[0];
112
+ if (file === undefined) {
113
+ io.stderr('ak-render: validate requires a spec path\n');
114
+ return 2;
115
+ }
116
+ const text = readSpecFile(file, io);
117
+ if (text === undefined)
118
+ return 2;
119
+ const result = validate(text, { source: file });
120
+ if (flags.json) {
121
+ io.stdout(`${JSON.stringify(result, null, 2)}\n`);
122
+ }
123
+ else if (result.ok) {
124
+ const { summary } = result;
125
+ io.stdout(`ok: ${file}\n title: ${summary.title}\n theme: ${summary.themePreset}\n blocks: ${summary.blocks} (nodes: ${summary.nodes})\n depth: ${summary.depth}, bytes: ${summary.bytes}\n`);
126
+ }
127
+ else {
128
+ reportDiagnostics(io, result.diagnostics);
129
+ }
130
+ if (!flags.json) {
131
+ for (const warning of result.diagnostics.filter((item) => item.severity === 'warning')) {
132
+ io.stderr(`warning: ${warning.path}: ${warning.message}\n`);
133
+ }
134
+ }
135
+ return result.ok ? 0 : 1;
136
+ },
137
+ },
138
+ catalog: {
139
+ summary: 'List available blocks and actions (compact).',
140
+ usage: 'ak-render catalog [--json]',
141
+ run: (_args, io, flags) => {
142
+ const listing = catalog();
143
+ if (flags.json) {
144
+ io.stdout(`${JSON.stringify(listing, null, 2)}\n`);
145
+ return 0;
146
+ }
147
+ io.stdout(`Page Spec v${listing.schemaVersion} — ${listing.blockCount} blocks\n\n`);
148
+ for (const entry of listing.blocks) {
149
+ io.stdout(`${entry.type.padEnd(16)} ${entry.kind.padEnd(10)} ${entry.summary}\n`);
150
+ }
151
+ io.stdout(`\nActions: ${listing.actions.map((action) => action.type).join(', ')}\n`);
152
+ return 0;
153
+ },
154
+ },
155
+ describe: {
156
+ summary: 'Show the full machine-readable contract for one block type.',
157
+ usage: 'ak-render describe <type> [--json]',
158
+ run: (args, io, flags) => {
159
+ const type = args[0];
160
+ if (type === undefined) {
161
+ io.stderr('ak-render: describe requires a block type\n');
162
+ return 2;
163
+ }
164
+ let contract;
165
+ try {
166
+ contract = describe(type);
167
+ }
168
+ catch (error) {
169
+ if (isRenderError(error)) {
170
+ io.stderr(`ak-render: ${error.message}\n`);
171
+ return 1;
172
+ }
173
+ throw error;
174
+ }
175
+ if (flags.json) {
176
+ io.stdout(`${JSON.stringify(contract, null, 2)}\n`);
177
+ return 0;
178
+ }
179
+ io.stdout(`${contract.type} (${contract.kind}, v${contract.version})\n\n`);
180
+ io.stdout(`purpose: ${contract.purpose}\n`);
181
+ io.stdout(`summary: ${contract.summary}\n`);
182
+ io.stdout(`props: ${Object.keys(contract.props).join(', ') || '(none)'}\n`);
183
+ io.stdout(`actions: ${contract.actions.join(', ') || '(none)'}\n`);
184
+ io.stdout(`features: ${contract.runtimeFeatures.join(', ') || '(none)'}\n`);
185
+ io.stdout(`network: ${contract.network}\n`);
186
+ io.stdout(`sizes: ${contract.sizing.sizes.join(', ')} (default: ${contract.sizing.default})\n`);
187
+ io.stdout(`a11y: ${contract.a11y}\n`);
188
+ return 0;
189
+ },
190
+ },
191
+ themes: {
192
+ summary: 'List available theme presets, including discovered project or user presets.',
193
+ usage: 'ak-render themes [--theme-file <file>] [--no-theme-discovery] [--json]',
194
+ run: (_args, io, flags) => {
195
+ const catalog = themeCatalogFor(flags, io);
196
+ const names = Object.keys(catalog.entries).sort();
197
+ if (flags.json) {
198
+ io.stdout(`${JSON.stringify(catalog.sources.sort((a, b) => (a.name < b.name ? -1 : 1)), null, 2)}\n`);
199
+ return 0;
200
+ }
201
+ for (const name of names) {
202
+ const source = catalog.sources.find((entry) => entry.name === name);
203
+ const origin = source?.origin ?? 'built-in';
204
+ const file = source?.file;
205
+ io.stdout(`${name.padEnd(16)} ${origin}${file === undefined ? '' : ` (${file})`}\n`);
206
+ }
207
+ return 0;
208
+ },
209
+ },
210
+ };
211
+ function helpText() {
212
+ const usage = Object.values(COMMANDS)
213
+ .map((command) => ` ${command.usage}`)
214
+ .join('\n');
215
+ const summaries = Object.entries(COMMANDS)
216
+ .map(([name, command]) => ` ${name.padEnd(10)} ${command.summary}`)
217
+ .join('\n');
218
+ return `${PACKAGE_NAME} ${VERSION}
219
+
220
+ Deterministic, offline compiler from a declarative Page Spec (JSON/YAML) to a
221
+ self-contained interactive HTML artifact. The local compiler is canonical: no
222
+ account, no network, no server.
223
+
224
+ Usage:
225
+ ${usage}
226
+ ak-render --help
227
+ ak-render --version
228
+
229
+ Commands:
230
+ ${summaries}
231
+
232
+ The first positional argument may be a spec path with the compile command
233
+ implied. All commands accept --json and never prompt.
234
+ `;
235
+ }
236
+ const VALUE_FLAGS = ['--out', '--theme', '--theme-file'];
237
+ /** Build the preset catalog for this invocation from flags and discovery. */
238
+ function themeCatalogFor(flags, io) {
239
+ const catalog = buildThemeCatalog({
240
+ cwd: process.cwd(),
241
+ home: homedir(),
242
+ ...(flags.themeFile === undefined ? {} : { files: [flags.themeFile] }),
243
+ discovery: flags.themeDiscovery,
244
+ });
245
+ for (const problem of catalog.problems) {
246
+ io.stderr(`warning: ${problem.path}: ${problem.message}\n`);
247
+ }
248
+ return catalog;
249
+ }
250
+ function parseArgs(args) {
251
+ const flags = { json: false, themeDiscovery: true };
252
+ const positional = [];
253
+ for (let index = 0; index < args.length; index += 1) {
254
+ const arg = args[index];
255
+ if (arg === undefined)
256
+ continue;
257
+ if (arg === '--json') {
258
+ flags.json = true;
259
+ continue;
260
+ }
261
+ if (arg === '--no-theme-discovery') {
262
+ flags.themeDiscovery = false;
263
+ continue;
264
+ }
265
+ const valueFlag = VALUE_FLAGS.find((candidate) => candidate === arg);
266
+ if (valueFlag !== undefined) {
267
+ const value = args[index + 1];
268
+ if (value === undefined)
269
+ return { error: `${valueFlag} requires a value` };
270
+ if (valueFlag === '--out')
271
+ flags.out = value;
272
+ else if (valueFlag === '--theme')
273
+ flags.theme = value;
274
+ else
275
+ flags.themeFile = value;
276
+ index += 1;
277
+ continue;
278
+ }
279
+ positional.push(arg);
280
+ }
281
+ return { flags, positional };
282
+ }
283
+ /** Run the CLI. Returns the process exit code. */
284
+ export function run(argv, io = defaultIo) {
285
+ const args = argv.filter((arg) => arg !== '');
286
+ const first = args[0];
287
+ if (args.length === 0) {
288
+ io.stdout(helpText());
289
+ return 2;
290
+ }
291
+ if (first === '--help' || first === '-h' || first === 'help') {
292
+ io.stdout(helpText());
293
+ return 0;
294
+ }
295
+ if (first === '--version' || first === '-v' || first === 'version') {
296
+ io.stdout(`${VERSION}\n`);
297
+ return 0;
298
+ }
299
+ const parsed = parseArgs(args.slice(1));
300
+ if ('error' in parsed) {
301
+ io.stderr(`ak-render: ${parsed.error}\n`);
302
+ return 2;
303
+ }
304
+ // `ak-render page.yaml --out page.html` is the documented primary surface.
305
+ const command = first === undefined ? undefined : COMMANDS[first];
306
+ const resolved = command ?? COMMANDS.compile;
307
+ const positional = command === undefined && first !== undefined
308
+ ? [first, ...parsed.positional]
309
+ : parsed.positional;
310
+ try {
311
+ return resolved === undefined ? 2 : resolved.run(positional, io, parsed.flags);
312
+ }
313
+ catch (error) {
314
+ if (isRenderError(error)) {
315
+ io.stderr(`ak-render: ${error.message}\n`);
316
+ return 1;
317
+ }
318
+ throw error;
319
+ }
320
+ }
321
+ /** True when this module is the process entry point (npm bin symlinks included). */
322
+ function isMainModule() {
323
+ const entry = process.argv[1];
324
+ if (entry === undefined)
325
+ return false;
326
+ try {
327
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
328
+ }
329
+ catch {
330
+ return false;
331
+ }
332
+ }
333
+ if (isMainModule()) {
334
+ process.exitCode = run(process.argv.slice(2));
335
+ }
336
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Diagnostics: how the compiler reports everything it found wrong.
3
+ *
4
+ * A diagnostic always carries a JSON path into the author-facing spec, and a
5
+ * node ID when the failure belongs to a node that already has one. Callers
6
+ * branch on `code`; `message` is for humans and may be reworded between
7
+ * releases.
8
+ */
9
+ import type { RenderErrorCode } from './errors.js';
10
+ export type DiagnosticSeverity = 'error' | 'warning';
11
+ export interface Diagnostic {
12
+ code: RenderErrorCode;
13
+ severity: DiagnosticSeverity;
14
+ message: string;
15
+ /** JSON path in the author-facing spec, e.g. `blocks[2].items[0].url`. */
16
+ path: string;
17
+ /** Normalized node ID, when the diagnostic belongs to a node. */
18
+ nodeId?: string;
19
+ details?: Record<string, unknown>;
20
+ }
21
+ export interface DiagnosticInput {
22
+ code: RenderErrorCode;
23
+ message: string;
24
+ path: string;
25
+ severity?: DiagnosticSeverity;
26
+ nodeId?: string;
27
+ details?: Record<string, unknown>;
28
+ }
29
+ /** Ordered, de-duplicating collector for diagnostics. */
30
+ export declare class DiagnosticBag {
31
+ private readonly items;
32
+ private readonly seen;
33
+ add(input: DiagnosticInput): void;
34
+ get size(): number;
35
+ get errorCount(): number;
36
+ get hasErrors(): boolean;
37
+ list(): Diagnostic[];
38
+ errors(): Diagnostic[];
39
+ warnings(): Diagnostic[];
40
+ }
41
+ /** Append an index or key to a JSON path. */
42
+ export declare function pathKey(base: string, key: string): string;
43
+ /** Append an array index to a JSON path. */
44
+ export declare function pathIndex(base: string, index: number): string;
45
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,yDAAyD;AACzD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAE1C,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAejC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,IAAI,UAAU,EAAE;IAIpB,MAAM,IAAI,UAAU,EAAE;IAItB,QAAQ,IAAI,UAAU,EAAE;CAGzB;AAED,6CAA6C;AAC7C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D"}