@spences10/pi-redact 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Scott Spence
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,100 @@
1
+ # @spences10/pi-redact
2
+
3
+ [![built with vite+](https://img.shields.io/badge/built%20with-Vite+-646CFF?logo=vite&logoColor=white)](https://viteplus.dev)
4
+ [![tested with vitest](https://img.shields.io/badge/tested%20with-Vitest-6E9F18?logo=vitest&logoColor=white)](https://vitest.dev)
5
+
6
+ Pi extension that redacts likely secrets from tool output before the
7
+ model sees them.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pi install npm:@spences10/pi-redact
13
+ ```
14
+
15
+ Local development from this monorepo:
16
+
17
+ ```bash
18
+ pnpm --filter @spences10/pi-redact run build
19
+ pi install ./packages/pi-redact
20
+ # or for one run only
21
+ pi -e ./packages/pi-redact
22
+ ```
23
+
24
+ ## What it does
25
+
26
+ `@spences10/pi-redact` listens for Pi `tool_result` events and
27
+ rewrites text content before it is added to model context. It is
28
+ intended as a last-mile safety net for accidental secrets in command
29
+ output, file reads, logs, and config files.
30
+
31
+ It currently detects and redacts:
32
+
33
+ - API-key-like fields such as `password`, `secret`, `token`, and
34
+ `api_key`
35
+ - GitHub classic and fine-grained tokens
36
+ - Tavily, Kagi, Brave, and Firecrawl API keys
37
+ - connection strings with embedded credentials
38
+ - SSH config metadata such as `Host`, `HostName`, `User`,
39
+ `IdentityFile`, `ProxyJump`, and forwarding directives
40
+
41
+ Redactions preserve a short prefix where helpful and append a marker
42
+ such as `[REDACTED:GitHub Token]`.
43
+
44
+ ## Commands
45
+
46
+ ### `/redact-stats`
47
+
48
+ Shows how many values were redacted in the current Pi session.
49
+
50
+ ```text
51
+ /redact-stats
52
+ ```
53
+
54
+ ## Example
55
+
56
+ If a tool returns:
57
+
58
+ ```text
59
+ GITHUB_TOKEN=ghp_abcdefghijklmnopqrstuvwxyz1234567890
60
+ ```
61
+
62
+ The model receives something like:
63
+
64
+ ```text
65
+ GITH********************[REDACTED:GitHub Token]
66
+ ```
67
+
68
+ ## Using from a custom harness
69
+
70
+ ```ts
71
+ import redact from '@spences10/pi-redact';
72
+
73
+ // pass `redact` as an ExtensionFactory to your Pi runtime
74
+ ```
75
+
76
+ `my-pi` imports this package directly and enables it as the built-in
77
+ `filter-output` extension.
78
+
79
+ ## Limitations
80
+
81
+ This extension is defensive, not a guarantee. It can miss novel secret
82
+ formats, and broad patterns can occasionally redact benign values. Use
83
+ proper secret hygiene as the primary control:
84
+
85
+ - do not print secrets unnecessarily
86
+ - avoid reading `.env` files into model context
87
+ - prefer scoped, revocable tokens
88
+ - rotate anything that may have been exposed
89
+
90
+ ## Development
91
+
92
+ ```bash
93
+ pnpm --filter @spences10/pi-redact run check
94
+ pnpm --filter @spences10/pi-redact run test
95
+ pnpm --filter @spences10/pi-redact run build
96
+ ```
97
+
98
+ ## License
99
+
100
+ MIT
@@ -0,0 +1,12 @@
1
+ import type { ExtensionAPI } from '@mariozechner/pi-coding-agent';
2
+ interface RedactionResult {
3
+ redacted: string;
4
+ count: number;
5
+ }
6
+ export declare function looks_like_ssh_config(text: string): boolean;
7
+ export declare function redact_ssh_config_metadata(text: string): RedactionResult;
8
+ export declare function redact_text(text: string, options?: {
9
+ force_ssh_config?: boolean;
10
+ }): RedactionResult;
11
+ export default function filter_output(pi: ExtensionAPI): Promise<void>;
12
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,177 @@
1
+ // Filter-output extension — redact secrets from tool output
2
+ // Patterns from https://github.com/spences10/nopeek
3
+ const SECRET_PATTERNS = [
4
+ { name: 'AWS Access Key', pattern: /AKIA[A-Z0-9]{16}/g },
5
+ { name: 'AWS Temp Access Key', pattern: /ASIA[A-Z0-9]{16}/g },
6
+ {
7
+ name: 'AWS Secret Key',
8
+ pattern: /\b(?:AWS_SECRET_ACCESS_KEY|aws_secret_access_key|secret_access_key|SecretAccessKey)\b\s*[:=]\s*["']?[A-Za-z0-9/+=]{40,}["']?/g,
9
+ },
10
+ {
11
+ name: 'Bearer Token',
12
+ pattern: /Bearer\s+[a-zA-Z0-9._-]{20,}/g,
13
+ },
14
+ {
15
+ name: 'OpenAI/Anthropic API Key',
16
+ pattern: /sk-[a-zA-Z0-9._-]{20,}/g,
17
+ },
18
+ {
19
+ name: 'Stripe Live Key',
20
+ pattern: /sk_live_[a-zA-Z0-9]{20,}/g,
21
+ },
22
+ {
23
+ name: 'Stripe Test Key',
24
+ pattern: /sk_test_[a-zA-Z0-9]{20,}/g,
25
+ },
26
+ {
27
+ name: 'Hetzner Token',
28
+ pattern: /(?:HCLOUD_TOKEN|hcloud_token|token)\s*[:=]\s*["']?[a-f0-9]{64}\b/g,
29
+ },
30
+ {
31
+ name: 'Private Key',
32
+ pattern: /-----BEGIN\s+[\w\s]*PRIVATE\s+KEY-----[\s\S]*?-----END\s+[\w\s]*PRIVATE\s+KEY-----/g,
33
+ },
34
+ {
35
+ name: 'Connection String with Password',
36
+ pattern: /:\/\/[^:]+:[^@]+@/g,
37
+ },
38
+ {
39
+ name: 'Generic Password Field',
40
+ pattern: /\b[\w-]*(?:password|passwd|secret|token|api[_-]?key)\b\s*[:=]\s*["']?[A-Za-z0-9._:/+=@!-]{8,}/gi,
41
+ },
42
+ {
43
+ name: 'Generic Secret Phrase',
44
+ pattern: /\b(?:password|passwd|secret|token|api[_-]?key)\b(?:\s+(?:is|was|seen|value|header))?\s*[:=]?\s+[A-Za-z0-9._:/+=@!-]{8,}/gi,
45
+ },
46
+ {
47
+ name: 'Tavily API Key',
48
+ pattern: /tvly-[a-zA-Z0-9_-]{20,}/g,
49
+ },
50
+ {
51
+ name: 'Kagi API Key',
52
+ pattern: /[a-zA-Z0-9_-]{40,}\.[a-zA-Z0-9_-]{40,}/g,
53
+ },
54
+ {
55
+ name: 'Brave API Key',
56
+ pattern: /BSA[A-Z0-9]{20,}/g,
57
+ },
58
+ {
59
+ name: 'Firecrawl API Key',
60
+ pattern: /fc-[a-f0-9]{32}/g,
61
+ },
62
+ {
63
+ name: 'GitHub Token',
64
+ pattern: /gh[pousr]_[a-zA-Z0-9]{36,}/g,
65
+ },
66
+ {
67
+ name: 'GitHub Fine-grained PAT',
68
+ pattern: /github_pat_[a-zA-Z0-9_]{20,}/g,
69
+ },
70
+ ];
71
+ const SSH_CONFIG_VALUE_DIRECTIVE_PATTERN = /^([ \t]*)(HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)(\s+)(.+)$/gim;
72
+ const SSH_CONFIG_HOST_PATTERN = /^([ \t]*)(Host)(\s+)(.+)$/gim;
73
+ const SSH_CONFIG_MATCH_PATTERN = /^([ \t]*)(Match)(\s+)(.+)$/gim;
74
+ export function looks_like_ssh_config(text) {
75
+ const has_scope_line = /^\s*(?:Host|Match)\b/m.test(text);
76
+ const has_sensitive_directive = /^\s*(?:HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)\b/im.test(text);
77
+ return has_scope_line && has_sensitive_directive;
78
+ }
79
+ export function redact_ssh_config_metadata(text) {
80
+ let count = 0;
81
+ const redact_directive_value = (match, indent, directive, spacing, value) => {
82
+ if (value.includes('[REDACTED:'))
83
+ return match;
84
+ count++;
85
+ return `${indent}${directive}${spacing}[REDACTED:SSH ${directive}]`;
86
+ };
87
+ let result = text.replace(SSH_CONFIG_VALUE_DIRECTIVE_PATTERN, redact_directive_value);
88
+ result = result.replace(SSH_CONFIG_HOST_PATTERN, (match, indent, directive, spacing, value) => {
89
+ const trimmed = value.trim();
90
+ if (trimmed === '*' || value.includes('[REDACTED:'))
91
+ return match;
92
+ count++;
93
+ return `${indent}${directive}${spacing}[REDACTED:SSH Host]`;
94
+ });
95
+ result = result.replace(SSH_CONFIG_MATCH_PATTERN, (match, indent, directive, spacing, value) => {
96
+ if (value.trim().toLowerCase() === 'all')
97
+ return match;
98
+ if (value.includes('[REDACTED:'))
99
+ return match;
100
+ count++;
101
+ return `${indent}${directive}${spacing}[REDACTED:SSH Match]`;
102
+ });
103
+ return { redacted: result, count };
104
+ }
105
+ function redact_secret_patterns(text) {
106
+ let count = 0;
107
+ let result = text;
108
+ for (const sp of SECRET_PATTERNS) {
109
+ sp.pattern.lastIndex = 0;
110
+ result = result.replace(sp.pattern, (match) => {
111
+ count++;
112
+ const prefix = match.slice(0, 4);
113
+ return `${prefix}${'*'.repeat(Math.min(match.length - 4, 20))}[REDACTED:${sp.name}]`;
114
+ });
115
+ }
116
+ return { redacted: result, count };
117
+ }
118
+ function is_ssh_config_path(path) {
119
+ if (typeof path !== 'string')
120
+ return false;
121
+ const normalized = path.replaceAll('\\', '/').toLowerCase();
122
+ return /(?:^|\/)(?:\.ssh\/(?:config|config\.d\/.+|conf\.d\/.+)|ssh_config)$/.test(normalized);
123
+ }
124
+ function should_force_ssh_config_redaction(event) {
125
+ if (event.toolName !== 'read')
126
+ return false;
127
+ if (!event.input || typeof event.input !== 'object')
128
+ return false;
129
+ return is_ssh_config_path(event.input.path);
130
+ }
131
+ function is_text_content(item) {
132
+ return item.type === 'text';
133
+ }
134
+ export function redact_text(text, options) {
135
+ let count = 0;
136
+ let result = text;
137
+ if (options?.force_ssh_config || looks_like_ssh_config(result)) {
138
+ const ssh_redaction = redact_ssh_config_metadata(result);
139
+ result = ssh_redaction.redacted;
140
+ count += ssh_redaction.count;
141
+ }
142
+ const secret_redaction = redact_secret_patterns(result);
143
+ result = secret_redaction.redacted;
144
+ count += secret_redaction.count;
145
+ return { redacted: result, count };
146
+ }
147
+ export default async function filter_output(pi) {
148
+ let totalRedacted = 0;
149
+ pi.on('tool_result', async (event) => {
150
+ if (!event.content)
151
+ return;
152
+ const force_ssh_config = should_force_ssh_config_redaction(event);
153
+ let modified = false;
154
+ const newContent = event.content.map((item) => {
155
+ if (!is_text_content(item) || !item.text)
156
+ return item;
157
+ const { redacted, count } = redact_text(item.text, {
158
+ force_ssh_config,
159
+ });
160
+ if (count > 0) {
161
+ modified = true;
162
+ totalRedacted += count;
163
+ }
164
+ return { ...item, text: redacted };
165
+ });
166
+ if (modified) {
167
+ return { content: newContent };
168
+ }
169
+ });
170
+ pi.registerCommand('redact-stats', {
171
+ description: 'Show how many secrets have been redacted',
172
+ handler: async (_args, ctx) => {
173
+ ctx.ui.notify(`Secrets redacted this session: ${totalRedacted}`);
174
+ },
175
+ });
176
+ }
177
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@spences10/pi-redact",
3
+ "version": "0.0.1",
4
+ "description": "Pi extension that redacts secrets from tool output before the model sees them",
5
+ "keywords": [
6
+ "pi",
7
+ "pi-package",
8
+ "redaction",
9
+ "secrets"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "Scott Spence <me@scottspence.com>",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/spences10/my-pi.git",
16
+ "directory": "packages/pi-redact"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "type": "module",
23
+ "main": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "dependencies": {
35
+ "@mariozechner/pi-ai": "^0.70.2",
36
+ "@mariozechner/pi-coding-agent": "^0.70.2"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^25.6.0",
40
+ "typescript": "^5.9.3",
41
+ "vitest": "^4.1.5"
42
+ },
43
+ "engines": {
44
+ "node": ">=22.0.0"
45
+ },
46
+ "pi": {
47
+ "extensions": [
48
+ "./dist/index.js"
49
+ ]
50
+ },
51
+ "scripts": {
52
+ "build": "tsc -p tsconfig.build.json",
53
+ "check": "tsc --noEmit -p tsconfig.json",
54
+ "test": "vitest run"
55
+ }
56
+ }