@twentyfirstmedia/ui 0.0.0-stage → 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 (56) hide show
  1. package/LICENSE +30 -0
  2. package/README.md +43 -2
  3. package/dist/add.d.ts +10 -0
  4. package/dist/add.d.ts.map +1 -0
  5. package/dist/add.js +28 -0
  6. package/dist/add.js.map +1 -0
  7. package/dist/diff.d.ts +6 -0
  8. package/dist/diff.d.ts.map +1 -0
  9. package/dist/diff.js +57 -0
  10. package/dist/diff.js.map +1 -0
  11. package/dist/index.d.ts +10 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +160 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/init.d.ts +12 -0
  16. package/dist/init.d.ts.map +1 -0
  17. package/dist/init.js +79 -0
  18. package/dist/init.js.map +1 -0
  19. package/dist/knowledge.d.ts +124 -0
  20. package/dist/knowledge.d.ts.map +1 -0
  21. package/dist/knowledge.js +494 -0
  22. package/dist/knowledge.js.map +1 -0
  23. package/dist/knowledge.json +1 -0
  24. package/dist/list.d.ts +3 -0
  25. package/dist/list.d.ts.map +1 -0
  26. package/dist/list.js +21 -0
  27. package/dist/list.js.map +1 -0
  28. package/dist/mcp-init.d.ts +21 -0
  29. package/dist/mcp-init.d.ts.map +1 -0
  30. package/dist/mcp-init.js +114 -0
  31. package/dist/mcp-init.js.map +1 -0
  32. package/dist/mcp.d.ts +71 -0
  33. package/dist/mcp.d.ts.map +1 -0
  34. package/dist/mcp.js +746 -0
  35. package/dist/mcp.js.map +1 -0
  36. package/dist/project.d.ts +14 -0
  37. package/dist/project.d.ts.map +1 -0
  38. package/dist/project.js +31 -0
  39. package/dist/project.js.map +1 -0
  40. package/dist/shared/theme.d.ts +61 -0
  41. package/dist/shared/theme.d.ts.map +1 -0
  42. package/dist/shared/theme.js +200 -0
  43. package/dist/shared/theme.js.map +1 -0
  44. package/dist/source.d.ts +35 -0
  45. package/dist/source.d.ts.map +1 -0
  46. package/dist/source.js +229 -0
  47. package/dist/source.js.map +1 -0
  48. package/dist/theme.d.ts +18 -0
  49. package/dist/theme.d.ts.map +1 -0
  50. package/dist/theme.js +65 -0
  51. package/dist/theme.js.map +1 -0
  52. package/dist/util.d.ts +21 -0
  53. package/dist/util.d.ts.map +1 -0
  54. package/dist/util.js +29 -0
  55. package/dist/util.js.map +1 -0
  56. package/package.json +47 -3
package/dist/source.js ADDED
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Reads component sources from the installed @twentyfirstmedia/ui-core package and builds a
3
+ * standalone copy of one component: the component itself plus the private helpers it needs,
4
+ * with every import pointing at the public package.
5
+ */
6
+ import { readFileSync, readdirSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+ import { dirname, join } from "node:path";
9
+ import { SCOPE } from "./util.js";
10
+ const DECL = /^(?:export\s+)?(?:declare\s+)?(?:async\s+)?(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)|interface\s+(\w+)|type\s+(\w+))/;
11
+ export function parseFile(name, text) {
12
+ const lines = text.split("\n");
13
+ const imports = new Map();
14
+ const blocks = [];
15
+ let client = false;
16
+ let pendingComment = [];
17
+ let cur = null;
18
+ let i = 0;
19
+ while (i < lines.length) {
20
+ const line = lines[i];
21
+ if (/^"use client";/.test(line)) {
22
+ client = true;
23
+ i++;
24
+ continue;
25
+ }
26
+ if (/^import /.test(line)) {
27
+ let stmt = line;
28
+ while (!/;\s*$/.test(stmt) && i + 1 < lines.length)
29
+ stmt += "\n" + lines[++i];
30
+ const from = /from\s+"([^"]+)"/.exec(stmt)?.[1] ?? "";
31
+ const type = /^import\s+type\b/.test(stmt);
32
+ const ns = /^import \* as (\w+)/.exec(stmt);
33
+ if (ns)
34
+ imports.set(ns[1], { from, type: false });
35
+ const named = /\{([^}]*)\}/.exec(stmt);
36
+ if (named)
37
+ for (const raw of named[1].split(",")) {
38
+ const n = raw.trim().replace(/^type\s+/, "");
39
+ if (n)
40
+ imports.set(n.split(/\s+as\s+/).pop(), {
41
+ from,
42
+ type: type || /^\s*type\s/.test(raw),
43
+ });
44
+ }
45
+ i++;
46
+ continue;
47
+ }
48
+ if (/^(\/\*|\/\/| \*)/.test(line) && (!cur || /^(\/\*|\/\/)/.test(line))) {
49
+ // a comment at column 0 belongs to the next declaration
50
+ pendingComment.push(line);
51
+ i++;
52
+ while (pendingComment[pendingComment.length - 1]?.startsWith("/*") &&
53
+ !/\*\/\s*$/.test(pendingComment[pendingComment.length - 1]) &&
54
+ i < lines.length) {
55
+ const last = pendingComment.pop();
56
+ pendingComment.push(last + "\n" + lines[i++]);
57
+ }
58
+ continue;
59
+ }
60
+ const m = DECL.exec(line);
61
+ if (m) {
62
+ cur = {
63
+ names: [m[1] || m[2] || m[3] || m[4]].filter(Boolean),
64
+ text: [...pendingComment, line].join("\n"),
65
+ };
66
+ pendingComment = [];
67
+ blocks.push(cur);
68
+ }
69
+ else if (cur && line.trim() !== "") {
70
+ // continuation of the current declaration, or a statement such as `X.kinds = …` after it
71
+ if (/^\w+\.\w+\s*=/.test(line) && pendingComment.length === 0)
72
+ cur.text += "\n\n" + line;
73
+ else
74
+ cur.text += "\n" + line;
75
+ }
76
+ else if (cur && line.trim() === "") {
77
+ cur.text += "\n";
78
+ }
79
+ i++;
80
+ }
81
+ for (const b of blocks)
82
+ b.text = b.text.replace(/\n+$/, "");
83
+ return { name, client, blocks, imports };
84
+ }
85
+ export function loadCore(cwd) {
86
+ const req = createRequire(join(cwd, "package.json"));
87
+ let pkgJson;
88
+ try {
89
+ pkgJson = req.resolve(`${SCOPE}/ui-core/package.json`);
90
+ }
91
+ catch {
92
+ throw new Error(`${SCOPE}/ui-core is not installed here. Run \`twentyfirst-ui init\` first (it installs the kit, which brings ui-core).`);
93
+ }
94
+ const dir = dirname(pkgJson);
95
+ const version = JSON.parse(readFileSync(pkgJson, "utf8")).version;
96
+ const compDir = join(dir, "src", "components");
97
+ const files = new Map();
98
+ for (const f of readdirSync(compDir).filter((x) => x.endsWith(".tsx") && !x.includes(".test."))) {
99
+ files.set(f.replace(/\.tsx$/, ""), parseFile(f, readFileSync(join(compDir, f), "utf8")));
100
+ }
101
+ const index = readFileSync(join(compDir, "index.ts"), "utf8");
102
+ const components = new Map();
103
+ for (const m of index.matchAll(/export \{([^}]*)\} from "\.\/([\w-]+)\.js";/g)) {
104
+ for (const n of m[1]
105
+ .split(",")
106
+ .map((x) => x.trim())
107
+ .filter(Boolean))
108
+ components.set(n, m[2]);
109
+ }
110
+ const rootIndex = readFileSync(join(dir, "src", "index.ts"), "utf8");
111
+ const publicNames = new Set(components.keys());
112
+ for (const m of rootIndex.matchAll(/export \{([^}]*)\}/g))
113
+ for (const raw of m[1].split(",")) {
114
+ const n = raw.trim().replace(/^type\s+/, "");
115
+ if (n)
116
+ publicNames.add(n);
117
+ }
118
+ const types = readFileSync(join(compDir, "types.ts"), "utf8");
119
+ for (const m of types.matchAll(/export (?:interface|type) (\w+)/g))
120
+ publicNames.add(m[1]);
121
+ publicNames.add("IconName");
122
+ publicNames.add("ToastOptions");
123
+ return { dir, version, files, publicNames, components };
124
+ }
125
+ /** Identifiers a piece of code refers to (strings and comments stripped). */
126
+ export function identifiers(code) {
127
+ const stripped = code
128
+ .replace(/\/\*[\s\S]*?\*\//g, " ")
129
+ .replace(/\/\/.*$/gm, " ")
130
+ .replace(/"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'/g, '""');
131
+ return new Set(stripped.match(/[A-Za-z_$][\w$]*/g) ?? []);
132
+ }
133
+ /** Builds the standalone source of one component. */
134
+ export function buildCopy(core, component) {
135
+ const file = core.components.get(component);
136
+ if (!file)
137
+ throw new Error(`Unknown component "${component}". Run \`twentyfirst-ui list\` to see all.`);
138
+ const included = [];
139
+ const seen = new Set();
140
+ const valueImports = new Set();
141
+ const typeImports = new Set();
142
+ let client = false;
143
+ let react = false;
144
+ const findBlock = (f, name) => core.files.get(f)?.blocks.find((b) => b.names.includes(name));
145
+ function include(f, name) {
146
+ const key = `${f}:${name}`;
147
+ if (seen.has(key))
148
+ return;
149
+ seen.add(key);
150
+ const src = core.files.get(f);
151
+ const block = findBlock(f, name);
152
+ if (!src || !block)
153
+ return;
154
+ if (src.client)
155
+ client = true;
156
+ included.push({ file: f, block });
157
+ for (const id of identifiers(block.text)) {
158
+ if (block.names.includes(id))
159
+ continue;
160
+ if (id === "React" && src.imports.get("React")) {
161
+ react = true;
162
+ continue;
163
+ }
164
+ const local = findBlock(f, id);
165
+ if (local) {
166
+ // another declaration of the same file: copy private helpers, import public ones
167
+ if (core.publicNames.has(id) && id !== component)
168
+ valueImports.add(id);
169
+ else
170
+ include(f, id);
171
+ continue;
172
+ }
173
+ const imp = src.imports.get(id);
174
+ if (!imp)
175
+ continue;
176
+ if (imp.from.startsWith("./") && !imp.from.startsWith("./types")) {
177
+ const other = imp.from.replace(/^\.\//, "").replace(/\.js$/, "");
178
+ if (core.publicNames.has(id))
179
+ (imp.type ? typeImports : valueImports).add(id);
180
+ else
181
+ include(other, id);
182
+ }
183
+ else if (imp.from.startsWith(".")) {
184
+ (imp.type ? typeImports : valueImports).add(id);
185
+ }
186
+ }
187
+ }
188
+ include(file, component);
189
+ // keep the original order of the source files, the component last
190
+ const order = [...core.files.keys()];
191
+ included.sort((a, b) => {
192
+ if (a.block.names.includes(component))
193
+ return 1;
194
+ if (b.block.names.includes(component))
195
+ return -1;
196
+ if (a.file !== b.file)
197
+ return order.indexOf(a.file) - order.indexOf(b.file);
198
+ const blocks = core.files.get(a.file)?.blocks ?? [];
199
+ return blocks.indexOf(a.block) - blocks.indexOf(b.block);
200
+ });
201
+ for (const n of included.flatMap((x) => x.block.names)) {
202
+ valueImports.delete(n);
203
+ typeImports.delete(n);
204
+ }
205
+ for (const n of valueImports)
206
+ typeImports.delete(n);
207
+ const lines = [];
208
+ if (client)
209
+ lines.push('"use client";');
210
+ lines.push(`/* ${component}: copied from ${SCOPE}/ui-core ${core.version} by \`twentyfirst-ui add\`. Edit freely; */`, `/* \`twentyfirst-ui diff ${component}\` shows what changed upstream since. */`);
211
+ if (react)
212
+ lines.push('import * as React from "react";');
213
+ if (valueImports.size)
214
+ lines.push(`import { ${[...valueImports].sort().join(", ")} } from "${SCOPE}/ui-core";`);
215
+ if (typeImports.size)
216
+ lines.push(`import type { ${[...typeImports].sort().join(", ")} } from "${SCOPE}/ui-core";`);
217
+ lines.push("", "");
218
+ const body = included
219
+ .map(({ block }) => {
220
+ // private helpers stay module-private in the copy; the component stays exported
221
+ const isComponent = block.names.includes(component);
222
+ return isComponent || /^export /m.test(block.text) === false
223
+ ? block.text
224
+ : block.text.replace(/^export /m, "");
225
+ })
226
+ .join("\n\n");
227
+ return { name: component, file: file, content: lines.join("\n") + body + "\n" };
228
+ }
229
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type ThemeInput } from "./shared/theme.js";
2
+ import { type Kit, type Logger } from "./util.js";
3
+ export interface ThemeOptions {
4
+ cwd: string;
5
+ source: string;
6
+ kit?: Kit;
7
+ /** Both kits loaded (themes.css): write the theme for both, scoped by data-kit. */
8
+ both?: boolean;
9
+ /** Where to write the theme; default: theme.css next to the app's stylesheet. */
10
+ out?: string;
11
+ log: Logger;
12
+ }
13
+ export declare function resolveTheme(source: string, cwd: string): {
14
+ name: string;
15
+ theme: ThemeInput;
16
+ };
17
+ export declare function theme(o: ThemeOptions): string;
18
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAUA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA2B,KAAK,GAAG,EAAE,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAE3E,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAgB7F;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAkC7C"}
package/dist/theme.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `twentyfirst-ui theme <source>`: writes a theme for the kit and imports it after the kit styles.
3
+ *
4
+ * The source is a preset name (`blue`, `violet`, …), a brand colour (`#2563eb`, light and
5
+ * optionally dark: `#2563eb,#60a5fa`), or a CSS file with a shadcn theme (ui.shadcn.com/themes,
6
+ * tweakcn): `:root { --primary: … }` and `.dark { … }`.
7
+ */
8
+ import { existsSync, readFileSync } from "node:fs";
9
+ import { dirname, join, relative, resolve } from "node:path";
10
+ import { detect } from "./project.js";
11
+ import { THEME_PRESETS, brandTheme, parseThemeCss, themeCss, } from "./shared/theme.js";
12
+ import { readConfig, read, write } from "./util.js";
13
+ export function resolveTheme(source, cwd) {
14
+ const preset = THEME_PRESETS[source.toLowerCase()];
15
+ if (preset)
16
+ return { name: `${preset.label} preset`, theme: preset.theme };
17
+ const colours = source.split(",").map((s) => s.trim());
18
+ if (colours.every((c) => /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(c)))
19
+ return { name: `brand colour ${source}`, theme: brandTheme(colours[0], colours[1]) };
20
+ const file = resolve(cwd, source);
21
+ if (existsSync(file)) {
22
+ const theme = parseThemeCss(readFileSync(file, "utf8"));
23
+ if (!theme.light && !theme.dark && !theme.radius)
24
+ throw new Error(`${source} has no theme variables (:root { --primary: … } and .dark { … })`);
25
+ return { name: relative(cwd, file), theme };
26
+ }
27
+ throw new Error(`"${source}" is not a preset (${Object.keys(THEME_PRESETS).join(", ")}), a hex colour or a CSS file`);
28
+ }
29
+ export function theme(o) {
30
+ const config = readConfig(o.cwd);
31
+ const kit = o.kit ?? config?.kit ?? "halo";
32
+ const both = o.both ?? !!config?.both;
33
+ const { name, theme: input } = resolveTheme(o.source, o.cwd);
34
+ const p = detect(o.cwd);
35
+ const sheet = config?.css ? join(o.cwd, config.css) : p.css;
36
+ const out = o.out
37
+ ? resolve(o.cwd, o.out)
38
+ : join(sheet ? dirname(sheet) : join(o.cwd, p.srcDir ? "src/app" : "app"), "theme.css");
39
+ const kits = both ? ["halo", "pro"] : [kit];
40
+ const css = `/* Twentyfirst UI theme from ${name}. Generated by twentyfirst-ui theme; edit freely. */\n` +
41
+ kits.map((k) => themeCss(input, { kit: k, scoped: both })).join("\n");
42
+ write(out, css);
43
+ o.log.log(`${relative(o.cwd, out)}: theme for ${both ? "both kits" : kit} (${name})`);
44
+ // import it once, after the kit styles so it wins on order too
45
+ if (sheet) {
46
+ const text = read(sheet) ?? "";
47
+ const rel = relative(dirname(sheet), out).replace(/\\/g, "/");
48
+ const spec = rel.startsWith(".") ? rel : `./${rel}`;
49
+ if (!text.includes(spec)) {
50
+ const lines = text.split("\n");
51
+ let last = -1;
52
+ lines.forEach((l, i) => {
53
+ if (/^\s*@import\b/.test(l))
54
+ last = i;
55
+ });
56
+ lines.splice(last + 1, 0, `@import "${spec}";`);
57
+ write(sheet, lines.join("\n"));
58
+ o.log.log(`${relative(o.cwd, sheet)}: imports ${spec}`);
59
+ }
60
+ }
61
+ else
62
+ o.log.log(`Import ${relative(o.cwd, out)} once, after the kit's styles.css.`);
63
+ return out;
64
+ }
65
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ export declare const SCOPE = "@twentyfirstmedia";
2
+ export declare const CONFIG_FILE = "twentyfirst.json";
3
+ export type Kit = "halo" | "pro";
4
+ export interface Config {
5
+ kit: Kit;
6
+ /** Load both kits (themes.css) and switch with data-kit at runtime. */
7
+ both?: boolean;
8
+ css?: string;
9
+ components: string;
10
+ }
11
+ export declare function read(path: string): string | null;
12
+ export declare function write(path: string, content: string): void;
13
+ export declare function readJson<T>(path: string): T | null;
14
+ export declare function readConfig(cwd: string): Config | null;
15
+ export declare function kebab(name: string): string;
16
+ export interface Logger {
17
+ log(msg: string): void;
18
+ warn(msg: string): void;
19
+ }
20
+ export declare const consoleLogger: Logger;
21
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,sBAAsB,CAAC;AACzC,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,MAAM,MAAM,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC;AAEjC,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,GAAG,CAAC;IACT,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAGzD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAGlD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAErD;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1C;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,aAAa,EAAE,MAG3B,CAAC"}
package/dist/util.js ADDED
@@ -0,0 +1,29 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ export const SCOPE = "@twentyfirstmedia";
4
+ export const CONFIG_FILE = "twentyfirst.json";
5
+ export function read(path) {
6
+ return existsSync(path) ? readFileSync(path, "utf8") : null;
7
+ }
8
+ export function write(path, content) {
9
+ mkdirSync(dirname(path), { recursive: true });
10
+ writeFileSync(path, content);
11
+ }
12
+ export function readJson(path) {
13
+ const s = read(path);
14
+ return s ? JSON.parse(s) : null;
15
+ }
16
+ export function readConfig(cwd) {
17
+ return readJson(join(cwd, CONFIG_FILE));
18
+ }
19
+ export function kebab(name) {
20
+ return name
21
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
22
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
23
+ .toLowerCase();
24
+ }
25
+ export const consoleLogger = {
26
+ log: (m) => console.log(m),
27
+ warn: (m) => console.warn(m),
28
+ };
29
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,KAAK,GAAG,mBAAmB,CAAC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAY9C,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,OAAe;IACjD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAI,IAAY;IACtC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,QAAQ,CAAS,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,IAAI;SACR,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC;SACzC,WAAW,EAAE,CAAC;AACnB,CAAC;AAOD,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "@twentyfirstmedia/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "CLI and MCP server for the Twentyfirst UI kits: set up an app, copy components, give coding agents the docs.",
5
+ "license": "MIT",
6
+ "author": "Twentyfirst Media (https://twentyfirst.media)",
7
+ "homepage": "https://ui.twentyfirst.media/halo/cli/",
8
+ "bugs": {
9
+ "url": "https://github.com/twentyfirstmedia/ui/issues"
10
+ },
11
+ "keywords": [
12
+ "react",
13
+ "ui",
14
+ "cli",
15
+ "mcp",
16
+ "model-context-protocol",
17
+ "claude-code",
18
+ "cursor",
19
+ "design-system"
20
+ ],
21
+ "type": "module",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/twentyfirstmedia/ui.git",
25
+ "directory": "packages/cli"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "provenance": true
30
+ },
31
+ "bin": {
32
+ "twentyfirst-ui": "./dist/index.js"
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "devDependencies": {
38
+ "@modelcontextprotocol/sdk": "1.32.2",
39
+ "@types/node": "26.6.6",
40
+ "typescript": "6.0.3",
41
+ "vitest": "5.1.0"
42
+ },
43
+ "engines": {
44
+ "node": ">=20"
45
+ },
46
+ "scripts": {
47
+ "build": "node ../../scripts/copy-shared.ts && tsc -p tsconfig.build.json && node ../../scripts/knowledge.ts dist/knowledge.json",
48
+ "typecheck": "node ../../scripts/copy-shared.ts && tsc --noEmit"
49
+ }
6
50
  }