@kidd-cli/cli 0.2.0 → 0.3.1

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.
@@ -1,5 +1,6 @@
1
- import { n as isKebabCase, r as renderTemplate, t as writeFiles } from "../../write-CdoqLFeH.mjs";
2
- import { t as detectProject } from "../../detect-DcO0_CWy.mjs";
1
+ import { n as renderTemplate, t as writeFiles } from "../../write-BF8u0sRy.mjs";
2
+ import { t as isKebabCase } from "../../validate-D3mbQfJT.mjs";
3
+ import { t as detectProject } from "../../detect-Cxj1jrYq.mjs";
3
4
  import { command } from "@kidd-cli/core";
4
5
  import { join } from "node:path";
5
6
  import { loadConfig } from "@kidd-cli/config/loader";
@@ -48,7 +49,7 @@ const addCommandCommand = command({
48
49
  }
49
50
  ctx.spinner.stop("Command created!");
50
51
  const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
51
- if (summary.length > 0) ctx.output.raw(summary);
52
+ if (summary.length > 0) ctx.logger.print(summary);
52
53
  }
53
54
  });
54
55
  /**
@@ -0,0 +1,6 @@
1
+ import { Command } from "@kidd-cli/core";
2
+
3
+ //#region src/commands/add/config.d.ts
4
+ declare const addConfigCommand: Command;
5
+ //#endregion
6
+ export { addConfigCommand as default };
@@ -0,0 +1,55 @@
1
+ import { n as renderTemplate, t as writeFiles } from "../../write-BF8u0sRy.mjs";
2
+ import { t as detectProject } from "../../detect-Cxj1jrYq.mjs";
3
+ import { command } from "@kidd-cli/core";
4
+ import { join } from "node:path";
5
+ import { readManifest } from "@kidd-cli/utils/manifest";
6
+ //#region src/commands/add/config.ts
7
+ const addConfigCommand = command({
8
+ description: "Add a config schema to your project",
9
+ handler: async (ctx) => {
10
+ const [detectError, project] = await detectProject(process.cwd());
11
+ if (detectError) return ctx.fail(detectError.message);
12
+ if (!project) return ctx.fail("Not in a kidd project. Run `kidd init` first.");
13
+ const projectName = await resolveProjectName(project.rootDir);
14
+ ctx.spinner.start("Generating config...");
15
+ const [renderError, rendered] = await renderTemplate({
16
+ templateDir: join(import.meta.dirname, "..", "..", "lib", "templates", "config"),
17
+ variables: { name: projectName }
18
+ });
19
+ if (renderError) {
20
+ ctx.spinner.stop("Failed");
21
+ return ctx.fail(renderError.message);
22
+ }
23
+ const [writeError, result] = await writeFiles({
24
+ files: rendered,
25
+ outputDir: join(project.rootDir, "src"),
26
+ overwrite: false
27
+ });
28
+ if (writeError) {
29
+ ctx.spinner.stop("Failed");
30
+ return ctx.fail(writeError.message);
31
+ }
32
+ ctx.spinner.stop("Config created!");
33
+ const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
34
+ if (summary.length > 0) ctx.logger.print(summary);
35
+ ctx.logger.newline();
36
+ ctx.logger.print("Next steps:");
37
+ ctx.logger.print(" 1. Add fields to the config schema in src/config.ts");
38
+ ctx.logger.print(" 2. Import and pass the schema to cli({ config: { schema: configSchema } })");
39
+ }
40
+ });
41
+ const DEFAULT_NAME = "my-app";
42
+ /**
43
+ * Resolve the project name from the project's package.json.
44
+ *
45
+ * @param rootDir - The project root directory.
46
+ * @returns The project name from package.json, or a default fallback.
47
+ * @private
48
+ */
49
+ async function resolveProjectName(rootDir) {
50
+ const [error, manifest] = await readManifest(rootDir);
51
+ if (error || !manifest.name) return DEFAULT_NAME;
52
+ return manifest.name;
53
+ }
54
+ //#endregion
55
+ export { addConfigCommand as default };
@@ -1,5 +1,5 @@
1
1
  import { command } from "@kidd-cli/core";
2
2
  //#region src/commands/add/index.ts
3
- const addCommand = command({ description: "Add a command or middleware to your project" });
3
+ const addCommand = command({ description: "Add a command, middleware, or config to your project" });
4
4
  //#endregion
5
5
  export { addCommand as default };
@@ -1,5 +1,6 @@
1
- import { n as isKebabCase, r as renderTemplate, t as writeFiles } from "../../write-CdoqLFeH.mjs";
2
- import { t as detectProject } from "../../detect-DcO0_CWy.mjs";
1
+ import { n as renderTemplate, t as writeFiles } from "../../write-BF8u0sRy.mjs";
2
+ import { t as isKebabCase } from "../../validate-D3mbQfJT.mjs";
3
+ import { t as detectProject } from "../../detect-Cxj1jrYq.mjs";
3
4
  import { command } from "@kidd-cli/core";
4
5
  import { join } from "node:path";
5
6
  import { z } from "zod";
@@ -43,7 +44,7 @@ const addMiddlewareCommand = command({
43
44
  }
44
45
  ctx.spinner.stop("Middleware created!");
45
46
  const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
46
- if (summary.length > 0) ctx.output.raw(summary);
47
+ if (summary.length > 0) ctx.logger.print(summary);
47
48
  }
48
49
  });
49
50
  /**
@@ -22,10 +22,10 @@ const commandsCommand = command({
22
22
  const tree = await buildTree(await autoload({ dir: commandsDir }));
23
23
  ctx.spinner.stop("Commands");
24
24
  if (tree.length === 0) {
25
- ctx.output.write("No commands found");
25
+ ctx.logger.print("No commands found");
26
26
  return;
27
27
  }
28
- ctx.output.raw(`${renderTree(tree)}\n`);
28
+ ctx.logger.print(renderTree(tree));
29
29
  }
30
30
  });
31
31
  /**
@@ -538,7 +538,7 @@ const doctorCommand = command({
538
538
  total: results.length,
539
539
  warnings
540
540
  });
541
- ctx.output.raw(summary);
541
+ ctx.logger.print(summary);
542
542
  if (failed > 0) ctx.fail(`${failed} ${pluralizeCheck(failed)} failed`);
543
543
  }
544
544
  });
@@ -607,7 +607,7 @@ async function applyFixes(results, context) {
607
607
  */
608
608
  function displayResults(ctx, results, fixResults) {
609
609
  const output = results.map((result) => formatResultLine(result, fixResults)).join("");
610
- if (output.length > 0) ctx.output.raw(output);
610
+ if (output.length > 0) ctx.logger.print(output);
611
611
  }
612
612
  /**
613
613
  * Format a single check result line with optional hint.
@@ -1,31 +1,98 @@
1
- import { n as isKebabCase, r as renderTemplate, t as writeFiles } from "../write-CdoqLFeH.mjs";
1
+ import { n as renderTemplate, t as writeFiles } from "../write-BF8u0sRy.mjs";
2
+ import { t as isKebabCase } from "../validate-D3mbQfJT.mjs";
2
3
  import { createRequire } from "node:module";
3
4
  import { command } from "@kidd-cli/core";
4
5
  import { dirname, join } from "node:path";
5
6
  import { readManifest } from "@kidd-cli/utils/manifest";
6
7
  import { z } from "zod";
7
- import { attempt } from "@kidd-cli/utils/fp";
8
- //#region src/generated/template-versions.ts
8
+ import { existsSync, readFileSync } from "node:fs";
9
+ import { attempt, err, match, ok } from "@kidd-cli/utils/fp";
10
+ import { parse } from "yaml";
11
+ //#region src/lib/template-versions.ts
9
12
  /**
10
- * Zod version from the workspace catalog.
13
+ * Zod schema for the `catalog` field in `pnpm-workspace.yaml`.
14
+ *
15
+ * @private
16
+ */
17
+ const catalogSchema = z.object({ catalog: z.object({
18
+ tsdown: z.string(),
19
+ typescript: z.string(),
20
+ vitest: z.string(),
21
+ zod: z.string()
22
+ }) });
23
+ /**
24
+ * Known locations for `pnpm-workspace.yaml` relative to this module.
25
+ *
26
+ * - First path covers the built `dist/` layout (yaml copied to `dist/`).
27
+ * - Second path covers running from source `src/lib/` during development.
28
+ *
29
+ * @private
30
+ */
31
+ const CANDIDATE_PATHS = [join(import.meta.dirname, "..", "pnpm-workspace.yaml"), join(import.meta.dirname, "..", "..", "..", "..", "pnpm-workspace.yaml")];
32
+ /**
33
+ * Locate `pnpm-workspace.yaml` by checking known candidate paths.
34
+ *
35
+ * @returns The resolved path, or `null` when no candidate exists.
36
+ * @private
11
37
  */
12
- const ZOD_VERSION = "^4.3.6";
38
+ function findWorkspaceYaml() {
39
+ return CANDIDATE_PATHS.find(existsSync) ?? null;
40
+ }
13
41
  /**
14
- * TypeScript version from the workspace catalog.
42
+ * Range operator prefixes recognized in version strings.
43
+ *
44
+ * @private
15
45
  */
16
- const TYPESCRIPT_VERSION = "^5.9.3";
46
+ const RANGE_PREFIXES = [
47
+ "^",
48
+ "~",
49
+ ">",
50
+ "<",
51
+ "="
52
+ ];
17
53
  /**
18
- * Vitest version from the workspace catalog.
54
+ * Normalize a version string to always include a caret range prefix.
55
+ *
56
+ * If the version already starts with a range operator (`^`, `~`, `>`, `<`, `=`)
57
+ * it is returned as-is. Otherwise a `^` prefix is added.
58
+ *
59
+ * @param version - The raw version string from the catalog.
60
+ * @returns The version prefixed with `^` when no range operator is present.
19
61
  */
20
- const VITEST_VERSION = "^4.0.18";
62
+ function normalizeVersion(version) {
63
+ return match(RANGE_PREFIXES.some((prefix) => version.startsWith(prefix))).with(true, () => version).with(false, () => `^${version}`).exhaustive();
64
+ }
21
65
  /**
22
- * Tsdown version from the workspace catalog.
66
+ * Read template dependency versions from the workspace catalog (`pnpm-workspace.yaml`).
67
+ *
68
+ * Resolves the workspace file from known relative locations, parses the YAML,
69
+ * validates the structure with Zod, and returns normalized version strings
70
+ * suitable for scaffolding `package.json` files in new projects.
71
+ *
72
+ * @returns A `Result` tuple with the resolved versions or an error.
23
73
  */
24
- const TSDOWN_VERSION = "^0.21.1";
74
+ function readTemplateVersions() {
75
+ const yamlPath = findWorkspaceYaml();
76
+ if (yamlPath === null) return err(/* @__PURE__ */ new Error("Could not locate pnpm-workspace.yaml"));
77
+ const [readError, content] = attempt(() => readFileSync(yamlPath, "utf8"));
78
+ if (readError) return err(readError);
79
+ const [parseError, rawParsed] = attempt(() => parse(content));
80
+ if (parseError) return err(parseError);
81
+ const validation = catalogSchema.safeParse(rawParsed);
82
+ if (!validation.success) return err(/* @__PURE__ */ new Error(`Invalid pnpm-workspace.yaml catalog: ${validation.error.message}`));
83
+ const { catalog } = validation.data;
84
+ return ok(Object.freeze({
85
+ tsdownVersion: normalizeVersion(catalog.tsdown),
86
+ typescriptVersion: normalizeVersion(catalog.typescript),
87
+ vitestVersion: normalizeVersion(catalog.vitest),
88
+ zodVersion: normalizeVersion(catalog.zod)
89
+ }));
90
+ }
25
91
  //#endregion
26
92
  //#region src/commands/init.ts
27
93
  const initCommand = command({
28
94
  args: z.object({
95
+ config: z.boolean().describe("Include config schema setup").optional(),
29
96
  description: z.string().describe("Project description").optional(),
30
97
  example: z.boolean().describe("Include example command").optional(),
31
98
  name: z.string().describe("Project name (kebab-case)").optional(),
@@ -41,7 +108,13 @@ const initCommand = command({
41
108
  const projectDescription = await resolveDescription(ctx);
42
109
  const packageManager = await resolvePackageManager(ctx);
43
110
  const includeExample = await resolveIncludeExample(ctx);
111
+ const includeConfig = await resolveIncludeConfig(ctx);
44
112
  ctx.spinner.start("Scaffolding project...");
113
+ const [versionsError, templateVersions] = readTemplateVersions();
114
+ if (versionsError) {
115
+ ctx.spinner.stop("Failed");
116
+ return ctx.fail(versionsError.message);
117
+ }
45
118
  const coreVersion = await resolveDependencyVersion("@kidd-cli/core");
46
119
  const cliVersion = await resolveSelfVersion();
47
120
  const [renderError, rendered] = await renderTemplate({
@@ -50,12 +123,10 @@ const initCommand = command({
50
123
  cliVersion,
51
124
  coreVersion,
52
125
  description: projectDescription,
126
+ includeConfig,
53
127
  name: projectName,
54
128
  packageManager,
55
- tsdownVersion: TSDOWN_VERSION,
56
- typescriptVersion: TYPESCRIPT_VERSION,
57
- vitestVersion: VITEST_VERSION,
58
- zodVersion: ZOD_VERSION
129
+ ...templateVersions
59
130
  }
60
131
  });
61
132
  if (renderError) {
@@ -63,7 +134,10 @@ const initCommand = command({
63
134
  return ctx.fail(renderError.message);
64
135
  }
65
136
  const [writeError] = await writeFiles({
66
- files: selectFiles(includeExample, rendered),
137
+ files: selectFiles({
138
+ includeConfig,
139
+ includeExample
140
+ }, rendered),
67
141
  outputDir: join(process.cwd(), projectName),
68
142
  overwrite: false
69
143
  });
@@ -72,10 +146,10 @@ const initCommand = command({
72
146
  return ctx.fail(writeError.message);
73
147
  }
74
148
  ctx.spinner.stop("Project created!");
75
- ctx.output.raw("");
76
- ctx.output.raw(`Next steps:`);
77
- ctx.output.raw(` cd ${projectName}`);
78
- ctx.output.raw(` ${packageManager} install`);
149
+ ctx.logger.newline();
150
+ ctx.logger.print("Next steps:");
151
+ ctx.logger.print(` cd ${projectName}`);
152
+ ctx.logger.print(` ${packageManager} install`);
79
153
  }
80
154
  });
81
155
  /**
@@ -155,26 +229,29 @@ async function resolveIncludeExample(ctx) {
155
229
  });
156
230
  }
157
231
  /**
158
- * Select the rendered files to write, optionally excluding the example command.
232
+ * Resolve whether to include config schema setup from args or prompt.
159
233
  *
160
- * @param includeExample - Whether to include the example hello command.
161
- * @param rendered - The full set of rendered files.
162
- * @returns The filtered file list.
234
+ * @param ctx - Command context.
235
+ * @returns True when the config schema file should be included.
163
236
  * @private
164
237
  */
165
- function selectFiles(includeExample, rendered) {
166
- if (includeExample) return rendered;
167
- return rendered.filter(excludeHelloCommand);
238
+ async function resolveIncludeConfig(ctx) {
239
+ if (ctx.args.config !== void 0) return ctx.args.config;
240
+ return ctx.prompts.confirm({
241
+ initialValue: false,
242
+ message: "Include config schema?"
243
+ });
168
244
  }
169
245
  /**
170
- * Filter predicate that excludes the hello.ts example command.
246
+ * Select the rendered files to write, optionally excluding the example command and config.
171
247
  *
172
- * @param file - A rendered file to check.
173
- * @returns True when the file is not the hello command.
248
+ * @param options - Flags controlling which optional files to include.
249
+ * @param rendered - The full set of rendered files.
250
+ * @returns The filtered file list.
174
251
  * @private
175
252
  */
176
- function excludeHelloCommand(file) {
177
- return !file.relativePath.includes("commands/hello.ts");
253
+ function selectFiles(options, rendered) {
254
+ return rendered.filter((file) => options.includeExample || !file.relativePath.includes("commands/hello.ts")).filter((file) => options.includeConfig || !file.relativePath.includes("config.ts"));
178
255
  }
179
256
  const DEFAULT_VERSION = "0.0.0";
180
257
  /**
@@ -189,7 +266,10 @@ const DEFAULT_VERSION = "0.0.0";
189
266
  */
190
267
  async function resolveSelfVersion() {
191
268
  const [error, manifest] = await readManifest(join(import.meta.dirname, "..", ".."));
192
- if (error || !manifest.version) return DEFAULT_VERSION;
269
+ if (error || !manifest.version) {
270
+ console.warn("Warning: Could not resolve CLI version, using fallback 0.0.0");
271
+ return DEFAULT_VERSION;
272
+ }
193
273
  return manifest.version;
194
274
  }
195
275
  /**
@@ -206,9 +286,15 @@ async function resolveSelfVersion() {
206
286
  async function resolveDependencyVersion(packageName) {
207
287
  const require = createRequire(import.meta.url);
208
288
  const [resolveError, entryPath] = attempt(() => require.resolve(packageName));
209
- if (resolveError || entryPath === null) return DEFAULT_VERSION;
289
+ if (resolveError || entryPath === null) {
290
+ console.warn(`Warning: Could not resolve version for ${packageName}, using fallback 0.0.0`);
291
+ return DEFAULT_VERSION;
292
+ }
210
293
  const [manifestError, manifest] = await readManifest(join(dirname(entryPath), ".."));
211
- if (manifestError || !manifest.version) return DEFAULT_VERSION;
294
+ if (manifestError || !manifest.version) {
295
+ console.warn(`Warning: Could not resolve version for ${packageName}, using fallback 0.0.0`);
296
+ return DEFAULT_VERSION;
297
+ }
212
298
  return manifest.version;
213
299
  }
214
300
  //#endregion
package/dist/index.mjs CHANGED
@@ -7,27 +7,31 @@ import { readManifest } from "@kidd-cli/utils/manifest";
7
7
  *
8
8
  * Reads package.json one directory above `baseDir` (the dist output sits
9
9
  * one level below the package root) and ensures all required fields are
10
- * present. Throws immediately if the manifest cannot be read or any
11
- * required field is missing — this is an unrecoverable entry-point guard.
10
+ * present. Returns an error Result if the manifest cannot be read or any
11
+ * required field is missing.
12
12
  *
13
13
  * @param baseDir - The directory the CLI entry file lives in (typically `import.meta.dirname`).
14
- * @returns A validated {@link CLIManifest} with all required fields.
14
+ * @returns A Result tuple: error on failure, validated {@link CLIManifest} on success.
15
15
  */
16
16
  async function loadCLIManifest(baseDir) {
17
17
  const [manifestError, manifest] = await readManifest(join(baseDir, ".."));
18
- if (manifestError) throw new Error(`Failed to read CLI manifest: ${manifestError.message}`);
19
- if (!manifest.name) throw new Error("CLI manifest is missing required field: name");
20
- if (!manifest.version) throw new Error("CLI manifest is missing required field: version");
21
- if (!manifest.description) throw new Error("CLI manifest is missing required field: description");
22
- return {
18
+ if (manifestError) return [/* @__PURE__ */ new Error(`Failed to read CLI manifest: ${manifestError.message}`), null];
19
+ if (!manifest.name) return [/* @__PURE__ */ new Error("CLI manifest is missing required field: name"), null];
20
+ if (!manifest.version) return [/* @__PURE__ */ new Error("CLI manifest is missing required field: version"), null];
21
+ if (!manifest.description) return [/* @__PURE__ */ new Error("CLI manifest is missing required field: description"), null];
22
+ return [null, {
23
23
  description: manifest.description,
24
24
  name: manifest.name,
25
25
  version: manifest.version
26
- };
26
+ }];
27
27
  }
28
28
  //#endregion
29
29
  //#region src/index.ts
30
- const manifest = await loadCLIManifest(import.meta.dirname);
30
+ const [manifestError, manifest] = await loadCLIManifest(import.meta.dirname);
31
+ if (manifestError) {
32
+ console.error(manifestError.message);
33
+ process.exit(1);
34
+ }
31
35
  await cli({
32
36
  commands: `${import.meta.dirname}/commands`,
33
37
  description: manifest.description,
@@ -0,0 +1,16 @@
1
+ import type { ConfigType } from '@kidd-cli/core'
2
+ import { z } from 'zod'
3
+
4
+ /**
5
+ * Runtime config schema for the {{ name }} CLI.
6
+ *
7
+ * This schema validates config files loaded at startup (e.g. `.{{ name }}.jsonc`).
8
+ * The inferred type is merged into `ctx.config` via module augmentation below.
9
+ */
10
+ export const configSchema = z.object({
11
+ // Add your config fields here
12
+ })
13
+
14
+ declare module '@kidd-cli/core' {
15
+ interface CliConfig extends ConfigType<typeof configSchema> {}
16
+ }
@@ -7,6 +7,6 @@ export default command({
7
7
  name: z.string().describe('Name to greet').default('world'),
8
8
  }),
9
9
  handler: async (ctx) => {
10
- ctx.output.raw(`Hello, ${ctx.args.name}!`)
10
+ ctx.logger.print(`Hello, ${ctx.args.name}!`)
11
11
  },
12
12
  })
@@ -0,0 +1,16 @@
1
+ import type { ConfigType } from '@kidd-cli/core'
2
+ import { z } from 'zod'
3
+
4
+ /**
5
+ * Runtime config schema for the {{ name }} CLI.
6
+ *
7
+ * This schema validates config files loaded at startup (e.g. `.{{ name }}.jsonc`).
8
+ * The inferred type is merged into `ctx.config` via module augmentation below.
9
+ */
10
+ export const configSchema = z.object({
11
+ // Add your config fields here
12
+ })
13
+
14
+ declare module '@kidd-cli/core' {
15
+ interface CliConfig extends ConfigType<typeof configSchema> {}
16
+ }
@@ -1,8 +1,13 @@
1
1
  import { cli } from '@kidd-cli/core'
2
-
2
+ {% if includeConfig %}
3
+ import { configSchema } from './config.js'
4
+ {% endif %}
3
5
  void cli({
4
6
  name: '{{ name }}',
5
7
  version: '0.0.0',
6
8
  description: '{{ description }}',
7
9
  commands: import.meta.dirname + '/commands',
8
- })
10
+ {% if includeConfig %} config: {
11
+ schema: configSchema,
12
+ },
13
+ {% endif %}})
@@ -0,0 +1,15 @@
1
+ packages:
2
+ - packages/*
3
+ - examples/*
4
+
5
+ catalog:
6
+ '@types/node': ^25.5.0
7
+ '@vitest/coverage-v8': ^4.1.0
8
+ es-toolkit: ^1.45.1
9
+ liquidjs: ^10.25.0
10
+ ts-pattern: ^5.9.0
11
+ tsdown: 0.21.3
12
+ tsx: ^4.21.0
13
+ typescript: ^5.9.3
14
+ vitest: ^4.1.0
15
+ zod: ^4.3.6
@@ -0,0 +1,16 @@
1
+ //#region src/lib/validate.ts
2
+ const KEBAB_CASE_CHARS_RE = /^[a-z][\da-z-]*$/;
3
+ /**
4
+ * Check whether a string is valid kebab-case.
5
+ *
6
+ * @param value - The string to validate.
7
+ * @returns True when the string is kebab-case.
8
+ */
9
+ function isKebabCase(value) {
10
+ if (!KEBAB_CASE_CHARS_RE.test(value)) return false;
11
+ if (value.endsWith("-")) return false;
12
+ if (value.includes("--")) return false;
13
+ return true;
14
+ }
15
+ //#endregion
16
+ export { isKebabCase as t };
@@ -92,21 +92,6 @@ function isGenerateError(value) {
92
92
  return "type" in value && "message" in value;
93
93
  }
94
94
  //#endregion
95
- //#region src/lib/validate.ts
96
- const KEBAB_CASE_CHARS_RE = /^[a-z][\da-z-]*$/;
97
- /**
98
- * Check whether a string is valid kebab-case.
99
- *
100
- * @param value - The string to validate.
101
- * @returns True when the string is kebab-case.
102
- */
103
- function isKebabCase(value) {
104
- if (!KEBAB_CASE_CHARS_RE.test(value)) return false;
105
- if (value.endsWith("-")) return false;
106
- if (value.includes("--")) return false;
107
- return true;
108
- }
109
- //#endregion
110
95
  //#region src/lib/write.ts
111
96
  /**
112
97
  * Write rendered files to disk with optional conflict detection.
@@ -160,4 +145,4 @@ async function writeSingleFile(file, outputDir, overwrite) {
160
145
  }
161
146
  }
162
147
  //#endregion
163
- export { isKebabCase as n, renderTemplate as r, writeFiles as t };
148
+ export { renderTemplate as n, writeFiles as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kidd-cli/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "DX companion CLI for the kidd framework",
5
5
  "keywords": [
6
6
  "cli",
@@ -25,21 +25,21 @@
25
25
  "fs-extra": "^11.3.4",
26
26
  "liquidjs": "^10.25.0",
27
27
  "picocolors": "^1.1.1",
28
+ "yaml": "^2.8.2",
28
29
  "zod": "^4.3.6",
29
- "@kidd-cli/bundler": "0.2.0",
30
- "@kidd-cli/config": "0.1.4",
31
- "@kidd-cli/core": "0.4.0",
30
+ "@kidd-cli/bundler": "0.2.1",
31
+ "@kidd-cli/config": "0.1.5",
32
+ "@kidd-cli/core": "0.5.1",
32
33
  "@kidd-cli/utils": "0.1.4"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/fs-extra": "^11.0.4",
36
- "tsdown": "0.21.1",
37
+ "tsdown": "0.21.3",
37
38
  "typescript": "^5.9.3",
38
- "vitest": "^4.0.18",
39
- "yaml": "^2.8.0"
39
+ "vitest": "^4.1.0"
40
40
  },
41
41
  "scripts": {
42
- "build": "tsdown && mkdir -p dist/lib && cp -r src/lib/templates dist/lib/templates",
42
+ "build": "tsdown && mkdir -p dist/lib && cp -r src/lib/templates dist/lib/templates && cp ../../pnpm-workspace.yaml dist/pnpm-workspace.yaml",
43
43
  "typecheck": "tsgo --noEmit",
44
44
  "lint": "oxlint --ignore-pattern node_modules",
45
45
  "lint:fix": "oxlint --fix --ignore-pattern node_modules",