@chiralkit/cli 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/add.d.ts +4 -0
- package/dist/add.js +118 -0
- package/dist/add.js.map +1 -0
- package/dist/agents/subprocess.d.ts +10 -0
- package/dist/agents/subprocess.js +43 -0
- package/dist/agents/subprocess.js.map +1 -0
- package/dist/automation/index.d.ts +14 -0
- package/dist/automation/index.js +129 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/install.d.ts +19 -0
- package/dist/automation/install.js +116 -0
- package/dist/automation/install.js.map +1 -0
- package/dist/automation/parsers/audit-report.d.ts +2 -0
- package/dist/automation/parsers/audit-report.js +42 -0
- package/dist/automation/parsers/audit-report.js.map +1 -0
- package/dist/automation/parsers/exit-code.d.ts +2 -0
- package/dist/automation/parsers/exit-code.js +6 -0
- package/dist/automation/parsers/exit-code.js.map +1 -0
- package/dist/automation/parsers/index.d.ts +10 -0
- package/dist/automation/parsers/index.js +13 -0
- package/dist/automation/parsers/index.js.map +1 -0
- package/dist/automation/parsers/observer-snapshot.d.ts +2 -0
- package/dist/automation/parsers/observer-snapshot.js +30 -0
- package/dist/automation/parsers/observer-snapshot.js.map +1 -0
- package/dist/automation/parsers/plan-report.d.ts +2 -0
- package/dist/automation/parsers/plan-report.js +53 -0
- package/dist/automation/parsers/plan-report.js.map +1 -0
- package/dist/automation/parsers/refinement-report.d.ts +2 -0
- package/dist/automation/parsers/refinement-report.js +149 -0
- package/dist/automation/parsers/refinement-report.js.map +1 -0
- package/dist/automation/parsers/types.d.ts +7 -0
- package/dist/automation/parsers/types.js +2 -0
- package/dist/automation/parsers/types.js.map +1 -0
- package/dist/automation/run.d.ts +25 -0
- package/dist/automation/run.js +68 -0
- package/dist/automation/run.js.map +1 -0
- package/dist/automation/schema.d.ts +130 -0
- package/dist/automation/schema.js +46 -0
- package/dist/automation/schema.js.map +1 -0
- package/dist/automation/status.d.ts +16 -0
- package/dist/automation/status.js +56 -0
- package/dist/automation/status.js.map +1 -0
- package/dist/automation/verifiers/index.d.ts +7 -0
- package/dist/automation/verifiers/index.js +5 -0
- package/dist/automation/verifiers/index.js.map +1 -0
- package/dist/automation/verifiers/shell.d.ts +5 -0
- package/dist/automation/verifiers/shell.js +17 -0
- package/dist/automation/verifiers/shell.js.map +1 -0
- package/dist/automation/verifiers/types.d.ts +12 -0
- package/dist/automation/verifiers/types.js +2 -0
- package/dist/automation/verifiers/types.js.map +1 -0
- package/dist/backlog/add.d.ts +10 -0
- package/dist/backlog/add.js +30 -0
- package/dist/backlog/add.js.map +1 -0
- package/dist/backlog/index.d.ts +1 -0
- package/dist/backlog/index.js +53 -0
- package/dist/backlog/index.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +110 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.d.ts +2 -0
- package/dist/detect.js +26 -0
- package/dist/detect.js.map +1 -0
- package/dist/doctor-invariants.d.ts +6 -0
- package/dist/doctor-invariants.js +50 -0
- package/dist/doctor-invariants.js.map +1 -0
- package/dist/doctor.d.ts +13 -0
- package/dist/doctor.js +281 -0
- package/dist/doctor.js.map +1 -0
- package/dist/generate.d.ts +1 -0
- package/dist/generate.js +275 -0
- package/dist/generate.js.map +1 -0
- package/dist/generator/agent.d.ts +8 -0
- package/dist/generator/agent.js +66 -0
- package/dist/generator/agent.js.map +1 -0
- package/dist/generator/api.d.ts +7 -0
- package/dist/generator/api.js +42 -0
- package/dist/generator/api.js.map +1 -0
- package/dist/generator/config.d.ts +23 -0
- package/dist/generator/config.js +121 -0
- package/dist/generator/config.js.map +1 -0
- package/dist/generator/parse-response.d.ts +5 -0
- package/dist/generator/parse-response.js +58 -0
- package/dist/generator/parse-response.js.map +1 -0
- package/dist/generator/prompt.d.ts +9 -0
- package/dist/generator/prompt.js +166 -0
- package/dist/generator/prompt.js.map +1 -0
- package/dist/generator/request.d.ts +17 -0
- package/dist/generator/request.js +15 -0
- package/dist/generator/request.js.map +1 -0
- package/dist/generators/prompts/stencil.md +45 -0
- package/dist/generators/prompts/vue.md +54 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +89 -0
- package/dist/init.js.map +1 -0
- package/dist/installers/context.d.ts +4 -0
- package/dist/installers/context.js +120 -0
- package/dist/installers/context.js.map +1 -0
- package/dist/installers/index.d.ts +7 -0
- package/dist/installers/index.js +22 -0
- package/dist/installers/index.js.map +1 -0
- package/dist/installers/installer.d.ts +12 -0
- package/dist/installers/installer.js +30 -0
- package/dist/installers/installer.js.map +1 -0
- package/dist/installers/stencil/django-template/installer.d.ts +10 -0
- package/dist/installers/stencil/django-template/installer.js +77 -0
- package/dist/installers/stencil/django-template/installer.js.map +1 -0
- package/dist/installers/stencil/react/installer.d.ts +9 -0
- package/dist/installers/stencil/react/installer.js +22 -0
- package/dist/installers/stencil/react/installer.js.map +1 -0
- package/dist/installers/stencil/react/manifest.json +17 -0
- package/dist/installers/types.d.ts +24 -0
- package/dist/installers/types.js +2 -0
- package/dist/installers/types.js.map +1 -0
- package/dist/lock.d.ts +25 -0
- package/dist/lock.js +86 -0
- package/dist/lock.js.map +1 -0
- package/dist/manifest.d.ts +1 -0
- package/dist/manifest.js +93 -0
- package/dist/manifest.js.map +1 -0
- package/dist/pm/audit.d.ts +36 -0
- package/dist/pm/audit.js +147 -0
- package/dist/pm/audit.js.map +1 -0
- package/dist/pm/backlog.d.ts +3 -0
- package/dist/pm/backlog.js +123 -0
- package/dist/pm/backlog.js.map +1 -0
- package/dist/pm/brief.d.ts +4 -0
- package/dist/pm/brief.js +18 -0
- package/dist/pm/brief.js.map +1 -0
- package/dist/pm/git.d.ts +3 -0
- package/dist/pm/git.js +43 -0
- package/dist/pm/git.js.map +1 -0
- package/dist/pm/grid.d.ts +8 -0
- package/dist/pm/grid.js +16 -0
- package/dist/pm/grid.js.map +1 -0
- package/dist/pm/index.d.ts +25 -0
- package/dist/pm/index.js +199 -0
- package/dist/pm/index.js.map +1 -0
- package/dist/pm/observe.d.ts +55 -0
- package/dist/pm/observe.js +177 -0
- package/dist/pm/observe.js.map +1 -0
- package/dist/pm/plan.d.ts +54 -0
- package/dist/pm/plan.js +151 -0
- package/dist/pm/plan.js.map +1 -0
- package/dist/pm/refinement-worktree.d.ts +31 -0
- package/dist/pm/refinement-worktree.js +160 -0
- package/dist/pm/refinement-worktree.js.map +1 -0
- package/dist/pm/refinement.d.ts +79 -0
- package/dist/pm/refinement.js +326 -0
- package/dist/pm/refinement.js.map +1 -0
- package/dist/pm/render.d.ts +2 -0
- package/dist/pm/render.js +39 -0
- package/dist/pm/render.js.map +1 -0
- package/dist/pm/roadmap-rings.d.ts +7 -0
- package/dist/pm/roadmap-rings.js +31 -0
- package/dist/pm/roadmap-rings.js.map +1 -0
- package/dist/pm/roadmap.d.ts +2 -0
- package/dist/pm/roadmap.js +118 -0
- package/dist/pm/roadmap.js.map +1 -0
- package/dist/pm/snapshot.d.ts +10 -0
- package/dist/pm/snapshot.js +129 -0
- package/dist/pm/snapshot.js.map +1 -0
- package/dist/pm/types.d.ts +99 -0
- package/dist/pm/types.js +29 -0
- package/dist/pm/types.js.map +1 -0
- package/dist/registry-layout.d.ts +18 -0
- package/dist/registry-layout.js +122 -0
- package/dist/registry-layout.js.map +1 -0
- package/dist/scaffold-registry.d.ts +10 -0
- package/dist/scaffold-registry.js +283 -0
- package/dist/scaffold-registry.js.map +1 -0
- package/dist/scaffold.d.ts +1 -0
- package/dist/scaffold.js +32 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/spec-from-react.d.ts +11 -0
- package/dist/spec-from-react.js +522 -0
- package/dist/spec-from-react.js.map +1 -0
- package/dist/spec-from-stencil.d.ts +7 -0
- package/dist/spec-from-stencil.js +275 -0
- package/dist/spec-from-stencil.js.map +1 -0
- package/dist/spec.d.ts +1 -0
- package/dist/spec.js +60 -0
- package/dist/spec.js.map +1 -0
- package/dist/tokens-map.d.ts +11 -0
- package/dist/tokens-map.js +43 -0
- package/dist/tokens-map.js.map +1 -0
- package/dist/update.d.ts +39 -0
- package/dist/update.js +490 -0
- package/dist/update.js.map +1 -0
- package/dist/workspace-init.d.ts +9 -0
- package/dist/workspace-init.js +119 -0
- package/dist/workspace-init.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { access, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parseModule } from "@chiralkit/registry-schema";
|
|
4
|
+
import { resolveKitsRoot } from "@chiralkit/kits";
|
|
5
|
+
import { MODULE_ENVELOPE_FILENAME } from "./registry-layout.js";
|
|
6
|
+
// Resolve the registry root via workspace alias — no relative path.
|
|
7
|
+
const registryRoot = join(resolveKitsRoot(), "ui", "registry");
|
|
8
|
+
// spec-from-stencil is Stencil-only, so its default target (when the caller
|
|
9
|
+
// doesn't pass an explicit registryDir — i.e. the direct `chiralkit spec
|
|
10
|
+
// from-stencil <name>` CLI command) always lives under the design-system
|
|
11
|
+
// family.
|
|
12
|
+
const DESIGN_SYSTEM_FAMILY = "design-system";
|
|
13
|
+
// The @Prop decorator regex captures:
|
|
14
|
+
// 1: name
|
|
15
|
+
// 2: TS type annotation (may be a union, wraps across lines in source
|
|
16
|
+
// but we normalize whitespace before matching)
|
|
17
|
+
// 3: default value (may be undefined)
|
|
18
|
+
// A trailing `?` on the name means optional; `!` means required-no-default.
|
|
19
|
+
// Both `:type` and `=default` are optional individually — Stencil accepts
|
|
20
|
+
// `@Prop() disabled = false;` (type inferred from initializer) as well as
|
|
21
|
+
// `@Prop() code!: string;` (required, no default). When only a default is
|
|
22
|
+
// present, `parsePropTypeFromDefault` recovers the type from typeof(default).
|
|
23
|
+
const PROP_RE = /@Prop\(\)\s+(\w+)([!?])?\s*(?::\s*([^=;]+?))?\s*(?:=\s*([^;]+?))?\s*;/g;
|
|
24
|
+
// The @Event decorator regex:
|
|
25
|
+
// 1: name
|
|
26
|
+
// 2: payload type (inside EventEmitter<...>)
|
|
27
|
+
const EVENT_RE = /@Event\(\)\s+(\w+)!?\s*:\s*EventEmitter\s*<\s*([^>]+?)\s*>\s*;/g;
|
|
28
|
+
// @Component({ tag: "ds-foo", ... }) — extracts the tag name.
|
|
29
|
+
const COMPONENT_TAG_RE = /@Component\s*\(\s*\{[^}]*?\btag\s*:\s*["']([^"']+)["']/;
|
|
30
|
+
// CSS token references — captures category + name from `var(--ds-<cat>-<name>)`.
|
|
31
|
+
const TOKEN_RE = /var\(--ds-([a-z]+)-([a-z0-9-]+)\)/g;
|
|
32
|
+
// Parses one prop's type annotation into a structured shape. Handles:
|
|
33
|
+
// - `boolean` → { type: boolean }
|
|
34
|
+
// - `string` → { type: string }
|
|
35
|
+
// - `number` → { type: number }
|
|
36
|
+
// - `"a" | "b" | "c"` → { type: enum, values: [a, b, c] }
|
|
37
|
+
// - Anything else → { type: string } with a WARN comment (safe default).
|
|
38
|
+
function parsePropType(annotation) {
|
|
39
|
+
// Normalize: collapse whitespace, trim, and strip an optional leading `|`
|
|
40
|
+
// (TypeScript allows `variant: | "a" | "b"` — common for multi-line
|
|
41
|
+
// unions like ds-badge's). Without stripping the leading pipe the
|
|
42
|
+
// enum-shape regex below fails to match those (subtle plan-authoring bug
|
|
43
|
+
// caught during Plan 2 Task 1 execution).
|
|
44
|
+
const normalized = annotation
|
|
45
|
+
.replace(/\s+/g, " ")
|
|
46
|
+
.trim()
|
|
47
|
+
.replace(/^\|\s*/, "");
|
|
48
|
+
if (normalized === "boolean")
|
|
49
|
+
return { type: "boolean" };
|
|
50
|
+
if (normalized === "string")
|
|
51
|
+
return { type: "string" };
|
|
52
|
+
if (normalized === "number")
|
|
53
|
+
return { type: "number" };
|
|
54
|
+
// String-literal union → enum. Matches `"a" | "b"` or `'a' | 'b'`.
|
|
55
|
+
const litRe = /["']([^"']+)["']/g;
|
|
56
|
+
const values = [];
|
|
57
|
+
let m;
|
|
58
|
+
while ((m = litRe.exec(normalized)) !== null) {
|
|
59
|
+
if (m[1] !== undefined)
|
|
60
|
+
values.push(m[1]);
|
|
61
|
+
}
|
|
62
|
+
if (values.length > 0 && /^["'].+["']\s*(\|\s*["'].+["']\s*)+$/.test(normalized)) {
|
|
63
|
+
return { type: "enum", values };
|
|
64
|
+
}
|
|
65
|
+
// Unknown / complex type — fall back to string (spec.json only handles the
|
|
66
|
+
// four primitives above; anything richer needs human review anyway).
|
|
67
|
+
return { type: "string" };
|
|
68
|
+
}
|
|
69
|
+
function parsePropDefault(raw) {
|
|
70
|
+
if (raw === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
const t = raw.trim();
|
|
73
|
+
if (t === "true")
|
|
74
|
+
return true;
|
|
75
|
+
if (t === "false")
|
|
76
|
+
return false;
|
|
77
|
+
if (/^-?\d+(\.\d+)?$/.test(t))
|
|
78
|
+
return Number(t);
|
|
79
|
+
const stringMatch = t.match(/^["']([^"']*)["']$/);
|
|
80
|
+
if (stringMatch)
|
|
81
|
+
return stringMatch[1];
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
// Falls back to inferring a prop's type from its default value when the
|
|
85
|
+
// source has no explicit annotation (Stencil pattern: `@Prop() flag = false;`).
|
|
86
|
+
function parsePropTypeFromDefault(parsedDefault) {
|
|
87
|
+
const t = typeof parsedDefault;
|
|
88
|
+
if (t === "boolean")
|
|
89
|
+
return { type: "boolean" };
|
|
90
|
+
if (t === "number")
|
|
91
|
+
return { type: "number" };
|
|
92
|
+
return { type: "string" };
|
|
93
|
+
}
|
|
94
|
+
function extractProps(source) {
|
|
95
|
+
const normalized = source.replace(/\r\n/g, "\n");
|
|
96
|
+
// Collapse multi-line prop declarations onto one line so PROP_RE catches
|
|
97
|
+
// them (e.g. `@Prop() variant:\n | "a"\n | "b" = "a";` in ds-badge).
|
|
98
|
+
const flattened = normalized.replace(/@Prop\(\)[\s\S]*?;/g, (m) => m.replace(/\s+/g, " "));
|
|
99
|
+
const props = [];
|
|
100
|
+
let m;
|
|
101
|
+
while ((m = PROP_RE.exec(flattened)) !== null) {
|
|
102
|
+
const name = m[1];
|
|
103
|
+
const marker = m[2];
|
|
104
|
+
const typeAnnotation = m[3];
|
|
105
|
+
const defaultRaw = m[4];
|
|
106
|
+
const parsedDefault = defaultRaw !== undefined ? parsePropDefault(defaultRaw) : undefined;
|
|
107
|
+
const parsed = typeAnnotation !== undefined
|
|
108
|
+
? parsePropType(typeAnnotation)
|
|
109
|
+
: parsePropTypeFromDefault(parsedDefault);
|
|
110
|
+
props.push({
|
|
111
|
+
name,
|
|
112
|
+
type: parsed.type,
|
|
113
|
+
...(parsed.values ? { values: parsed.values } : {}),
|
|
114
|
+
...(parsedDefault !== undefined ? { default: parsedDefault } : {}),
|
|
115
|
+
optional: marker === "?" || defaultRaw !== undefined,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return props;
|
|
119
|
+
}
|
|
120
|
+
function extractEvents(source) {
|
|
121
|
+
const events = [];
|
|
122
|
+
let m;
|
|
123
|
+
while ((m = EVENT_RE.exec(source)) !== null) {
|
|
124
|
+
events.push({ name: m[1], payload: m[2].trim() });
|
|
125
|
+
}
|
|
126
|
+
return events;
|
|
127
|
+
}
|
|
128
|
+
function extractTag(source) {
|
|
129
|
+
const m = source.match(COMPONENT_TAG_RE);
|
|
130
|
+
return m?.[1];
|
|
131
|
+
}
|
|
132
|
+
function extractTokensUsed(css) {
|
|
133
|
+
const result = {
|
|
134
|
+
colors: [],
|
|
135
|
+
spacing: [],
|
|
136
|
+
radius: [],
|
|
137
|
+
font: [],
|
|
138
|
+
shadow: [],
|
|
139
|
+
};
|
|
140
|
+
const seen = new Set();
|
|
141
|
+
let m;
|
|
142
|
+
while ((m = TOKEN_RE.exec(css)) !== null) {
|
|
143
|
+
const category = m[1];
|
|
144
|
+
const name = m[2];
|
|
145
|
+
const key = `${category}:${name}`;
|
|
146
|
+
if (seen.has(key))
|
|
147
|
+
continue;
|
|
148
|
+
seen.add(key);
|
|
149
|
+
// Map category to the tokens_used bucket. Unknown categories are skipped.
|
|
150
|
+
switch (category) {
|
|
151
|
+
case "color":
|
|
152
|
+
result.colors.push(name);
|
|
153
|
+
break;
|
|
154
|
+
case "spacing":
|
|
155
|
+
result.spacing.push(name);
|
|
156
|
+
break;
|
|
157
|
+
case "radius":
|
|
158
|
+
result.radius.push(name);
|
|
159
|
+
break;
|
|
160
|
+
case "font":
|
|
161
|
+
result.font.push(name);
|
|
162
|
+
break;
|
|
163
|
+
case "shadow":
|
|
164
|
+
result.shadow.push(name);
|
|
165
|
+
break;
|
|
166
|
+
// ignore other categories (e.g. --ds-transition-*) until schema grows
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
async function fileExists(path) {
|
|
172
|
+
try {
|
|
173
|
+
await access(path);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
export async function runFromStencil(name, opts) {
|
|
181
|
+
// opts.registryDir / opts.sourceDir let callers (e.g. runScaffoldRegistry)
|
|
182
|
+
// point this extractor at a tmpdir fixture or a scaffold-in-progress
|
|
183
|
+
// layout instead of the workspace-resolved @chiralkit/registry package.
|
|
184
|
+
// The existing `spec from-stencil` CLI command never passes either, so
|
|
185
|
+
// it falls through to the original defaults unchanged.
|
|
186
|
+
const moduleDir = opts.registryDir ?? join(registryRoot, DESIGN_SYSTEM_FAMILY, name);
|
|
187
|
+
const stencilDir = opts.sourceDir ?? join(moduleDir, "implementations", "stencil");
|
|
188
|
+
// The envelope (module.json) is only expected to already exist for the
|
|
189
|
+
// "regenerate spec.json for an existing registry module" flow. When
|
|
190
|
+
// opts.sourceDir is provided, the caller is scaffolding a brand-new module
|
|
191
|
+
// (module.json hasn't been written yet) and already knows this is a
|
|
192
|
+
// Stencil component — skip the envelope lookup/validation in that case.
|
|
193
|
+
let envelopeTag;
|
|
194
|
+
if (opts.sourceDir === undefined) {
|
|
195
|
+
const envelopePath = join(moduleDir, MODULE_ENVELOPE_FILENAME);
|
|
196
|
+
if (!(await fileExists(envelopePath))) {
|
|
197
|
+
console.error(`spec from-stencil: no such module '${name}' at ${moduleDir}`);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
const envelope = parseModule(JSON.parse(await readFile(envelopePath, "utf8")));
|
|
201
|
+
if (envelope.type !== "ui-component") {
|
|
202
|
+
console.error(`spec from-stencil: '${name}' is type ${envelope.type}, not ui-component`);
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
const envelopeSpec = envelope.spec;
|
|
206
|
+
if (envelopeSpec.tech !== "stencil") {
|
|
207
|
+
console.error(`spec from-stencil: '${name}' spec.tech is '${envelopeSpec.tech}', not stencil`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
envelopeTag = envelopeSpec.tag;
|
|
211
|
+
}
|
|
212
|
+
const entries = await readdir(stencilDir);
|
|
213
|
+
const tsxName = entries.find((e) => e.endsWith(".tsx"));
|
|
214
|
+
const cssName = entries.find((e) => e.endsWith(".css"));
|
|
215
|
+
if (!tsxName) {
|
|
216
|
+
console.error(`spec from-stencil: no .tsx file found under ${stencilDir}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
const tsxSource = await readFile(join(stencilDir, tsxName), "utf8");
|
|
220
|
+
const cssSource = cssName
|
|
221
|
+
? await readFile(join(stencilDir, cssName), "utf8")
|
|
222
|
+
: "";
|
|
223
|
+
const tag = extractTag(tsxSource) ?? envelopeTag ?? `ds-${name}`;
|
|
224
|
+
const props = extractProps(tsxSource);
|
|
225
|
+
const events = extractEvents(tsxSource);
|
|
226
|
+
const tokens = extractTokensUsed(cssSource);
|
|
227
|
+
// Build the draft. Every top-level key is optional per componentContractSchema
|
|
228
|
+
// except name and version; we emit only what we have.
|
|
229
|
+
const draft = {
|
|
230
|
+
name,
|
|
231
|
+
version: "1.0.0",
|
|
232
|
+
};
|
|
233
|
+
if (props.length > 0) {
|
|
234
|
+
draft.props = Object.fromEntries(props.map((p) => {
|
|
235
|
+
const shape = { type: p.type };
|
|
236
|
+
if (p.values)
|
|
237
|
+
shape.values = p.values;
|
|
238
|
+
if (p.default !== undefined)
|
|
239
|
+
shape.default = p.default;
|
|
240
|
+
return [p.name, shape];
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
if (events.length > 0) {
|
|
244
|
+
draft.events = Object.fromEntries(events.map((e) => [e.name, e.payload ? { payload: e.payload } : {}]));
|
|
245
|
+
}
|
|
246
|
+
// Only include tokens buckets that have at least one entry — schema allows
|
|
247
|
+
// omission of any bucket, so the output stays minimal.
|
|
248
|
+
const tokensFiltered = Object.fromEntries(Object.entries(tokens).filter(([, v]) => v.length > 0));
|
|
249
|
+
if (Object.keys(tokensFiltered).length > 0) {
|
|
250
|
+
draft.tokens_used = tokensFiltered;
|
|
251
|
+
}
|
|
252
|
+
// Write output.
|
|
253
|
+
const outPath = join(moduleDir, "spec.json");
|
|
254
|
+
const exists = await fileExists(outPath);
|
|
255
|
+
if (exists && !opts.force) {
|
|
256
|
+
console.error(`spec from-stencil: ${outPath} already exists; pass --force to overwrite`);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
// moduleDir may not exist yet when opts.registryDir points at a
|
|
260
|
+
// scaffold-in-progress target (runScaffoldRegistry calls this before the
|
|
261
|
+
// rest of the registry entry is written). No-op for the existing-module
|
|
262
|
+
// flow, where moduleDir is already present.
|
|
263
|
+
await mkdir(moduleDir, { recursive: true });
|
|
264
|
+
await writeFile(outPath, JSON.stringify(draft, null, 2) + "\n", "utf8");
|
|
265
|
+
// Summary + explicit review-required nudge.
|
|
266
|
+
console.log(`Wrote draft: ${outPath}`);
|
|
267
|
+
console.log(` tag: ${tag}`);
|
|
268
|
+
console.log(` props: ${props.length}`);
|
|
269
|
+
console.log(` events: ${events.length}`);
|
|
270
|
+
console.log(` tokens_used: ${Object.values(tokens).reduce((s, arr) => s + arr.length, 0)} references across ${Object.keys(tokensFiltered).length} categories`);
|
|
271
|
+
console.log("");
|
|
272
|
+
console.log("This is a draft. Review and add slot, a11y, and state_machine (for patterns) by hand.");
|
|
273
|
+
console.log("Complex prop types (non-primitive, non-enum unions) fell back to 'string' — verify and adjust.");
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=spec-from-stencil.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-from-stencil.js","sourceRoot":"","sources":["../src/spec-from-stencil.ts"],"names":[],"mappings":"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"}
|
package/dist/spec.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runSpec(rest: string[]): Promise<void>;
|
package/dist/spec.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { runFromStencil } from "./spec-from-stencil.js";
|
|
2
|
+
import { runFromReact } from "./spec-from-react.js";
|
|
3
|
+
// Subcommand dispatcher for `chiralkit spec ...`. Currently one action;
|
|
4
|
+
// grows as Plan 2+ add spec-authoring aids (spec new, spec validate, ...).
|
|
5
|
+
export async function runSpec(rest) {
|
|
6
|
+
const [action, ...args] = rest;
|
|
7
|
+
switch (action) {
|
|
8
|
+
case "from-stencil": {
|
|
9
|
+
const name = args[0];
|
|
10
|
+
if (!name) {
|
|
11
|
+
console.error("spec from-stencil: missing module name");
|
|
12
|
+
console.error("Usage: chiralkit spec from-stencil <name> [--force]");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const force = args.includes("--force");
|
|
16
|
+
await runFromStencil(name, { force });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
case "from-react": {
|
|
20
|
+
const sourcePath = args[0];
|
|
21
|
+
if (!sourcePath) {
|
|
22
|
+
console.error("spec from-react: missing source path");
|
|
23
|
+
console.error('Usage: chiralkit spec from-react <path-to-tsx> --tokens-map <path> [--name <slug>] [--export <Name>] [--version <semver>] [--out <path>] [--force] [--strict] [--dry-run]');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const tokensIdx = args.indexOf("--tokens-map");
|
|
27
|
+
if (tokensIdx === -1 || args[tokensIdx + 1] === undefined) {
|
|
28
|
+
console.error("spec from-react: --tokens-map <path> is required");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const tokensMapPath = args[tokensIdx + 1];
|
|
32
|
+
const readFlagValue = (flag) => {
|
|
33
|
+
const i = args.indexOf(flag);
|
|
34
|
+
return i === -1 ? undefined : args[i + 1];
|
|
35
|
+
};
|
|
36
|
+
await runFromReact(sourcePath, {
|
|
37
|
+
tokensMapPath,
|
|
38
|
+
name: readFlagValue("--name"),
|
|
39
|
+
exportName: readFlagValue("--export"),
|
|
40
|
+
version: readFlagValue("--version"),
|
|
41
|
+
outPath: readFlagValue("--out"),
|
|
42
|
+
force: args.includes("--force"),
|
|
43
|
+
strict: args.includes("--strict"),
|
|
44
|
+
dryRun: args.includes("--dry-run"),
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
case undefined:
|
|
49
|
+
console.error("spec: missing action");
|
|
50
|
+
console.error("Actions:");
|
|
51
|
+
console.error(" from-stencil <name> [--force]");
|
|
52
|
+
console.error(" from-react <path-to-tsx> --tokens-map <path> [--name --export --version --out --force --strict --dry-run]");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
return;
|
|
55
|
+
default:
|
|
56
|
+
console.error(`spec: unknown action '${action}'`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=spec.js.map
|
package/dist/spec.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type TokensCategory = "colors" | "spacing" | "radius" | "font" | "shadow";
|
|
2
|
+
export interface TokensMap {
|
|
3
|
+
readonly $schema?: string;
|
|
4
|
+
readonly generatedFrom?: string;
|
|
5
|
+
readonly colors: Readonly<Record<string, string>>;
|
|
6
|
+
readonly spacing: Readonly<Record<string, string>>;
|
|
7
|
+
readonly radius: Readonly<Record<string, string>>;
|
|
8
|
+
readonly font: Readonly<Record<string, string>>;
|
|
9
|
+
readonly shadow: Readonly<Record<string, string>>;
|
|
10
|
+
}
|
|
11
|
+
export declare function loadTokensMap(path: string): Promise<TokensMap>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
const CATEGORIES = [
|
|
3
|
+
"colors",
|
|
4
|
+
"spacing",
|
|
5
|
+
"radius",
|
|
6
|
+
"font",
|
|
7
|
+
"shadow",
|
|
8
|
+
];
|
|
9
|
+
// Loads and structurally validates a tokens map. Rejects with a clear error
|
|
10
|
+
// on missing categories, non-object entries, or non-string values. The
|
|
11
|
+
// validation is intentionally lax on the mapping itself (any Tailwind class
|
|
12
|
+
// name is accepted as a key) — the domain check is "does the class name
|
|
13
|
+
// appear in the source?" and that happens later in the extractor.
|
|
14
|
+
export async function loadTokensMap(path) {
|
|
15
|
+
const raw = await readFile(path, "utf8");
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = JSON.parse(raw);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw new Error(`tokens map at ${path} is not valid JSON: ${err.message}`);
|
|
22
|
+
}
|
|
23
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
24
|
+
throw new Error(`tokens map at ${path} must be a JSON object`);
|
|
25
|
+
}
|
|
26
|
+
const obj = parsed;
|
|
27
|
+
for (const cat of CATEGORIES) {
|
|
28
|
+
const val = obj[cat];
|
|
29
|
+
if (val === undefined) {
|
|
30
|
+
throw new Error(`tokens map at ${path} is missing category "${cat}" (expected object; may be empty)`);
|
|
31
|
+
}
|
|
32
|
+
if (val === null || typeof val !== "object" || Array.isArray(val)) {
|
|
33
|
+
throw new Error(`tokens map at ${path}: category "${cat}" must be a JSON object`);
|
|
34
|
+
}
|
|
35
|
+
for (const [k, v] of Object.entries(val)) {
|
|
36
|
+
if (typeof v !== "string") {
|
|
37
|
+
throw new Error(`tokens map at ${path}: ${cat}["${k}"] must be a string, got ${typeof v}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=tokens-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens-map.js","sourceRoot":"","sources":["../src/tokens-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAc5C,MAAM,UAAU,GAA8B;IAC5C,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,MAAM;IACN,QAAQ;CACT,CAAC;AAEF,4EAA4E;AAC5E,uEAAuE;AACvE,4EAA4E;AAC5E,wEAAwE;AACxE,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,uBAAwB,GAAa,CAAC,OAAO,EAAE,CACrE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,wBAAwB,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,yBAAyB,GAAG,mCAAmC,CACrF,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,eAAe,GAAG,yBAAyB,CACjE,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,KAAK,GAAG,KAAK,CAAC,4BAA4B,OAAO,CAAC,EAAE,CAC1E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAmB,CAAC;AAC7B,CAAC"}
|
package/dist/update.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ModuleType } from "@chiralkit/registry-schema";
|
|
2
|
+
export interface ModuleUpdatePlan {
|
|
3
|
+
key: string;
|
|
4
|
+
name: string;
|
|
5
|
+
type: ModuleType;
|
|
6
|
+
fromVersion: string;
|
|
7
|
+
toVersion: string;
|
|
8
|
+
changes: FileChange[];
|
|
9
|
+
localEdits: LocalEdit[];
|
|
10
|
+
}
|
|
11
|
+
export interface FileChange {
|
|
12
|
+
kind: "modified" | "added" | "removed";
|
|
13
|
+
relPath: string;
|
|
14
|
+
patch: string;
|
|
15
|
+
}
|
|
16
|
+
export interface LocalEdit {
|
|
17
|
+
relPath: string;
|
|
18
|
+
patch: string;
|
|
19
|
+
}
|
|
20
|
+
export interface UpdateOptions {
|
|
21
|
+
moduleFilter?: string;
|
|
22
|
+
type?: ModuleType;
|
|
23
|
+
check?: boolean;
|
|
24
|
+
yes?: boolean;
|
|
25
|
+
cwd?: string;
|
|
26
|
+
confirm?: (message: string) => Promise<boolean>;
|
|
27
|
+
now?: () => string;
|
|
28
|
+
kitsRoot?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function runUpdate(argv: string[]): Promise<number>;
|
|
31
|
+
export declare function runUpdateWith(opts: UpdateOptions): Promise<number>;
|
|
32
|
+
export declare function unifiedDiff(fromLabel: string, toLabel: string, a: string, b: string): string;
|
|
33
|
+
export interface LockInitOptions {
|
|
34
|
+
cwd?: string;
|
|
35
|
+
now?: () => string;
|
|
36
|
+
kitsRoot?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function runLock(argv: string[]): Promise<number>;
|
|
39
|
+
export declare function runLockInit(opts: LockInitOptions): Promise<number>;
|