guardrails-ref 1.2.1 → 1.2.3
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 +21 -1
- package/dist/add.d.ts +1 -1
- package/dist/add.js +10 -9
- package/dist/cli.js +26 -8
- package/dist/init.d.ts +1 -1
- package/dist/init.js +17 -11
- package/dist/path-utils.d.ts +6 -0
- package/dist/path-utils.js +14 -0
- package/dist/remove.d.ts +1 -1
- package/dist/remove.js +10 -9
- package/dist/templates.js +1 -0
- package/dist/upgrade.d.ts +1 -1
- package/dist/upgrade.js +9 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,23 +20,31 @@ Creates `.agents/guardrails/`, adds the `no-plaintext-secrets` example, and conf
|
|
|
20
20
|
|
|
21
21
|
> **Note:** IDEs don't yet recognize guardrails natively. The `setup` command adds a rule so the AI reads them. Once IDEs add support, this won't be needed.
|
|
22
22
|
|
|
23
|
+
**User-level guardrails:** Use `--user` or path `~` to work with `~/.agents/guardrails/` (applies across all projects). Example: `npx guardrails-ref init --user`.
|
|
24
|
+
|
|
23
25
|
## Commands
|
|
24
26
|
|
|
25
27
|
| Command | Description |
|
|
26
28
|
|---------|-------------|
|
|
27
29
|
| `npx guardrails-ref init [path]` | Create `.agents/guardrails/`, add no-plaintext-secrets, configure Cursor, Claude Code, and VS Code Copilot |
|
|
28
30
|
| `npx guardrails-ref init --minimal [path]` | Create `.agents/guardrails/` only (no example, no setup) |
|
|
31
|
+
| `npx guardrails-ref init --user` | Create `~/.agents/guardrails/` (user-level; setup is project-specific) |
|
|
29
32
|
| `npx guardrails-ref add <name> [name2 ...] [path]` | Add example guardrail(s) — pass multiple names to add several at once |
|
|
30
|
-
| `npx guardrails-ref
|
|
33
|
+
| `npx guardrails-ref add <name> --user` or `add <name> ~` | Add to user-level `~/.agents/guardrails/` |
|
|
34
|
+
| `npx guardrails-ref remove <name> [path]` | Remove a guardrail |
|
|
35
|
+
| `npx guardrails-ref remove <name> --user` or `remove <name> ~` | Remove from user-level |
|
|
31
36
|
| `npx guardrails-ref setup [path]` | Add the guardrail rule to Cursor, Claude Code, and VS Code Copilot |
|
|
32
37
|
| `npx guardrails-ref setup --remove [path]` | Remove the guardrail rule from IDE configs |
|
|
33
38
|
| `npx guardrails-ref setup --ide <name> [path]` | Target IDE: `cursor`, `claude`, `copilot`, or `auto` (only configured IDEs) |
|
|
34
39
|
| `npx guardrails-ref setup --dry-run [path]` | Show what would be added/removed without writing files |
|
|
35
40
|
| `npx guardrails-ref setup --check [path]` | Show which IDEs are configured and whether they have the rule |
|
|
36
41
|
| `npx guardrails-ref validate [path]` | Validate GUARDRAIL.md files (use `--json` for JSON, `--strict` to fail on warnings) |
|
|
42
|
+
| `npx guardrails-ref validate --user` or `validate ~` | Validate user-level guardrails |
|
|
37
43
|
| `npx guardrails-ref check [path]` | Validate with minimal output (CI-friendly, use `--strict` to fail on warnings) |
|
|
38
44
|
| `npx guardrails-ref upgrade [path]` | Update installed guardrails to latest templates (use `--dry-run` to preview, `--diff` to show changes) |
|
|
45
|
+
| `npx guardrails-ref upgrade --user` or `upgrade ~` | Upgrade user-level guardrails |
|
|
39
46
|
| `npx guardrails-ref list [path]` | List discovered guardrails (use `--json` for JSON output) |
|
|
47
|
+
| `npx guardrails-ref list --user` or `list ~` | List user-level guardrails |
|
|
40
48
|
| `npx guardrails-ref why <name>` | Show guardrail template content (e.g. `why no-destructive-commands`) |
|
|
41
49
|
|
|
42
50
|
## Supported IDEs
|
|
@@ -66,12 +74,19 @@ Or with full output or JSON:
|
|
|
66
74
|
## Examples
|
|
67
75
|
|
|
68
76
|
```bash
|
|
77
|
+
# Project-level (default)
|
|
69
78
|
npx guardrails-ref init
|
|
70
79
|
npx guardrails-ref add no-destructive-commands no-hardcoded-urls
|
|
71
80
|
npx guardrails-ref add no-new-deps-without-approval
|
|
72
81
|
npx guardrails-ref why no-destructive-commands
|
|
73
82
|
npx guardrails-ref validate .
|
|
74
83
|
npx guardrails-ref list .
|
|
84
|
+
|
|
85
|
+
# User-level (~/.agents/guardrails/)
|
|
86
|
+
npx guardrails-ref init --user
|
|
87
|
+
npx guardrails-ref add no-plaintext-secrets --user
|
|
88
|
+
npx guardrails-ref list --user
|
|
89
|
+
npx guardrails-ref validate ~
|
|
75
90
|
```
|
|
76
91
|
|
|
77
92
|
## Available guardrails (add command)
|
|
@@ -82,9 +97,14 @@ npx guardrails-ref list .
|
|
|
82
97
|
| `no-placeholder-credentials` | Fake or placeholder API keys instead of asking for real values |
|
|
83
98
|
| `no-silent-error-handling` | Catching errors without surfacing them to the user |
|
|
84
99
|
| `require-access-control` | Exposing sensitive data or admin actions without role checks |
|
|
100
|
+
| `artifact-verification` | Destructive ops without plan.md and audit log |
|
|
101
|
+
| `context-rotation` | Continuing in polluted context; reset when 80% full or 10+ errors |
|
|
85
102
|
| `database-migrations` | Direct schema changes instead of migrations |
|
|
86
103
|
| `no-destructive-commands` | rm -rf, DROP TABLE, TRUNCATE without approval |
|
|
104
|
+
| `no-eval-or-dynamic-code` | eval(), new Function(), or dynamic code execution |
|
|
87
105
|
| `no-new-deps-without-approval` | New packages without approval |
|
|
106
|
+
| `privilege-boundaries` | Touching node_modules, .git, lockfiles, .env without approval |
|
|
107
|
+
| `require-commit-approval` | git commit or push without explicit user approval |
|
|
88
108
|
| `no-hardcoded-urls` | Hardcoded API URLs, base URLs, endpoints |
|
|
89
109
|
| `no-sudo-commands` | sudo/su/root commands without approval |
|
|
90
110
|
| `rate-limiting` | Runaway tool calls and API loops |
|
package/dist/add.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function runAdd(name: string, projectPath?: string): boolean;
|
|
1
|
+
export declare function runAdd(name: string, projectPath?: string, userScope?: boolean): boolean;
|
package/dist/add.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { resolveGuardrailsDir } from "./path-utils.js";
|
|
4
5
|
import { TEMPLATES, TEMPLATE_NAMES } from "./templates.js";
|
|
5
|
-
export function runAdd(name, projectPath = ".") {
|
|
6
|
+
export function runAdd(name, projectPath = ".", userScope = false) {
|
|
6
7
|
const normalized = name.toLowerCase().replace(/\s+/g, "-");
|
|
7
8
|
const content = TEMPLATES[normalized];
|
|
8
9
|
if (!content) {
|
|
@@ -10,20 +11,20 @@ export function runAdd(name, projectPath = ".") {
|
|
|
10
11
|
console.log(chalk.gray("Available: " + TEMPLATE_NAMES.join(", ")));
|
|
11
12
|
return false;
|
|
12
13
|
}
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
14
|
+
const guardrailsDir = resolveGuardrailsDir(projectPath, userScope);
|
|
15
|
+
const exampleDir = join(guardrailsDir, normalized);
|
|
16
|
+
const exampleFile = join(exampleDir, "GUARDRAIL.md");
|
|
17
|
+
const pathLabel = userScope ? "~/.agents/guardrails/" : ".agents/guardrails/";
|
|
17
18
|
if (existsSync(exampleFile)) {
|
|
18
|
-
console.log(chalk.yellow(
|
|
19
|
+
console.log(chalk.yellow(pathLabel + normalized + "/GUARDRAIL.md already exists"));
|
|
19
20
|
return true;
|
|
20
21
|
}
|
|
21
22
|
if (!existsSync(guardrailsDir)) {
|
|
22
23
|
mkdirSync(guardrailsDir, { recursive: true });
|
|
23
|
-
console.log(chalk.green("✓") + " Created
|
|
24
|
+
console.log(chalk.green("✓") + " Created " + pathLabel);
|
|
24
25
|
}
|
|
25
26
|
mkdirSync(exampleDir, { recursive: true });
|
|
26
27
|
writeFileSync(exampleFile, content);
|
|
27
|
-
console.log(chalk.green("✓") + " Added
|
|
28
|
+
console.log(chalk.green("✓") + " Added " + pathLabel + normalized + "/GUARDRAIL.md");
|
|
28
29
|
return true;
|
|
29
30
|
}
|
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ import { runAdd } from "./add.js";
|
|
|
11
11
|
import { runWhy } from "./why.js";
|
|
12
12
|
import { runRemove } from "./remove.js";
|
|
13
13
|
import { runUpgrade } from "./upgrade.js";
|
|
14
|
+
import { resolveGuardrailsDir } from "./path-utils.js";
|
|
14
15
|
import { TEMPLATE_NAMES } from "./templates.js";
|
|
15
16
|
const require = createRequire(import.meta.url);
|
|
16
17
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -20,7 +21,9 @@ program
|
|
|
20
21
|
.description("Validate and list Agent Guardrails (GUARDRAIL.md) files")
|
|
21
22
|
.version(pkg.version);
|
|
22
23
|
function runValidate(path, options) {
|
|
23
|
-
const
|
|
24
|
+
const userScope = options.user ?? path === "~";
|
|
25
|
+
const pathToScan = userScope ? resolveGuardrailsDir("~", true) : path;
|
|
26
|
+
const result = validatePath(pathToScan);
|
|
24
27
|
const hasWarnings = result.results.some((r) => r.warnings.length > 0);
|
|
25
28
|
const hasErrors = result.invalid > 0;
|
|
26
29
|
const strictFail = options.strict && hasWarnings;
|
|
@@ -93,6 +96,7 @@ program
|
|
|
93
96
|
.description("Validate GUARDRAIL.md files in a directory or a single file")
|
|
94
97
|
.option("-j, --json", "Output as JSON")
|
|
95
98
|
.option("-s, --strict", "Fail on warnings (CI mode)")
|
|
99
|
+
.option("-u, --user", "Use user-level guardrails (~/.agents/guardrails/)")
|
|
96
100
|
.action(function (path) {
|
|
97
101
|
const opts = this.opts();
|
|
98
102
|
runValidate(path ?? ".", opts);
|
|
@@ -109,15 +113,17 @@ program
|
|
|
109
113
|
.command("init [path]")
|
|
110
114
|
.description("Create .agents/guardrails/, add no-plaintext-secrets, and run setup (one command to get started)")
|
|
111
115
|
.option("-m, --minimal", "Create .agents/guardrails/ only, no example and no setup")
|
|
116
|
+
.option("-u, --user", "Create ~/.agents/guardrails/ (user-level); setup is project-specific")
|
|
112
117
|
.action(function (path) {
|
|
113
118
|
const opts = this.opts();
|
|
114
|
-
runInit(path ?? ".", opts.minimal);
|
|
119
|
+
runInit(path ?? ".", opts.minimal, opts.user);
|
|
115
120
|
});
|
|
116
121
|
program
|
|
117
122
|
.command("add [names...]")
|
|
118
123
|
.description("Add example guardrail(s) by name — pass multiple to add several at once")
|
|
119
124
|
.option("-l, --list", "List available guardrails to add")
|
|
120
125
|
.option("-p, --path <path>", "Target directory", ".")
|
|
126
|
+
.option("-u, --user", "Add to user-level ~/.agents/guardrails/")
|
|
121
127
|
.action(function (names = []) {
|
|
122
128
|
const opts = this.opts();
|
|
123
129
|
if (opts.list) {
|
|
@@ -132,7 +138,7 @@ program
|
|
|
132
138
|
// --path takes precedence when explicitly provided (opts.path !== ".")
|
|
133
139
|
let targetPath = opts.path ?? ".";
|
|
134
140
|
const args = names.filter((n) => n != null && String(n).trim());
|
|
135
|
-
const looksLikePath = (s) => s === "." || s === ".." || s.includes("/") || s.includes("\\");
|
|
141
|
+
const looksLikePath = (s) => s === "." || s === ".." || s === "~" || s.includes("/") || s.includes("\\");
|
|
136
142
|
if (args.length >= 1 && looksLikePath(args[args.length - 1])) {
|
|
137
143
|
if (args.length === 1) {
|
|
138
144
|
console.log("Usage: npx guardrails-ref add <name> [name2 ...] [path]");
|
|
@@ -151,11 +157,13 @@ program
|
|
|
151
157
|
process.exit(1);
|
|
152
158
|
return;
|
|
153
159
|
}
|
|
160
|
+
const userScope = opts.user ?? targetPath === "~";
|
|
161
|
+
const addPath = userScope ? "~" : targetPath;
|
|
154
162
|
let failed = 0;
|
|
155
163
|
for (const name of args) {
|
|
156
164
|
if (!name.trim())
|
|
157
165
|
continue;
|
|
158
|
-
if (!runAdd(name,
|
|
166
|
+
if (!runAdd(name, addPath, userScope))
|
|
159
167
|
failed++;
|
|
160
168
|
}
|
|
161
169
|
process.exit(failed > 0 ? 1 : 0);
|
|
@@ -165,15 +173,22 @@ program
|
|
|
165
173
|
.description("Update installed guardrails to latest template versions")
|
|
166
174
|
.option("-n, --dry-run", "Show what would be updated without writing")
|
|
167
175
|
.option("-d, --diff", "Show diff for each updated guardrail")
|
|
176
|
+
.option("-u, --user", "Upgrade user-level ~/.agents/guardrails/")
|
|
168
177
|
.action(function (path) {
|
|
169
178
|
const opts = this.opts();
|
|
170
|
-
|
|
179
|
+
const p = path ?? ".";
|
|
180
|
+
const userScope = opts.user ?? p === "~";
|
|
181
|
+
runUpgrade(userScope ? "~" : p, opts.dryRun, opts.diff, userScope);
|
|
171
182
|
});
|
|
172
183
|
program
|
|
173
184
|
.command("remove <name> [path]")
|
|
174
185
|
.description("Remove a guardrail from .agents/guardrails/")
|
|
175
|
-
.
|
|
176
|
-
|
|
186
|
+
.option("-u, --user", "Remove from user-level ~/.agents/guardrails/")
|
|
187
|
+
.action(function (name, path) {
|
|
188
|
+
const opts = this.opts();
|
|
189
|
+
const p = path ?? ".";
|
|
190
|
+
const userScope = opts.user ?? p === "~";
|
|
191
|
+
const ok = runRemove(name, userScope ? "~" : p, userScope);
|
|
177
192
|
process.exit(ok ? 0 : 1);
|
|
178
193
|
});
|
|
179
194
|
program
|
|
@@ -220,9 +235,12 @@ program
|
|
|
220
235
|
.command("list [path]")
|
|
221
236
|
.description("List discovered guardrails")
|
|
222
237
|
.option("-j, --json", "Output as JSON")
|
|
238
|
+
.option("-u, --user", "List user-level ~/.agents/guardrails/")
|
|
223
239
|
.action(function (path) {
|
|
224
240
|
const opts = this.opts();
|
|
225
|
-
const
|
|
241
|
+
const userScope = opts.user ?? path === "~";
|
|
242
|
+
const pathToScan = userScope ? resolveGuardrailsDir("~", true) : (path ?? ".");
|
|
243
|
+
const guardrails = listGuardrails(pathToScan);
|
|
226
244
|
if (opts.json) {
|
|
227
245
|
console.log(JSON.stringify({ guardrails, total: guardrails.length }, null, 2));
|
|
228
246
|
process.exit(guardrails.length === 0 ? 1 : 0);
|
package/dist/init.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export interface InitResult {
|
|
|
3
3
|
exampleCreated: boolean;
|
|
4
4
|
setupDone: string;
|
|
5
5
|
}
|
|
6
|
-
export declare function runInit(projectPath?: string, minimal?: boolean): InitResult;
|
|
6
|
+
export declare function runInit(projectPath?: string, minimal?: boolean, userScope?: boolean): InitResult;
|
package/dist/init.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { resolveGuardrailsDir } from "./path-utils.js";
|
|
4
5
|
import { runSetup } from "./setup.js";
|
|
5
6
|
import { TEMPLATES } from "./templates.js";
|
|
6
|
-
export function runInit(projectPath = ".", minimal = false) {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const exampleFile = resolve(exampleDir, "GUARDRAIL.md");
|
|
7
|
+
export function runInit(projectPath = ".", minimal = false, userScope = false) {
|
|
8
|
+
const guardrailsDir = resolveGuardrailsDir(projectPath, userScope);
|
|
9
|
+
const exampleDir = join(guardrailsDir, "no-plaintext-secrets");
|
|
10
|
+
const exampleFile = join(exampleDir, "GUARDRAIL.md");
|
|
11
11
|
let exampleCreated = false;
|
|
12
12
|
if (!existsSync(guardrailsDir)) {
|
|
13
13
|
mkdirSync(guardrailsDir, { recursive: true });
|
|
14
|
-
console.log(chalk.green("✓") + " Created .agents/guardrails/");
|
|
14
|
+
console.log(chalk.green("✓") + " Created " + (userScope ? "~/.agents/guardrails/" : ".agents/guardrails/"));
|
|
15
15
|
}
|
|
16
|
-
if (minimal) {
|
|
16
|
+
if (minimal || userScope) {
|
|
17
|
+
if (userScope && !existsSync(exampleFile)) {
|
|
18
|
+
mkdirSync(exampleDir, { recursive: true });
|
|
19
|
+
writeFileSync(exampleFile, TEMPLATES["no-plaintext-secrets"]);
|
|
20
|
+
exampleCreated = true;
|
|
21
|
+
console.log(chalk.green("✓") + " Created ~/.agents/guardrails/no-plaintext-secrets/GUARDRAIL.md");
|
|
22
|
+
}
|
|
17
23
|
return {
|
|
18
24
|
guardrailsDir,
|
|
19
|
-
exampleCreated
|
|
20
|
-
setupDone: "",
|
|
25
|
+
exampleCreated,
|
|
26
|
+
setupDone: userScope ? "(setup is project-specific; run setup in each project)" : "",
|
|
21
27
|
};
|
|
22
28
|
}
|
|
23
29
|
if (!existsSync(exampleFile)) {
|
|
@@ -29,7 +35,7 @@ export function runInit(projectPath = ".", minimal = false) {
|
|
|
29
35
|
else {
|
|
30
36
|
console.log(chalk.yellow(" .agents/guardrails/no-plaintext-secrets/GUARDRAIL.md already exists"));
|
|
31
37
|
}
|
|
32
|
-
const setupResult = runSetup(projectPath);
|
|
38
|
+
const setupResult = runSetup(projectPath); // project-level only
|
|
33
39
|
console.log(setupResult.message);
|
|
34
40
|
return {
|
|
35
41
|
guardrailsDir,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the guardrails directory path.
|
|
3
|
+
* When userScope or path is "~", returns ~/.agents/guardrails (user-level).
|
|
4
|
+
* Otherwise returns <path>/.agents/guardrails (project-level).
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveGuardrailsDir(path: string, userScope?: boolean): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { homedir } from "os";
|
|
2
|
+
import { join, resolve } from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the guardrails directory path.
|
|
5
|
+
* When userScope or path is "~", returns ~/.agents/guardrails (user-level).
|
|
6
|
+
* Otherwise returns <path>/.agents/guardrails (project-level).
|
|
7
|
+
*/
|
|
8
|
+
export function resolveGuardrailsDir(path, userScope) {
|
|
9
|
+
if (userScope || path === "~" || path === "~/") {
|
|
10
|
+
return join(homedir(), ".agents", "guardrails");
|
|
11
|
+
}
|
|
12
|
+
const root = resolve(path);
|
|
13
|
+
return join(root, ".agents", "guardrails");
|
|
14
|
+
}
|
package/dist/remove.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function runRemove(name: string, projectPath?: string): boolean;
|
|
1
|
+
export declare function runRemove(name: string, projectPath?: string, userScope?: boolean): boolean;
|
package/dist/remove.js
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { existsSync, readdirSync, rmSync, rmdirSync } from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { resolveGuardrailsDir } from "./path-utils.js";
|
|
4
5
|
import { listGuardrails } from "./validate.js";
|
|
5
|
-
export function runRemove(name, projectPath = ".") {
|
|
6
|
+
export function runRemove(name, projectPath = ".", userScope = false) {
|
|
6
7
|
const normalized = name.toLowerCase().replace(/\s+/g, "-");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const guardrailsDir = resolveGuardrailsDir(projectPath, userScope);
|
|
9
|
+
const targetDir = join(guardrailsDir, normalized);
|
|
10
|
+
const targetFile = join(targetDir, "GUARDRAIL.md");
|
|
11
|
+
const pathLabel = userScope ? "~/.agents/guardrails/" : ".agents/guardrails/";
|
|
11
12
|
if (!existsSync(targetFile)) {
|
|
12
13
|
const guardrails = listGuardrails(guardrailsDir);
|
|
13
14
|
const names = guardrails.map((g) => g.name);
|
|
14
|
-
console.log(chalk.red("Guardrail not found:") + "
|
|
15
|
+
console.log(chalk.red("Guardrail not found:") + " " + pathLabel + normalized);
|
|
15
16
|
if (names.length > 0) {
|
|
16
17
|
console.log(chalk.gray("Installed: " + names.join(", ")));
|
|
17
18
|
}
|
|
18
19
|
return false;
|
|
19
20
|
}
|
|
20
21
|
rmSync(targetDir, { recursive: true });
|
|
21
|
-
console.log(chalk.green("✓") + " Removed
|
|
22
|
+
console.log(chalk.green("✓") + " Removed " + pathLabel + normalized);
|
|
22
23
|
// Remove parent dir if empty
|
|
23
24
|
try {
|
|
24
25
|
const remaining = readdirSync(guardrailsDir);
|
|
25
26
|
if (remaining.length === 0) {
|
|
26
27
|
rmdirSync(guardrailsDir);
|
|
27
|
-
console.log(chalk.green("✓") + " Removed empty
|
|
28
|
+
console.log(chalk.green("✓") + " Removed empty " + pathLabel);
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
catch {
|
package/dist/templates.js
CHANGED
|
@@ -37,6 +37,7 @@ Implementing authentication endpoints, adding logging, integrating third-party A
|
|
|
37
37
|
- Use bcrypt with 12 salt rounds for password hashing
|
|
38
38
|
- Always require HTTPS for authentication endpoints
|
|
39
39
|
- Use a \`redactSensitive()\` helper when logging objects that may contain secrets
|
|
40
|
+
- Audit all logs before committing to ensure no credentials are included
|
|
40
41
|
|
|
41
42
|
## Reason
|
|
42
43
|
API keys were exposed in git during a 2025 security audit. Plaintext credentials in logs led to emergency key rotation.
|
package/dist/upgrade.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export interface UpgradeResult {
|
|
|
3
3
|
skipped: string[];
|
|
4
4
|
notFound: string[];
|
|
5
5
|
}
|
|
6
|
-
export declare function runUpgrade(projectPath?: string, dryRun?: boolean, showDiff?: boolean): UpgradeResult;
|
|
6
|
+
export declare function runUpgrade(projectPath?: string, dryRun?: boolean, showDiff?: boolean, userScope?: boolean): UpgradeResult;
|
package/dist/upgrade.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { createPatch } from "diff";
|
|
5
|
+
import { resolveGuardrailsDir } from "./path-utils.js";
|
|
5
6
|
import { TEMPLATES } from "./templates.js";
|
|
6
7
|
function printDiff(name, current, template) {
|
|
7
8
|
const patch = createPatch(".agents/guardrails/" + name + "/GUARDRAIL.md", current, template, "current", "template");
|
|
@@ -12,12 +13,12 @@ function printDiff(name, current, template) {
|
|
|
12
13
|
console.log(chalk.gray(body));
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
export function runUpgrade(projectPath = ".", dryRun = false, showDiff = false) {
|
|
16
|
-
const
|
|
17
|
-
const guardrailsDir = resolve(root, ".agents", "guardrails");
|
|
16
|
+
export function runUpgrade(projectPath = ".", dryRun = false, showDiff = false, userScope = false) {
|
|
17
|
+
const guardrailsDir = resolveGuardrailsDir(projectPath, userScope);
|
|
18
18
|
const result = { updated: [], skipped: [], notFound: [] };
|
|
19
|
+
const pathLabel = userScope ? "~/.agents/guardrails/" : ".agents/guardrails/";
|
|
19
20
|
if (!existsSync(guardrailsDir)) {
|
|
20
|
-
console.log(chalk.yellow("No
|
|
21
|
+
console.log(chalk.yellow("No " + pathLabel + " directory found"));
|
|
21
22
|
return result;
|
|
22
23
|
}
|
|
23
24
|
const entries = readdirSync(guardrailsDir, { withFileTypes: true });
|
|
@@ -26,7 +27,7 @@ export function runUpgrade(projectPath = ".", dryRun = false, showDiff = false)
|
|
|
26
27
|
continue;
|
|
27
28
|
const name = ent.name.toLowerCase().replace(/\s+/g, "-");
|
|
28
29
|
const template = TEMPLATES[name];
|
|
29
|
-
const filePath =
|
|
30
|
+
const filePath = join(guardrailsDir, ent.name, "GUARDRAIL.md");
|
|
30
31
|
if (!existsSync(filePath))
|
|
31
32
|
continue;
|
|
32
33
|
if (!template) {
|
|
@@ -44,10 +45,10 @@ export function runUpgrade(projectPath = ".", dryRun = false, showDiff = false)
|
|
|
44
45
|
printDiff(name, current, template);
|
|
45
46
|
}
|
|
46
47
|
writeFileSync(filePath, template);
|
|
47
|
-
console.log(chalk.green("✓") + " Updated
|
|
48
|
+
console.log(chalk.green("✓") + " Updated " + pathLabel + name + "/GUARDRAIL.md");
|
|
48
49
|
}
|
|
49
50
|
else {
|
|
50
|
-
console.log(chalk.cyan("Would update") + "
|
|
51
|
+
console.log(chalk.cyan("Would update") + " " + pathLabel + name + "/GUARDRAIL.md");
|
|
51
52
|
if (showDiff) {
|
|
52
53
|
printDiff(name, current, template);
|
|
53
54
|
}
|
package/package.json
CHANGED