delivery-friction-analyzer 0.26.0 → 0.27.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "delivery-friction-analyzer",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Local GitHub pull request analytics for delivery friction reports.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/release-log.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ### 2026-07-04 — Guided Setup Guard Clarity
6
+
7
+ - What changed: Interactive setup now stops as soon as users enter this tool's product repository, explains that no GitHub data was collected and no files were written, and keeps Conventional Commit PR class setup as a short prompt with detailed `?` help.
8
+ - Why it matters: First-time users and maintainers get the blocking self-analysis decision before answering unrelated setup questions, while PR class setup stays easier to answer without losing the guidance needed to avoid misleading classifications.
9
+ - Who is affected: Users running `--interactive` live GitHub setup, especially when they enter the analyzer's own repository or review the optional Conventional Commit PR class preset.
10
+ - Action needed: None.
11
+ - PR: https://github.com/hannasdev/delivery-friction-analyzer/pull/74
12
+
5
13
  ### 2026-07-04 — Local Sample Checkout Command
6
14
 
7
15
  - What changed: Local checkouts now expose `npm run sample` for the bundled tutorial sample, while README guidance keeps the public `npx` package path first and shows checkout usage separately.
@@ -38,7 +38,8 @@ const PACKAGE_JSON_URL = new URL("../../package.json", import.meta.url);
38
38
  const SAMPLE_SOURCE_BUNDLE_URL = new URL("../../examples/tutorial/source-bundle.json", import.meta.url);
39
39
  const SAMPLE_PROFILE_URL = new URL("../../examples/tutorial/profile.json", import.meta.url);
40
40
  const STARTER_PROFILE_PROMPT_COPY = "Starter profiles are valid, but until you add rules the report may classify PR classes, file roles, and functional surfaces as unknown.";
41
- const CONVENTIONAL_COMMIT_PRESET_PROMPT_COPY = "Add Conventional Commit PR class rules?\nUse this when PR titles usually start with feat:, fix:, docs:, test:, chore(deps):, or similar prefixes.\nIt writes title-based dependency, feature, fix, docs, test, and maintenance classes so fewer PRs are classified as unknown.\nSkip it for release titles, ticket prefixes, free-form titles, or another custom PR taxonomy.\nIt does not change scoring, rankings, GitHub collection, or CSV export shape.";
41
+ const CONVENTIONAL_COMMIT_PRESET_PROMPT_COPY = "Add Conventional Commit PR class rules? Use this only when PR titles usually start with prefixes like feat:, fix:, docs:, test:, or chore(deps):.";
42
+ const CONVENTIONAL_COMMIT_PRESET_HELP_COPY = "Writes title-based dependency, feature, fix, docs, test, and maintenance PR class rules to the repository profile. Accept only when most PR titles use Conventional Commit prefixes such as feat:, fix:, docs:, test:, or chore(deps):. Skip for release titles, ticket prefixes, free-form titles, or another custom PR taxonomy. Existing PR class rules are kept. This changes profile interpretation only; it does not change scoring, rankings, GitHub collection, or CSV export shape.";
42
43
  const STARTER_PROFILE_COMPLETION_COPY = "Created a starter profile. Review or refine it before relying on report labels for PR classes, file roles, or functional surfaces.";
43
44
  const MISSING_PROFILE_GUIDANCE = `Live GitHub analysis needs a repository-profile.v1 JSON file.
44
45
  Run with --interactive to create a starter profile, or pass --profile path/to/profile.json.
@@ -1058,15 +1059,11 @@ function withAvailablePrClassRuleIds(profile, rules) {
1058
1059
  }
1059
1060
 
1060
1061
  async function promptConventionalCommitPrClassPreset(promptAdapter, output, profile) {
1061
- const hasExistingPrClasses = Array.isArray(profile.prClasses) && profile.prClasses.length > 0;
1062
- const message = hasExistingPrClasses
1063
- ? `${CONVENTIONAL_COMMIT_PRESET_PROMPT_COPY} Existing PR class rules will be kept.`
1064
- : CONVENTIONAL_COMMIT_PRESET_PROMPT_COPY;
1065
1062
  const shouldAddPreset = await askUntilValid(promptAdapter, {
1066
1063
  id: "addConventionalCommitPrClasses",
1067
1064
  type: "confirm",
1068
- message,
1069
- help: "Optional profile setup: add reusable title rules when Conventional Commit prefixes match this repository. This changes profile classification only, not scoring or GitHub collection.",
1065
+ message: CONVENTIONAL_COMMIT_PRESET_PROMPT_COPY,
1066
+ help: CONVENTIONAL_COMMIT_PRESET_HELP_COPY,
1070
1067
  defaultValue: false,
1071
1068
  }, {
1072
1069
  output,
@@ -1318,6 +1315,13 @@ function shouldPromptInteractiveOption(options, key) {
1318
1315
  return !hasOwnOption(options, key);
1319
1316
  }
1320
1317
 
1318
+ function rejectInteractiveProductRepository(repository, { productRepository, allowProductRepository = false } = {}) {
1319
+ const targetInput = targetInputFromRepositorySlug(repository);
1320
+ if (!allowProductRepository && isProductRepositoryTarget(targetInput, productRepository ?? DEFAULT_PRODUCT_REPOSITORY)) {
1321
+ throw new Error(productRepositoryTargetError(targetInput));
1322
+ }
1323
+ }
1324
+
1321
1325
  export async function collectInteractiveAnalyzeGithubOptions(options, {
1322
1326
  promptAdapter = null,
1323
1327
  input = process.stdin,
@@ -1350,6 +1354,10 @@ export async function collectInteractiveAnalyzeGithubOptions(options, {
1350
1354
  validate: validateRepositorySlug,
1351
1355
  });
1352
1356
  }
1357
+ rejectInteractiveProductRepository(resolved.repository, {
1358
+ productRepository: options.productRepository,
1359
+ allowProductRepository: options.allowProductRepository,
1360
+ });
1353
1361
 
1354
1362
  if (resolved.limit === undefined) {
1355
1363
  resolved.limit = await askUntilValid(adapter, {
@@ -103,10 +103,12 @@ export function productRepositoryTargetError(input) {
103
103
  : "the requested repository";
104
104
  return `Cannot analyze ${repository} because it is this tool's product repository. The guard prevents accidental self-analysis during normal live runs; it is not a data-security boundary.
105
105
 
106
+ No GitHub data was collected, and no files were written.
107
+
106
108
  To learn the tool, run the bundled sample:
107
109
  delivery-friction-analyzer --source sample --out reports/tutorial
108
110
 
109
111
  To analyze a different repository, pass --repo owner/name.
110
112
 
111
- If you intentionally want to analyze this product repository, rerun with --allow-product-repository. The CLI will check that required data is readable before writing artifacts. No GitHub data was collected.`;
113
+ If you intentionally want to analyze this product repository, rerun with --allow-product-repository. The CLI will check that required data is readable before writing artifacts.`;
112
114
  }