@prompt-lint/rules 1.0.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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -0
  3. package/dist/convention/filename-naming.d.ts +16 -0
  4. package/dist/convention/filename-naming.d.ts.map +1 -0
  5. package/dist/convention/filename-naming.js +50 -0
  6. package/dist/convention/filename-naming.js.map +1 -0
  7. package/dist/cost/high-token-estimate.d.ts +4 -0
  8. package/dist/cost/high-token-estimate.d.ts.map +1 -0
  9. package/dist/cost/high-token-estimate.js +51 -0
  10. package/dist/cost/high-token-estimate.js.map +1 -0
  11. package/dist/generated/manifest.d.ts +19 -0
  12. package/dist/generated/manifest.d.ts.map +1 -0
  13. package/dist/generated/manifest.js +98 -0
  14. package/dist/generated/manifest.js.map +1 -0
  15. package/dist/helpers/filename.d.ts +19 -0
  16. package/dist/helpers/filename.d.ts.map +1 -0
  17. package/dist/helpers/filename.js +59 -0
  18. package/dist/helpers/filename.js.map +1 -0
  19. package/dist/helpers/index.d.ts +16 -0
  20. package/dist/helpers/index.d.ts.map +1 -0
  21. package/dist/helpers/index.js +16 -0
  22. package/dist/helpers/index.js.map +1 -0
  23. package/dist/helpers/instruction-override.d.ts +28 -0
  24. package/dist/helpers/instruction-override.d.ts.map +1 -0
  25. package/dist/helpers/instruction-override.js +43 -0
  26. package/dist/helpers/instruction-override.js.map +1 -0
  27. package/dist/helpers/pii.d.ts +31 -0
  28. package/dist/helpers/pii.d.ts.map +1 -0
  29. package/dist/helpers/pii.js +36 -0
  30. package/dist/helpers/pii.js.map +1 -0
  31. package/dist/helpers/regex.d.ts +53 -0
  32. package/dist/helpers/regex.d.ts.map +1 -0
  33. package/dist/helpers/regex.js +79 -0
  34. package/dist/helpers/regex.js.map +1 -0
  35. package/dist/helpers/structured-data.d.ts +19 -0
  36. package/dist/helpers/structured-data.d.ts.map +1 -0
  37. package/dist/helpers/structured-data.js +72 -0
  38. package/dist/helpers/structured-data.js.map +1 -0
  39. package/dist/helpers/tokens.d.ts +26 -0
  40. package/dist/helpers/tokens.d.ts.map +1 -0
  41. package/dist/helpers/tokens.js +63 -0
  42. package/dist/helpers/tokens.js.map +1 -0
  43. package/dist/helpers/vague-quantifiers.d.ts +20 -0
  44. package/dist/helpers/vague-quantifiers.d.ts.map +1 -0
  45. package/dist/helpers/vague-quantifiers.js +83 -0
  46. package/dist/helpers/vague-quantifiers.js.map +1 -0
  47. package/dist/helpers/variables.d.ts +36 -0
  48. package/dist/helpers/variables.d.ts.map +1 -0
  49. package/dist/helpers/variables.js +66 -0
  50. package/dist/helpers/variables.js.map +1 -0
  51. package/dist/index.d.ts +62 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +80 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/quality/missing-output-schema.d.ts +15 -0
  56. package/dist/quality/missing-output-schema.d.ts.map +1 -0
  57. package/dist/quality/missing-output-schema.js +39 -0
  58. package/dist/quality/missing-output-schema.js.map +1 -0
  59. package/dist/quality/vague-quantifier-language.d.ts +13 -0
  60. package/dist/quality/vague-quantifier-language.d.ts.map +1 -0
  61. package/dist/quality/vague-quantifier-language.js +34 -0
  62. package/dist/quality/vague-quantifier-language.js.map +1 -0
  63. package/dist/security/instruction-override-pattern.d.ts +17 -0
  64. package/dist/security/instruction-override-pattern.d.ts.map +1 -0
  65. package/dist/security/instruction-override-pattern.js +39 -0
  66. package/dist/security/instruction-override-pattern.js.map +1 -0
  67. package/dist/security/pii-pattern.d.ts +18 -0
  68. package/dist/security/pii-pattern.d.ts.map +1 -0
  69. package/dist/security/pii-pattern.js +56 -0
  70. package/dist/security/pii-pattern.js.map +1 -0
  71. package/dist/structure/missing-description.d.ts +14 -0
  72. package/dist/structure/missing-description.d.ts.map +1 -0
  73. package/dist/structure/missing-description.js +32 -0
  74. package/dist/structure/missing-description.js.map +1 -0
  75. package/dist/structure/missing-model.d.ts +16 -0
  76. package/dist/structure/missing-model.d.ts.map +1 -0
  77. package/dist/structure/missing-model.js +34 -0
  78. package/dist/structure/missing-model.js.map +1 -0
  79. package/dist/structure/undefined-variable.d.ts +15 -0
  80. package/dist/structure/undefined-variable.d.ts.map +1 -0
  81. package/dist/structure/undefined-variable.js +39 -0
  82. package/dist/structure/undefined-variable.js.map +1 -0
  83. package/dist/structure/unused-variable.d.ts +15 -0
  84. package/dist/structure/unused-variable.d.ts.map +1 -0
  85. package/dist/structure/unused-variable.js +38 -0
  86. package/dist/structure/unused-variable.js.map +1 -0
  87. package/dist/test-helpers.d.ts +40 -0
  88. package/dist/test-helpers.d.ts.map +1 -0
  89. package/dist/test-helpers.js +52 -0
  90. package/dist/test-helpers.js.map +1 -0
  91. package/package.json +42 -0
@@ -0,0 +1,38 @@
1
+ import { defineRule } from "@prompt-lint/rule-engine";
2
+ import { collectBodyVariables, collectDeclaredVariables } from "../helpers/index.js";
3
+ /**
4
+ * `structure/unused-variable`
5
+ *
6
+ * Reports a finding for every variable declared in `frontmatter.variables`
7
+ * that is **not** referenced anywhere in the parsed prompt body. Each
8
+ * unused variable is emitted separately so reporters can point at the
9
+ * exact identifier.
10
+ *
11
+ * The rule does not emit duplicate findings even if the same name was
12
+ * declared multiple times in the frontmatter.
13
+ */
14
+ const unusedVariableRule = defineRule({
15
+ id: "structure/unused-variable",
16
+ description: "Flags variables defined in frontmatter but never referenced in the prompt body.",
17
+ defaultSeverity: "warning",
18
+ options: Object.freeze([]),
19
+ check: ({ file, report }) => {
20
+ const declared = collectDeclaredVariables(file);
21
+ const referenced = new Set(collectBodyVariables(file).map((v) => v.name));
22
+ for (const name of declared) {
23
+ if (referenced.has(name))
24
+ continue;
25
+ report({
26
+ message: `Declared variable \`${name}\` is never referenced in the prompt body.`,
27
+ severity: "warning",
28
+ suggestions: [
29
+ `Reference \`{{ ${name} }}\` somewhere in the body, or`,
30
+ "Remove the entry from `variables:` in the frontmatter.",
31
+ ],
32
+ });
33
+ }
34
+ return { findings: [] };
35
+ },
36
+ });
37
+ export default unusedVariableRule;
38
+ //# sourceMappingURL=unused-variable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-variable.js","sourceRoot":"","sources":["../../src/structure/unused-variable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAErD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAEpF;;;;;;;;;;GAUG;AACH,MAAM,kBAAkB,GAAmB,UAAU,CAAC;IACpD,EAAE,EAAE,2BAA2B;IAC/B,WAAW,EAAE,iFAAiF;IAC9F,eAAe,EAAE,SAAS;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACzE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAQ;YAClC,MAAM,CAAC;gBACL,OAAO,EAAE,uBAAuB,IAAI,4CAA4C;gBAChF,QAAQ,EAAE,SAAS;gBACnB,WAAW,EAAE;oBACX,kBAAkB,IAAI,iCAAiC;oBACvD,wDAAwD;iBACzD;aACF,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;IACzB,CAAC;CACF,CAAC,CAAA;AAEF,eAAe,kBAAkB,CAAA"}
@@ -0,0 +1,40 @@
1
+ import type { Finding, PromptFile, RuleContext } from "@prompt-lint/types";
2
+ /**
3
+ * Construct a `RuleContext` for a single rule call.
4
+ *
5
+ * The helper ports the engine's `runOneRuleOneFile` plumbing so unit tests
6
+ * can exercise `rule.check(ctx)` directly without spinning up the engine.
7
+ */
8
+ export declare function makeContext(file: PromptFile, options?: Readonly<Record<string, unknown>>): {
9
+ context: RuleContext;
10
+ emitted: Omit<Finding, "ruleId" | "fileId" | "filePath">[];
11
+ };
12
+ /**
13
+ * Run a rule synchronously and return its emitted findings together with
14
+ * any findings the rule returned from `check`.
15
+ *
16
+ * Variables in the body are extracted via `@prompt-lint/parser` so the
17
+ * tests do not have to enumerate each `{{ var }}` reference manually.
18
+ */
19
+ export declare function runRule(rule: {
20
+ check: (ctx: RuleContext) => RuleResult | Promise<RuleResult>;
21
+ }, input?: {
22
+ path?: string;
23
+ body?: string;
24
+ frontmatter?: PromptFile["frontmatter"];
25
+ variables?: PromptFile["variables"];
26
+ format?: PromptFile["format"];
27
+ }, options?: Readonly<Record<string, unknown>>): Promise<{
28
+ findings: Finding[];
29
+ emitted: Omit<Finding, "ruleId" | "fileId" | "filePath">[];
30
+ }>;
31
+ interface RuleResult {
32
+ findings: readonly unknown[];
33
+ }
34
+ /**
35
+ * Convenience helper for tests that prefer to start from a parsed-style
36
+ * `PromptFile` literal.
37
+ */
38
+ export declare function frozen<T>(value: T): T;
39
+ export {};
40
+ //# sourceMappingURL=test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../src/test-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAE1E;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC9C;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,EAAE,CAAA;CAAE,CAUtF;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE;IAAE,KAAK,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,EACvE,KAAK,GAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;IACvC,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAA;IACnC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;CACzB,EACN,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC9C,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,EAAE,CAAA;CAAE,CAAC,CAiB9F;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAErC"}
@@ -0,0 +1,52 @@
1
+ import { collectVariables, scanVariables } from "@prompt-lint/parser";
2
+ import { makePromptFile } from "@prompt-lint/test-utils";
3
+ /**
4
+ * Construct a `RuleContext` for a single rule call.
5
+ *
6
+ * The helper ports the engine's `runOneRuleOneFile` plumbing so unit tests
7
+ * can exercise `rule.check(ctx)` directly without spinning up the engine.
8
+ */
9
+ export function makeContext(file, options = {}) {
10
+ const emitted = [];
11
+ const context = Object.freeze({
12
+ file,
13
+ options: Object.freeze({ ...options }),
14
+ report: (raw) => {
15
+ emitted.push({ ...raw });
16
+ },
17
+ });
18
+ return { context, emitted };
19
+ }
20
+ /**
21
+ * Run a rule synchronously and return its emitted findings together with
22
+ * any findings the rule returned from `check`.
23
+ *
24
+ * Variables in the body are extracted via `@prompt-lint/parser` so the
25
+ * tests do not have to enumerate each `{{ var }}` reference manually.
26
+ */
27
+ export async function runRule(rule, input = {}, options = {}) {
28
+ const body = input.body ?? "";
29
+ const occurrences = scanVariables(body);
30
+ const variables = collectVariables(occurrences);
31
+ const file = makePromptFile({
32
+ path: input.path ?? "prompts/sample.prompt.md",
33
+ format: input.format ?? "prompt.md",
34
+ body,
35
+ frontmatter: (input.frontmatter ?? {}),
36
+ variables,
37
+ });
38
+ const { context, emitted } = makeContext(file, options);
39
+ const result = await rule.check(context);
40
+ return {
41
+ findings: Array.isArray(result.findings) ? result.findings : [],
42
+ emitted,
43
+ };
44
+ }
45
+ /**
46
+ * Convenience helper for tests that prefer to start from a parsed-style
47
+ * `PromptFile` literal.
48
+ */
49
+ export function frozen(value) {
50
+ return Object.freeze(value);
51
+ }
52
+ //# sourceMappingURL=test-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../src/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,IAAgB,EAChB,UAA6C,EAAE;IAE/C,MAAM,OAAO,GAAsD,EAAE,CAAA;IACrE,MAAM,OAAO,GAAgB,MAAM,CAAC,MAAM,CAAC;QACzC,IAAI;QACJ,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;QACtC,MAAM,EAAE,CAAC,GAAoD,EAAE,EAAE;YAC/D,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAA;QAC1B,CAAC;KACF,CAAC,CAAA;IACF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAA;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAuE,EACvE,QAMI,EAAE,EACN,UAA6C,EAAE;IAE/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAA;IAC7B,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,0BAA0B;QAC9C,MAAM,EAAE,KAAK,CAAC,MAAM,IAAK,WAAoC;QAC7D,IAAI;QACJ,WAAW,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAA8B;QACnE,SAAS;KACV,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACxC,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,QAAsB,CAAC,CAAC,CAAC,EAAE;QAC9E,OAAO;KACR,CAAA;AACH,CAAC;AAMD;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAI,KAAQ;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@prompt-lint/rules",
3
+ "version": "1.0.0",
4
+ "description": "Built-in lint rules for PromptLint V1.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "!**/*.tsbuildinfo"
18
+ ],
19
+ "dependencies": {
20
+ "@prompt-lint/parser": "1.0.0",
21
+ "@prompt-lint/types": "1.0.0",
22
+ "@prompt-lint/rule-engine": "1.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "20.17.10",
26
+ "typescript": "5.7.2",
27
+ "vitest": "2.1.8",
28
+ "@prompt-lint/biome-config": "0.0.0",
29
+ "@prompt-lint/test-utils": "0.0.0",
30
+ "@prompt-lint/tsconfig": "0.0.0"
31
+ },
32
+ "scripts": {
33
+ "lint": "biome check src",
34
+ "lint:fix": "biome check --write src",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "vitest",
37
+ "test:run": "vitest run",
38
+ "build": "tsc -p tsconfig.build.json",
39
+ "clean": "rm -rf dist .turbo coverage",
40
+ "topo": "echo \"topo\""
41
+ }
42
+ }