veto-leash 0.1.3 → 1.0.1
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 +111 -196
- package/dist/ast/builtins.d.ts +28 -0
- package/dist/ast/builtins.d.ts.map +1 -0
- package/dist/ast/builtins.js +361 -0
- package/dist/ast/builtins.js.map +1 -0
- package/dist/ast/checker.d.ts +17 -0
- package/dist/ast/checker.d.ts.map +1 -0
- package/dist/ast/checker.js +97 -0
- package/dist/ast/checker.js.map +1 -0
- package/dist/ast/index.d.ts +5 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +7 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/ast/parser.d.ts +55 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +210 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/ast/query.d.ts +48 -0
- package/dist/ast/query.d.ts.map +1 -0
- package/dist/ast/query.js +102 -0
- package/dist/ast/query.js.map +1 -0
- package/dist/ast/validate-cli.d.ts +21 -0
- package/dist/ast/validate-cli.d.ts.map +1 -0
- package/dist/ast/validate-cli.js +73 -0
- package/dist/ast/validate-cli.js.map +1 -0
- package/dist/cli.js +105 -21
- package/dist/cli.js.map +1 -1
- package/dist/compiler/builtins.d.ts.map +1 -1
- package/dist/compiler/builtins.js +721 -4
- package/dist/compiler/builtins.js.map +1 -1
- package/dist/compiler/commands.d.ts +40 -0
- package/dist/compiler/commands.d.ts.map +1 -0
- package/dist/compiler/commands.js +311 -0
- package/dist/compiler/commands.js.map +1 -0
- package/dist/compiler/content.d.ts +160 -0
- package/dist/compiler/content.d.ts.map +1 -0
- package/dist/compiler/content.js +461 -0
- package/dist/compiler/content.js.map +1 -0
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +34 -7
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/llm.d.ts.map +1 -1
- package/dist/compiler/llm.js +96 -9
- package/dist/compiler/llm.js.map +1 -1
- package/dist/compiler/prompt.d.ts +1 -1
- package/dist/compiler/prompt.d.ts.map +1 -1
- package/dist/compiler/prompt.js +247 -15
- package/dist/compiler/prompt.js.map +1 -1
- package/dist/config/leash-parser.d.ts +29 -0
- package/dist/config/leash-parser.d.ts.map +1 -0
- package/dist/config/leash-parser.js +70 -0
- package/dist/config/leash-parser.js.map +1 -0
- package/dist/config/loader.d.ts +2 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +18 -8
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/config/watcher.d.ts +18 -0
- package/dist/config/watcher.d.ts.map +1 -0
- package/dist/config/watcher.js +102 -0
- package/dist/config/watcher.js.map +1 -0
- package/dist/matcher.d.ts +18 -0
- package/dist/matcher.d.ts.map +1 -1
- package/dist/matcher.js +43 -0
- package/dist/matcher.js.map +1 -1
- package/dist/native/claude-code.d.ts.map +1 -1
- package/dist/native/claude-code.js +294 -50
- package/dist/native/claude-code.js.map +1 -1
- package/dist/native/cursor.d.ts +14 -1
- package/dist/native/cursor.d.ts.map +1 -1
- package/dist/native/cursor.js +340 -34
- package/dist/native/cursor.js.map +1 -1
- package/dist/native/index.d.ts +5 -0
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +56 -10
- package/dist/native/index.js.map +1 -1
- package/dist/native/opencode.d.ts.map +1 -1
- package/dist/native/opencode.js +15 -3
- package/dist/native/opencode.js.map +1 -1
- package/dist/native/validator.d.ts +15 -0
- package/dist/native/validator.d.ts.map +1 -0
- package/dist/native/validator.js +368 -0
- package/dist/native/validator.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/wrapper/daemon.d.ts.map +1 -1
- package/dist/wrapper/daemon.js +31 -2
- package/dist/wrapper/daemon.js.map +1 -1
- package/languages/tree-sitter-javascript.wasm +0 -0
- package/languages/tree-sitter-tsx.wasm +0 -0
- package/languages/tree-sitter-typescript.wasm +0 -0
- package/package.json +5 -2
package/dist/compiler/llm.js
CHANGED
|
@@ -1,28 +1,115 @@
|
|
|
1
1
|
// src/compiler/llm.ts
|
|
2
|
-
import { GoogleGenAI } from '@google/genai';
|
|
2
|
+
import { GoogleGenAI, Type } from '@google/genai';
|
|
3
3
|
import { SYSTEM_PROMPT } from './prompt.js';
|
|
4
4
|
// Native JSON schema - GUARANTEES valid output from Gemini
|
|
5
|
+
// Using Type enum for proper schema typing
|
|
5
6
|
const POLICY_SCHEMA = {
|
|
6
|
-
type:
|
|
7
|
+
type: Type.OBJECT,
|
|
7
8
|
properties: {
|
|
8
9
|
action: {
|
|
9
|
-
type:
|
|
10
|
+
type: Type.STRING,
|
|
10
11
|
enum: ['delete', 'modify', 'execute', 'read'],
|
|
12
|
+
description: 'The action type this policy restricts',
|
|
11
13
|
},
|
|
12
14
|
include: {
|
|
13
|
-
type:
|
|
14
|
-
items: { type:
|
|
15
|
-
description: 'Glob patterns for protected files',
|
|
15
|
+
type: Type.ARRAY,
|
|
16
|
+
items: { type: Type.STRING },
|
|
17
|
+
description: 'Glob patterns for protected files (can be empty for command-only policies)',
|
|
16
18
|
},
|
|
17
19
|
exclude: {
|
|
18
|
-
type:
|
|
19
|
-
items: { type:
|
|
20
|
+
type: Type.ARRAY,
|
|
21
|
+
items: { type: Type.STRING },
|
|
20
22
|
description: 'Glob patterns for safe exceptions',
|
|
21
23
|
},
|
|
22
24
|
description: {
|
|
23
|
-
type:
|
|
25
|
+
type: Type.STRING,
|
|
24
26
|
description: 'Human-readable description of what is protected',
|
|
25
27
|
},
|
|
28
|
+
commandRules: {
|
|
29
|
+
type: Type.ARRAY,
|
|
30
|
+
description: 'Optional command-level rules for tool/command preferences',
|
|
31
|
+
items: {
|
|
32
|
+
type: Type.OBJECT,
|
|
33
|
+
properties: {
|
|
34
|
+
block: {
|
|
35
|
+
type: Type.ARRAY,
|
|
36
|
+
items: { type: Type.STRING },
|
|
37
|
+
description: 'Glob patterns for commands to block (e.g., "npm install*", "sudo *")',
|
|
38
|
+
},
|
|
39
|
+
suggest: {
|
|
40
|
+
type: Type.STRING,
|
|
41
|
+
description: 'Optional suggestion for alternative command',
|
|
42
|
+
},
|
|
43
|
+
reason: {
|
|
44
|
+
type: Type.STRING,
|
|
45
|
+
description: 'Human-readable reason for blocking',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ['block', 'reason'],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
contentRules: {
|
|
52
|
+
type: Type.ARRAY,
|
|
53
|
+
description: 'Optional content-level rules to check file contents for banned patterns',
|
|
54
|
+
items: {
|
|
55
|
+
type: Type.OBJECT,
|
|
56
|
+
properties: {
|
|
57
|
+
pattern: {
|
|
58
|
+
type: Type.STRING,
|
|
59
|
+
description: 'Regex pattern to match in file content (e.g., "import.*lodash", "console\\.log")',
|
|
60
|
+
},
|
|
61
|
+
fileTypes: {
|
|
62
|
+
type: Type.ARRAY,
|
|
63
|
+
items: { type: Type.STRING },
|
|
64
|
+
description: 'File patterns where this rule applies (e.g., ["*.ts", "*.js"])',
|
|
65
|
+
},
|
|
66
|
+
reason: {
|
|
67
|
+
type: Type.STRING,
|
|
68
|
+
description: 'Human-readable reason for blocking',
|
|
69
|
+
},
|
|
70
|
+
suggest: {
|
|
71
|
+
type: Type.STRING,
|
|
72
|
+
description: 'Optional suggestion for alternative',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ['pattern', 'fileTypes', 'reason'],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
astRules: {
|
|
79
|
+
type: Type.ARRAY,
|
|
80
|
+
description: 'Optional AST-based rules for precise code pattern matching (TypeScript/JavaScript only)',
|
|
81
|
+
items: {
|
|
82
|
+
type: Type.OBJECT,
|
|
83
|
+
properties: {
|
|
84
|
+
id: {
|
|
85
|
+
type: Type.STRING,
|
|
86
|
+
description: 'Unique identifier for this rule (e.g., "no-lodash-import")',
|
|
87
|
+
},
|
|
88
|
+
query: {
|
|
89
|
+
type: Type.STRING,
|
|
90
|
+
description: 'Tree-sitter S-expression query (e.g., "(import_statement source: (string) @s (#match? @s \\"lodash\\"))")',
|
|
91
|
+
},
|
|
92
|
+
languages: {
|
|
93
|
+
type: Type.ARRAY,
|
|
94
|
+
items: { type: Type.STRING },
|
|
95
|
+
description: 'Languages this rule applies to: ["typescript", "javascript"]',
|
|
96
|
+
},
|
|
97
|
+
reason: {
|
|
98
|
+
type: Type.STRING,
|
|
99
|
+
description: 'Human-readable reason for blocking',
|
|
100
|
+
},
|
|
101
|
+
suggest: {
|
|
102
|
+
type: Type.STRING,
|
|
103
|
+
description: 'Optional suggestion for alternative',
|
|
104
|
+
},
|
|
105
|
+
regexPreFilter: {
|
|
106
|
+
type: Type.STRING,
|
|
107
|
+
description: 'Fast pre-filter string - if content does not contain this, skip AST parsing',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
required: ['id', 'query', 'languages', 'reason'],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
26
113
|
},
|
|
27
114
|
required: ['action', 'include', 'exclude', 'description'],
|
|
28
115
|
};
|
package/dist/compiler/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/compiler/llm.ts"],"names":[],"mappings":"AAAA,sBAAsB;AAEtB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/compiler/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SYSTEM_PROMPT = "You are a permission policy compiler for AI coding agents.\n\nConvert natural language restrictions into precise glob patterns.\n\nCRITICAL: Understand SEMANTIC INTENT, not just keywords.\n\nEXAMPLES OF SEMANTIC UNDERSTANDING:\n\n\"test files\" means TEST SOURCE CODE:\n include: [\"*.test.*\", \"*.spec.*\", \"__tests__/**\", \"test/**/*.ts\"]\n exclude: [\"test-results.*\", \"test-output.*\", \"coverage/**\"]\n \n\"config files\" means CONFIGURATION, not files that configure:\n include: [\"*.config.*\", \"tsconfig*\", \".eslintrc*\", \"vite.config.*\"]\n exclude: []\n\n\"env files\" means ENVIRONMENT SECRETS:\n include: [\".env\", \".env.*\", \"**/.env\", \"**/.env.*\"]\n exclude: [\".env.example\", \".env.template\"]\n\n\"migrations\" means DATABASE SCHEMA CHANGES:\n include: [\"**/migrations/**\", \"*migrate*\", \"prisma/migrations/**\"]\n exclude: []\n\nPATTERN RULES:\n- Always include **/ variants for recursive matching\n- \"starts with X\" \u2192 [\"X*\", \"**/X*\"] \n- \"ends with X\" \u2192 [\"*X\", \"**/*X\"]\n- \"contains X\" \u2192 [\"*X*\", \"**/*X*\"]\n- \"in directory X\" \u2192 [\"X/**\"]\n\nINCLUDE = what to PROTECT (be generous)\nEXCLUDE = what to ALLOW (carve out exceptions)\n\nOutput JSON only. No explanation.";
|
|
1
|
+
export declare const SYSTEM_PROMPT = "You are a permission policy compiler for AI coding agents.\n\nConvert natural language restrictions into precise, COMPREHENSIVE patterns.\n\nCRITICAL: \n1. Understand SEMANTIC INTENT, not just keywords\n2. Generate MULTIPLE patterns to catch ALL variants of a violation\n3. Use 'strict' mode to avoid false positives in comments/strings\n4. Include 'exceptions' patterns to prevent false positives\n5. For TypeScript/JavaScript code patterns, prefer astRules over contentRules (zero false positives)\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nBUILT-IN AST RULES (DO NOT REGENERATE)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nThese restrictions have pre-built AST rules. Return ONLY the basic policy structure:\n- \"no lodash\" \u2192 handled by builtin\n- \"no moment\" \u2192 handled by builtin \n- \"no jquery\" \u2192 handled by builtin\n- \"no axios\" \u2192 handled by builtin\n- \"no any\" / \"no any types\" \u2192 handled by builtin\n- \"no console\" / \"no console.log\" \u2192 handled by builtin\n- \"no eval\" \u2192 handled by builtin\n- \"no innerhtml\" \u2192 handled by builtin\n- \"no debugger\" \u2192 handled by builtin\n- \"no var\" \u2192 handled by builtin\n- \"no alert\" \u2192 handled by builtin\n- \"no class components\" \u2192 handled by builtin\n\nFor these, return minimal policy:\n{\n \"action\": \"modify\",\n \"include\": [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\"],\n \"exclude\": [],\n \"description\": \"<the restriction>\"\n}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nFILE-LEVEL POLICIES (include/exclude patterns)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\"test files\" means TEST SOURCE CODE:\n include: [\"*.test.*\", \"*.spec.*\", \"__tests__/**\", \"test/**/*.ts\"]\n exclude: [\"test-results.*\", \"test-output.*\", \"coverage/**\"]\n \n\"config files\" means CONFIGURATION:\n include: [\"*.config.*\", \"tsconfig*\", \".eslintrc*\", \"vite.config.*\"]\n exclude: []\n\n\"env files\" means ENVIRONMENT SECRETS:\n include: [\".env\", \".env.*\", \"**/.env\", \"**/.env.*\"]\n exclude: [\".env.example\", \".env.template\"]\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nCOMMAND-LEVEL POLICIES (commandRules)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nFor tool/command preferences, generate commandRules array.\n\n\"prefer pnpm\" or \"use pnpm not npm\":\n commandRules: [\n { block: [\"npm install*\", \"npm i *\", \"npm i\", \"npm ci\"], suggest: \"pnpm install\", reason: \"Project uses pnpm\" }\n ]\n\nCOMMAND PATTERN RULES:\n- \"command *\" matches command with any args\n- Include common aliases: npm i = npm install, bun a = bun add\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nCONTENT-LEVEL POLICIES (contentRules) - COMPREHENSIVE\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nCRITICAL: Generate MULTIPLE patterns to catch ALL import/usage variants.\n\n\"no lodash\" - Must catch ALL these forms:\n contentRules: [\n {\n pattern: \"(?:import|require)\\\\s*(?:\\\\(|\\\\s).*['\"]lodash(?:[-./][^'\"]*)?['\"]\",\n fileTypes: [\"*.ts\", \"*.js\", \"*.tsx\", \"*.jsx\"],\n reason: \"Use native methods instead of lodash\",\n suggest: \"Use Array.map(), filter(), Object.keys()\",\n mode: \"strict\"\n }\n ]\n // This catches:\n // - import _ from 'lodash'\n // - import { map } from 'lodash'\n // - import * as _ from 'lodash'\n // - import map from 'lodash/map'\n // - import map from 'lodash.map'\n // - import _ from 'lodash-es'\n // - require('lodash')\n // - await import('lodash')\n\n\"no any types\" - Must catch ALL these forms:\n contentRules: [\n {\n pattern: \"(?::\\\\s*any\\\\s*(?:[,;)\\\\]=]|$)|<\\\\s*any\\\\s*>|as\\\\s+any\\\\b)\",\n fileTypes: [\"*.ts\", \"*.tsx\"],\n reason: \"Use proper TypeScript types\",\n suggest: \"Use unknown or specific types\",\n mode: \"strict\",\n exceptions: [\"(?:const|let|var|function)\\\\s+\\\\w*any\\\\w*\"]\n },\n {\n pattern: \"Array\\\\s*<\\\\s*any\\\\s*>\",\n fileTypes: [\"*.ts\", \"*.tsx\"],\n reason: \"Avoid Array<any>\",\n mode: \"strict\"\n },\n {\n pattern: \"Record\\\\s*<[^>]*,\\\\s*any\\\\s*>\",\n fileTypes: [\"*.ts\", \"*.tsx\"],\n reason: \"Avoid Record<string, any>\",\n mode: \"strict\"\n },\n {\n pattern: \"type\\\\s+\\\\w+\\\\s*=\\\\s*any\\\\s*;\",\n fileTypes: [\"*.ts\", \"*.tsx\"],\n reason: \"Avoid type alias to any\",\n mode: \"strict\"\n }\n ]\n // This catches:\n // - : any\n // - <any>\n // - as any\n // - Array<any>\n // - Record<string, any>\n // - Promise<any>\n // - type Foo = any\n // - <T = any>\n // But NOT:\n // - const anyValue = 5 (variable name)\n // - \"any\" in strings (mode: strict)\n // - // any in comments (mode: strict)\n\n\"no console.log\" - Must catch ALL these forms:\n contentRules: [\n {\n pattern: \"\\\\bconsole\\\\s*\\\\.\\\\s*log\\\\s*\\\\(\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"Use proper logging\",\n mode: \"strict\"\n },\n {\n pattern: \"console\\\\s*\\\\[\\\\s*['\"]log['\"]\\\\s*\\\\]\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"Console accessed via bracket notation\",\n mode: \"strict\"\n },\n {\n pattern: \"\\\\{\\\\s*log(?:\\\\s*:\\\\s*\\\\w+)?\\\\s*\\\\}\\\\s*=\\\\s*console\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"Destructured console.log detected\",\n mode: \"strict\"\n }\n ]\n // This catches:\n // - console.log(\n // - console['log'](\n // - const { log } = console\n // - const { log: myLog } = console\n\n\"no class components\" (React):\n contentRules: [\n {\n pattern: \"class\\\\s+\\\\w+\\\\s+extends\\\\s+(?:React\\\\s*\\\\.\\\\s*)?(?:Pure)?Component\\\\s*(?:<|\\\\{)\",\n fileTypes: [\"*.tsx\", \"*.jsx\"],\n reason: \"Use functional components with hooks\",\n suggest: \"const Component = () => { ... }\",\n mode: \"strict\"\n }\n ]\n // This catches:\n // - class Foo extends Component {\n // - class Foo extends React.Component {\n // - class Foo extends PureComponent {\n // - class Foo extends Component<Props> {\n\n\"no eval\" - Must catch ALL unsafe eval-like constructs:\n contentRules: [\n {\n pattern: \"\\\\beval\\\\s*\\\\(\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"eval() is a security risk\",\n mode: \"strict\"\n },\n {\n pattern: \"new\\\\s+Function\\\\s*\\\\(\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"new Function() is equivalent to eval()\",\n mode: \"strict\"\n },\n {\n pattern: \"setTimeout\\\\s*\\\\(\\\\s*['\"]\",\n fileTypes: [\"*.ts\", \"*.js\"],\n reason: \"setTimeout with string is eval-like\",\n mode: \"strict\"\n }\n ]\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nCONTENT RULE OPTIONS\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nmode (optional):\n - \"fast\": Direct regex match (default, fastest, may have false positives)\n - \"strict\": Strip comments/strings before matching (recommended for most rules)\n\nexceptions (optional):\n - Array of regex patterns that indicate FALSE POSITIVES\n - If exception matches context around the main match, rule is NOT violated\n - Example: Don't flag 'any' in variable names like 'anyValue'\n\nfileTypes:\n - Array of glob patterns: [\"*.ts\", \"*.tsx\", \"*.js\"]\n - Use specific types, not broad patterns\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nAST RULES (PREFERRED FOR TS/JS - ZERO FALSE POSITIVES)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nFor TypeScript/JavaScript code patterns NOT covered by builtins, generate astRules.\nAST rules use tree-sitter S-expression queries - they NEVER match comments or strings.\n\nFormat:\n astRules: [{\n id: \"unique-rule-id\",\n query: \"(tree_sitter_query) @capture\",\n languages: [\"typescript\", \"javascript\"],\n reason: \"Why this is blocked\",\n suggest: \"Alternative approach\",\n regexPreFilter: \"fast_string_check\"\n }]\n\nCommon query patterns:\n (import_statement source: (string) @s (#match? @s \"pattern\")) - imports\n (call_expression function: (identifier) @fn (#eq? @fn \"name\")) - function calls\n (type_annotation (predefined_type) @t (#eq? @t \"any\")) - type annotations\n\nALWAYS include regexPreFilter for performance (skips AST if string not found).\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nBEST PRACTICES\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1. ALWAYS generate multiple contentRules to catch ALL variants\n2. USE mode: \"strict\" for patterns that might appear in comments/strings\n3. ADD exceptions for common false positive patterns\n4. INCLUDE word boundaries (\\b) to avoid partial matches\n5. For imports, catch: ES6 import, CommonJS require, dynamic import, submodules\n6. For types, catch: annotations, generics, assertions, aliases\n7. For function calls, catch: direct calls, bracket notation, destructuring\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nDECISION TREE\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1. If about FILES (test files, .env, configs) \u2192 use include/exclude\n2. If about COMMANDS/TOOLS (npm vs pnpm, jest vs vitest) \u2192 use commandRules\n3. If about TS/JS CODE PATTERNS and matches a builtin \u2192 return minimal policy (handled by builtin)\n4. If about TS/JS CODE PATTERNS not covered by builtin \u2192 use astRules (zero false positives)\n5. If about non-TS/JS CODE PATTERNS \u2192 use contentRules with mode: \"strict\"\n6. If about PREVENTING PACKAGE \u2192 use commandRules + astRules (or contentRules for non-JS)\n\nOutput JSON only. No explanation.";
|
|
2
2
|
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/compiler/prompt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/compiler/prompt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gtdA0QQ,CAAC"}
|
package/dist/compiler/prompt.js
CHANGED
|
@@ -1,17 +1,50 @@
|
|
|
1
1
|
// src/compiler/prompt.ts
|
|
2
2
|
export const SYSTEM_PROMPT = `You are a permission policy compiler for AI coding agents.
|
|
3
3
|
|
|
4
|
-
Convert natural language restrictions into precise
|
|
4
|
+
Convert natural language restrictions into precise, COMPREHENSIVE patterns.
|
|
5
5
|
|
|
6
|
-
CRITICAL:
|
|
6
|
+
CRITICAL:
|
|
7
|
+
1. Understand SEMANTIC INTENT, not just keywords
|
|
8
|
+
2. Generate MULTIPLE patterns to catch ALL variants of a violation
|
|
9
|
+
3. Use 'strict' mode to avoid false positives in comments/strings
|
|
10
|
+
4. Include 'exceptions' patterns to prevent false positives
|
|
11
|
+
5. For TypeScript/JavaScript code patterns, prefer astRules over contentRules (zero false positives)
|
|
7
12
|
|
|
8
|
-
|
|
13
|
+
═══════════════════════════════════════════════════════════════
|
|
14
|
+
BUILT-IN AST RULES (DO NOT REGENERATE)
|
|
15
|
+
═══════════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
These restrictions have pre-built AST rules. Return ONLY the basic policy structure:
|
|
18
|
+
- "no lodash" → handled by builtin
|
|
19
|
+
- "no moment" → handled by builtin
|
|
20
|
+
- "no jquery" → handled by builtin
|
|
21
|
+
- "no axios" → handled by builtin
|
|
22
|
+
- "no any" / "no any types" → handled by builtin
|
|
23
|
+
- "no console" / "no console.log" → handled by builtin
|
|
24
|
+
- "no eval" → handled by builtin
|
|
25
|
+
- "no innerhtml" → handled by builtin
|
|
26
|
+
- "no debugger" → handled by builtin
|
|
27
|
+
- "no var" → handled by builtin
|
|
28
|
+
- "no alert" → handled by builtin
|
|
29
|
+
- "no class components" → handled by builtin
|
|
30
|
+
|
|
31
|
+
For these, return minimal policy:
|
|
32
|
+
{
|
|
33
|
+
"action": "modify",
|
|
34
|
+
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
|
|
35
|
+
"exclude": [],
|
|
36
|
+
"description": "<the restriction>"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
═══════════════════════════════════════════════════════════════
|
|
40
|
+
FILE-LEVEL POLICIES (include/exclude patterns)
|
|
41
|
+
═══════════════════════════════════════════════════════════════
|
|
9
42
|
|
|
10
43
|
"test files" means TEST SOURCE CODE:
|
|
11
44
|
include: ["*.test.*", "*.spec.*", "__tests__/**", "test/**/*.ts"]
|
|
12
45
|
exclude: ["test-results.*", "test-output.*", "coverage/**"]
|
|
13
46
|
|
|
14
|
-
"config files" means CONFIGURATION
|
|
47
|
+
"config files" means CONFIGURATION:
|
|
15
48
|
include: ["*.config.*", "tsconfig*", ".eslintrc*", "vite.config.*"]
|
|
16
49
|
exclude: []
|
|
17
50
|
|
|
@@ -19,19 +52,218 @@ EXAMPLES OF SEMANTIC UNDERSTANDING:
|
|
|
19
52
|
include: [".env", ".env.*", "**/.env", "**/.env.*"]
|
|
20
53
|
exclude: [".env.example", ".env.template"]
|
|
21
54
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
55
|
+
═══════════════════════════════════════════════════════════════
|
|
56
|
+
COMMAND-LEVEL POLICIES (commandRules)
|
|
57
|
+
═══════════════════════════════════════════════════════════════
|
|
58
|
+
|
|
59
|
+
For tool/command preferences, generate commandRules array.
|
|
60
|
+
|
|
61
|
+
"prefer pnpm" or "use pnpm not npm":
|
|
62
|
+
commandRules: [
|
|
63
|
+
{ block: ["npm install*", "npm i *", "npm i", "npm ci"], suggest: "pnpm install", reason: "Project uses pnpm" }
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
COMMAND PATTERN RULES:
|
|
67
|
+
- "command *" matches command with any args
|
|
68
|
+
- Include common aliases: npm i = npm install, bun a = bun add
|
|
69
|
+
|
|
70
|
+
═══════════════════════════════════════════════════════════════
|
|
71
|
+
CONTENT-LEVEL POLICIES (contentRules) - COMPREHENSIVE
|
|
72
|
+
═══════════════════════════════════════════════════════════════
|
|
73
|
+
|
|
74
|
+
CRITICAL: Generate MULTIPLE patterns to catch ALL import/usage variants.
|
|
75
|
+
|
|
76
|
+
"no lodash" - Must catch ALL these forms:
|
|
77
|
+
contentRules: [
|
|
78
|
+
{
|
|
79
|
+
pattern: "(?:import|require)\\\\s*(?:\\\\(|\\\\s).*['\"]lodash(?:[-./][^'\"]*)?['\"]",
|
|
80
|
+
fileTypes: ["*.ts", "*.js", "*.tsx", "*.jsx"],
|
|
81
|
+
reason: "Use native methods instead of lodash",
|
|
82
|
+
suggest: "Use Array.map(), filter(), Object.keys()",
|
|
83
|
+
mode: "strict"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
// This catches:
|
|
87
|
+
// - import _ from 'lodash'
|
|
88
|
+
// - import { map } from 'lodash'
|
|
89
|
+
// - import * as _ from 'lodash'
|
|
90
|
+
// - import map from 'lodash/map'
|
|
91
|
+
// - import map from 'lodash.map'
|
|
92
|
+
// - import _ from 'lodash-es'
|
|
93
|
+
// - require('lodash')
|
|
94
|
+
// - await import('lodash')
|
|
95
|
+
|
|
96
|
+
"no any types" - Must catch ALL these forms:
|
|
97
|
+
contentRules: [
|
|
98
|
+
{
|
|
99
|
+
pattern: "(?::\\\\s*any\\\\s*(?:[,;)\\\\]=]|$)|<\\\\s*any\\\\s*>|as\\\\s+any\\\\b)",
|
|
100
|
+
fileTypes: ["*.ts", "*.tsx"],
|
|
101
|
+
reason: "Use proper TypeScript types",
|
|
102
|
+
suggest: "Use unknown or specific types",
|
|
103
|
+
mode: "strict",
|
|
104
|
+
exceptions: ["(?:const|let|var|function)\\\\s+\\\\w*any\\\\w*"]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
pattern: "Array\\\\s*<\\\\s*any\\\\s*>",
|
|
108
|
+
fileTypes: ["*.ts", "*.tsx"],
|
|
109
|
+
reason: "Avoid Array<any>",
|
|
110
|
+
mode: "strict"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
pattern: "Record\\\\s*<[^>]*,\\\\s*any\\\\s*>",
|
|
114
|
+
fileTypes: ["*.ts", "*.tsx"],
|
|
115
|
+
reason: "Avoid Record<string, any>",
|
|
116
|
+
mode: "strict"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
pattern: "type\\\\s+\\\\w+\\\\s*=\\\\s*any\\\\s*;",
|
|
120
|
+
fileTypes: ["*.ts", "*.tsx"],
|
|
121
|
+
reason: "Avoid type alias to any",
|
|
122
|
+
mode: "strict"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
// This catches:
|
|
126
|
+
// - : any
|
|
127
|
+
// - <any>
|
|
128
|
+
// - as any
|
|
129
|
+
// - Array<any>
|
|
130
|
+
// - Record<string, any>
|
|
131
|
+
// - Promise<any>
|
|
132
|
+
// - type Foo = any
|
|
133
|
+
// - <T = any>
|
|
134
|
+
// But NOT:
|
|
135
|
+
// - const anyValue = 5 (variable name)
|
|
136
|
+
// - "any" in strings (mode: strict)
|
|
137
|
+
// - // any in comments (mode: strict)
|
|
138
|
+
|
|
139
|
+
"no console.log" - Must catch ALL these forms:
|
|
140
|
+
contentRules: [
|
|
141
|
+
{
|
|
142
|
+
pattern: "\\\\bconsole\\\\s*\\\\.\\\\s*log\\\\s*\\\\(",
|
|
143
|
+
fileTypes: ["*.ts", "*.js"],
|
|
144
|
+
reason: "Use proper logging",
|
|
145
|
+
mode: "strict"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
pattern: "console\\\\s*\\\\[\\\\s*['\"]log['\"]\\\\s*\\\\]",
|
|
149
|
+
fileTypes: ["*.ts", "*.js"],
|
|
150
|
+
reason: "Console accessed via bracket notation",
|
|
151
|
+
mode: "strict"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
pattern: "\\\\{\\\\s*log(?:\\\\s*:\\\\s*\\\\w+)?\\\\s*\\\\}\\\\s*=\\\\s*console",
|
|
155
|
+
fileTypes: ["*.ts", "*.js"],
|
|
156
|
+
reason: "Destructured console.log detected",
|
|
157
|
+
mode: "strict"
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
// This catches:
|
|
161
|
+
// - console.log(
|
|
162
|
+
// - console['log'](
|
|
163
|
+
// - const { log } = console
|
|
164
|
+
// - const { log: myLog } = console
|
|
165
|
+
|
|
166
|
+
"no class components" (React):
|
|
167
|
+
contentRules: [
|
|
168
|
+
{
|
|
169
|
+
pattern: "class\\\\s+\\\\w+\\\\s+extends\\\\s+(?:React\\\\s*\\\\.\\\\s*)?(?:Pure)?Component\\\\s*(?:<|\\\\{)",
|
|
170
|
+
fileTypes: ["*.tsx", "*.jsx"],
|
|
171
|
+
reason: "Use functional components with hooks",
|
|
172
|
+
suggest: "const Component = () => { ... }",
|
|
173
|
+
mode: "strict"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
// This catches:
|
|
177
|
+
// - class Foo extends Component {
|
|
178
|
+
// - class Foo extends React.Component {
|
|
179
|
+
// - class Foo extends PureComponent {
|
|
180
|
+
// - class Foo extends Component<Props> {
|
|
181
|
+
|
|
182
|
+
"no eval" - Must catch ALL unsafe eval-like constructs:
|
|
183
|
+
contentRules: [
|
|
184
|
+
{
|
|
185
|
+
pattern: "\\\\beval\\\\s*\\\\(",
|
|
186
|
+
fileTypes: ["*.ts", "*.js"],
|
|
187
|
+
reason: "eval() is a security risk",
|
|
188
|
+
mode: "strict"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
pattern: "new\\\\s+Function\\\\s*\\\\(",
|
|
192
|
+
fileTypes: ["*.ts", "*.js"],
|
|
193
|
+
reason: "new Function() is equivalent to eval()",
|
|
194
|
+
mode: "strict"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
pattern: "setTimeout\\\\s*\\\\(\\\\s*['\"]",
|
|
198
|
+
fileTypes: ["*.ts", "*.js"],
|
|
199
|
+
reason: "setTimeout with string is eval-like",
|
|
200
|
+
mode: "strict"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
═══════════════════════════════════════════════════════════════
|
|
205
|
+
CONTENT RULE OPTIONS
|
|
206
|
+
═══════════════════════════════════════════════════════════════
|
|
207
|
+
|
|
208
|
+
mode (optional):
|
|
209
|
+
- "fast": Direct regex match (default, fastest, may have false positives)
|
|
210
|
+
- "strict": Strip comments/strings before matching (recommended for most rules)
|
|
211
|
+
|
|
212
|
+
exceptions (optional):
|
|
213
|
+
- Array of regex patterns that indicate FALSE POSITIVES
|
|
214
|
+
- If exception matches context around the main match, rule is NOT violated
|
|
215
|
+
- Example: Don't flag 'any' in variable names like 'anyValue'
|
|
216
|
+
|
|
217
|
+
fileTypes:
|
|
218
|
+
- Array of glob patterns: ["*.ts", "*.tsx", "*.js"]
|
|
219
|
+
- Use specific types, not broad patterns
|
|
220
|
+
|
|
221
|
+
═══════════════════════════════════════════════════════════════
|
|
222
|
+
AST RULES (PREFERRED FOR TS/JS - ZERO FALSE POSITIVES)
|
|
223
|
+
═══════════════════════════════════════════════════════════════
|
|
224
|
+
|
|
225
|
+
For TypeScript/JavaScript code patterns NOT covered by builtins, generate astRules.
|
|
226
|
+
AST rules use tree-sitter S-expression queries - they NEVER match comments or strings.
|
|
227
|
+
|
|
228
|
+
Format:
|
|
229
|
+
astRules: [{
|
|
230
|
+
id: "unique-rule-id",
|
|
231
|
+
query: "(tree_sitter_query) @capture",
|
|
232
|
+
languages: ["typescript", "javascript"],
|
|
233
|
+
reason: "Why this is blocked",
|
|
234
|
+
suggest: "Alternative approach",
|
|
235
|
+
regexPreFilter: "fast_string_check"
|
|
236
|
+
}]
|
|
237
|
+
|
|
238
|
+
Common query patterns:
|
|
239
|
+
(import_statement source: (string) @s (#match? @s "pattern")) - imports
|
|
240
|
+
(call_expression function: (identifier) @fn (#eq? @fn "name")) - function calls
|
|
241
|
+
(type_annotation (predefined_type) @t (#eq? @t "any")) - type annotations
|
|
242
|
+
|
|
243
|
+
ALWAYS include regexPreFilter for performance (skips AST if string not found).
|
|
244
|
+
|
|
245
|
+
═══════════════════════════════════════════════════════════════
|
|
246
|
+
BEST PRACTICES
|
|
247
|
+
═══════════════════════════════════════════════════════════════
|
|
248
|
+
|
|
249
|
+
1. ALWAYS generate multiple contentRules to catch ALL variants
|
|
250
|
+
2. USE mode: "strict" for patterns that might appear in comments/strings
|
|
251
|
+
3. ADD exceptions for common false positive patterns
|
|
252
|
+
4. INCLUDE word boundaries (\\b) to avoid partial matches
|
|
253
|
+
5. For imports, catch: ES6 import, CommonJS require, dynamic import, submodules
|
|
254
|
+
6. For types, catch: annotations, generics, assertions, aliases
|
|
255
|
+
7. For function calls, catch: direct calls, bracket notation, destructuring
|
|
25
256
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- "ends with X" → ["*X", "**/*X"]
|
|
30
|
-
- "contains X" → ["*X*", "**/*X*"]
|
|
31
|
-
- "in directory X" → ["X/**"]
|
|
257
|
+
═══════════════════════════════════════════════════════════════
|
|
258
|
+
DECISION TREE
|
|
259
|
+
═══════════════════════════════════════════════════════════════
|
|
32
260
|
|
|
33
|
-
|
|
34
|
-
|
|
261
|
+
1. If about FILES (test files, .env, configs) → use include/exclude
|
|
262
|
+
2. If about COMMANDS/TOOLS (npm vs pnpm, jest vs vitest) → use commandRules
|
|
263
|
+
3. If about TS/JS CODE PATTERNS and matches a builtin → return minimal policy (handled by builtin)
|
|
264
|
+
4. If about TS/JS CODE PATTERNS not covered by builtin → use astRules (zero false positives)
|
|
265
|
+
5. If about non-TS/JS CODE PATTERNS → use contentRules with mode: "strict"
|
|
266
|
+
6. If about PREVENTING PACKAGE → use commandRules + astRules (or contentRules for non-JS)
|
|
35
267
|
|
|
36
268
|
Output JSON only. No explanation.`;
|
|
37
269
|
//# sourceMappingURL=prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/compiler/prompt.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,MAAM,CAAC,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/compiler/prompt.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCA0QK,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface LeashPolicy {
|
|
2
|
+
raw: string;
|
|
3
|
+
restriction: string;
|
|
4
|
+
reason?: string;
|
|
5
|
+
extend?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse a simple .leash file into policies.
|
|
9
|
+
*
|
|
10
|
+
* Format:
|
|
11
|
+
* # Comment lines start with #
|
|
12
|
+
* no lodash
|
|
13
|
+
* no any types - enforces strict TypeScript
|
|
14
|
+
* extend @acme/typescript-strict
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseLeashFile(content: string): LeashPolicy[];
|
|
17
|
+
/**
|
|
18
|
+
* Detect if content is simple .leash format (not YAML).
|
|
19
|
+
* YAML format has 'version:' or 'policies:' keys.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isSimpleLeashFormat(content: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Convert parsed policies to the internal LeashConfig format.
|
|
24
|
+
*/
|
|
25
|
+
export declare function policiesToConfig(policies: LeashPolicy[]): {
|
|
26
|
+
version: 1;
|
|
27
|
+
policies: string[];
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=leash-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leash-parser.d.ts","sourceRoot":"","sources":["../../src/config/leash-parser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAM7D;AAqBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAiB5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAAE,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAO5F"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/config/leash-parser.ts
|
|
2
|
+
// Simple plain-text .leash file parser
|
|
3
|
+
// Format: one policy per line, # for comments, ` - ` for optional reason
|
|
4
|
+
/**
|
|
5
|
+
* Parse a simple .leash file into policies.
|
|
6
|
+
*
|
|
7
|
+
* Format:
|
|
8
|
+
* # Comment lines start with #
|
|
9
|
+
* no lodash
|
|
10
|
+
* no any types - enforces strict TypeScript
|
|
11
|
+
* extend @acme/typescript-strict
|
|
12
|
+
*/
|
|
13
|
+
export function parseLeashFile(content) {
|
|
14
|
+
return content
|
|
15
|
+
.split('\n')
|
|
16
|
+
.map(line => line.trim())
|
|
17
|
+
.filter(line => line && !line.startsWith('#'))
|
|
18
|
+
.map(parseLine);
|
|
19
|
+
}
|
|
20
|
+
function parseLine(line) {
|
|
21
|
+
// Handle extend directive
|
|
22
|
+
if (line.startsWith('extend ')) {
|
|
23
|
+
const target = line.slice(7).trim();
|
|
24
|
+
return { raw: line, restriction: '', extend: target };
|
|
25
|
+
}
|
|
26
|
+
// Split by ' - ' for optional reason
|
|
27
|
+
const dashIndex = line.indexOf(' - ');
|
|
28
|
+
if (dashIndex !== -1) {
|
|
29
|
+
const restriction = line.slice(0, dashIndex).trim();
|
|
30
|
+
const reason = line.slice(dashIndex + 3).trim();
|
|
31
|
+
return { raw: line, restriction, reason };
|
|
32
|
+
}
|
|
33
|
+
// Simple policy without reason
|
|
34
|
+
return { raw: line, restriction: line };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Detect if content is simple .leash format (not YAML).
|
|
38
|
+
* YAML format has 'version:' or 'policies:' keys.
|
|
39
|
+
*/
|
|
40
|
+
export function isSimpleLeashFormat(content) {
|
|
41
|
+
const trimmed = content.trim();
|
|
42
|
+
// Empty file = simple format (will result in no policies)
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
return true;
|
|
45
|
+
// Check first meaningful line
|
|
46
|
+
const lines = trimmed.split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#'));
|
|
47
|
+
if (lines.length === 0)
|
|
48
|
+
return true;
|
|
49
|
+
// YAML indicators
|
|
50
|
+
const firstLine = lines[0];
|
|
51
|
+
if (firstLine.startsWith('version:'))
|
|
52
|
+
return false;
|
|
53
|
+
if (firstLine.startsWith('policies:'))
|
|
54
|
+
return false;
|
|
55
|
+
if (firstLine.startsWith('{'))
|
|
56
|
+
return false; // JSON
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Convert parsed policies to the internal LeashConfig format.
|
|
61
|
+
*/
|
|
62
|
+
export function policiesToConfig(policies) {
|
|
63
|
+
return {
|
|
64
|
+
version: 1,
|
|
65
|
+
policies: policies
|
|
66
|
+
.filter(p => p.restriction) // Skip extend directives for now
|
|
67
|
+
.map(p => p.restriction),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=leash-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leash-parser.js","sourceRoot":"","sources":["../../src/config/leash-parser.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,uCAAuC;AACvC,yEAAyE;AASzE;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,OAAO;SACX,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC7C,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,0BAA0B;IAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACxD,CAAC;IAED,qCAAqC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAC5C,CAAC;IAED,+BAA+B;IAC/B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAE/B,0DAA0D;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,8BAA8B;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,kBAAkB;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,CAAE,OAAO;IAErD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAuB;IACtD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,QAAQ;aACf,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAE,iCAAiC;aAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;KAC3B,CAAC;AACJ,CAAC"}
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { type LeashConfig, type CompiledLeashConfig } from './schema.js';
|
|
|
5
5
|
export declare function findLeashConfig(dir?: string): string | null;
|
|
6
6
|
/**
|
|
7
7
|
* Load and parse .leash config
|
|
8
|
+
* Supports both simple plain-text format and YAML format.
|
|
8
9
|
*/
|
|
9
10
|
export declare function loadLeashConfig(path: string): LeashConfig | null;
|
|
10
11
|
/**
|
|
@@ -12,7 +13,7 @@ export declare function loadLeashConfig(path: string): LeashConfig | null;
|
|
|
12
13
|
*/
|
|
13
14
|
export declare function compileLeashConfig(config: LeashConfig): Promise<CompiledLeashConfig>;
|
|
14
15
|
/**
|
|
15
|
-
* Create a new .leash config file
|
|
16
|
+
* Create a new .leash config file (simple plain-text format)
|
|
16
17
|
*/
|
|
17
18
|
export declare function createLeashConfig(dir?: string): string;
|
|
18
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AAUrB;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAW1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAmChE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAwB9B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAcrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAEnE"}
|