create-keeno 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 iliesw
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 CHANGED
@@ -1,3 +1,25 @@
1
- # Temporary Holding Version
1
+ # create-keeno
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Scaffolds a new [Keeno](https://github.com/iliesw/Keeno) project.
4
+
5
+ ```bash
6
+ bun create keeno my-app
7
+ npm create keeno@latest my-app
8
+ pnpm create keeno my-app
9
+ yarn create keeno my-app
10
+ ```
11
+
12
+ It asks for anything not given on the command line:
13
+
14
+ | Option | |
15
+ |---|---|
16
+ | `[dir]` | Where to create the project. Its name becomes the package name. |
17
+ | `-t, --template` | `router`: pages in `src/pages` with file-based routing, a layout and a 404 page (default). `minimal`: a single `App.kn`. |
18
+ | `--tailwind`, `--no-tailwind` | Add Tailwind CSS (default: no). |
19
+ | `--install`, `--no-install` | Install dependencies with the package manager that ran the command. |
20
+ | `-f, --force` | Write into a non-empty directory. |
21
+ | `-y, --yes` | Use the defaults for everything not given, without asking. |
22
+
23
+ The project uses Vite, TypeScript and `keeno-check`, with `dev`, `build`, `preview` and `check` scripts.
24
+
25
+ The Keeno package versions it writes are the ones released with this version of create-keeno.
@@ -0,0 +1,326 @@
1
+ // ../../../../../../../tmp/keeno-build/create-keeno/src/scaffold.ts
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ var TEMPLATES = {
6
+ router: "Pages in src/pages with file-based routing, a layout and a 404 page",
7
+ minimal: "A single App.kn component"
8
+ };
9
+ var KEENO_PACKAGES = ["@inflector/keeno", "@inflector/keeno-router", "@inflector/vite-plugin-keeno", "@inflector/keeno-check"];
10
+ var VERSIONS = {
11
+ vite: "^7.0.0",
12
+ typescript: "^5.6.3",
13
+ tailwindcss: "^4.1.0",
14
+ "@tailwindcss/vite": "^4.1.0"
15
+ };
16
+ function keenoVersions() {
17
+ let dir = path.dirname(fileURLToPath(import.meta.url));
18
+ let pkg;
19
+ for (;; ) {
20
+ const file = path.join(dir, "package.json");
21
+ if (existsSync(file)) {
22
+ pkg = JSON.parse(readFileSync(file, "utf8"));
23
+ if (pkg.name === "create-keeno")
24
+ break;
25
+ }
26
+ const parent = path.dirname(dir);
27
+ if (parent === dir)
28
+ throw new Error("create-keeno: cannot find its own package.json");
29
+ dir = parent;
30
+ }
31
+ const out = {};
32
+ for (const name of KEENO_PACKAGES) {
33
+ const range = pkg.devDependencies?.[name];
34
+ if (!range)
35
+ throw new Error(`create-keeno: no version for ${name}`);
36
+ out[name] = range.startsWith("workspace:") ? `^${workspaceVersion(path.dirname(dir), name)}` : range;
37
+ }
38
+ return out;
39
+ }
40
+ function workspaceVersion(packagesDir, name) {
41
+ for (const entry of readdirSync(packagesDir)) {
42
+ const file = path.join(packagesDir, entry, "package.json");
43
+ if (!existsSync(file))
44
+ continue;
45
+ const pkg = JSON.parse(readFileSync(file, "utf8"));
46
+ if (pkg.name === name)
47
+ return pkg.version;
48
+ }
49
+ throw new Error(`create-keeno: workspace package ${name} not found in ${packagesDir}`);
50
+ }
51
+ function toPackageName(dir) {
52
+ const name = path.basename(path.resolve(dir)).trim().toLowerCase().replace(/[^a-z0-9._~-]+/g, "-").replace(/^[._-]+|-+$/g, "");
53
+ return name || "keeno-app";
54
+ }
55
+ var sortKeys = (o) => Object.fromEntries(Object.entries(o).sort(([a], [b]) => a.localeCompare(b)));
56
+ function projectFiles(options) {
57
+ const { name, template, tailwind } = options;
58
+ const v = options.versions ?? keenoVersions();
59
+ const router = template === "router";
60
+ const dependencies = { "@inflector/keeno": v["@inflector/keeno"] };
61
+ if (router)
62
+ dependencies["@inflector/keeno-router"] = v["@inflector/keeno-router"];
63
+ const devDependencies = {
64
+ "@inflector/keeno-check": v["@inflector/keeno-check"],
65
+ "@inflector/vite-plugin-keeno": v["@inflector/vite-plugin-keeno"],
66
+ typescript: VERSIONS.typescript,
67
+ vite: VERSIONS.vite
68
+ };
69
+ if (tailwind) {
70
+ devDependencies.tailwindcss = VERSIONS.tailwindcss;
71
+ devDependencies["@tailwindcss/vite"] = VERSIONS["@tailwindcss/vite"];
72
+ }
73
+ const pkg = {
74
+ name,
75
+ private: true,
76
+ version: "0.0.0",
77
+ type: "module",
78
+ scripts: { dev: "vite", build: "vite build", preview: "vite preview", check: "keeno-check" },
79
+ dependencies: sortKeys(dependencies),
80
+ devDependencies: sortKeys(devDependencies)
81
+ };
82
+ const files = {
83
+ "package.json": JSON.stringify(pkg, null, 2) + `
84
+ `,
85
+ ".gitignore": `node_modules
86
+ dist
87
+ *.local
88
+ .DS_Store
89
+ `,
90
+ "README.md": readme(name, router),
91
+ "index.html": `<!doctype html>
92
+ <html lang="en">
93
+ <head>
94
+ <meta charset="UTF-8" />
95
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
96
+ <title>${escapeHtml(name)}</title>
97
+ </head>
98
+ <body>
99
+ <div id="app"></div>
100
+ <script type="module" src="/src/main.ts"></script>
101
+ </body>
102
+ </html>
103
+ `,
104
+ "tsconfig.json": `{
105
+ "compilerOptions": {
106
+ "target": "ES2022",
107
+ "module": "ESNext",
108
+ "moduleResolution": "Bundler",
109
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
110
+ "strict": true,
111
+ "skipLibCheck": true,
112
+ "noEmit": true
113
+ },
114
+ "include": ["src", "vite.config.ts"]
115
+ }
116
+ `,
117
+ "vite.config.ts": viteConfig(router, tailwind),
118
+ "src/env.d.ts": `/// <reference types="vite/client" />
119
+ ${router ? `/// <reference types="@inflector/vite-plugin-keeno/client" />
120
+ ` : ""}
121
+ declare module '*.kn' {
122
+ const Component: import('@inflector/keeno').Component
123
+ export default Component
124
+ }
125
+ `,
126
+ "src/main.ts": router ? `import { mount } from '@inflector/keeno'
127
+ import Pages from 'virtual:keeno-pages'
128
+ import './app.css'
129
+
130
+ // Routes come from the files in src/pages.
131
+ mount(Pages, document.getElementById('app')!)
132
+ ` : `import { mount } from '@inflector/keeno'
133
+ import App from './App.kn'
134
+ import './app.css'
135
+
136
+ mount(App, document.getElementById('app')!)
137
+ `,
138
+ "src/app.css": (tailwind ? `@import 'tailwindcss';
139
+
140
+ ` : "") + GLOBAL_CSS
141
+ };
142
+ if (router) {
143
+ files["src/pages/_layout.kn"] = LAYOUT;
144
+ files["src/pages/index.kn"] = counterPage("Home");
145
+ files["src/pages/about.kn"] = ABOUT;
146
+ files["src/pages/_404.kn"] = NOT_FOUND;
147
+ } else {
148
+ files["src/App.kn"] = counterPage(name);
149
+ }
150
+ return files;
151
+ }
152
+ function scaffold(dir, options) {
153
+ const root = path.resolve(dir);
154
+ const files = projectFiles(options);
155
+ for (const [file, contents] of Object.entries(files)) {
156
+ const dest = path.join(root, file);
157
+ mkdirSync(path.dirname(dest), { recursive: true });
158
+ writeFileSync(dest, contents);
159
+ }
160
+ return { dir: root, files: Object.keys(files) };
161
+ }
162
+ function isEmptyDir(dir) {
163
+ if (!existsSync(dir))
164
+ return true;
165
+ return readdirSync(dir).every((f) => f === ".git");
166
+ }
167
+ var escapeHtml = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
168
+ function viteConfig(router, tailwind) {
169
+ const imports = [`import { defineConfig } from 'vite'`, `import keeno from '@inflector/vite-plugin-keeno'`];
170
+ if (tailwind)
171
+ imports.push(`import tailwindcss from '@tailwindcss/vite'`);
172
+ const plugins = [router ? `keeno({ useFileRouter: true, pages: './src/pages' })` : "keeno()"];
173
+ if (tailwind)
174
+ plugins.push("tailwindcss()");
175
+ return `${imports.join(`
176
+ `)}
177
+
178
+ export default defineConfig({
179
+ ${router ? ` // File-based routing: each .kn file in src/pages is a route.
180
+ ` : ""} plugins: [${plugins.join(", ")}],
181
+ })
182
+ `;
183
+ }
184
+ function readme(name, router) {
185
+ return `# ${name}
186
+
187
+ A [Keeno](https://github.com/iliesw/Keeno) app.
188
+
189
+ | Command | |
190
+ |---|---|
191
+ | \`dev\` | Start the dev server |
192
+ | \`build\` | Build for production into \`dist/\` |
193
+ | \`preview\` | Serve the production build |
194
+ | \`check\` | Type-check every \`.kn\` and \`.ts\` file |
195
+
196
+ ${router ? "Pages live in `src/pages`: `index.kn` is `/`, `about.kn` is `/about`, `_layout.kn` wraps every page and `_404.kn` renders unknown URLs." : "Start editing `src/App.kn`."}
197
+ `;
198
+ }
199
+ var GLOBAL_CSS = `:root {
200
+ font-family: system-ui, sans-serif;
201
+ color: #1f2937;
202
+ background: #f5f5f4;
203
+ }
204
+
205
+ body {
206
+ margin: 0;
207
+ }
208
+ `;
209
+ var counterPage = (title) => `<script lang="ts">
210
+ const count = state(0)
211
+ const doubled = derived(() => count * 2)
212
+ </script>
213
+
214
+ <main>
215
+ <h1>${escapeHtml(title)}</h1>
216
+ <p>Clicked {count} times ({doubled} doubled)</p>
217
+ <button type="button" onClick={() => count.set(count + 1)}>+1</button>
218
+ </main>
219
+
220
+ <style>
221
+ main {
222
+ max-width: 32rem;
223
+ margin: 2rem auto;
224
+ padding: 1.5rem;
225
+ background: white;
226
+ border-radius: 12px;
227
+ box-shadow: 0 1px 4px rgb(0 0 0 / 0.1);
228
+ }
229
+ h1 {
230
+ margin-top: 0;
231
+ color: teal;
232
+ }
233
+ button {
234
+ background: teal;
235
+ color: white;
236
+ border: 0;
237
+ border-radius: 6px;
238
+ padding: 0.4rem 0.8rem;
239
+ cursor: pointer;
240
+ }
241
+ </style>
242
+ `;
243
+ var LAYOUT = `<script lang="ts">
244
+ import type { Children } from '@inflector/keeno'
245
+ import { Link } from '@inflector/keeno-router'
246
+ // Wraps every page and stays mounted while you navigate between them.
247
+ const { children } = props<{ children: Children }>()
248
+ </script>
249
+
250
+ <nav>
251
+ <Link href="/" exact>Home</Link>
252
+ <Link href="/about">About</Link>
253
+ </nav>
254
+ {children}
255
+
256
+ <style>
257
+ nav {
258
+ display: flex;
259
+ justify-content: center;
260
+ gap: 0.5rem;
261
+ padding: 1rem;
262
+ }
263
+ a {
264
+ color: teal;
265
+ text-decoration: none;
266
+ padding: 0.3rem 0.8rem;
267
+ border-radius: 6px;
268
+ }
269
+ .active {
270
+ background: rgb(0 128 128 / 0.12);
271
+ }
272
+ </style>
273
+ `;
274
+ var ABOUT = `<script lang="ts">
275
+ import { Link } from '@inflector/keeno-router'
276
+ </script>
277
+
278
+ <main>
279
+ <h1>About</h1>
280
+ <p>
281
+ This page is <code>src/pages/about.kn</code>. Add a file to <code>src/pages</code> to add a route.
282
+ </p>
283
+ <p><Link href="/">Back home</Link></p>
284
+ </main>
285
+
286
+ <style>
287
+ main {
288
+ max-width: 32rem;
289
+ margin: 2rem auto;
290
+ padding: 1.5rem;
291
+ background: white;
292
+ border-radius: 12px;
293
+ }
294
+ h1 {
295
+ margin-top: 0;
296
+ }
297
+ a {
298
+ color: teal;
299
+ }
300
+ </style>
301
+ `;
302
+ var NOT_FOUND = `<script lang="ts">
303
+ import { Link, useRoute } from '@inflector/keeno-router'
304
+ const route = useRoute()
305
+ </script>
306
+
307
+ <main>
308
+ <h1>Not found</h1>
309
+ <p>There is no page at <code>{route.path}</code>. <Link href="/">Go home</Link></p>
310
+ </main>
311
+
312
+ <style>
313
+ main {
314
+ max-width: 32rem;
315
+ margin: 2rem auto;
316
+ padding: 1.5rem;
317
+ background: white;
318
+ border-radius: 12px;
319
+ }
320
+ a {
321
+ color: teal;
322
+ }
323
+ </style>
324
+ `;
325
+
326
+ export { TEMPLATES, keenoVersions, toPackageName, projectFiles, scaffold, isEmptyDir };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ TEMPLATES,
4
+ isEmptyDir,
5
+ scaffold,
6
+ toPackageName
7
+ } from "./chunks/scaffold-wbdjagd0.js";
8
+
9
+ // ../../../../../../../tmp/keeno-build/create-keeno/src/cli.ts
10
+ import { spawnSync } from "node:child_process";
11
+ import path from "node:path";
12
+ import { createInterface } from "node:readline/promises";
13
+ var HELP = `Usage: create-keeno [dir] [options]
14
+
15
+ dir where to create the project (default: asked, or keeno-app)
16
+ -t, --template ${Object.entries(TEMPLATES).map(([k, d]) => `${k}: ${d}`).join(`
17
+ `)}
18
+ --tailwind add Tailwind CSS (--no-tailwind to skip)
19
+ --install install dependencies after scaffolding
20
+ -f, --force write into a non-empty directory
21
+ -y, --yes use the defaults for everything not given
22
+ `;
23
+ var color = process.stdout.isTTY && !process.env.NO_COLOR;
24
+ var paint = (code) => (s) => color ? `\x1B[${code}m${s}\x1B[0m` : s;
25
+ var bold = paint(1);
26
+ var dim = paint(2);
27
+ var cyan = paint(36);
28
+ var red = paint(31);
29
+ function fail(message, code = 1) {
30
+ process.stderr.write(`${red("create-keeno:")} ${message}
31
+ `);
32
+ process.exit(code);
33
+ }
34
+ var args = process.argv.slice(2);
35
+ if (args.includes("-h") || args.includes("--help")) {
36
+ process.stdout.write(HELP);
37
+ process.exit(0);
38
+ }
39
+ var dirArg;
40
+ var template;
41
+ var tailwind;
42
+ var install;
43
+ var force = false;
44
+ var yes = false;
45
+ for (let i = 0;i < args.length; i++) {
46
+ const a = args[i];
47
+ if (a === "-t" || a === "--template" || a.startsWith("--template=")) {
48
+ const value = a.includes("=") ? a.slice(a.indexOf("=") + 1) : args[++i];
49
+ if (!value || !(value in TEMPLATES))
50
+ fail(`unknown template ${value ?? "(none)"}; use ${Object.keys(TEMPLATES).join(" or ")}`, 2);
51
+ template = value;
52
+ } else if (a === "--tailwind")
53
+ tailwind = true;
54
+ else if (a === "--no-tailwind")
55
+ tailwind = false;
56
+ else if (a === "--install")
57
+ install = true;
58
+ else if (a === "--no-install")
59
+ install = false;
60
+ else if (a === "-f" || a === "--force")
61
+ force = true;
62
+ else if (a === "-y" || a === "--yes")
63
+ yes = true;
64
+ else if (a.startsWith("-"))
65
+ fail(`unknown option ${a}
66
+
67
+ ${HELP}`, 2);
68
+ else if (dirArg === undefined)
69
+ dirArg = a;
70
+ else
71
+ fail(`unexpected argument ${a}`, 2);
72
+ }
73
+ var interactive = !yes && !!process.stdin.isTTY && !!process.stdout.isTTY;
74
+ var rl = interactive ? createInterface({ input: process.stdin, output: process.stdout }) : undefined;
75
+ rl?.on("SIGINT", () => {
76
+ process.stdout.write(`
77
+ `);
78
+ process.exit(130);
79
+ });
80
+ async function text(question, fallback) {
81
+ if (!rl)
82
+ return fallback;
83
+ const answer = (await rl.question(`${cyan("?")} ${bold(question)} ${dim(`(${fallback})`)} `)).trim();
84
+ return answer || fallback;
85
+ }
86
+ async function confirm(question, fallback) {
87
+ if (!rl)
88
+ return fallback;
89
+ for (;; ) {
90
+ const answer = (await rl.question(`${cyan("?")} ${bold(question)} ${dim(fallback ? "(Y/n)" : "(y/N)")} `)).trim().toLowerCase();
91
+ if (!answer)
92
+ return fallback;
93
+ if (answer === "y" || answer === "yes")
94
+ return true;
95
+ if (answer === "n" || answer === "no")
96
+ return false;
97
+ }
98
+ }
99
+ async function select(question, choices) {
100
+ const keys = Object.keys(choices);
101
+ if (!rl)
102
+ return keys[0];
103
+ process.stdout.write(`${cyan("?")} ${bold(question)}
104
+ `);
105
+ keys.forEach((k, i) => process.stdout.write(` ${cyan(String(i + 1))}. ${k} ${dim(`- ${choices[k]}`)}
106
+ `));
107
+ for (;; ) {
108
+ const answer = (await rl.question(` ${dim(`1-${keys.length}`)} ${dim("(1)")} `)).trim();
109
+ if (!answer)
110
+ return keys[0];
111
+ const picked = keys[Number(answer) - 1] ?? keys.find((k) => k === answer);
112
+ if (picked)
113
+ return picked;
114
+ }
115
+ }
116
+ function packageManager() {
117
+ const agent = process.env.npm_config_user_agent ?? "";
118
+ for (const pm of ["pnpm", "yarn", "bun"])
119
+ if (agent.startsWith(pm))
120
+ return pm;
121
+ return "npm";
122
+ }
123
+ process.stdout.write(`
124
+ ${bold(cyan("Keeno"))} ${dim("- create a new project")}
125
+
126
+ `);
127
+ var dir = dirArg ?? await text("Project directory", "keeno-app");
128
+ var target = path.resolve(dir);
129
+ if (!force && !isEmptyDir(target)) {
130
+ const proceed = await confirm(`${dir} is not empty. Write into it anyway?`, false);
131
+ if (!proceed)
132
+ fail(`${dir} is not empty (use --force to write into it)`);
133
+ }
134
+ template ??= yes ? "router" : await select("Template", TEMPLATES);
135
+ tailwind ??= await confirm("Add Tailwind CSS?", false);
136
+ var pm = packageManager();
137
+ install ??= await confirm(`Install dependencies with ${pm}?`, interactive);
138
+ rl?.close();
139
+ var { files } = scaffold(target, { name: toPackageName(target), template, tailwind });
140
+ process.stdout.write(`
141
+ ${dim(`Created ${files.length} files in`)} ${target}
142
+ `);
143
+ if (install) {
144
+ process.stdout.write(`
145
+ ${dim(`$ ${pm} install`)}
146
+ `);
147
+ const r = spawnSync(pm, ["install"], { cwd: target, stdio: "inherit", shell: process.platform === "win32" });
148
+ if (r.status !== 0)
149
+ fail(`${pm} install failed; run it yourself in ${dir}`);
150
+ }
151
+ var run = (script) => pm === "npm" || pm === "bun" ? `${pm} run ${script}` : `${pm} ${script}`;
152
+ var rel = path.relative(process.cwd(), target);
153
+ var steps = [rel && `cd ${/\s/.test(rel) ? JSON.stringify(rel) : rel}`, !install && `${pm} install`, run("dev")].filter(Boolean);
154
+ process.stdout.write(`
155
+ ${bold("Next:")}
156
+ ${steps.map((s) => ` ${cyan(s)}`).join(`
157
+ `)}
158
+
159
+ `);
@@ -0,0 +1,31 @@
1
+ export declare const TEMPLATES: {
2
+ readonly router: "Pages in src/pages with file-based routing, a layout and a 404 page";
3
+ readonly minimal: "A single App.kn component";
4
+ };
5
+ export type Template = keyof typeof TEMPLATES;
6
+ export interface Options {
7
+ /** package.json `name`. */
8
+ name: string;
9
+ template: Template;
10
+ tailwind: boolean;
11
+ /** Version ranges of the Keeno packages, by package name (default: `keenoVersions()`). */
12
+ versions?: Record<string, string>;
13
+ }
14
+ /**
15
+ * Ranges for the Keeno packages, from this package's devDependencies: a published create-keeno has the
16
+ * released versions there (`bun pm pack` rewrites `workspace:` ranges); in the monorepo they are read
17
+ * from the sibling packages.
18
+ */
19
+ export declare function keenoVersions(): Record<string, string>;
20
+ /** A valid npm package name from a directory name. */
21
+ export declare function toPackageName(dir: string): string;
22
+ /** Every file of the new project, by path relative to its root. */
23
+ export declare function projectFiles(options: Options): Record<string, string>;
24
+ export interface ScaffoldResult {
25
+ dir: string;
26
+ files: string[];
27
+ }
28
+ /** Write the project into `dir` (created when missing). */
29
+ export declare function scaffold(dir: string, options: Options): ScaffoldResult;
30
+ /** True when `dir` is missing or has nothing but a .git directory. */
31
+ export declare function isEmptyDir(dir: string): boolean;
@@ -0,0 +1,16 @@
1
+ import {
2
+ TEMPLATES,
3
+ isEmptyDir,
4
+ keenoVersions,
5
+ projectFiles,
6
+ scaffold,
7
+ toPackageName
8
+ } from "./chunks/scaffold-wbdjagd0.js";
9
+ export {
10
+ TEMPLATES,
11
+ isEmptyDir,
12
+ keenoVersions,
13
+ projectFiles,
14
+ scaffold,
15
+ toPackageName
16
+ };
package/package.json CHANGED
@@ -1,6 +1,63 @@
1
1
  {
2
2
  "name": "create-keeno",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.4.0",
4
+ "description": "Scaffold a new Keeno project: npm create keeno",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/iliesw/Keeno.git",
9
+ "directory": "packages/create-keeno"
10
+ },
11
+ "homepage": "https://github.com/iliesw/Keeno/tree/main/packages/create-keeno#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/iliesw/Keeno/issues"
14
+ },
15
+ "keywords": [
16
+ "keeno",
17
+ "create",
18
+ "scaffold",
19
+ "template",
20
+ "cli"
21
+ ],
22
+ "type": "module",
23
+ "bin": {
24
+ "create-keeno": "./dist/cli.js"
25
+ },
26
+ "main": "./dist/scaffold.js",
27
+ "types": "./dist/scaffold.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "keeno-source": "./src/scaffold.ts",
31
+ "types": "./dist/scaffold.d.ts",
32
+ "import": "./dist/scaffold.js",
33
+ "default": "./dist/scaffold.js"
34
+ },
35
+ "./cli": {
36
+ "keeno-source": "./src/cli.ts",
37
+ "types": "./dist/cli.d.ts",
38
+ "import": "./dist/cli.js",
39
+ "default": "./dist/cli.js"
40
+ },
41
+ "./package.json": "./package.json"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "scripts": {
47
+ "build": "bun ../../scripts/build-package.ts --target=node",
48
+ "prepack": "bun run build"
49
+ },
50
+ "//": "Not installed with the CLI: the generated project depends on these. `bun pm pack` turns the workspace ranges into the released versions, which the CLI reads from this file.",
51
+ "devDependencies": {
52
+ "@inflector/keeno": "^0.4.0",
53
+ "@inflector/keeno-check": "^0.1.3",
54
+ "@inflector/keeno-router": "^0.2.0",
55
+ "@inflector/vite-plugin-keeno": "^0.4.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=18"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ }
63
+ }