@cms-lab/cli 1.2.1 → 1.2.3

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/README.md CHANGED
@@ -14,6 +14,7 @@ cms-lab init --cms strapi --router pages
14
14
  cms-lab doctor
15
15
  cms-lab doctor --debug --verbose 2
16
16
  cms-lab scan --report
17
+ cms-lab scan --report --share-report
17
18
  cms-lab scan --markdown
18
19
  cms-lab scan --junit
19
20
  cms-lab scan --slack-webhook "$CMS_LAB_SLACK_WEBHOOK"
@@ -23,6 +24,7 @@ cms-lab scan --json --include-sensitive-output
23
24
  cms-lab scan --max-warnings 0
24
25
  cms-lab scan --strict
25
26
  cms-lab agent-context
27
+ cms-lab agent-context --mode cms-only
26
28
  cms-lab agent-context --preset all
27
29
  cms-lab agent-context --preset claude
28
30
  cms-lab agent-context --preset gemini
@@ -51,17 +53,22 @@ unless `--include-sensitive-output` is passed explicitly.
51
53
  CI strictness can be raised with `--fail-on warning`, `--max-warnings <count>`,
52
54
  `--max-info <count>`, or `--strict`.
53
55
 
54
- Exports include local HTML (`--report`), Markdown (`--markdown`), JUnit XML
55
- (`--junit`), and redacted Slack incoming webhook summaries
56
- (`--slack-webhook <url>`). Slack notifications send counts and diagnostic codes
57
- only, never raw CMS payloads, local paths, or webhook URLs.
56
+ Exports include local HTML (`--report`), share-safe local HTML
57
+ (`--report --share-report`), Markdown (`--markdown`), JUnit XML (`--junit`),
58
+ and redacted Slack incoming webhook summaries (`--slack-webhook <url>`).
59
+ Share-safe HTML redacts CMS source IDs and local project paths while keeping
60
+ diagnostic codes, severity, route paths, and field paths visible. Slack
61
+ notifications send counts and diagnostic codes only, never raw CMS payloads,
62
+ local paths, or webhook URLs.
58
63
 
59
64
  `cms-lab agent-context` writes safe handoff files so coding agents can read the
60
65
  cms-lab docs, package links, route mappings, and safe project facts before
61
66
  attempting fixes. The default preset writes `AGENTS.md` plus shared files in
62
67
  `.cms-lab/`. Tool-specific presets can write `CLAUDE.md`, `GEMINI.md`, Copilot
63
68
  instructions, and a reusable Copilot prompt. Existing files are not overwritten
64
- unless `--force` is passed.
69
+ unless `--force` is passed. Use `--mode cms-only` in backend-only CMS projects;
70
+ the generated context will state that no frontend was detected and that route
71
+ scans need a running app.
65
72
 
66
73
  ## Config
67
74
 
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-7YUQWS4P.js";
4
+ } from "./chunk-M5O5QRR3.js";
5
5
 
6
6
  // src/bin.ts
7
7
  var exitCode = await runCli(process.argv.slice(2));
@@ -131,30 +131,34 @@ function renderAgentContextFiles(options) {
131
131
  if (includeAgentsMd) {
132
132
  files.push({
133
133
  path: "AGENTS.md",
134
- content: renderAgentsMd(contextPath, promptPath)
134
+ content: renderAgentsMd(contextPath, promptPath, options.project)
135
135
  });
136
136
  }
137
137
  if (options.preset === "claude" || options.preset === "all") {
138
138
  files.push({
139
139
  path: "CLAUDE.md",
140
- content: renderClaudeMd(contextPath, promptPath)
140
+ content: renderClaudeMd(contextPath, promptPath, options.project)
141
141
  });
142
142
  }
143
143
  if (options.preset === "gemini" || options.preset === "all") {
144
144
  files.push({
145
145
  path: "GEMINI.md",
146
- content: renderGeminiMd(contextPath, promptPath)
146
+ content: renderGeminiMd(contextPath, promptPath, options.project)
147
147
  });
148
148
  }
149
149
  if (options.preset === "copilot" || options.preset === "all") {
150
150
  files.push(
151
151
  {
152
152
  path: ".github/copilot-instructions.md",
153
- content: renderCopilotInstructions(contextPath, promptPath)
153
+ content: renderCopilotInstructions(
154
+ contextPath,
155
+ promptPath,
156
+ options.project
157
+ )
154
158
  },
155
159
  {
156
160
  path: ".github/prompts/cms-lab-fix.prompt.md",
157
- content: renderCopilotPrompt(contextPath, promptPath)
161
+ content: renderCopilotPrompt(contextPath, promptPath, options.project)
158
162
  }
159
163
  );
160
164
  }
@@ -170,10 +174,10 @@ function renderAgentContextFiles(options) {
170
174
  );
171
175
  return files;
172
176
  }
173
- function renderAgentsMd(contextPath, promptPath) {
177
+ function renderAgentsMd(contextPath, promptPath, project) {
174
178
  return `# cms-lab agent handoff
175
179
 
176
- This project uses cms-lab to check CMS content against the routes and fields the Next.js app expects.
180
+ ${agentProjectSummary(project)}
177
181
 
178
182
  Before changing code for CMS-related failures:
179
183
 
@@ -184,47 +188,47 @@ Before changing code for CMS-related failures:
184
188
  - npm: ${NPM_URL}
185
189
  - Docs: ${DOCS_URL}
186
190
  4. Run \`npx @cms-lab/cli doctor\` before a first scan.
187
- 5. Run \`npx @cms-lab/cli scan --ci --report\` to reproduce diagnostics.
191
+ 5. ${agentScanInstruction(project)}
188
192
  6. Use \`npx @cms-lab/cli explain <CODE>\` for diagnostic details.
189
193
 
190
194
  Do not print or commit CMS tokens, webhook URLs, private site URLs, raw CMS payloads, or local absolute paths.
191
195
  `;
192
196
  }
193
- function renderClaudeMd(contextPath, promptPath) {
197
+ function renderClaudeMd(contextPath, promptPath, project) {
194
198
  return `# cms-lab Claude Code context
195
199
 
196
200
  @${contextPath}
197
201
  @${promptPath}
198
202
 
199
- Use these cms-lab files before changing code for CMS route, field, SEO, or report diagnostics. Run \`npx @cms-lab/cli doctor\` first when connecting a project, then run \`npx @cms-lab/cli scan --ci --report\` to reproduce the current diagnostics.
203
+ Use these cms-lab files before changing code for CMS route, field, SEO, or report diagnostics. ${toolScanGuidance(project)}
200
204
 
201
205
  Do not print or commit CMS tokens, webhook URLs, private site URLs, raw CMS payloads, or local absolute paths.
202
206
  `;
203
207
  }
204
- function renderGeminiMd(contextPath, promptPath) {
208
+ function renderGeminiMd(contextPath, promptPath, project) {
205
209
  return `# cms-lab Gemini CLI context
206
210
 
207
211
  @${contextPath}
208
212
  @${promptPath}
209
213
 
210
- Use these cms-lab files before changing code for CMS route, field, SEO, or report diagnostics. Run \`npx @cms-lab/cli doctor\` first when connecting a project, then run \`npx @cms-lab/cli scan --ci --report\` to reproduce the current diagnostics.
214
+ Use these cms-lab files before changing code for CMS route, field, SEO, or report diagnostics. ${toolScanGuidance(project)}
211
215
 
212
216
  Do not print or commit CMS tokens, webhook URLs, private site URLs, raw CMS payloads, or local absolute paths.
213
217
  `;
214
218
  }
215
- function renderCopilotInstructions(contextPath, promptPath) {
219
+ function renderCopilotInstructions(contextPath, promptPath, project) {
216
220
  return `# cms-lab Copilot instructions
217
221
 
218
- This project uses cms-lab to check CMS content against the routes and fields the Next.js app expects.
222
+ ${agentProjectSummary(project)}
219
223
 
220
224
  - Read \`${contextPath}\` before changing code for CMS diagnostics.
221
225
  - Use \`${promptPath}\` when asked to investigate a cms-lab failure.
222
- - Prefer reproducing with \`npx @cms-lab/cli scan --ci --report\` before editing application code.
226
+ - ${toolScanBullet(project)}
223
227
  - Use \`npx @cms-lab/cli explain <CODE>\` before deciding where a diagnostic should be fixed.
224
228
  - Do not print or commit CMS tokens, webhook URLs, private site URLs, raw CMS payloads, or local absolute paths.
225
229
  `;
226
230
  }
227
- function renderCopilotPrompt(contextPath, promptPath) {
231
+ function renderCopilotPrompt(contextPath, promptPath, project) {
228
232
  return `# Fix cms-lab diagnostics
229
233
 
230
234
  Use this prompt when investigating cms-lab diagnostics in this repository.
@@ -232,7 +236,7 @@ Use this prompt when investigating cms-lab diagnostics in this repository.
232
236
  1. Read \`${contextPath}\`.
233
237
  2. Read \`${promptPath}\`.
234
238
  3. Run \`npx @cms-lab/cli doctor\`.
235
- 4. Run \`npx @cms-lab/cli scan --ci --report\`.
239
+ 4. ${toolPromptScanStep(project)}
236
240
  5. For each diagnostic code, run \`npx @cms-lab/cli explain <CODE>\`.
237
241
  6. Decide whether the fix belongs in CMS content, cms-lab route mapping, or application code.
238
242
  7. Make the smallest verifiable change and rerun cms-lab.
@@ -254,7 +258,7 @@ Use this file to orient coding agents before they work on CMS route, field, SEO,
254
258
  ## Project scan model
255
259
 
256
260
  - Config file: ${options.configFile}
257
- - Framework: ${projectLabel(options.project)}
261
+ ${projectFact(options.project)}
258
262
  - CMS provider: ${options.config.cms.provider}
259
263
  - Site URL: configured in cms-lab config (redacted)
260
264
 
@@ -272,11 +276,13 @@ ${checksSummary(options.config)}
272
276
 
273
277
  \`\`\`sh
274
278
  npx @cms-lab/cli doctor
275
- npx @cms-lab/cli scan --ci --report
279
+ ${options.project ? "npx @cms-lab/cli scan --ci --report" : "# Add or start the frontend before running route scans"}
276
280
  npx @cms-lab/cli scan --json
277
281
  npx @cms-lab/cli explain CMS-ROUTE-404
278
282
  \`\`\`
279
283
 
284
+ ${options.project ? "" : "Route scans require a running frontend. Use this context to document the CMS shape now, then add route mappings and scan commands once the frontend exists.\n"}
285
+
280
286
  ## Agent workflow
281
287
 
282
288
  - Read the cms-lab config and this context before editing application code.
@@ -289,7 +295,7 @@ npx @cms-lab/cli explain CMS-ROUTE-404
289
295
  function renderPromptFile(options) {
290
296
  return `# cms-lab agent prompt
291
297
 
292
- You are working in a Next.js project that uses cms-lab to catch CMS-driven failures before deploy.
298
+ ${promptProjectSummary(options.project)}
293
299
 
294
300
  This prompt is suitable for agents such as Claude Code, Codex, Gemini CLI, Antigravity, OpenCode, and similar coding agents.
295
301
 
@@ -308,10 +314,12 @@ npx @cms-lab/cli scan --ci --report
308
314
 
309
315
  Project facts:
310
316
 
311
- - Framework: ${projectLabel(options.project)}
317
+ ${projectFact(options.project)}
312
318
  - CMS provider: ${options.config.cms.provider}
313
319
  - Route mappings: ${options.config.routes.map((route) => `${route.type} -> ${route.pattern}`).join(", ")}
314
320
 
321
+ ${options.project ? "" : "Add frontend route config before running route scans. The frontend has not been detected yet, so use this context for CMS schema, collection, and route-planning work first.\n"}
322
+
315
323
  When diagnostics appear, use \`npx @cms-lab/cli explain <CODE>\` before deciding whether the fix belongs in CMS content, route mapping, or application code.
316
324
 
317
325
  Never reveal CMS tokens, private site URLs, webhook URLs, raw CMS payloads, or local absolute paths in commits, issues, pull requests, logs, or summaries.
@@ -399,6 +407,48 @@ function projectLabel(project) {
399
407
  }
400
408
  return `${project.framework} ${project.router}`;
401
409
  }
410
+ function projectFact(project) {
411
+ if (!project) {
412
+ return "- Frontend: not detected";
413
+ }
414
+ return `- Framework: ${projectLabel(project)}`;
415
+ }
416
+ function agentProjectSummary(project) {
417
+ if (!project) {
418
+ return "This project uses cms-lab to describe CMS content expectations before a frontend has been detected.";
419
+ }
420
+ return "This project uses cms-lab to check CMS content against the routes and fields the Next.js app expects.";
421
+ }
422
+ function agentScanInstruction(project) {
423
+ if (!project) {
424
+ return "Add or start the frontend before running route scans.";
425
+ }
426
+ return "Run `npx @cms-lab/cli scan --ci --report` to reproduce diagnostics.";
427
+ }
428
+ function promptProjectSummary(project) {
429
+ if (!project) {
430
+ return "You are working in a CMS/backend project where the frontend has not been detected yet. Use cms-lab to document the CMS shape and prepare route checks before deploy.";
431
+ }
432
+ return "You are working in a Next.js project that uses cms-lab to catch CMS-driven failures before deploy.";
433
+ }
434
+ function toolScanGuidance(project) {
435
+ if (!project) {
436
+ return "The frontend has not been detected yet; run `npx @cms-lab/cli doctor` for config checks and add or start the frontend before route scans.";
437
+ }
438
+ return "Run `npx @cms-lab/cli doctor` first when connecting a project, then run `npx @cms-lab/cli scan --ci --report` to reproduce the current diagnostics.";
439
+ }
440
+ function toolScanBullet(project) {
441
+ if (!project) {
442
+ return "The frontend has not been detected yet; use the context for CMS setup work and add or start the frontend before route scans.";
443
+ }
444
+ return "Prefer reproducing with `npx @cms-lab/cli scan --ci --report` before editing application code.";
445
+ }
446
+ function toolPromptScanStep(project) {
447
+ if (!project) {
448
+ return "The frontend has not been detected yet; add or start it before running `npx @cms-lab/cli scan --ci --report`.";
449
+ }
450
+ return "Run `npx @cms-lab/cli scan --ci --report`.";
451
+ }
402
452
  function trimSlashes(value) {
403
453
  let start = 0;
404
454
  let end = value.length;
@@ -515,7 +565,7 @@ var noColor = {
515
565
  // src/index.ts
516
566
  async function runCli(argv, dependencies = {}) {
517
567
  let exitCode = 0;
518
- const program = new Command().name("cms-lab").description("Catch CMS bugs before deploy.").version("1.2.1").exitOverride().configureOutput({
568
+ const program = new Command().name("cms-lab").description("Catch CMS bugs before deploy.").version("1.2.3").exitOverride().configureOutput({
519
569
  writeOut: (text) => writeStdout(dependencies, text),
520
570
  writeErr: (text) => writeStderr(dependencies, text)
521
571
  });
@@ -547,6 +597,9 @@ Examples:
547
597
  ).option(
548
598
  "--report [path]",
549
599
  "Write an HTML report. Defaults to .cms-lab/report.html"
600
+ ).option(
601
+ "--share-report",
602
+ "Redact CMS source IDs and local project paths in the HTML report"
550
603
  ).option(
551
604
  "--markdown [path]",
552
605
  "Write a Markdown summary. Defaults to .cms-lab/summary.md"
@@ -634,7 +687,7 @@ Examples:
634
687
  ).action(async (options) => {
635
688
  exitCode = await runInit(options, dependencies);
636
689
  });
637
- program.command("agent-context").description("Generate AI-agent handoff files for cms-lab projects.").option("--config <path>", "Path to cms-lab config file").option(
690
+ program.command("agent-context").description("Generate AI-agent handoff files for cms-lab projects.").option("--config <path>", "Path to cms-lab config file").option("--mode <mode>", "Project mode: auto, next, or cms-only", "auto").option(
638
691
  "--out <dir>",
639
692
  "Directory for generated cms-lab agent files",
640
693
  ".cms-lab"
@@ -648,6 +701,7 @@ Examples:
648
701
  Examples:
649
702
  cms-lab agent-context
650
703
  cms-lab agent-context --config cms-lab.config.ts
704
+ cms-lab agent-context --mode cms-only
651
705
  cms-lab agent-context --preset all
652
706
  cms-lab agent-context --preset claude
653
707
  cms-lab agent-context --preset copilot
@@ -758,7 +812,9 @@ async function runScan(options, dependencies) {
758
812
  });
759
813
  const status = exitCode === 0 ? "passed" : "failed";
760
814
  const endReport = debug.time("exports", 2);
761
- await maybeWriteReport(options.report, result, cwd);
815
+ await maybeWriteReport(options.report, result, cwd, {
816
+ share: Boolean(options.shareReport)
817
+ });
762
818
  await maybeWriteMarkdown(options.markdown, result, status, cwd);
763
819
  await maybeWriteJUnit(options.junit, result, cwd);
764
820
  const slackSent = await maybePostSlack({
@@ -1003,12 +1059,20 @@ async function runInit(options, dependencies) {
1003
1059
  async function runAgentContext(options, dependencies) {
1004
1060
  const cwd = dependencies.cwd ?? process.cwd();
1005
1061
  try {
1062
+ const mode = parseAgentContextMode(options.mode);
1006
1063
  const loaded = await loadCmsLabConfig({ cwd, configPath: options.config });
1007
- const project = await detectNextProject(cwd);
1008
- assertConfiguredRouterMatchesProject(
1009
- loaded.config.framework.router,
1010
- project
1011
- );
1064
+ const project = mode === "cms-only" ? void 0 : await detectOptionalNextProject(cwd, mode);
1065
+ if (project) {
1066
+ assertConfiguredRouterMatchesProject(
1067
+ loaded.config.framework.router,
1068
+ project
1069
+ );
1070
+ } else {
1071
+ writeStdout(
1072
+ dependencies,
1073
+ "No Next.js project detected; generating CMS-only agent context.\n"
1074
+ );
1075
+ }
1012
1076
  const files = renderAgentContextFiles({
1013
1077
  config: loaded.config,
1014
1078
  project,
@@ -1059,6 +1123,23 @@ async function runAgentContext(options, dependencies) {
1059
1123
  return 2;
1060
1124
  }
1061
1125
  }
1126
+ function parseAgentContextMode(value) {
1127
+ const mode = value ?? "auto";
1128
+ if (mode === "auto" || mode === "next" || mode === "cms-only") {
1129
+ return mode;
1130
+ }
1131
+ throw new ConfigLoadError("--mode must be one of: auto, next, cms-only");
1132
+ }
1133
+ async function detectOptionalNextProject(cwd, mode) {
1134
+ try {
1135
+ return await detectNextProject(cwd);
1136
+ } catch (error) {
1137
+ if (mode === "next" || !(error instanceof ConfigLoadError)) {
1138
+ throw error;
1139
+ }
1140
+ return void 0;
1141
+ }
1142
+ }
1062
1143
  function writeStdout(dependencies, text) {
1063
1144
  if (dependencies.stdout) {
1064
1145
  dependencies.stdout(text);
@@ -1428,13 +1509,17 @@ function exitCodeForResult(result, options) {
1428
1509
  function thresholdExceeded(result, maxWarnings, maxInfo) {
1429
1510
  return maxWarnings !== void 0 && result.summary.warnings > maxWarnings || maxInfo !== void 0 && result.summary.info > maxInfo;
1430
1511
  }
1431
- async function maybeWriteReport(report, result, cwd) {
1512
+ async function maybeWriteReport(report, result, cwd, options = {}) {
1432
1513
  if (!report) {
1433
1514
  return;
1434
1515
  }
1435
1516
  const path = reportPathFromOption(report, cwd);
1436
1517
  await mkdir(dirname(path), { recursive: true });
1437
- await writeFile(path, renderHtmlReport(result), "utf8");
1518
+ await writeFile(
1519
+ path,
1520
+ renderHtmlReport(result, { privacy: options.share ? "share" : "full" }),
1521
+ "utf8"
1522
+ );
1438
1523
  }
1439
1524
  function reportPathFromOption(report, cwd) {
1440
1525
  return resolve(
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runCli
3
- } from "./chunk-7YUQWS4P.js";
3
+ } from "./chunk-M5O5QRR3.js";
4
4
  export {
5
5
  runCli
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cms-lab/cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "type": "module",
5
5
  "description": "Catch CMS bugs before deploy.",
6
6
  "license": "MIT",
@@ -47,15 +47,15 @@
47
47
  "dependencies": {
48
48
  "commander": "^14.0.2",
49
49
  "picocolors": "^1.1.1",
50
- "@cms-lab/directus": "1.2.1",
51
- "@cms-lab/next": "1.2.1",
52
- "@cms-lab/contentful": "1.2.1",
53
- "@cms-lab/prismic": "1.2.1",
54
- "@cms-lab/core": "1.2.1",
55
- "@cms-lab/reporter": "1.2.1",
56
- "@cms-lab/wordpress": "1.2.1",
57
- "@cms-lab/strapi": "1.2.1",
58
- "@cms-lab/sanity": "1.2.1"
50
+ "@cms-lab/contentful": "1.2.3",
51
+ "@cms-lab/core": "1.2.3",
52
+ "@cms-lab/prismic": "1.2.3",
53
+ "@cms-lab/reporter": "1.2.3",
54
+ "@cms-lab/sanity": "1.2.3",
55
+ "@cms-lab/strapi": "1.2.3",
56
+ "@cms-lab/next": "1.2.3",
57
+ "@cms-lab/wordpress": "1.2.3",
58
+ "@cms-lab/directus": "1.2.3"
59
59
  },
60
60
  "author": "Afaq Rashid",
61
61
  "scripts": {