contentrain 0.17.0 → 0.18.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/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { i as pc } from "./ui-B8l_LC36.mjs";
3
3
  import { defineCommand, runMain } from "citty";
4
4
  //#region package.json
5
- var version = "0.17.0";
5
+ var version = "0.18.0";
6
6
  //#endregion
7
7
  //#region src/utils/debug.ts
8
8
  /**
@@ -43,7 +43,7 @@ runMain(defineCommand({
43
43
  description: "Contentrain CLI — AI content governance infrastructure"
44
44
  },
45
45
  subCommands: {
46
- init: () => import("./init-CqQgYoJq.mjs").then((m) => m.default),
46
+ init: () => import("./init-CBOoHnjq.mjs").then((m) => m.default),
47
47
  import: () => import("./import-DXA71z9x.mjs").then((m) => m.default),
48
48
  delta: () => import("./delta-D6Cp9BdP.mjs").then((m) => m.default),
49
49
  status: () => import("./status-DSzoldCi.mjs").then((m) => m.default),
@@ -8,6 +8,7 @@ import { join } from "node:path";
8
8
  import { writeModel } from "@contentrain/mcp/core/model-manager";
9
9
  import { ensureDir, pathExists, writeJson } from "@contentrain/mcp/util/fs";
10
10
  import { createGit } from "@contentrain/mcp/git/identity";
11
+ import { LOCALE_PATTERN } from "@contentrain/types";
11
12
  import { buildBranchName, createTransaction } from "@contentrain/mcp/git/transaction";
12
13
  import { detectStackInfo } from "@contentrain/mcp/util/detect";
13
14
  import { getTemplate, listTemplates } from "@contentrain/mcp/templates";
@@ -83,11 +84,32 @@ var init_default = defineCommand({
83
84
  type: "boolean",
84
85
  description: "Skip prompts, use defaults",
85
86
  required: false
87
+ },
88
+ locales: {
89
+ type: "string",
90
+ description: "Supported locales, comma-separated; the first is the default (e.g. \"tr\" or \"en,tr\"). Default: en",
91
+ required: false
92
+ },
93
+ domains: {
94
+ type: "string",
95
+ description: "Content domains, comma-separated (e.g. \"docs\"). Default: marketing,blog,system",
96
+ required: false
86
97
  }
87
98
  },
88
99
  async run({ args }) {
89
100
  const projectRoot = await resolveProjectRoot(args.root);
90
101
  intro(pc.bold("contentrain init"));
102
+ let flagLocales;
103
+ let flagDomains;
104
+ try {
105
+ flagLocales = parseListFlag(args.locales, "locale");
106
+ flagDomains = parseListFlag(args.domains, "domain");
107
+ } catch (error) {
108
+ log.error(error instanceof Error ? error.message : String(error));
109
+ process.exitCode = 1;
110
+ outro("");
111
+ return;
112
+ }
91
113
  if ((await loadProjectContext(projectRoot)).initialized) {
92
114
  log.warning("Project already initialized.");
93
115
  log.message(`Run ${pc.cyan("contentrain status")} to see current state.`);
@@ -101,17 +123,7 @@ var init_default = defineCommand({
101
123
  if (info.monorepo) log.info(`Monorepo: ${pc.green("Yes")}${info.monorepoTool ? ` (${info.monorepoTool})` : ""}`);
102
124
  if (info.features.length > 0) log.info(`Features: ${info.features.map((f) => pc.dim(f)).join(", ")}`);
103
125
  if (args.yes) {
104
- await executeInit(projectRoot, {
105
- stack: info.stack,
106
- locales: ["en"],
107
- domains: [
108
- "marketing",
109
- "blog",
110
- "system"
111
- ],
112
- workflow: "auto-merge",
113
- template: null
114
- });
126
+ await executeInit(projectRoot, defaultInitOptions(info.stack, flagLocales, flagDomains));
115
127
  outro(pc.green("Initialized with defaults!"));
116
128
  return;
117
129
  }
@@ -192,7 +204,7 @@ var init_default = defineCommand({
192
204
  initialValue: info.stack
193
205
  });
194
206
  if (isCancel(stackChoice)) return handleCancel();
195
- const localeChoices = await multiselect({
207
+ const localeChoices = flagLocales ?? await multiselect({
196
208
  message: "Supported locales",
197
209
  options: COMMON_LOCALES.map((l) => ({
198
210
  value: l.value,
@@ -202,7 +214,7 @@ var init_default = defineCommand({
202
214
  required: true
203
215
  });
204
216
  if (isCancel(localeChoices)) return handleCancel();
205
- const domainChoices = await multiselect({
217
+ const domainChoices = flagDomains ?? await multiselect({
206
218
  message: "Content domains",
207
219
  options: [
208
220
  {
@@ -287,6 +299,21 @@ var init_default = defineCommand({
287
299
  outro("");
288
300
  }
289
301
  });
302
+ const DOMAIN_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
303
+ /**
304
+ * A comma-separated `--locales` / `--domains` value as a list: trimmed, empty items and repeats dropped, order kept
305
+ * (the first locale is the default). `undefined` when the flag was not given; throws on an invalid item, so a typo
306
+ * never becomes a config value.
307
+ */
308
+ function parseListFlag(value, kind) {
309
+ if (value === void 0) return void 0;
310
+ const items = [...new Set(String(value).split(",").map((item) => item.trim()).filter(Boolean))];
311
+ if (items.length === 0) throw new Error(`--${kind}s needs at least one ${kind}`);
312
+ const pattern = kind === "locale" ? LOCALE_PATTERN : DOMAIN_PATTERN;
313
+ const bad = items.filter((item) => !pattern.test(item));
314
+ if (bad.length > 0) throw new Error(kind === "locale" ? `Invalid locale ${bad.map((b) => `"${b}"`).join(", ")}: use ISO 639-1 codes such as "en", "tr" or "pt-BR"` : `Invalid domain ${bad.map((b) => `"${b}"`).join(", ")}: use lowercase letters, digits and hyphens, such as "docs" or "marketing"`);
315
+ return items;
316
+ }
290
317
  /**
291
318
  * Print stack-aware guidance for wiring the generated `#contentrain` client
292
319
  * into the host project. Init does not mutate the host's bundler config or
@@ -314,6 +341,20 @@ function printStackWiring(stack) {
314
341
  log.message(pc.dim(" \"scripts\": { \"prebuild\": \"contentrain generate\", \"predev\": \"contentrain generate\" }"));
315
342
  if (stack === "nuxt") log.message(pc.dim(" Note (Nuxt): treat #contentrain as server-only — use it under server/ (e.g. server/api/*)."));
316
343
  }
344
+ /** What `init --yes` writes: the defaults, with `--locales` / `--domains` taking their place when given. */
345
+ function defaultInitOptions(stack, locales, domains) {
346
+ return {
347
+ stack,
348
+ locales: locales ?? ["en"],
349
+ domains: domains ?? [
350
+ "marketing",
351
+ "blog",
352
+ "system"
353
+ ],
354
+ workflow: "auto-merge",
355
+ template: null
356
+ };
357
+ }
317
358
  async function executeInit(projectRoot, opts) {
318
359
  const s = spinner();
319
360
  s.start("Initializing...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentrain",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "license": "MIT",
5
5
  "description": "CLI for Contentrain — AI content governance infrastructure",
6
6
  "type": "module",
@@ -47,12 +47,12 @@
47
47
  "simple-git": "^3.27.0",
48
48
  "ws": "^8.18.0",
49
49
  "zod": "^3.24.0",
50
- "@contentrain/mcp": "3.10.1",
50
+ "@contentrain/mcp": "3.11.0",
51
+ "@contentrain/query": "7.6.43",
51
52
  "@contentrain/rules": "0.7.3",
52
- "@contentrain/query": "7.6.42",
53
53
  "@contentrain/skills": "0.9.6",
54
- "@contentrain/types": "1.62.0",
55
- "@contentrain/wp-import": "0.13.0"
54
+ "@contentrain/types": "1.63.0",
55
+ "@contentrain/wp-import": "0.14.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/ws": "^8.5.0",