prompt-guard-cli 0.1.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.
- package/.prompt-guard.json.example +14 -0
- package/LICENSE +21 -0
- package/README.md +200 -0
- package/bin/prompt-guard +56 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +467 -0
- package/dist/index.js.map +1 -0
- package/dist/smart-relevance.d.ts +37 -0
- package/dist/smart-relevance.d.ts.map +1 -0
- package/dist/smart-relevance.js +91 -0
- package/dist/smart-relevance.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contextFiles": ["PROJECT.md", "CONTEXT.md", "README.md"],
|
|
3
|
+
"enabledChecks": ["files-mentioned", "tests-mentioned", "success-criteria", "constraints", "local-env", "context-window"],
|
|
4
|
+
"autoInject": true,
|
|
5
|
+
"confirmBeforeSend": true,
|
|
6
|
+
"maxContextTokens": 4000,
|
|
7
|
+
"modelLimits": {
|
|
8
|
+
"claude": 100000,
|
|
9
|
+
"claude-opus": 200000,
|
|
10
|
+
"gpt-4": 8000,
|
|
11
|
+
"gpt-4-turbo": 128000,
|
|
12
|
+
"cursor": 8000
|
|
13
|
+
}
|
|
14
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mohammed Wasif
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Prompt Guard
|
|
2
|
+
|
|
3
|
+
> Context-aware prompt enhancement for AI coding agents
|
|
4
|
+
|
|
5
|
+
Prompt Guard reads your project's `.md` files and automatically injects relevant context into your prompts before sending them to Claude, Cursor, or any AI coding agent.
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
You type: `"refactor the auth system"`
|
|
10
|
+
|
|
11
|
+
The AI doesn't know:
|
|
12
|
+
- You're using JWT tokens
|
|
13
|
+
- You have a PostgreSQL database
|
|
14
|
+
- Your team requires 90% test coverage
|
|
15
|
+
- You can't break the existing API
|
|
16
|
+
|
|
17
|
+
**Result:** Generic code that doesn't fit your project.
|
|
18
|
+
|
|
19
|
+
## The Solution
|
|
20
|
+
|
|
21
|
+
Prompt Guard reads `PROJECT.md`, `CONTEXT.md`, `AGENTS.md` and enhances your prompt:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
## Project Context
|
|
25
|
+
|
|
26
|
+
### From PROJECT.md:
|
|
27
|
+
- Tech Stack: Node.js, Express, PostgreSQL
|
|
28
|
+
- Auth: JWT tokens with 24h expiry
|
|
29
|
+
- Testing: Jest with 90% coverage requirement
|
|
30
|
+
|
|
31
|
+
### From CONTEXT.md:
|
|
32
|
+
- Always write tests for new features
|
|
33
|
+
- Don't break existing APIs without versioning
|
|
34
|
+
- Keep functions under 50 lines
|
|
35
|
+
|
|
36
|
+
## User Request
|
|
37
|
+
|
|
38
|
+
refactor the auth system
|
|
39
|
+
|
|
40
|
+
## Instructions
|
|
41
|
+
- Consider the project context above
|
|
42
|
+
- Follow any patterns or conventions mentioned
|
|
43
|
+
- If tests are mentioned in context, include them
|
|
44
|
+
- Respect any constraints from the context files
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Result:** Code that actually fits your project.
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g prompt-guard-cli
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### 1. Initialize in your project
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd your-project
|
|
61
|
+
prompt-guard-cli init
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This creates:
|
|
65
|
+
- `PROJECT.md` — Your project overview, tech stack, architecture
|
|
66
|
+
- `CONTEXT.md` — Coding conventions, patterns, constraints
|
|
67
|
+
|
|
68
|
+
### 2. Edit the context files
|
|
69
|
+
|
|
70
|
+
Fill in `PROJECT.md` and `CONTEXT.md` with your project details.
|
|
71
|
+
|
|
72
|
+
### 3. Check your prompts
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
prompt-guard-cli check "add user login"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Output:
|
|
79
|
+
```
|
|
80
|
+
⚠ No specific files mentioned
|
|
81
|
+
→ Add file paths like "src/auth/**" or "update login.js"
|
|
82
|
+
|
|
83
|
+
⚠ No tests or validation criteria mentioned
|
|
84
|
+
→ Add "include tests" or "should handle X cases"
|
|
85
|
+
|
|
86
|
+
ℹ No constraints mentioned
|
|
87
|
+
→ Consider adding "don't break existing API" or "keep under 100 lines"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 4. Enhance and send
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
prompt-guard-cli enhance "add user login" | claude
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Commands
|
|
97
|
+
|
|
98
|
+
- `prompt-guard-cli init` — Create context files in current project
|
|
99
|
+
- `prompt-guard-cli check <prompt>` — Check for missing context
|
|
100
|
+
- `prompt-guard-cli enhance <prompt>` — Enhance with context
|
|
101
|
+
- `prompt-guard-cli config` — Show current configuration
|
|
102
|
+
|
|
103
|
+
## Shell Integration
|
|
104
|
+
|
|
105
|
+
Add to your `.zshrc` or `.bashrc`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Auto-enhance all claude commands
|
|
109
|
+
alias claude='prompt-guard-cli enhance'
|
|
110
|
+
|
|
111
|
+
# Or check before sending
|
|
112
|
+
claude() {
|
|
113
|
+
prompt-guard-cli check "$*"
|
|
114
|
+
read -q "REPLY?Continue? [y/N] "
|
|
115
|
+
echo
|
|
116
|
+
if [[ $REPLY == "y" ]]; then
|
|
117
|
+
command claude "$(prompt-guard-cli enhance "$*")"
|
|
118
|
+
fi
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Context Files
|
|
123
|
+
|
|
124
|
+
Prompt Guard looks for these files in your project root:
|
|
125
|
+
|
|
126
|
+
| File | Purpose |
|
|
127
|
+
|------|---------|
|
|
128
|
+
| `PROJECT.md` | Tech stack, architecture, entry points |
|
|
129
|
+
| `CONTEXT.md` | Coding conventions, patterns, constraints |
|
|
130
|
+
| `AGENTS.md` | Agent-specific instructions |
|
|
131
|
+
| `SOUL.md` | Project philosophy, values |
|
|
132
|
+
| `README.md` | Fallback for basic context |
|
|
133
|
+
|
|
134
|
+
## Configuration
|
|
135
|
+
|
|
136
|
+
Create `.prompt-guard.json` in your project root:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"contextFiles": ["PROJECT.md", "CONTEXT.md"],
|
|
141
|
+
"enabledChecks": ["files-mentioned", "tests-mentioned"],
|
|
142
|
+
"autoInject": true,
|
|
143
|
+
"confirmBeforeSend": true
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## How It Works
|
|
148
|
+
|
|
149
|
+
1. **Load Context** — Reads `.md` files from project root
|
|
150
|
+
2. **Parse Prompt** — Analyzes your prompt for completeness
|
|
151
|
+
3. **Check** — Identifies missing context (files, tests, criteria)
|
|
152
|
+
4. **Enhance** — Injects relevant context into the prompt
|
|
153
|
+
5. **Send** — Outputs enhanced prompt to your AI agent
|
|
154
|
+
|
|
155
|
+
## Privacy
|
|
156
|
+
|
|
157
|
+
- Only reads files you specify
|
|
158
|
+
- No data sent to external servers
|
|
159
|
+
- Context stays local to your machine
|
|
160
|
+
- No AI calls made by Prompt Guard itself
|
|
161
|
+
|
|
162
|
+
## Why This Matters
|
|
163
|
+
|
|
164
|
+
**Without context:**
|
|
165
|
+
```
|
|
166
|
+
User: "add caching"
|
|
167
|
+
AI: Generic Redis setup that doesn't fit your stack
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**With context:**
|
|
171
|
+
```
|
|
172
|
+
Context: "Using Node.js, PostgreSQL, already have Redis for sessions"
|
|
173
|
+
User: "add caching"
|
|
174
|
+
AI: Extends existing Redis setup, adds cache layer to DB queries
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Roadmap
|
|
178
|
+
|
|
179
|
+
**Current (v0.1.0):**
|
|
180
|
+
- [x] CLI tool with check/enhance commands
|
|
181
|
+
- [x] Context file loading (PROJECT.md, CONTEXT.md, etc.)
|
|
182
|
+
- [x] Config file support (.prompt-guard.json)
|
|
183
|
+
- [x] Local environment sanitization
|
|
184
|
+
- [x] Context window protection with auto-truncation
|
|
185
|
+
- [x] Token estimation
|
|
186
|
+
- [x] 6 built-in checks (files, tests, criteria, constraints, local-env, context-window)
|
|
187
|
+
|
|
188
|
+
**Coming Soon:**
|
|
189
|
+
- [ ] VS Code extension
|
|
190
|
+
- [ ] Cursor/Copilot integration
|
|
191
|
+
- [ ] Smart context relevance scoring
|
|
192
|
+
- [ ] Team-shared context templates
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
|
197
|
+
|
|
198
|
+
## Contributing
|
|
199
|
+
|
|
200
|
+
PRs welcome! This is a weekend project that grew out of frustration with generic AI code.
|
package/bin/prompt-guard
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { PromptGuard } = require('../dist/index');
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
|
|
8
|
+
if (args.length === 0) {
|
|
9
|
+
console.log('Usage: prompt-guard <command> [options]');
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log('Commands:');
|
|
12
|
+
console.log(' check <prompt> Check a prompt for missing context');
|
|
13
|
+
console.log(' enhance <prompt> Enhance prompt with context from .md files');
|
|
14
|
+
console.log(' relevance <prompt> Show context relevance scoring');
|
|
15
|
+
console.log(' config Show current configuration');
|
|
16
|
+
console.log(' init Initialize prompt-guard in current project');
|
|
17
|
+
console.log('');
|
|
18
|
+
console.log('Examples:');
|
|
19
|
+
console.log(' prompt-guard-cli check "refactor auth system"');
|
|
20
|
+
console.log(' prompt-guard-cli enhance "add user login" --agent claude');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const [command, ...rest] = args;
|
|
25
|
+
const promptText = rest.join(' ');
|
|
26
|
+
|
|
27
|
+
const guard = new PromptGuard();
|
|
28
|
+
|
|
29
|
+
switch (command) {
|
|
30
|
+
case 'check':
|
|
31
|
+
const results = await guard.check(promptText);
|
|
32
|
+
guard.displayResults(results);
|
|
33
|
+
break;
|
|
34
|
+
case 'enhance':
|
|
35
|
+
const enhanced = await guard.enhance(promptText);
|
|
36
|
+
console.log(enhanced);
|
|
37
|
+
break;
|
|
38
|
+
case 'relevance':
|
|
39
|
+
const { SmartRelevance } = require('../dist/smart-relevance');
|
|
40
|
+
const relevance = new SmartRelevance(guard);
|
|
41
|
+
const report = await relevance.generateRelevanceReport(promptText);
|
|
42
|
+
console.log(report);
|
|
43
|
+
break;
|
|
44
|
+
case 'config':
|
|
45
|
+
guard.showConfig();
|
|
46
|
+
break;
|
|
47
|
+
case 'init':
|
|
48
|
+
await guard.init();
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
console.error(`Unknown command: ${command}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
main().catch(console.error);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
interface ContextFile {
|
|
2
|
+
name: string;
|
|
3
|
+
content: string;
|
|
4
|
+
relevance: number;
|
|
5
|
+
}
|
|
6
|
+
interface CheckResult {
|
|
7
|
+
type: 'warning' | 'error' | 'info';
|
|
8
|
+
message: string;
|
|
9
|
+
suggestion?: string;
|
|
10
|
+
}
|
|
11
|
+
interface Config {
|
|
12
|
+
contextFiles: string[];
|
|
13
|
+
enabledChecks: string[];
|
|
14
|
+
autoInject: boolean;
|
|
15
|
+
confirmBeforeSend: boolean;
|
|
16
|
+
maxContextTokens: number;
|
|
17
|
+
modelLimits: Record<string, number>;
|
|
18
|
+
}
|
|
19
|
+
export declare class PromptGuard {
|
|
20
|
+
private config;
|
|
21
|
+
private contextCache;
|
|
22
|
+
constructor(config?: Partial<Config>, projectPath?: string);
|
|
23
|
+
/**
|
|
24
|
+
* Load configuration from .prompt-guard.json file
|
|
25
|
+
*/
|
|
26
|
+
private loadFileConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Load context from .md files in project root
|
|
29
|
+
* Filters out local environment specifics to prevent overfitting
|
|
30
|
+
*/
|
|
31
|
+
loadContext(projectPath?: string): Promise<ContextFile[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Remove local environment specifics that cause overfitting
|
|
34
|
+
*/
|
|
35
|
+
private sanitizeLocalEnv;
|
|
36
|
+
/**
|
|
37
|
+
* Check a prompt for missing context
|
|
38
|
+
*/
|
|
39
|
+
check(promptText: string): Promise<CheckResult[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Enhance prompt with context from .md files
|
|
42
|
+
* Respects context window limits
|
|
43
|
+
*/
|
|
44
|
+
enhance(promptText: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Display check results with formatting
|
|
47
|
+
*/
|
|
48
|
+
displayResults(results: CheckResult[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Initialize prompt-guard in current project
|
|
51
|
+
*/
|
|
52
|
+
init(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Show current configuration
|
|
55
|
+
*/
|
|
56
|
+
showConfig(): void;
|
|
57
|
+
private hasFileReferences;
|
|
58
|
+
private hasTestReferences;
|
|
59
|
+
private hasSuccessCriteria;
|
|
60
|
+
private hasConstraints;
|
|
61
|
+
private checkLocalEnvReferences;
|
|
62
|
+
private calculateRelevance;
|
|
63
|
+
private truncateContent;
|
|
64
|
+
/**
|
|
65
|
+
* Estimate token count (rough approximation: ~4 chars per token)
|
|
66
|
+
*/
|
|
67
|
+
private estimateTokens;
|
|
68
|
+
private getProjectTemplate;
|
|
69
|
+
private getContextTemplate;
|
|
70
|
+
}
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,MAAM;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAkC;gBAE1C,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAE,MAAsB;IAsBzE;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;;OAGG;IACG,WAAW,CAAC,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAyB9E;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgCxB;;OAEG;IACG,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAwEvD;;;OAGG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2ElD;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IAqB5C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B3B;;OAEG;IACH,UAAU,IAAI,IAAI;IAWlB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,uBAAuB;IA0B/B,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,kBAAkB;IA6B1B,OAAO,CAAC,kBAAkB;CAyB3B"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.PromptGuard = void 0;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
class PromptGuard {
|
|
44
|
+
constructor(config, projectPath = process.cwd()) {
|
|
45
|
+
this.contextCache = new Map();
|
|
46
|
+
// Load config from .prompt-guard.json if it exists
|
|
47
|
+
const fileConfig = this.loadFileConfig(projectPath);
|
|
48
|
+
this.config = {
|
|
49
|
+
contextFiles: ['PROJECT.md', 'SOUL.md', 'AGENTS.md', 'CONTEXT.md', 'README.md'],
|
|
50
|
+
enabledChecks: ['files-mentioned', 'tests-mentioned', 'success-criteria', 'constraints', 'local-env', 'context-window'],
|
|
51
|
+
autoInject: true,
|
|
52
|
+
confirmBeforeSend: true,
|
|
53
|
+
maxContextTokens: 4000, // Default: leave room for response
|
|
54
|
+
modelLimits: {
|
|
55
|
+
'claude': 100000,
|
|
56
|
+
'claude-opus': 200000,
|
|
57
|
+
'gpt-4': 8000,
|
|
58
|
+
'gpt-4-turbo': 128000,
|
|
59
|
+
'cursor': 8000
|
|
60
|
+
},
|
|
61
|
+
...fileConfig,
|
|
62
|
+
...config
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Load configuration from .prompt-guard.json file
|
|
67
|
+
*/
|
|
68
|
+
loadFileConfig(projectPath) {
|
|
69
|
+
const configPath = path.join(projectPath, '.prompt-guard.json');
|
|
70
|
+
if (fs.existsSync(configPath)) {
|
|
71
|
+
try {
|
|
72
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
73
|
+
return JSON.parse(content);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
console.warn(chalk_1.default.yellow('⚠ Failed to parse .prompt-guard.json, using defaults'));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Load context from .md files in project root
|
|
83
|
+
* Filters out local environment specifics to prevent overfitting
|
|
84
|
+
*/
|
|
85
|
+
async loadContext(projectPath = process.cwd()) {
|
|
86
|
+
const contextFiles = [];
|
|
87
|
+
for (const fileName of this.config.contextFiles) {
|
|
88
|
+
const filePath = path.join(projectPath, fileName);
|
|
89
|
+
if (fs.existsSync(filePath)) {
|
|
90
|
+
let content = fs.readFileSync(filePath, 'utf-8');
|
|
91
|
+
// Sanitize content to remove local environment specifics
|
|
92
|
+
content = this.sanitizeLocalEnv(content);
|
|
93
|
+
this.contextCache.set(fileName, content);
|
|
94
|
+
contextFiles.push({
|
|
95
|
+
name: fileName,
|
|
96
|
+
content: this.truncateContent(content, 2000),
|
|
97
|
+
relevance: this.calculateRelevance(fileName)
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return contextFiles;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Remove local environment specifics that cause overfitting
|
|
105
|
+
*/
|
|
106
|
+
sanitizeLocalEnv(content) {
|
|
107
|
+
// Remove absolute paths
|
|
108
|
+
content = content.replace(/\/Users\/\w+|\/home\/\w+|C:\\Users\\\w+/g, '<USER_HOME>');
|
|
109
|
+
// Remove local ports (keep common ones like 3000, 8080 as examples)
|
|
110
|
+
content = content.replace(/localhost:\d{4,5}/g, (match) => {
|
|
111
|
+
const port = parseInt(match.split(':')[1]);
|
|
112
|
+
// Keep common ports as examples, redact others
|
|
113
|
+
if ([3000, 3001, 8080, 8000].includes(port)) {
|
|
114
|
+
return match;
|
|
115
|
+
}
|
|
116
|
+
return 'localhost:<PORT>';
|
|
117
|
+
});
|
|
118
|
+
// Remove API keys and tokens
|
|
119
|
+
content = content.replace(/(api[_-]?key|token|secret|password)\s*[:=]\s*['"\w-]+/gi, '$1: <REDACTED>');
|
|
120
|
+
// Remove local file paths but keep relative ones
|
|
121
|
+
content = content.replace(/\/\w+\/\w+\/[^\s]+\.(js|ts|json|md)/g, (match) => {
|
|
122
|
+
// Keep relative paths (starting with ./ or ../ or src/)
|
|
123
|
+
if (match.startsWith('./') || match.startsWith('../') || match.startsWith('src/')) {
|
|
124
|
+
return match;
|
|
125
|
+
}
|
|
126
|
+
return '<LOCAL_PATH>';
|
|
127
|
+
});
|
|
128
|
+
// Remove machine-specific config
|
|
129
|
+
content = content.replace(/(hostname|computer name|machine|device):\s*\w+/gi, '$1: <MACHINE>');
|
|
130
|
+
return content;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check a prompt for missing context
|
|
134
|
+
*/
|
|
135
|
+
async check(promptText) {
|
|
136
|
+
const results = [];
|
|
137
|
+
// Check 1: Files mentioned
|
|
138
|
+
if (!this.hasFileReferences(promptText)) {
|
|
139
|
+
results.push({
|
|
140
|
+
type: 'warning',
|
|
141
|
+
message: 'No specific files mentioned',
|
|
142
|
+
suggestion: 'Add file paths like "src/auth/**" or "update login.js"'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Check 2: Tests mentioned
|
|
146
|
+
if (!this.hasTestReferences(promptText)) {
|
|
147
|
+
results.push({
|
|
148
|
+
type: 'warning',
|
|
149
|
+
message: 'No tests or validation criteria mentioned',
|
|
150
|
+
suggestion: 'Add "include tests" or "should handle X cases"'
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Check 3: Success criteria
|
|
154
|
+
if (!this.hasSuccessCriteria(promptText)) {
|
|
155
|
+
results.push({
|
|
156
|
+
type: 'warning',
|
|
157
|
+
message: 'No clear success criteria',
|
|
158
|
+
suggestion: 'Add "should pass all tests" or "must handle 10k req/s"'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Check 4: Constraints
|
|
162
|
+
if (!this.hasConstraints(promptText)) {
|
|
163
|
+
results.push({
|
|
164
|
+
type: 'info',
|
|
165
|
+
message: 'No constraints mentioned',
|
|
166
|
+
suggestion: 'Consider adding "don\'t break existing API" or "keep under 100 lines"'
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Check 5: Local environment references (overfitting risk)
|
|
170
|
+
const localEnvIssues = this.checkLocalEnvReferences(promptText);
|
|
171
|
+
if (localEnvIssues.length > 0) {
|
|
172
|
+
results.push({
|
|
173
|
+
type: 'warning',
|
|
174
|
+
message: 'Prompt contains local environment references',
|
|
175
|
+
suggestion: `Remove: ${localEnvIssues.join(', ')}. Use relative paths and generic config instead.`
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// Check 6: Context window size
|
|
179
|
+
const estimatedTokens = this.estimateTokens(promptText);
|
|
180
|
+
const contextFiles = await this.loadContext();
|
|
181
|
+
const contextTokens = contextFiles.reduce((sum, f) => sum + this.estimateTokens(f.content), 0);
|
|
182
|
+
const totalTokens = estimatedTokens + contextTokens;
|
|
183
|
+
if (totalTokens > this.config.maxContextTokens) {
|
|
184
|
+
results.push({
|
|
185
|
+
type: 'error',
|
|
186
|
+
message: `Context window will be exceeded (~${totalTokens} tokens)`,
|
|
187
|
+
suggestion: `Reduce context files or truncate content. Current: ${contextFiles.length} files, ${contextTokens} tokens of context. Try removing less relevant .md files.`
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else if (totalTokens > this.config.maxContextTokens * 0.8) {
|
|
191
|
+
results.push({
|
|
192
|
+
type: 'warning',
|
|
193
|
+
message: `Approaching context limit (~${totalTokens} tokens)`,
|
|
194
|
+
suggestion: 'Consider truncating context files or removing less relevant ones. Leave room for AI response.'
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return results;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Enhance prompt with context from .md files
|
|
201
|
+
* Respects context window limits
|
|
202
|
+
*/
|
|
203
|
+
async enhance(promptText) {
|
|
204
|
+
let contextFiles = await this.loadContext();
|
|
205
|
+
if (contextFiles.length === 0) {
|
|
206
|
+
console.log(chalk_1.default.yellow('No context files found. Run `prompt-guard init` to create them.'));
|
|
207
|
+
return promptText;
|
|
208
|
+
}
|
|
209
|
+
// Check context window and truncate if needed
|
|
210
|
+
const promptTokens = this.estimateTokens(promptText);
|
|
211
|
+
const instructionsTokens = 100; // Approximate
|
|
212
|
+
let availableTokens = this.config.maxContextTokens - promptTokens - instructionsTokens;
|
|
213
|
+
// Sort by relevance and truncate if needed
|
|
214
|
+
contextFiles.sort((a, b) => b.relevance - a.relevance);
|
|
215
|
+
let totalContextTokens = 0;
|
|
216
|
+
const includedFiles = [];
|
|
217
|
+
for (const file of contextFiles) {
|
|
218
|
+
const fileTokens = this.estimateTokens(file.content);
|
|
219
|
+
if (totalContextTokens + fileTokens <= availableTokens) {
|
|
220
|
+
includedFiles.push(file);
|
|
221
|
+
totalContextTokens += fileTokens;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// Try to truncate this file to fit
|
|
225
|
+
const remainingTokens = availableTokens - totalContextTokens;
|
|
226
|
+
if (remainingTokens > 500) { // Only include if we can fit meaningful content
|
|
227
|
+
const truncatedContent = this.truncateContent(file.content, remainingTokens * 4);
|
|
228
|
+
includedFiles.push({
|
|
229
|
+
...file,
|
|
230
|
+
content: truncatedContent + '\n... (truncated due to context limit)'
|
|
231
|
+
});
|
|
232
|
+
totalContextTokens += remainingTokens;
|
|
233
|
+
}
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (includedFiles.length < contextFiles.length && includedFiles.length > 0) {
|
|
238
|
+
console.log(chalk_1.default.yellow(`⚠ Context truncated: using ${includedFiles.length}/${contextFiles.length} files to fit context window`));
|
|
239
|
+
}
|
|
240
|
+
else if (includedFiles.length === 0 && contextFiles.length > 0) {
|
|
241
|
+
console.log(chalk_1.default.yellow(`⚠ Context window too small: no context files included. Increase maxContextTokens or shorten prompt.`));
|
|
242
|
+
}
|
|
243
|
+
let enhancedPrompt = '';
|
|
244
|
+
// Add context header only if we have context
|
|
245
|
+
if (includedFiles.length > 0) {
|
|
246
|
+
enhancedPrompt += `## Project Context\n\n`;
|
|
247
|
+
}
|
|
248
|
+
for (const file of includedFiles) {
|
|
249
|
+
enhancedPrompt += `### From ${file.name}:\n${file.content}\n\n`;
|
|
250
|
+
}
|
|
251
|
+
// Add the original prompt
|
|
252
|
+
enhancedPrompt += `## User Request\n\n${promptText}\n\n`;
|
|
253
|
+
// Add instructions for the AI
|
|
254
|
+
enhancedPrompt += `## Instructions\n\n`;
|
|
255
|
+
if (includedFiles.length > 0) {
|
|
256
|
+
enhancedPrompt += `- Consider the project context above\n`;
|
|
257
|
+
enhancedPrompt += `- Follow any patterns or conventions mentioned\n`;
|
|
258
|
+
enhancedPrompt += `- If tests are mentioned in context, include them\n`;
|
|
259
|
+
enhancedPrompt += `- Respect any constraints from the context files\n`;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
enhancedPrompt += `- No project context available — ask for clarification if needed\n`;
|
|
263
|
+
enhancedPrompt += `- Follow general best practices\n`;
|
|
264
|
+
}
|
|
265
|
+
return enhancedPrompt;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Display check results with formatting
|
|
269
|
+
*/
|
|
270
|
+
displayResults(results) {
|
|
271
|
+
if (results.length === 0) {
|
|
272
|
+
console.log(chalk_1.default.green('✓ All checks passed!'));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
console.log(chalk_1.default.bold('\nPrompt Analysis:\n'));
|
|
276
|
+
for (const result of results) {
|
|
277
|
+
const icon = result.type === 'error' ? '✗' : result.type === 'warning' ? '⚠' : 'ℹ';
|
|
278
|
+
const color = result.type === 'error' ? chalk_1.default.red : result.type === 'warning' ? chalk_1.default.yellow : chalk_1.default.blue;
|
|
279
|
+
console.log(color(`${icon} ${result.message}`));
|
|
280
|
+
if (result.suggestion) {
|
|
281
|
+
console.log(chalk_1.default.gray(` → ${result.suggestion}`));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
console.log('');
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Initialize prompt-guard in current project
|
|
288
|
+
*/
|
|
289
|
+
async init() {
|
|
290
|
+
const projectPath = process.cwd();
|
|
291
|
+
console.log(chalk_1.default.bold('Initializing prompt-guard...\n'));
|
|
292
|
+
// Create PROJECT.md template
|
|
293
|
+
const projectMdPath = path.join(projectPath, 'PROJECT.md');
|
|
294
|
+
if (!fs.existsSync(projectMdPath)) {
|
|
295
|
+
fs.writeFileSync(projectMdPath, this.getProjectTemplate());
|
|
296
|
+
console.log(chalk_1.default.green('✓ Created PROJECT.md'));
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
console.log(chalk_1.default.yellow('⚠ PROJECT.md already exists'));
|
|
300
|
+
}
|
|
301
|
+
// Create CONTEXT.md template
|
|
302
|
+
const contextMdPath = path.join(projectPath, 'CONTEXT.md');
|
|
303
|
+
if (!fs.existsSync(contextMdPath)) {
|
|
304
|
+
fs.writeFileSync(contextMdPath, this.getContextTemplate());
|
|
305
|
+
console.log(chalk_1.default.green('✓ Created CONTEXT.md'));
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
console.log(chalk_1.default.yellow('⚠ CONTEXT.md already exists'));
|
|
309
|
+
}
|
|
310
|
+
console.log(chalk_1.default.bold('\nNext steps:'));
|
|
311
|
+
console.log('1. Edit PROJECT.md with your project details');
|
|
312
|
+
console.log('2. Edit CONTEXT.md with coding conventions');
|
|
313
|
+
console.log('3. Run `prompt-guard check "your prompt"` to test');
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Show current configuration
|
|
317
|
+
*/
|
|
318
|
+
showConfig() {
|
|
319
|
+
console.log(chalk_1.default.bold('Prompt Guard Configuration:\n'));
|
|
320
|
+
console.log('Context files:', this.config.contextFiles.join(', '));
|
|
321
|
+
console.log('Enabled checks:', this.config.enabledChecks.join(', '));
|
|
322
|
+
console.log('Auto-inject:', this.config.autoInject);
|
|
323
|
+
console.log('Confirm before send:', this.config.confirmBeforeSend);
|
|
324
|
+
console.log('Max context tokens:', this.config.maxContextTokens);
|
|
325
|
+
console.log('Model limits:', Object.keys(this.config.modelLimits).join(', '));
|
|
326
|
+
}
|
|
327
|
+
// Helper methods
|
|
328
|
+
hasFileReferences(prompt) {
|
|
329
|
+
const filePatterns = [
|
|
330
|
+
/\b\w+\.(js|ts|jsx|tsx|py|go|rs|java|cpp|c|h)\b/,
|
|
331
|
+
/\b(src|lib|app|components|utils|tests?)\/[\w\/]+/,
|
|
332
|
+
/\*\.[\w]+/, // *.js, *.ts, etc.
|
|
333
|
+
/\b(file|files|path|paths)\b/i
|
|
334
|
+
];
|
|
335
|
+
return filePatterns.some(pattern => pattern.test(prompt));
|
|
336
|
+
}
|
|
337
|
+
hasTestReferences(prompt) {
|
|
338
|
+
const testPatterns = [
|
|
339
|
+
/\btest(s)?\b/i,
|
|
340
|
+
/\bspec\b/i,
|
|
341
|
+
/\bvalidation\b/i,
|
|
342
|
+
/\bverify\b/i,
|
|
343
|
+
/\bshould\s+\w+/i,
|
|
344
|
+
/\bmust\s+\w+/i
|
|
345
|
+
];
|
|
346
|
+
return testPatterns.some(pattern => pattern.test(prompt));
|
|
347
|
+
}
|
|
348
|
+
hasSuccessCriteria(prompt) {
|
|
349
|
+
const criteriaPatterns = [
|
|
350
|
+
/\b(should|must|needs? to)\s+\w+/i,
|
|
351
|
+
/\bgoal\b/i,
|
|
352
|
+
/\bsuccess\b/i,
|
|
353
|
+
/\bcriteria\b/i,
|
|
354
|
+
/\bhandle\s+\d+/i,
|
|
355
|
+
/\bpass\b/i
|
|
356
|
+
];
|
|
357
|
+
return criteriaPatterns.some(pattern => pattern.test(prompt));
|
|
358
|
+
}
|
|
359
|
+
hasConstraints(prompt) {
|
|
360
|
+
const constraintPatterns = [
|
|
361
|
+
/\b(don't|do not|never)\s+\w+/i,
|
|
362
|
+
/\bavoid\b/i,
|
|
363
|
+
/\blimit\b/i,
|
|
364
|
+
/\bmax\b/i,
|
|
365
|
+
/\bconstraint\b/i,
|
|
366
|
+
/\bwithout\s+breaking\b/i
|
|
367
|
+
];
|
|
368
|
+
return constraintPatterns.some(pattern => pattern.test(prompt));
|
|
369
|
+
}
|
|
370
|
+
checkLocalEnvReferences(prompt) {
|
|
371
|
+
const issues = [];
|
|
372
|
+
// Check for absolute paths
|
|
373
|
+
if (/\/Users\/\w+|\/home\/\w+|C:\\Users\\\w+/.test(prompt)) {
|
|
374
|
+
issues.push('absolute paths (/Users/..., /home/...)');
|
|
375
|
+
}
|
|
376
|
+
// Check for local ports
|
|
377
|
+
if (/localhost:\d{4,5}/.test(prompt)) {
|
|
378
|
+
issues.push('localhost ports');
|
|
379
|
+
}
|
|
380
|
+
// Check for machine-specific terms
|
|
381
|
+
if (/\b(my mac|my laptop|my machine|my computer)\b/i.test(prompt)) {
|
|
382
|
+
issues.push('machine-specific references');
|
|
383
|
+
}
|
|
384
|
+
// Check for local file paths that aren't relative
|
|
385
|
+
if (/\/[a-z]+\/[a-z]+\/[^\s]+\.(js|ts|json)/i.test(prompt)) {
|
|
386
|
+
issues.push('absolute file paths');
|
|
387
|
+
}
|
|
388
|
+
return issues;
|
|
389
|
+
}
|
|
390
|
+
calculateRelevance(fileName) {
|
|
391
|
+
const relevanceMap = {
|
|
392
|
+
'PROJECT.md': 1.0,
|
|
393
|
+
'CONTEXT.md': 0.9,
|
|
394
|
+
'AGENTS.md': 0.8,
|
|
395
|
+
'SOUL.md': 0.7,
|
|
396
|
+
'README.md': 0.6
|
|
397
|
+
};
|
|
398
|
+
return relevanceMap[fileName] || 0.5;
|
|
399
|
+
}
|
|
400
|
+
truncateContent(content, maxLength) {
|
|
401
|
+
if (content.length <= maxLength)
|
|
402
|
+
return content;
|
|
403
|
+
return content.substring(0, maxLength) + '\n... (truncated)';
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Estimate token count (rough approximation: ~4 chars per token)
|
|
407
|
+
*/
|
|
408
|
+
estimateTokens(text) {
|
|
409
|
+
// Rough estimate: 1 token ≈ 4 characters for English text
|
|
410
|
+
return Math.ceil(text.length / 4);
|
|
411
|
+
}
|
|
412
|
+
getProjectTemplate() {
|
|
413
|
+
return `# Project Context
|
|
414
|
+
|
|
415
|
+
## Overview
|
|
416
|
+
Brief description of what this project does.
|
|
417
|
+
|
|
418
|
+
## Tech Stack
|
|
419
|
+
- Language:
|
|
420
|
+
- Framework:
|
|
421
|
+
- Database:
|
|
422
|
+
- Key Dependencies:
|
|
423
|
+
|
|
424
|
+
## Architecture
|
|
425
|
+
- Main entry point:
|
|
426
|
+
- Core modules:
|
|
427
|
+
- Testing framework:
|
|
428
|
+
|
|
429
|
+
## Coding Conventions
|
|
430
|
+
- Style guide:
|
|
431
|
+
- Naming conventions:
|
|
432
|
+
- File organization:
|
|
433
|
+
|
|
434
|
+
## Constraints
|
|
435
|
+
- Performance requirements:
|
|
436
|
+
- Compatibility requirements:
|
|
437
|
+
- Security considerations:
|
|
438
|
+
`;
|
|
439
|
+
}
|
|
440
|
+
getContextTemplate() {
|
|
441
|
+
return `# Coding Context
|
|
442
|
+
|
|
443
|
+
## Patterns to Follow
|
|
444
|
+
- Always write tests for new features
|
|
445
|
+
- Use TypeScript strict mode
|
|
446
|
+
- Prefer functional components
|
|
447
|
+
- Keep functions under 50 lines
|
|
448
|
+
|
|
449
|
+
## Things to Avoid
|
|
450
|
+
- Don't use any types
|
|
451
|
+
- Don't skip error handling
|
|
452
|
+
- Don't break existing APIs without versioning
|
|
453
|
+
|
|
454
|
+
## Testing Requirements
|
|
455
|
+
- Unit tests for utilities
|
|
456
|
+
- Integration tests for APIs
|
|
457
|
+
- E2E tests for critical paths
|
|
458
|
+
|
|
459
|
+
## Performance Targets
|
|
460
|
+
- Page load under 2 seconds
|
|
461
|
+
- API response under 200ms
|
|
462
|
+
- Bundle size under 100KB
|
|
463
|
+
`;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
exports.PromptGuard = PromptGuard;
|
|
467
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PromptGuard } from './index';
|
|
2
|
+
interface ScoredContext {
|
|
3
|
+
fileName: string;
|
|
4
|
+
content: string;
|
|
5
|
+
score: number;
|
|
6
|
+
matchedKeywords: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Smart context relevance scoring using keyword matching
|
|
10
|
+
* Future: Could use embeddings for semantic similarity
|
|
11
|
+
*/
|
|
12
|
+
export declare class SmartRelevance {
|
|
13
|
+
private guard;
|
|
14
|
+
constructor(guard: PromptGuard);
|
|
15
|
+
/**
|
|
16
|
+
* Score context files based on relevance to the prompt
|
|
17
|
+
*/
|
|
18
|
+
scoreContext(prompt: string, projectPath?: string): Promise<ScoredContext[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Extract keywords from text
|
|
21
|
+
*/
|
|
22
|
+
private extractKeywords;
|
|
23
|
+
/**
|
|
24
|
+
* Find matching keywords between two sets
|
|
25
|
+
*/
|
|
26
|
+
private findMatches;
|
|
27
|
+
/**
|
|
28
|
+
* Get the top N most relevant context files
|
|
29
|
+
*/
|
|
30
|
+
getTopContext(prompt: string, projectPath?: string, topN?: number): Promise<ScoredContext[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Generate a relevance report for debugging
|
|
33
|
+
*/
|
|
34
|
+
generateRelevanceReport(prompt: string, projectPath?: string): Promise<string>;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=smart-relevance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-relevance.d.ts","sourceRoot":"","sources":["../src/smart-relevance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAc;gBAEf,KAAK,EAAE,WAAW;IAI9B;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAkCjG;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,WAAW,GAAE,MAAsB,EACnC,IAAI,GAAE,MAAU,GACf,OAAO,CAAC,aAAa,EAAE,CAAC;IAK3B;;OAEG;IACG,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBpG"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SmartRelevance = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Smart context relevance scoring using keyword matching
|
|
6
|
+
* Future: Could use embeddings for semantic similarity
|
|
7
|
+
*/
|
|
8
|
+
class SmartRelevance {
|
|
9
|
+
constructor(guard) {
|
|
10
|
+
this.guard = guard;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Score context files based on relevance to the prompt
|
|
14
|
+
*/
|
|
15
|
+
async scoreContext(prompt, projectPath = process.cwd()) {
|
|
16
|
+
// Load all context files
|
|
17
|
+
const contextFiles = await this.guard.loadContext(projectPath);
|
|
18
|
+
// Extract keywords from prompt
|
|
19
|
+
const promptKeywords = this.extractKeywords(prompt);
|
|
20
|
+
// Score each file
|
|
21
|
+
const scored = contextFiles.map(file => {
|
|
22
|
+
const fileKeywords = this.extractKeywords(file.content);
|
|
23
|
+
const matchedKeywords = this.findMatches(promptKeywords, fileKeywords);
|
|
24
|
+
// Calculate score based on:
|
|
25
|
+
// 1. Keyword overlap (50%)
|
|
26
|
+
// 2. File relevance weight (30%)
|
|
27
|
+
// 3. Content density (20%)
|
|
28
|
+
const keywordScore = matchedKeywords.length / Math.max(promptKeywords.length, 1);
|
|
29
|
+
const relevanceWeight = file.relevance;
|
|
30
|
+
const densityScore = Math.min(file.content.length / 5000, 1); // Normalize to 0-1
|
|
31
|
+
const score = (keywordScore * 0.5) + (relevanceWeight * 0.3) + (densityScore * 0.2);
|
|
32
|
+
return {
|
|
33
|
+
fileName: file.name,
|
|
34
|
+
content: file.content,
|
|
35
|
+
score,
|
|
36
|
+
matchedKeywords
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
// Sort by score descending
|
|
40
|
+
return scored.sort((a, b) => b.score - a.score);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract keywords from text
|
|
44
|
+
*/
|
|
45
|
+
extractKeywords(text) {
|
|
46
|
+
// Convert to lowercase and extract words
|
|
47
|
+
const words = text.toLowerCase()
|
|
48
|
+
.replace(/[^\w\s]/g, ' ')
|
|
49
|
+
.split(/\s+/)
|
|
50
|
+
.filter(word => word.length > 3); // Filter out short words
|
|
51
|
+
// Remove common stop words
|
|
52
|
+
const stopWords = new Set([
|
|
53
|
+
'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had', 'her', 'was', 'one', 'our', 'out', 'day', 'get', 'has', 'him', 'his', 'how', 'man', 'new', 'now', 'old', 'see', 'two', 'way', 'who', 'boy', 'did', 'its', 'let', 'put', 'say', 'she', 'too', 'use', 'with', 'have', 'this', 'will', 'your', 'from', 'they', 'know', 'want', 'been', 'good', 'much', 'some', 'time', 'very', 'when', 'come', 'here', 'just', 'like', 'long', 'make', 'many', 'over', 'such', 'take', 'than', 'them', 'well', 'were'
|
|
54
|
+
]);
|
|
55
|
+
// Filter stop words and get unique keywords
|
|
56
|
+
const keywords = [...new Set(words)].filter(word => !stopWords.has(word));
|
|
57
|
+
return keywords;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Find matching keywords between two sets
|
|
61
|
+
*/
|
|
62
|
+
findMatches(promptKeywords, fileKeywords) {
|
|
63
|
+
const fileSet = new Set(fileKeywords);
|
|
64
|
+
return promptKeywords.filter(kw => fileSet.has(kw));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the top N most relevant context files
|
|
68
|
+
*/
|
|
69
|
+
async getTopContext(prompt, projectPath = process.cwd(), topN = 3) {
|
|
70
|
+
const scored = await this.scoreContext(prompt, projectPath);
|
|
71
|
+
return scored.slice(0, topN);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Generate a relevance report for debugging
|
|
75
|
+
*/
|
|
76
|
+
async generateRelevanceReport(prompt, projectPath = process.cwd()) {
|
|
77
|
+
const scored = await this.scoreContext(prompt, projectPath);
|
|
78
|
+
let report = '# Context Relevance Report\n\n';
|
|
79
|
+
report += `Prompt: "${prompt}"\n\n`;
|
|
80
|
+
report += '## File Rankings\n\n';
|
|
81
|
+
for (let i = 0; i < scored.length; i++) {
|
|
82
|
+
const ctx = scored[i];
|
|
83
|
+
report += `${i + 1}. **${ctx.fileName}** (score: ${ctx.score.toFixed(2)})\n`;
|
|
84
|
+
report += ` - Matched keywords: ${ctx.matchedKeywords.join(', ') || 'none'}\n`;
|
|
85
|
+
report += ` - Content length: ${ctx.content.length} chars\n\n`;
|
|
86
|
+
}
|
|
87
|
+
return report;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.SmartRelevance = SmartRelevance;
|
|
91
|
+
//# sourceMappingURL=smart-relevance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-relevance.js","sourceRoot":"","sources":["../src/smart-relevance.ts"],"names":[],"mappings":";;;AASA;;;GAGG;AACH,MAAa,cAAc;IAGzB,YAAY,KAAkB;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,cAAsB,OAAO,CAAC,GAAG,EAAE;QACpE,yBAAyB;QACzB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAE/D,+BAA+B;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAEpD,kBAAkB;QAClB,MAAM,MAAM,GAAoB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACtD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YAEvE,4BAA4B;YAC5B,2BAA2B;YAC3B,iCAAiC;YACjC,2BAA2B;YAC3B,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACjF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;YACvC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB;YAEjF,MAAM,KAAK,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;YAEpF,OAAO;gBACL,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK;gBACL,eAAe;aAChB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAAY;QAClC,yCAAyC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;aAC7B,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;aACxB,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,yBAAyB;QAE7D,2BAA2B;QAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;YACxB,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;SACzf,CAAC,CAAC;QAEH,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,cAAwB,EAAE,YAAsB;QAClE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QACtC,OAAO,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,MAAc,EACd,cAAsB,OAAO,CAAC,GAAG,EAAE,EACnC,OAAe,CAAC;QAEhB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,uBAAuB,CAAC,MAAc,EAAE,cAAsB,OAAO,CAAC,GAAG,EAAE;QAC/E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAE5D,IAAI,MAAM,GAAG,gCAAgC,CAAC;QAC9C,MAAM,IAAI,YAAY,MAAM,OAAO,CAAC;QACpC,MAAM,IAAI,sBAAsB,CAAC;QAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,QAAQ,cAAc,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7E,MAAM,IAAI,0BAA0B,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;YACjF,MAAM,IAAI,wBAAwB,GAAG,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC;QACnE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAxGD,wCAwGC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prompt-guard-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Context-aware prompt enhancement for AI coding agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"prompt-guard": "bin/prompt-guard"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"lint": "eslint src/**/*.ts"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"prompt",
|
|
18
|
+
"claude",
|
|
19
|
+
"cursor",
|
|
20
|
+
"context",
|
|
21
|
+
"llm"
|
|
22
|
+
],
|
|
23
|
+
"author": "Mohammed Wasif",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/jest": "^29.0.0",
|
|
27
|
+
"@types/node": "^20.0.0",
|
|
28
|
+
"eslint": "^8.0.0",
|
|
29
|
+
"jest": "^29.0.0",
|
|
30
|
+
"ts-jest": "^29.4.6",
|
|
31
|
+
"typescript": "^5.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"chalk": "^4.1.2",
|
|
35
|
+
"commander": "^11.0.0",
|
|
36
|
+
"glob": "^10.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|