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