eslint-plugin-ai-guard 1.1.11 โ†’ 1.1.12

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
@@ -57,6 +57,29 @@ This writes:
57
57
  Your AI tools will now avoid these patterns before you even run the linter.
58
58
  Use `--force` to regenerate after upgrading to a new version with new rules.
59
59
 
60
+ ## ๐Ÿค– Set Up AI Agent Rules
61
+
62
+ Generate instruction files so Claude Code, Cursor, and GitHub Copilot
63
+ automatically avoid the 17 most common AI-generated anti-patterns:
64
+
65
+ ```bash
66
+ npx ai-guard init-context
67
+ ```
68
+
69
+ Follow the prompts to select your agent(s). Or generate all at once:
70
+
71
+ ```bash
72
+ npx ai-guard init-context --all
73
+ ```
74
+
75
+ This writes:
76
+ - `CLAUDE.md` โ€” read automatically by Claude Code
77
+ - `.cursorrules` โ€” read automatically by Cursor
78
+ - `.github/copilot-instructions.md` โ€” read automatically by GitHub Copilot
79
+
80
+ Your AI tools will now avoid these patterns before you even run the linter.
81
+ Use `--force` to regenerate after upgrading to a new version with new rules.
82
+
60
83
  ## ๐Ÿงช Real-World Usage Philosophy
61
84
 
62
85
  `ai-guard` is designed for production adoption in existing codebases:
package/dist/cli/index.js CHANGED
@@ -1772,6 +1772,30 @@ var SECTION_MAP = {
1772
1772
  function getSections(categories) {
1773
1773
  return categories.map((cat) => SECTION_MAP[cat]()).join("\n\n");
1774
1774
  }
1775
+ function workflowGuidanceMarkdown() {
1776
+ return `## Workflow Guardrails
1777
+ - Follow user and repository instructions first; apply these rules on top.
1778
+ - Reuse existing project patterns and libraries before introducing new abstractions.
1779
+ - If a rule must be bypassed intentionally, add a suppression comment with reason:
1780
+ \`ai-guard-disable <rule-name> -- reason: <why>\`.
1781
+ - Before finalizing changes, run tests/lint and \`ai-guard run\` when available.`;
1782
+ }
1783
+ function workflowGuidanceCursor() {
1784
+ return `## Workflow Guardrails
1785
+
1786
+ - Follow user and repository instructions first.
1787
+ - Prefer existing project patterns and dependencies.
1788
+ - If bypassing a rule intentionally, add: ai-guard-disable <rule-name> -- reason: <why>.
1789
+ - Validate generated code with tests/lint and ai-guard run when available.`;
1790
+ }
1791
+ function workflowGuidanceCopilot() {
1792
+ return `## Required Workflow
1793
+
1794
+ - Follow user and repository instructions first.
1795
+ - Prefer edits that match existing architecture and dependencies.
1796
+ - If intentionally violating an ai-guard rule, add an inline suppression with a reason.
1797
+ - Run tests/lint and \`ai-guard run\` before finalizing changes when possible.`;
1798
+ }
1775
1799
  function generateClaudeFile(version, categories) {
1776
1800
  return `<!-- DO NOT EDIT MANUALLY \u2014 generated by eslint-plugin-ai-guard -->
1777
1801
  <!-- Regenerate: npx ai-guard init-context --force -->
@@ -1781,6 +1805,8 @@ function generateClaudeFile(version, categories) {
1781
1805
  You are coding in a project that uses eslint-plugin-ai-guard.
1782
1806
  Avoid generating the following patterns. They will be flagged as lint errors.
1783
1807
 
1808
+ ${workflowGuidanceMarkdown()}
1809
+
1784
1810
  ${getSections(categories)}
1785
1811
 
1786
1812
  ---
@@ -1877,6 +1903,8 @@ anti-patterns generated by AI coding tools. Follow these rules when
1877
1903
  generating or editing code in this project. Violations will be flagged
1878
1904
  as lint errors.
1879
1905
 
1906
+ ${workflowGuidanceCursor()}
1907
+
1880
1908
  ${sections}
1881
1909
 
1882
1910
  ---
@@ -1978,6 +2006,8 @@ function generateCopilotFile(version, categories) {
1978
2006
  This project uses \`eslint-plugin-ai-guard\`. Follow these rules to avoid
1979
2007
  generating patterns that will be flagged as lint errors.
1980
2008
 
2009
+ ${workflowGuidanceCopilot()}
2010
+
1981
2011
  ## Quick Reference
1982
2012
 
1983
2013
  ${copilotQuickRef(categories)}
@@ -2041,10 +2071,19 @@ function parseCategories(raw) {
2041
2071
  }
2042
2072
  return valid.length > 0 ? valid : ALL_CATEGORIES;
2043
2073
  }
2074
+ function normalizeSelectedAgents(raw) {
2075
+ if (Array.isArray(raw)) {
2076
+ return raw.filter((value) => typeof value === "string");
2077
+ }
2078
+ if (typeof raw === "string") {
2079
+ return [raw];
2080
+ }
2081
+ return [];
2082
+ }
2044
2083
  function registerInitContextCommand(program2) {
2045
2084
  program2.command("init-context").description(
2046
2085
  "Generate AI agent instruction files (CLAUDE.md, .cursorrules, copilot-instructions.md)\nso Claude Code, Cursor, and GitHub Copilot avoid the 17 most common AI anti-patterns."
2047
- ).option("--all", "Generate files for all agents (skip prompt)").option("--force", "Overwrite existing files without asking").option("--dry-run", "Print what would be generated without writing files").option("--rules <categories>", "Comma-separated categories: async,security,error-handling,quality").action(async (opts) => {
2086
+ ).option("-a, --all", "Generate files for all agents (skip prompt)").option("--force", "Overwrite existing files without asking").option("--dry-run", "Print what would be generated without writing files").option("--rules <categories>", "Comma-separated categories: async,security,error-handling,quality").action(async (opts) => {
2048
2087
  const cwd = process.cwd();
2049
2088
  const version = getPackageVersion2(cwd);
2050
2089
  const categories = parseCategories(opts.rules);
@@ -2059,23 +2098,39 @@ function registerInitContextCommand(program2) {
2059
2098
  if (opts.all) {
2060
2099
  selectedAgents = [...AGENTS];
2061
2100
  } else {
2062
- const response = await (0, import_prompts2.default)({
2063
- type: "multiselect",
2064
- name: "agents",
2065
- message: "Which AI agents do you use?",
2066
- choices: [
2067
- { title: "Claude Code", value: "claude", description: "\u2192 writes CLAUDE.md" },
2068
- { title: "Cursor", value: "cursor", description: "\u2192 writes .cursorrules" },
2069
- { title: "GitHub Copilot", value: "copilot", description: "\u2192 writes .github/copilot-instructions.md" },
2070
- { title: "All three (recommended)", value: "all", description: "\u2192 writes all files" }
2071
- ],
2072
- hint: "- space to select, enter to confirm"
2073
- });
2074
- if (!response.agents || response.agents.length === 0) {
2075
- log.info("No agents selected. Nothing to do.");
2101
+ let wasCancelled = false;
2102
+ const response = await (0, import_prompts2.default)(
2103
+ {
2104
+ type: "multiselect",
2105
+ name: "agents",
2106
+ message: "Which AI agents do you use?",
2107
+ choices: [
2108
+ { title: "Claude Code", value: "claude", description: "\u2192 writes CLAUDE.md" },
2109
+ { title: "Cursor", value: "cursor", description: "\u2192 writes .cursorrules" },
2110
+ { title: "GitHub Copilot", value: "copilot", description: "\u2192 writes .github/copilot-instructions.md" },
2111
+ { title: "All three (recommended)", value: "all", description: "\u2192 writes all files" }
2112
+ ],
2113
+ hint: "Space: select | Enter: confirm",
2114
+ instructions: true,
2115
+ min: 1,
2116
+ warn: "Select at least one agent."
2117
+ },
2118
+ {
2119
+ onCancel: () => {
2120
+ wasCancelled = true;
2121
+ return false;
2122
+ }
2123
+ }
2124
+ );
2125
+ if (wasCancelled) {
2126
+ log.info("Selection cancelled. Nothing to do.");
2127
+ return;
2128
+ }
2129
+ const selected = normalizeSelectedAgents(response.agents);
2130
+ if (selected.length === 0) {
2131
+ log.info("No valid agents selected. Use --all to generate all files.");
2076
2132
  return;
2077
2133
  }
2078
- const selected = response.agents;
2079
2134
  if (selected.includes("all")) {
2080
2135
  selectedAgents = [...AGENTS];
2081
2136
  } else {