slopbrick 0.18.5 → 0.18.7

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.
@@ -34757,6 +34757,9 @@ var expiredCodeExampleRule = createRule({
34757
34757
  const issues = [];
34758
34758
  const source = facts.v2?._source;
34759
34759
  if (!source) return issues;
34760
+ const packages = declaredPackages(context.cwd);
34761
+ const packageName = context.packageName;
34762
+ if (packageName) packages.add(packageName);
34760
34763
  const blocks = extractFencedCodeBlocks(source);
34761
34764
  for (const block of blocks) {
34762
34765
  if (!CODE_LANGS.has(block.lang)) continue;
@@ -34764,7 +34767,7 @@ var expiredCodeExampleRule = createRule({
34764
34767
  const imports = extractImports(block.body);
34765
34768
  for (const imp of imports) {
34766
34769
  const pkgName = stripSubpath(imp);
34767
- if (context.packages.has(pkgName)) continue;
34770
+ if (packages.has(pkgName)) continue;
34768
34771
  issues.push({
34769
34772
  ruleId: "docs/expired-code-example",
34770
34773
  category: "docs",
@@ -34785,6 +34788,7 @@ var expiredCodeExampleRule = createRule({
34785
34788
  var import_node_fs4 = require("fs");
34786
34789
  var import_node_path4 = require("path");
34787
34790
  var RESERVED = /* @__PURE__ */ new Set([
34791
+ // JS reserved words
34788
34792
  "true",
34789
34793
  "false",
34790
34794
  "null",
@@ -34884,7 +34888,472 @@ var RESERVED = /* @__PURE__ */ new Set([
34884
34888
  "next",
34885
34889
  "vue",
34886
34890
  "angular",
34887
- "svelte"
34891
+ "svelte",
34892
+ // Framework / runtime names
34893
+ "html",
34894
+ "astro",
34895
+ "python",
34896
+ "jvm",
34897
+ "kotlin",
34898
+ "swift",
34899
+ "dart",
34900
+ "ruby",
34901
+ "rust",
34902
+ "cpp",
34903
+ "go",
34904
+ "java",
34905
+ "php",
34906
+ "php-html",
34907
+ "csharp",
34908
+ "typescript",
34909
+ "javascript",
34910
+ "jsx",
34911
+ "tsx",
34912
+ "mjs",
34913
+ "cjs",
34914
+ "esnext",
34915
+ "es6",
34916
+ "es2022",
34917
+ "es2023",
34918
+ "esm",
34919
+ "cjs",
34920
+ "umd",
34921
+ "amd",
34922
+ "commonjs",
34923
+ "require",
34924
+ "module",
34925
+ "exports",
34926
+ "define",
34927
+ "global",
34928
+ "window",
34929
+ "document",
34930
+ "process",
34931
+ "console",
34932
+ "buffer",
34933
+ "stream",
34934
+ "fetch",
34935
+ "axios",
34936
+ "express",
34937
+ "fastify",
34938
+ "koa",
34939
+ "hapi",
34940
+ "nextjs",
34941
+ "nuxt",
34942
+ "remix",
34943
+ "gatsby",
34944
+ "sveltekit",
34945
+ "solid",
34946
+ "preact",
34947
+ "qwik",
34948
+ "lit",
34949
+ "stencil",
34950
+ "marko",
34951
+ "alpine",
34952
+ "stimulus",
34953
+ "turbo",
34954
+ "hotwire",
34955
+ // Models / providers
34956
+ "gpt",
34957
+ "claude",
34958
+ "gpt-3",
34959
+ "gpt-3.5",
34960
+ "gpt-4",
34961
+ "gpt-oss",
34962
+ "haiku",
34963
+ "sonnet",
34964
+ "opus",
34965
+ "aider",
34966
+ "tabby",
34967
+ "copilot",
34968
+ "cursor",
34969
+ "windsurf",
34970
+ "devin",
34971
+ "claude-code",
34972
+ // LLM-detection lingo
34973
+ "heuristic",
34974
+ "heuristics",
34975
+ "calibrate",
34976
+ "calibration",
34977
+ "calibrator",
34978
+ "corpus",
34979
+ "baseline",
34980
+ "baselines",
34981
+ "corpus-baselines",
34982
+ "lift",
34983
+ "recall",
34984
+ "precision",
34985
+ "fpRate",
34986
+ "ratio",
34987
+ "verdict",
34988
+ "USEFUL",
34989
+ "NOISY",
34990
+ "INVERTED",
34991
+ "HYGIENE",
34992
+ "DORMANT",
34993
+ "OK",
34994
+ "aiSpecific",
34995
+ "defaultOff",
34996
+ // Common slop-audit verbs/nouns
34997
+ "commit",
34998
+ "push",
34999
+ "reset",
35000
+ "rebase",
35001
+ "merge",
35002
+ "cherry-pick",
35003
+ "revert",
35004
+ "scan",
35005
+ "parse",
35006
+ "build",
35007
+ "test",
35008
+ "lint",
35009
+ "format",
35010
+ "check",
35011
+ "audit",
35012
+ "fix",
35013
+ "patch",
35014
+ "diff",
35015
+ "pr",
35016
+ "ci",
35017
+ "cd",
35018
+ "gh",
35019
+ "npm",
35020
+ "npx",
35021
+ "pnpm",
35022
+ "yaml",
35023
+ "json",
35024
+ "toml",
35025
+ "csv",
35026
+ "md",
35027
+ "mdx",
35028
+ "sh",
35029
+ "bash",
35030
+ "zsh",
35031
+ "fish",
35032
+ "ascii",
35033
+ "utf8",
35034
+ "utf-8",
35035
+ "base64",
35036
+ "hex",
35037
+ "binary",
35038
+ "text",
35039
+ // Common design / ui terms
35040
+ "flex",
35041
+ "grid",
35042
+ "auto",
35043
+ "min",
35044
+ "max",
35045
+ "fill",
35046
+ "stretch",
35047
+ "wrap",
35048
+ "nowrap",
35049
+ "inline",
35050
+ "block",
35051
+ "hidden",
35052
+ "visible",
35053
+ "static",
35054
+ "fixed",
35055
+ "absolute",
35056
+ "relative",
35057
+ "sticky",
35058
+ "pointer",
35059
+ "cursor",
35060
+ "focus",
35061
+ "hover",
35062
+ "active",
35063
+ "disabled",
35064
+ "readonly",
35065
+ "primary",
35066
+ "secondary",
35067
+ "tertiary",
35068
+ "success",
35069
+ "warning",
35070
+ "danger",
35071
+ "info",
35072
+ "muted",
35073
+ "sm",
35074
+ "md",
35075
+ "lg",
35076
+ "xl",
35077
+ "xxl",
35078
+ "xs",
35079
+ "2xl",
35080
+ "3xl",
35081
+ "4xl",
35082
+ // Math / types
35083
+ "array",
35084
+ "map",
35085
+ "set",
35086
+ "weakmap",
35087
+ "weakset",
35088
+ "object",
35089
+ "string",
35090
+ "number",
35091
+ "boolean",
35092
+ "bigint",
35093
+ "symbol",
35094
+ "null",
35095
+ "undefined",
35096
+ "any",
35097
+ "unknown",
35098
+ "never",
35099
+ "void",
35100
+ "readonly",
35101
+ "private",
35102
+ "public",
35103
+ "protected",
35104
+ "static",
35105
+ "abstract",
35106
+ "async",
35107
+ "generator",
35108
+ "iterator",
35109
+ "iterable",
35110
+ "promise",
35111
+ "observable",
35112
+ // Auth / domain
35113
+ "admin",
35114
+ "user",
35115
+ "guest",
35116
+ "anonymous",
35117
+ "authenticated",
35118
+ "unauthenticated",
35119
+ "jwt",
35120
+ "oauth",
35121
+ "oidc",
35122
+ "saml",
35123
+ "csrf",
35124
+ "xss",
35125
+ "sql",
35126
+ "nosql",
35127
+ "orm",
35128
+ "prisma",
35129
+ "drizzle",
35130
+ "sequelize",
35131
+ "mongoose",
35132
+ "redis",
35133
+ "postgres",
35134
+ "mysql",
35135
+ "sqlite",
35136
+ "kafka",
35137
+ "rabbitmq",
35138
+ "graphql",
35139
+ "rest",
35140
+ "grpc",
35141
+ "websocket",
35142
+ // slop-audit specific
35143
+ "slopbrick",
35144
+ "usebrick",
35145
+ "deadcode",
35146
+ "unused",
35147
+ "orphan",
35148
+ "zombie",
35149
+ "blocker",
35150
+ "warning",
35151
+ "info",
35152
+ "error",
35153
+ "verbose",
35154
+ "debug",
35155
+ "silly",
35156
+ "p50",
35157
+ "p90",
35158
+ "p95",
35159
+ "p99",
35160
+ "min",
35161
+ "max",
35162
+ "avg",
35163
+ "mean",
35164
+ "median",
35165
+ "ratchet",
35166
+ "tier",
35167
+ "composite",
35168
+ "fitness",
35169
+ "fpr",
35170
+ "tpr",
35171
+ "roc",
35172
+ "should",
35173
+ "could",
35174
+ "would",
35175
+ "might",
35176
+ "must",
35177
+ "shall",
35178
+ "may",
35179
+ "can",
35180
+ "todo",
35181
+ "fixme",
35182
+ "xxx",
35183
+ "hack",
35184
+ "note",
35185
+ "warning",
35186
+ "attention",
35187
+ "h1",
35188
+ "h2",
35189
+ "h3",
35190
+ "h4",
35191
+ "h5",
35192
+ "h6",
35193
+ "strong",
35194
+ "em",
35195
+ "b",
35196
+ "i",
35197
+ "u",
35198
+ "true",
35199
+ "false",
35200
+ "yes",
35201
+ "no",
35202
+ "on",
35203
+ "off",
35204
+ "enable",
35205
+ "disable",
35206
+ "ltr",
35207
+ "rtl",
35208
+ "auto",
35209
+ "start",
35210
+ "end",
35211
+ "center",
35212
+ "baseline",
35213
+ "stretch",
35214
+ "rounded",
35215
+ "sharp",
35216
+ "outline",
35217
+ "ghost",
35218
+ "link",
35219
+ "filled",
35220
+ "row",
35221
+ "col",
35222
+ "gap",
35223
+ "pad",
35224
+ "margin",
35225
+ "padding",
35226
+ "border",
35227
+ "shadow",
35228
+ "transparent",
35229
+ "currentcolor",
35230
+ "inherit",
35231
+ "initial",
35232
+ "unset",
35233
+ "revert",
35234
+ "hover",
35235
+ "focus",
35236
+ "active",
35237
+ "disabled",
35238
+ "checked",
35239
+ "indeterminate",
35240
+ "open",
35241
+ "close",
35242
+ "expanded",
35243
+ "collapsed",
35244
+ "selected",
35245
+ "pressed",
35246
+ // Web/CSS
35247
+ "div",
35248
+ "span",
35249
+ "p",
35250
+ "a",
35251
+ "img",
35252
+ "ul",
35253
+ "ol",
35254
+ "li",
35255
+ "table",
35256
+ "tr",
35257
+ "td",
35258
+ "th",
35259
+ "thead",
35260
+ "tbody",
35261
+ "tfoot",
35262
+ "caption",
35263
+ "figure",
35264
+ "figcaption",
35265
+ "main",
35266
+ "section",
35267
+ "article",
35268
+ "aside",
35269
+ "header",
35270
+ "footer",
35271
+ "nav",
35272
+ "form",
35273
+ "input",
35274
+ "button",
35275
+ "select",
35276
+ "option",
35277
+ "textarea",
35278
+ "label",
35279
+ "fieldset",
35280
+ "legend",
35281
+ "details",
35282
+ "summary",
35283
+ "dialog",
35284
+ "menu",
35285
+ "menuitem",
35286
+ "template",
35287
+ "slot",
35288
+ "picture",
35289
+ "source",
35290
+ "track",
35291
+ "video",
35292
+ "audio",
35293
+ "canvas",
35294
+ "svg",
35295
+ "iframe",
35296
+ "embed",
35297
+ "object",
35298
+ "portal",
35299
+ // Common business terms
35300
+ "api",
35301
+ "cli",
35302
+ "ui",
35303
+ "ux",
35304
+ "sdk",
35305
+ "ide",
35306
+ "cli",
35307
+ "docs",
35308
+ "doc",
35309
+ "blog",
35310
+ "post",
35311
+ "page",
35312
+ "view",
35313
+ "tab",
35314
+ "panel",
35315
+ "card",
35316
+ "list",
35317
+ "grid",
35318
+ "form",
35319
+ "modal",
35320
+ "menu",
35321
+ "button",
35322
+ "icon",
35323
+ "avatar",
35324
+ "badge",
35325
+ "chip",
35326
+ "tooltip",
35327
+ "popover",
35328
+ "dropdown",
35329
+ "banner",
35330
+ "alert",
35331
+ "toast",
35332
+ "notification",
35333
+ "drawer",
35334
+ "sidebar",
35335
+ "navbar",
35336
+ "header",
35337
+ "footer",
35338
+ "hero",
35339
+ "cta",
35340
+ "cta-primary",
35341
+ "cta-secondary",
35342
+ "pricing",
35343
+ "price",
35344
+ "cost",
35345
+ "rate",
35346
+ "percent",
35347
+ "pct",
35348
+ "count",
35349
+ "total",
35350
+ "small",
35351
+ "medium",
35352
+ "large",
35353
+ "xl",
35354
+ "xxl",
35355
+ "tiny",
35356
+ "huge"
34888
35357
  ]);
34889
35358
  var SOURCE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
34890
35359
  var SOURCE_ROOTS = ["src", "lib", "app", "components"];
@@ -34922,7 +35391,12 @@ function collectExports(cwd) {
34922
35391
  /\bexport\s+class\s+([A-Za-z_$][\w$]*)/g,
34923
35392
  /\bexport\s+interface\s+([A-Za-z_$][\w$]*)/g,
34924
35393
  /\bexport\s+type\s+([A-Za-z_$][\w$]*)/g,
34925
- /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g
35394
+ /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g,
35395
+ // v0.18.6: also collect field names from `export interface` and
35396
+ // `export type` declarations. Without this, fields like
35397
+ // `crossFileDrift`, `aiQuality`, `engineeringHygiene` are
35398
+ // flagged as stale even though they're valid type fields.
35399
+ /^\s*(?:readonly\s+)?([A-Za-z_$][\w$]*)\s*[?:]/gm
34926
35400
  ]) {
34927
35401
  let m;
34928
35402
  while ((m = re.exec(source)) !== null) {
@@ -34933,6 +35407,21 @@ function collectExports(cwd) {
34933
35407
  }
34934
35408
  return out;
34935
35409
  }
35410
+ function looksLikeProseLabel(inside) {
35411
+ const trimmed = inside.trim();
35412
+ if (trimmed.length === 0) return false;
35413
+ if (trimmed.startsWith("`") || trimmed.startsWith("/")) return true;
35414
+ if (trimmed.includes("`")) return true;
35415
+ if (/\d+\s+[a-z]/i.test(trimmed)) return true;
35416
+ const parts = trimmed.split(",").map((s) => s.trim());
35417
+ if (parts.length >= 3) {
35418
+ const allNumeric = parts.every((p) => /^\d+\.?\d*$/.test(p));
35419
+ if (!allNumeric) return true;
35420
+ }
35421
+ if (trimmed.length > 40 && !trimmed.includes(",")) return true;
35422
+ if (trimmed.includes("\u2014") || trimmed.includes("\u2013")) return true;
35423
+ return false;
35424
+ }
34936
35425
  var staleFunctionReferenceRule = createRule({
34937
35426
  id: "docs/stale-function-reference",
34938
35427
  category: "docs",
@@ -34952,8 +35441,39 @@ var staleFunctionReferenceRule = createRule({
34952
35441
  if (text.length < 3) continue;
34953
35442
  if (RESERVED.has(text.toLowerCase())) continue;
34954
35443
  if (context.exports.has(text)) continue;
34955
- const end = Math.min(source.length, span.index + text.length + 50);
34956
- if (!/\(/.test(source.slice(span.index, end))) continue;
35444
+ const lineEnd = source.indexOf("\n", span.index);
35445
+ const restOfLine = source.slice(
35446
+ span.index,
35447
+ lineEnd === -1 ? source.length : lineEnd
35448
+ );
35449
+ const closeTick = restOfLine.indexOf("`", 1);
35450
+ if (closeTick === -1) continue;
35451
+ const afterTick = restOfLine.slice(closeTick + 1);
35452
+ const directCall = /^\s*\(/.test(afterTick);
35453
+ let identifierRepeats = false;
35454
+ if (!directCall) {
35455
+ const afterSpan = restOfLine.slice(closeTick + 1);
35456
+ const needle = text + "(";
35457
+ identifierRepeats = afterSpan.indexOf(needle) !== -1;
35458
+ }
35459
+ if (!directCall && !identifierRepeats) continue;
35460
+ const beforeTickIdx = span.index - 1;
35461
+ const beforeChar = beforeTickIdx >= 0 ? source[beforeTickIdx] : "";
35462
+ if (beforeChar === "." || beforeChar === "|") continue;
35463
+ const parenStart = restOfLine.indexOf("(", closeTick);
35464
+ const parenEnd = restOfLine.indexOf(")", parenStart);
35465
+ if (parenStart !== -1 && parenEnd !== -1) {
35466
+ const inside = restOfLine.slice(parenStart + 1, parenEnd);
35467
+ const trimmed = inside.trim();
35468
+ if (looksLikeProseLabel(inside)) continue;
35469
+ const looksLikeTypeAnnotation = !inside.includes(":") && (/\b(string|number|boolean|null|undefined|object|array|required|optional|categorical|direct|n\/a|\bmapped\b|0[\-–][0-9]+|v[0-9]|higher is better|lower is better|added in|deprecated|pr-[0-9])\b/i.test(
35470
+ inside
35471
+ ) || // Short single-word label (≤ 24 chars, no `,`,
35472
+ // doesn't look like a function arg). Real function
35473
+ // calls are usually longer or contain commas.
35474
+ trimmed.length > 0 && trimmed.length <= 24 && !trimmed.includes(",") && /[a-zA-Z]/.test(trimmed));
35475
+ if (looksLikeTypeAnnotation) continue;
35476
+ }
34957
35477
  issues.push({
34958
35478
  ruleId: "docs/stale-function-reference",
34959
35479
  category: "docs",
@@ -35025,7 +35545,33 @@ var ENGLISH_WORD_DENYLIST = /* @__PURE__ */ new Set([
35025
35545
  "jsx",
35026
35546
  "ok",
35027
35547
  "no",
35028
- "yes"
35548
+ "yes",
35549
+ // v0.18.6: common English adjectives / adverbs that frequently
35550
+ // appear in backticked prose but are not package names.
35551
+ "aspirational",
35552
+ "concrete",
35553
+ "abstract",
35554
+ "inline",
35555
+ "exposed",
35556
+ "deprecated",
35557
+ "experimental",
35558
+ "stable",
35559
+ "beta",
35560
+ "alpha",
35561
+ "wip",
35562
+ "draft",
35563
+ "final",
35564
+ "shim",
35565
+ "polyfill",
35566
+ "stub",
35567
+ "mock",
35568
+ "fake",
35569
+ "real",
35570
+ "false",
35571
+ "true",
35572
+ "optional",
35573
+ "required",
35574
+ "default"
35029
35575
  ]);
35030
35576
  var stalePackageReferenceRule = createRule({
35031
35577
  id: "docs/stale-package-reference",
@@ -35187,7 +35733,9 @@ var brokenLinkRule = createRule({
35187
35733
  if (target.startsWith("#")) continue;
35188
35734
  if (target.startsWith("//")) continue;
35189
35735
  if (target.startsWith("/")) continue;
35190
- const resolved = (0, import_node_path6.join)(docDir, target);
35736
+ const filePart = target.split("#")[0] ?? target;
35737
+ if (filePart === "") continue;
35738
+ const resolved = (0, import_node_path6.join)(docDir, filePart);
35191
35739
  if ((0, import_node_fs6.existsSync)(resolved)) continue;
35192
35740
  issues.push({
35193
35741
  ruleId: "docs/broken-link",