@funkai/cli 0.3.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,5 @@
1
1
 
2
- > @funkai/cli@0.3.0 build /home/runner/work/funkai/funkai/packages/cli
2
+ > @funkai/cli@0.3.1 build /home/runner/work/funkai/funkai/packages/cli
3
3
  > kidd build
4
4
 
5
5
  [?25l│
@@ -10,6 +10,6 @@
10
10
  │ │
11
11
  │ entry dist/index.mjs │
12
12
  │ output dist │
13
- │ version 0.3.0
13
+ │ version 0.3.1
14
14
  │ │
15
15
  ├───────────────────────────╯
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @funkai/cli
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [ef51bd7]
8
+ - @funkai/prompts@0.4.1
9
+
3
10
  ## 0.3.0
4
11
 
5
12
  ### Minor Changes
package/README.md CHANGED
@@ -27,27 +27,27 @@ npm install @funkai/cli
27
27
  Generate typed TypeScript modules from `.prompt` files.
28
28
 
29
29
  ```bash
30
- funkai prompts generate --out .prompts/client --roots src/agents
30
+ funkai prompts generate --out .prompts/client --includes "src/agents/**"
31
31
  ```
32
32
 
33
- | Flag | Description |
34
- | ------------ | --------------------------------------------------- |
35
- | `--out` | Output directory for generated files |
36
- | `--roots` | Directories to scan recursively for `.prompt` files |
37
- | `--partials` | Custom partials directory |
38
- | `--silent` | Suppress output except errors |
33
+ | Flag | Description |
34
+ | ------------ | ----------------------------------------- |
35
+ | `--out` | Output directory for generated files |
36
+ | `--includes` | Glob patterns to scan for `.prompt` files |
37
+ | `--partials` | Custom partials directory |
38
+ | `--silent` | Suppress output except errors |
39
39
 
40
40
  ### `funkai prompts lint`
41
41
 
42
42
  Validate `.prompt` files without generating output.
43
43
 
44
44
  ```bash
45
- funkai prompts lint --roots src/agents
45
+ funkai prompts lint --includes "src/agents/**"
46
46
  ```
47
47
 
48
48
  | Flag | Description |
49
49
  | ------------ | -------------------------------------------------------- |
50
- | `--roots` | Directories to scan |
50
+ | `--includes` | Glob patterns to scan for `.prompt` files |
51
51
  | `--partials` | Custom partials directory (default: `.prompts/partials`) |
52
52
  | `--silent` | Suppress output except errors |
53
53
 
@@ -78,8 +78,8 @@ Configures VSCode file associations, Liquid extension recommendation, `.gitignor
78
78
 
79
79
  ## Documentation
80
80
 
81
- See the [Prompts SDK docs](../prompts/docs/overview.md) for the full file format, library API, and guides.
81
+ See the [Prompts concept](/concepts/prompts) and [Prompts CLI reference](/reference/prompts/cli) for the full file format, library API, and guides.
82
82
 
83
83
  ## License
84
84
 
85
- [MIT](../../LICENSE)
85
+ [MIT](https://github.com/joggrdocs/funkai/blob/main/LICENSE)
package/dist/index.mjs CHANGED
@@ -11,7 +11,7 @@ import ot from "node:readline";
11
11
  import { ReadStream } from "node:tty";
12
12
  import fs, { existsSync, lstatSync, mkdirSync, promises, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
13
13
  import path, { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
14
- import { attempt, attemptAsync } from "es-toolkit";
14
+ import { attempt, attemptAsync, isNil } from "es-toolkit";
15
15
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
16
16
  import { URL as URL$1, fileURLToPath, pathToFileURL } from "node:url";
17
17
  import { homedir } from "node:os";
@@ -142,7 +142,7 @@ var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
142
142
  }));
143
143
 
144
144
  //#endregion
145
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/tally-KfEitTrZ.js
145
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/tally-KfEitTrZ.js
146
146
  /**
147
147
  * Format a duration in milliseconds to a human-readable string.
148
148
  *
@@ -2154,7 +2154,7 @@ ${r ? styleText("cyan", x$2) : ""}
2154
2154
  }));
2155
2155
 
2156
2156
  //#endregion
2157
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/lib/logger.js
2157
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/lib/logger.js
2158
2158
  /**
2159
2159
  * Create a new {@link CliLogger} instance.
2160
2160
  *
@@ -2310,7 +2310,7 @@ var init_json$1 = __esmMin((() => {
2310
2310
  }));
2311
2311
 
2312
2312
  //#endregion
2313
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/create-context-vWwSL8R5.js
2313
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/create-context-vWwSL8R5.js
2314
2314
  /**
2315
2315
  * Create a ContextError with an exit code and optional error code.
2316
2316
  *
@@ -12623,7 +12623,7 @@ var init_dist$1 = __esmMin((() => {
12623
12623
  }));
12624
12624
 
12625
12625
  //#endregion
12626
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/config-BSyREvk7.js
12626
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/config-BSyREvk7.js
12627
12627
  /**
12628
12628
  * Determine the config format from a file path's extension.
12629
12629
  *
@@ -18384,11 +18384,9 @@ function generateSchemaExpression(vars) {
18384
18384
  }
18385
18385
  /** @private */
18386
18386
  function formatHeader(sourcePath) {
18387
- let sourceLine = "";
18388
- if (sourcePath) sourceLine = `// Source: ${sourcePath}\n`;
18389
18387
  return [
18390
18388
  "// ─── AUTO-GENERATED ────────────────────────────────────────",
18391
- `${sourceLine}// Regenerate: funkai prompts generate`,
18389
+ `${match(sourcePath).with(void 0, () => "").otherwise((p) => `// Source: ${p}\n`)}// Regenerate: funkai prompts generate`,
18392
18390
  "// ───────────────────────────────────────────────────────────"
18393
18391
  ].join("\n");
18394
18392
  }
@@ -18564,13 +18562,20 @@ var init_codegen = __esmMin((() => {}));
18564
18562
  * - **Error**: template uses a variable NOT declared in the schema (undefined var).
18565
18563
  * - **Warn**: schema declares a variable NOT used in the template (unused var).
18566
18564
  *
18567
- * @param name - Prompt name (for error messages).
18568
- * @param filePath - Source file path (for error messages).
18569
- * @param schemaVars - Variables declared in frontmatter schema.
18570
- * @param templateVars - Variables extracted from the template body.
18565
+ * @param params - Lint prompt parameters.
18571
18566
  * @returns Lint result with diagnostics.
18567
+ *
18568
+ * @example
18569
+ * ```ts
18570
+ * const result = lintPrompt({
18571
+ * name: 'greeting',
18572
+ * filePath: 'prompts/greeting.prompt',
18573
+ * schemaVars: [{ name: 'name', type: 'string', required: true }],
18574
+ * templateVars: ['name'],
18575
+ * });
18576
+ * ```
18572
18577
  */
18573
- function lintPrompt(name, filePath, schemaVars, templateVars) {
18578
+ function lintPrompt({ name, filePath, schemaVars, templateVars }) {
18574
18579
  const declared = new Set(schemaVars.map((v) => v.name));
18575
18580
  const used = new Set(templateVars);
18576
18581
  const undeclaredErrors = [...used].filter((varName) => !declared.has(varName)).map((varName) => ({
@@ -18654,11 +18659,12 @@ function parseParamsOrEmpty(raw, partialName) {
18654
18659
  */
18655
18660
  function parseParams(raw, partialName) {
18656
18661
  const literalMatches = [...raw.matchAll(LITERAL_PARAM_RE)];
18657
- const allParamNames = [...raw.matchAll(/(\w+)\s*:/g)].map((m) => m[1]);
18662
+ const allParamNames = [...raw.matchAll(/(\w+)\s*:/g)].map(([, m1]) => m1);
18658
18663
  return Object.fromEntries(allParamNames.map((name) => {
18659
- const literal = literalMatches.find((m) => m[1] === name);
18664
+ const literal = literalMatches.find(([, m1]) => m1 === name);
18660
18665
  if (!literal) throw new Error(`Cannot flatten {% render '${partialName}' %}: parameter "${name}" uses a variable reference. Only literal string values are supported at codegen time.`);
18661
- return [name, literal[2]];
18666
+ const { 2: literalValue } = literal;
18667
+ return [name, literalValue];
18662
18668
  }));
18663
18669
  }
18664
18670
  /** @private */
@@ -18686,10 +18692,12 @@ function renderPartial(engine, tag) {
18686
18692
  */
18687
18693
  function parseRenderTags(template) {
18688
18694
  return [...template.matchAll(RENDER_TAG_RE)].map((m) => {
18689
- const params = parseParamsOrEmpty((m[2] ?? "").trim(), m[1]);
18695
+ const [, partialName] = m;
18696
+ if (partialName === void 0) throw new Error("Malformed render tag: missing partial name");
18697
+ const params = parseParamsOrEmpty((m[2] ?? "").trim(), partialName);
18690
18698
  return {
18691
18699
  fullMatch: m[0],
18692
- partialName: m[1],
18700
+ partialName,
18693
18701
  params
18694
18702
  };
18695
18703
  });
@@ -18768,17 +18776,22 @@ function parseYamlContent(yaml, filePath) {
18768
18776
  function parseFrontmatter({ content, filePath }) {
18769
18777
  const fmMatch = content.match(FRONTMATTER_RE);
18770
18778
  if (!fmMatch) throw new Error(`No frontmatter found in ${filePath}`);
18771
- const parsed = parseYamlContent(fmMatch[1], filePath);
18779
+ const [, fmContent] = fmMatch;
18780
+ if (fmContent === void 0) throw new Error(`No frontmatter content found in ${filePath}`);
18781
+ const parsed = parseYamlContent(fmContent, filePath);
18772
18782
  if (!parsed || typeof parsed !== "object") throw new Error(`Frontmatter is not a valid object in ${filePath}`);
18773
18783
  const { name } = parsed;
18774
18784
  if (typeof name !== "string" || name.length === 0) throw new Error(`Missing or empty "name" in frontmatter: ${filePath}`);
18775
18785
  if (!NAME_RE.test(name)) throw new Error(`Invalid prompt name "${name}" in ${filePath}. Names must be lowercase alphanumeric with hyphens only.`);
18776
- return {
18786
+ const group = parseGroup(parsed["group"], filePath);
18787
+ const version = parseVersion(parsed["version"]);
18788
+ const result = {
18777
18789
  name,
18778
- group: parseGroup(parsed.group, filePath),
18779
- version: parseVersion(parsed.version),
18780
- schema: parseSchemaBlock(parsed.schema, filePath)
18790
+ schema: parseSchemaBlock(parsed["schema"], filePath)
18781
18791
  };
18792
+ if (group !== void 0) result.group = group;
18793
+ if (version !== void 0) result.version = version;
18794
+ return result;
18782
18795
  }
18783
18796
  /** @private */
18784
18797
  function stringOrDefault(value, fallback) {
@@ -18824,9 +18837,9 @@ function parseSchemaBlock(raw, filePath) {
18824
18837
  })).with(P.when((v) => typeof v === "object" && v !== null && !Array.isArray(v)), (def) => {
18825
18838
  return {
18826
18839
  name: varName,
18827
- type: stringOrDefault(def.type, "string"),
18828
- required: def.required !== false,
18829
- description: stringOrUndefined(def.description)
18840
+ type: stringOrDefault(def["type"], "string"),
18841
+ required: def["required"] !== false,
18842
+ description: stringOrUndefined(def["description"])
18830
18843
  };
18831
18844
  }).otherwise(() => {
18832
18845
  throw new Error(`Invalid schema definition for "${varName}" in ${filePath}. Expected a type string or an object with { type, required?, description? }.`);
@@ -18851,8 +18864,10 @@ function extractName(content) {
18851
18864
  const fmMatch = content.match(FRONTMATTER_RE);
18852
18865
  if (!fmMatch) return;
18853
18866
  try {
18854
- const parsed = parse(fmMatch[1]);
18855
- if (parsed !== null && parsed !== void 0 && typeof parsed.name === "string") return parsed.name;
18867
+ const [, fmContent] = fmMatch;
18868
+ if (fmContent === void 0) return;
18869
+ const parsed = parse(fmContent);
18870
+ if (parsed !== null && parsed !== void 0 && typeof parsed["name"] === "string") return parsed["name"];
18856
18871
  return;
18857
18872
  } catch {
18858
18873
  return;
@@ -18888,11 +18903,8 @@ function extractBaseDir(pattern) {
18888
18903
  "["
18889
18904
  ]);
18890
18905
  const parts = pattern.split("/");
18891
- const staticParts = [];
18892
- for (const part of parts) {
18893
- if ([...part].some((ch) => globChars.has(ch))) break;
18894
- staticParts.push(part);
18895
- }
18906
+ const firstGlobIndex = parts.findIndex((part) => [...part].some((ch) => globChars.has(ch)));
18907
+ const staticParts = match(firstGlobIndex).with(-1, () => parts).otherwise(() => parts.slice(0, firstGlobIndex));
18896
18908
  if (staticParts.length === 0) return ".";
18897
18909
  return staticParts.join("/");
18898
18910
  }
@@ -18984,11 +18996,13 @@ function validateUniqueness(prompts) {
18984
18996
  */
18985
18997
  function resolveGroupFromConfig(filePath, groups) {
18986
18998
  const matchPath = relative(process.cwd(), filePath).replaceAll("\\", "/");
18987
- for (const group of groups) {
18999
+ const matched = groups.find((group) => {
18988
19000
  const isIncluded = picomatch(group.includes);
18989
19001
  const isExcluded = picomatch(group.excludes ?? []);
18990
- if (isIncluded(matchPath) && !isExcluded(matchPath)) return group.name;
18991
- }
19002
+ return isIncluded(matchPath) && !isExcluded(matchPath);
19003
+ });
19004
+ if (isNil(matched)) return;
19005
+ return matched.name;
18992
19006
  }
18993
19007
  /**
18994
19008
  * Resolve the list of partial directories to search.
@@ -19008,12 +19022,9 @@ function resolvePartialsDirs(customDir) {
19008
19022
  * @returns Lint results for all discovered prompts.
19009
19023
  */
19010
19024
  function runLintPipeline(options) {
19011
- let excludes;
19012
- if (options.excludes) excludes = [...options.excludes];
19013
- const discovered = discoverPrompts({
19014
- includes: [...options.includes],
19015
- excludes
19016
- });
19025
+ const discoverLintOptions = { includes: [...options.includes] };
19026
+ if (options.excludes !== void 0) discoverLintOptions.excludes = [...options.excludes];
19027
+ const discovered = discoverPrompts(discoverLintOptions);
19017
19028
  const partialsDirs = resolvePartialsDirs(resolve(options.partials ?? ".prompts/partials"));
19018
19029
  const results = discovered.map((d) => {
19019
19030
  const raw = readFileSync(d.filePath, "utf8");
@@ -19025,7 +19036,12 @@ function runLintPipeline(options) {
19025
19036
  template: clean(raw),
19026
19037
  partialsDirs
19027
19038
  }));
19028
- return lintPrompt(frontmatter.name, d.filePath, frontmatter.schema, templateVars);
19039
+ return lintPrompt({
19040
+ name: frontmatter.name,
19041
+ filePath: d.filePath,
19042
+ schemaVars: frontmatter.schema,
19043
+ templateVars
19044
+ });
19029
19045
  });
19030
19046
  return {
19031
19047
  discovered: discovered.length,
@@ -19041,12 +19057,9 @@ function runLintPipeline(options) {
19041
19057
  * @returns Parsed prompts ready for code generation, along with lint results.
19042
19058
  */
19043
19059
  function runGeneratePipeline(options) {
19044
- let excludes;
19045
- if (options.excludes) excludes = [...options.excludes];
19046
- const discovered = discoverPrompts({
19047
- includes: [...options.includes],
19048
- excludes
19049
- });
19060
+ const discoverGenerateOptions = { includes: [...options.includes] };
19061
+ if (options.excludes !== void 0) discoverGenerateOptions.excludes = [...options.excludes];
19062
+ const discovered = discoverPrompts(discoverGenerateOptions);
19050
19063
  const partialsDirs = resolvePartialsDirs(resolve(options.partials ?? resolve(options.out, "../partials")));
19051
19064
  const configGroups = options.groups ?? [];
19052
19065
  const processed = discovered.map((d) => {
@@ -19061,15 +19074,21 @@ function runGeneratePipeline(options) {
19061
19074
  });
19062
19075
  const templateVars = extractVariables(template);
19063
19076
  const group = frontmatter.group ?? resolveGroupFromConfig(d.filePath, configGroups);
19077
+ const promptObj = {
19078
+ name: frontmatter.name,
19079
+ schema: frontmatter.schema,
19080
+ template,
19081
+ sourcePath: d.filePath
19082
+ };
19083
+ if (group !== void 0) promptObj.group = group;
19064
19084
  return {
19065
- lintResult: lintPrompt(frontmatter.name, d.filePath, frontmatter.schema, templateVars),
19066
- prompt: {
19085
+ lintResult: lintPrompt({
19067
19086
  name: frontmatter.name,
19068
- group,
19069
- schema: frontmatter.schema,
19070
- template,
19071
- sourcePath: d.filePath
19072
- }
19087
+ filePath: d.filePath,
19088
+ schemaVars: frontmatter.schema,
19089
+ templateVars
19090
+ }),
19091
+ prompt: promptObj
19073
19092
  };
19074
19093
  });
19075
19094
  const prompts = processed.map((p) => p.prompt);
@@ -19105,13 +19124,14 @@ function resolveGenerateArgs(args, config, fail) {
19105
19124
  const excludes = (config && config.excludes) ?? [];
19106
19125
  const partials = args.partials ?? (config && config.partials);
19107
19126
  if (!out) fail("Missing --out flag. Provide it via CLI or set prompts.out in funkai.config.ts.");
19108
- return {
19127
+ const resolved = {
19109
19128
  out,
19110
19129
  includes,
19111
19130
  excludes,
19112
- partials,
19113
19131
  silent: args.silent
19114
19132
  };
19133
+ if (partials !== void 0) resolved.partials = partials;
19134
+ return resolved;
19115
19135
  }
19116
19136
  /**
19117
19137
  * Shared handler for prompts code generation.
@@ -19120,13 +19140,15 @@ function resolveGenerateArgs(args, config, fail) {
19120
19140
  */
19121
19141
  function handleGenerate({ args, config, logger, fail }) {
19122
19142
  const { out, includes, excludes, partials, silent } = resolveGenerateArgs(args, config, fail);
19123
- const { discovered, lintResults, prompts } = runGeneratePipeline({
19143
+ const configGroups = config && config.groups;
19144
+ const pipelineOptions = {
19124
19145
  includes,
19125
19146
  excludes,
19126
- out,
19127
- partials,
19128
- groups: config && config.groups
19129
- });
19147
+ out
19148
+ };
19149
+ if (partials !== void 0) pipelineOptions.partials = partials;
19150
+ if (configGroups !== void 0) pipelineOptions.groups = configGroups;
19151
+ const { discovered, lintResults, prompts } = runGeneratePipeline(pipelineOptions);
19130
19152
  if (!silent) logger.info(`Found ${discovered} prompt(s)`);
19131
19153
  if (!silent) for (const prompt of prompts) {
19132
19154
  const varList = formatVarList(prompt.schema);
@@ -19169,8 +19191,12 @@ var init_generate$1 = __esmMin((() => {
19169
19191
  options: generateArgs,
19170
19192
  handler(ctx) {
19171
19193
  const config = getConfig(ctx);
19194
+ const generateArgs2 = { silent: ctx.args.silent };
19195
+ if (ctx.args.out !== void 0) generateArgs2.out = ctx.args.out;
19196
+ if (ctx.args.includes !== void 0) generateArgs2.includes = ctx.args.includes;
19197
+ if (ctx.args.partials !== void 0) generateArgs2.partials = ctx.args.partials;
19172
19198
  handleGenerate({
19173
- args: ctx.args,
19199
+ args: generateArgs2,
19174
19200
  config: config.prompts,
19175
19201
  logger: ctx.logger,
19176
19202
  fail: ctx.fail
@@ -19193,8 +19219,12 @@ var init_generate = __esmMin((() => {
19193
19219
  const { silent } = ctx.args;
19194
19220
  const config = getConfig(ctx);
19195
19221
  if (!silent) ctx.logger.info("Running prompts code generation...");
19222
+ const generateHandleArgs = { silent: ctx.args.silent };
19223
+ if (ctx.args.out !== void 0) generateHandleArgs.out = ctx.args.out;
19224
+ if (ctx.args.includes !== void 0) generateHandleArgs.includes = ctx.args.includes;
19225
+ if (ctx.args.partials !== void 0) generateHandleArgs.partials = ctx.args.partials;
19196
19226
  handleGenerate({
19197
- args: ctx.args,
19227
+ args: generateHandleArgs,
19198
19228
  config: config.prompts,
19199
19229
  logger: ctx.logger,
19200
19230
  fail: ctx.fail
@@ -19238,7 +19268,7 @@ async function setupPrompts(ctx) {
19238
19268
  mkdirSync(vscodeDir, { recursive: true });
19239
19269
  const extensionsPath = resolve(vscodeDir, EXTENSIONS_FILE);
19240
19270
  const extensions = readJsonFile(extensionsPath);
19241
- const recommendations = ensureRecommendation(extensions.recommendations ?? [], "sissel.shopify-liquid");
19271
+ const recommendations = ensureRecommendation(extensions["recommendations"] ?? [], "sissel.shopify-liquid");
19242
19272
  const updatedExtensions = {
19243
19273
  ...extensions,
19244
19274
  recommendations
@@ -19264,8 +19294,8 @@ async function setupPrompts(ctx) {
19264
19294
  })) {
19265
19295
  const tsconfigPath = resolve(TSCONFIG_FILE);
19266
19296
  const tsconfig = readJsonFile(tsconfigPath);
19267
- const compilerOptions = tsconfig.compilerOptions ?? {};
19268
- const existingPaths = compilerOptions.paths ?? {};
19297
+ const compilerOptions = tsconfig["compilerOptions"] ?? {};
19298
+ const existingPaths = compilerOptions["paths"] ?? {};
19269
19299
  if (existingPaths[PROMPTS_ALIAS]) ctx.logger.info(`${PROMPTS_ALIAS} alias already in ${tsconfigPath}`);
19270
19300
  else {
19271
19301
  const updatedTsconfig = {
@@ -19342,6 +19372,34 @@ var init_setup$1 = __esmMin((() => {
19342
19372
 
19343
19373
  //#endregion
19344
19374
  //#region src/commands/setup.ts
19375
+ /**
19376
+ * Gather prompt include patterns and output directory from the user.
19377
+ *
19378
+ * @private
19379
+ * @param ctx - CLI context for prompts.
19380
+ * @param hasPrompts - Whether the prompts domain is selected.
19381
+ * @returns The resolved prompt settings.
19382
+ */
19383
+ async function resolvePromptSettings(ctx, hasPrompts) {
19384
+ if (!hasPrompts) return {
19385
+ includes: ["src/prompts/**"],
19386
+ out: ".prompts/client"
19387
+ };
19388
+ const includesInput = await ctx.prompts.text({
19389
+ message: "Prompt include patterns (comma-separated)",
19390
+ defaultValue: "src/prompts/**",
19391
+ placeholder: "src/prompts/**"
19392
+ });
19393
+ const out = await ctx.prompts.text({
19394
+ message: "Output directory for generated prompt modules",
19395
+ defaultValue: ".prompts/client",
19396
+ placeholder: ".prompts/client"
19397
+ });
19398
+ return {
19399
+ includes: includesInput.split(",").map((r) => r.trim()),
19400
+ out
19401
+ };
19402
+ }
19345
19403
  /** @private */
19346
19404
  function buildConfigTemplate({ hasPrompts, hasAgents, includes, out }) {
19347
19405
  if (hasPrompts && hasAgents) return buildCustomTemplate(includes, out, true);
@@ -19393,20 +19451,7 @@ export default defineConfig({
19393
19451
  message: "Create funkai.config.ts?",
19394
19452
  initialValue: true
19395
19453
  })) {
19396
- let includes = ["src/prompts/**"];
19397
- let out = ".prompts/client";
19398
- if (hasPrompts) {
19399
- includes = (await ctx.prompts.text({
19400
- message: "Prompt include patterns (comma-separated)",
19401
- defaultValue: "src/prompts/**",
19402
- placeholder: "src/prompts/**"
19403
- })).split(",").map((r) => r.trim());
19404
- out = await ctx.prompts.text({
19405
- message: "Output directory for generated prompt modules",
19406
- defaultValue: ".prompts/client",
19407
- placeholder: ".prompts/client"
19408
- });
19409
- }
19454
+ const { includes, out } = await resolvePromptSettings(ctx, hasPrompts);
19410
19455
  const template = buildConfigTemplate({
19411
19456
  hasPrompts,
19412
19457
  hasAgents,
@@ -19443,12 +19488,16 @@ export default defineConfig({
19443
19488
  * @returns Resolved args with required fields guaranteed.
19444
19489
  */
19445
19490
  function resolveLintArgs(args, config, _fail) {
19446
- return {
19447
- includes: args.includes ?? (config && config.includes) ?? ["./**"],
19448
- excludes: (config && config.excludes) ?? [],
19449
- partials: args.partials ?? (config && config.partials),
19491
+ const includes = args.includes ?? (config && config.includes) ?? ["./**"];
19492
+ const excludes = (config && config.excludes) ?? [];
19493
+ const partials = args.partials ?? (config && config.partials);
19494
+ const resolved = {
19495
+ includes,
19496
+ excludes,
19450
19497
  silent: args.silent
19451
19498
  };
19499
+ if (partials !== void 0) resolved.partials = partials;
19500
+ return resolved;
19452
19501
  }
19453
19502
  /**
19454
19503
  * Shared handler for prompts lint/validation.
@@ -19457,11 +19506,12 @@ function resolveLintArgs(args, config, _fail) {
19457
19506
  */
19458
19507
  function handleLint({ args, config, logger, fail }) {
19459
19508
  const { includes, excludes, partials, silent } = resolveLintArgs(args, config, fail);
19460
- const { discovered, results } = runLintPipeline({
19509
+ const lintPipelineOptions = {
19461
19510
  includes,
19462
- excludes,
19463
- partials
19464
- });
19511
+ excludes
19512
+ };
19513
+ if (partials !== void 0) lintPipelineOptions.partials = partials;
19514
+ const { discovered, results } = runLintPipeline(lintPipelineOptions);
19465
19515
  if (!silent) logger.info(`Linting ${discovered} prompt(s)...`);
19466
19516
  const diagnostics = results.flatMap((result) => result.diagnostics);
19467
19517
  for (const diag of diagnostics) match(diag.level).with("error", () => logger.error(diag.message)).with("warn", () => logger.warn(diag.message)).exhaustive();
@@ -19492,8 +19542,11 @@ var init_lint = __esmMin((() => {
19492
19542
  options: lintArgs,
19493
19543
  handler(ctx) {
19494
19544
  const config = getConfig(ctx);
19545
+ const lintHandleArgs = { silent: ctx.args.silent };
19546
+ if (ctx.args.includes !== void 0) lintHandleArgs.includes = ctx.args.includes;
19547
+ if (ctx.args.partials !== void 0) lintHandleArgs.partials = ctx.args.partials;
19495
19548
  handleLint({
19496
- args: ctx.args,
19549
+ args: lintHandleArgs,
19497
19550
  config: config.prompts,
19498
19551
  logger: ctx.logger,
19499
19552
  fail: ctx.fail
@@ -19516,13 +19569,16 @@ var init_validate$1 = __esmMin((() => {
19516
19569
  const { silent } = ctx.args;
19517
19570
  const config = getConfig(ctx);
19518
19571
  if (!silent) ctx.logger.info("Running prompts validation...");
19572
+ const lintHandleArgs = { silent: ctx.args.silent };
19573
+ if (ctx.args.includes !== void 0) lintHandleArgs.includes = ctx.args.includes;
19574
+ if (ctx.args.partials !== void 0) lintHandleArgs.partials = ctx.args.partials;
19519
19575
  handleLint({
19520
- args: ctx.args,
19576
+ args: lintHandleArgs,
19521
19577
  config: config.prompts,
19522
19578
  logger: ctx.logger,
19523
19579
  fail: ctx.fail
19524
19580
  });
19525
- if (!silent) ctx.logger.success("All validations passed.");
19581
+ if (!silent) ctx.logger.success("No errors found.");
19526
19582
  }
19527
19583
  });
19528
19584
  }));
@@ -19565,6 +19621,7 @@ name: ${name}
19565
19621
  const firstInclude = match(promptsConfig).with({ includes: P.array(P.string).select() }, (includes) => {
19566
19622
  if (includes.length > 0) {
19567
19623
  const [pattern] = includes;
19624
+ if (pattern === void 0) return;
19568
19625
  const staticParts = pattern.split("/").filter((p) => !p.includes("*") && !p.includes("?"));
19569
19626
  if (staticParts.length > 0) return staticParts.join("/");
19570
19627
  return;
@@ -19618,7 +19675,7 @@ var init__virtual_kidd_static_commands = __esmMin((() => {
19618
19675
  }));
19619
19676
 
19620
19677
  //#endregion
19621
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/cli-DhHGZzjZ.js
19678
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/cli-DhHGZzjZ.js
19622
19679
  async function autoload() {
19623
19680
  return (await Promise.resolve().then(() => (init__virtual_kidd_static_commands(), _virtual_kidd_static_commands_exports))).autoload();
19624
19681
  }
@@ -20453,7 +20510,7 @@ function resolveVersion(explicit) {
20453
20510
  return err(VERSION_ERROR);
20454
20511
  }
20455
20512
  {
20456
- const parsed = VersionSchema.safeParse("0.3.0");
20513
+ const parsed = VersionSchema.safeParse("0.3.1");
20457
20514
  if (parsed.success) return ok(parsed.data);
20458
20515
  }
20459
20516
  return err(VERSION_ERROR);
@@ -20628,7 +20685,7 @@ var init_cli_DhHGZzjZ = __esmMin((() => {
20628
20685
  }));
20629
20686
 
20630
20687
  //#endregion
20631
- //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_h5jt7i6rdfwaknd5di57zdj5zy/node_modules/@kidd-cli/core/dist/index.js
20688
+ //#region ../../node_modules/.pnpm/@kidd-cli+core@0.10.0_chokidar@5.0.0_jiti@2.6.1_magicast@0.5.2_vitest@4.1.0_@opentelemetry+ap_ac2wgu34upx3xtuhxg7cvmcnvm/node_modules/@kidd-cli/core/dist/index.js
20632
20689
  var init_dist = __esmMin((() => {
20633
20690
  init_cli_DhHGZzjZ();
20634
20691
  }));