@spences10/pi-confirm-destructive 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 +21 -0
- package/README.md +71 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +339 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
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,71 @@
|
|
|
1
|
+
# @spences10/pi-confirm-destructive
|
|
2
|
+
|
|
3
|
+
[](https://github.com/badlogic/vite-plus)
|
|
4
|
+
|
|
5
|
+
Git-aware destructive action guard for the Pi coding agent.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pi install npm:@spences10/pi-confirm-destructive
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Local development from this monorepo:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm --filter @spences10/pi-confirm-destructive run build
|
|
17
|
+
pi install ./packages/pi-confirm-destructive
|
|
18
|
+
# or for one run only
|
|
19
|
+
pi -e ./packages/pi-confirm-destructive
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## What it does
|
|
23
|
+
|
|
24
|
+
The extension intercepts Pi `tool_call` and `user_bash` events before
|
|
25
|
+
they run and asks for confirmation when an action may destroy data
|
|
26
|
+
that Git cannot restore.
|
|
27
|
+
|
|
28
|
+
It allows common refactor operations on clean tracked files without
|
|
29
|
+
prompting, while guarding:
|
|
30
|
+
|
|
31
|
+
- untracked file deletes or overwrites
|
|
32
|
+
- tracked files with uncommitted changes
|
|
33
|
+
- broad destructive shell commands such as `find -delete`,
|
|
34
|
+
`git clean`, `rsync --delete`, `truncate`, `dd`, and disk tools
|
|
35
|
+
- destructive Prisma commands such as `prisma migrate reset` and
|
|
36
|
+
`prisma db push --force-reset`
|
|
37
|
+
- destructive database CLI calls through `psql`, `mysql`, `mariadb`,
|
|
38
|
+
or `sqlite3`
|
|
39
|
+
- custom/MCP tools with destructive names such as `delete`, `drop`,
|
|
40
|
+
`execute_write_query`, or `execute_schema_query`
|
|
41
|
+
|
|
42
|
+
In interactive mode the prompt offers:
|
|
43
|
+
|
|
44
|
+
- `Allow once`
|
|
45
|
+
- `Allow similar for this session`
|
|
46
|
+
- `Block`
|
|
47
|
+
|
|
48
|
+
In non-interactive mode destructive actions are blocked by default.
|
|
49
|
+
|
|
50
|
+
## Using from a custom harness
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import confirm_destructive from '@spences10/pi-confirm-destructive';
|
|
54
|
+
|
|
55
|
+
// pass `confirm_destructive` as an ExtensionFactory to your Pi runtime
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`my-pi` imports this package directly and enables it as the built-in
|
|
59
|
+
confirm-destructive guard.
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm --filter @spences10/pi-confirm-destructive run check
|
|
65
|
+
pnpm --filter @spences10/pi-confirm-destructive run test
|
|
66
|
+
pnpm --filter @spences10/pi-confirm-destructive run build
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ExtensionAPI, ToolCallEvent } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
export interface DestructiveAction {
|
|
3
|
+
title: string;
|
|
4
|
+
description: string;
|
|
5
|
+
reason: string;
|
|
6
|
+
allow_key: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function assess_bash_command(command: string, cwd?: string): DestructiveAction | undefined;
|
|
9
|
+
export declare function assess_tool_call(event: ToolCallEvent, cwd: string): DestructiveAction | undefined;
|
|
10
|
+
export default function confirm_destructive(pi: ExtensionAPI): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
// Confirm destructive tool calls before they run.
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
const DESTRUCTIVE_COMMAND_PATTERNS = [
|
|
6
|
+
{
|
|
7
|
+
pattern: /(^|[;&|]\s*)(npx\s+|pnpx\s+|pnpm\s+exec\s+|bunx\s+)?prisma\s+(migrate\s+reset|db\s+push\b[^;&|]*--force-reset|db\s+execute\b)/,
|
|
8
|
+
reason: 'Runs a potentially destructive Prisma database operation',
|
|
9
|
+
allow_key: 'bash:prisma-destructive',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
pattern: /(^|[;&|]\s*)(psql|mysql|mariadb|sqlite3)\b[^;&|]*\b(drop|delete\s+from|truncate|alter\s+table|update\s+\S+\s+set)\b/i,
|
|
13
|
+
reason: 'Runs destructive SQL through a database CLI',
|
|
14
|
+
allow_key: 'bash:db-cli-destructive-sql',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
pattern: /(^|[;&|]\s*)find\b[^;&|]*(\s-delete\b|-exec\s+(sudo\s+)?rm\b)/,
|
|
18
|
+
reason: 'Deletes files found by find',
|
|
19
|
+
allow_key: 'bash:find-delete',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
pattern: /(^|[;&|]\s*)git\s+clean\b[^;&|]*-[a-zA-Z]*[fdx][a-zA-Z]*/,
|
|
23
|
+
reason: 'Deletes untracked files or directories',
|
|
24
|
+
allow_key: 'bash:git-clean',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
pattern: /(^|[;&|]\s*)git\s+(checkout|restore)\b[^;&|]*(\s--\s+\.\s*$|\s\.\s*$)/,
|
|
28
|
+
reason: 'Discards working tree changes',
|
|
29
|
+
allow_key: 'bash:git-discard-all',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: /(^|[;&|]\s*)rsync\b[^;&|]*\s--delete\b/,
|
|
33
|
+
reason: 'Deletes destination files during sync',
|
|
34
|
+
allow_key: 'bash:rsync-delete',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: /(^|[;&|]\s*)truncate\b[^;&|]*(\s-s\s*0\b|\s--size\s*=?\s*0\b)/,
|
|
38
|
+
reason: 'Empties file contents',
|
|
39
|
+
allow_key: 'bash:truncate-zero',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
pattern: /(^|[;&|]\s*)dd\b[^;&|]*\bof=/,
|
|
43
|
+
reason: 'Overwrites a device or file with dd',
|
|
44
|
+
allow_key: 'bash:dd-output',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
pattern: /(^|[;&|]\s*)(mkfs|fdisk|parted|wipefs)\b/,
|
|
48
|
+
reason: 'Modifies disks or filesystems',
|
|
49
|
+
allow_key: 'bash:disk-tool',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
const DESTRUCTIVE_CUSTOM_TOOL_NAME = /(^|[_-])(delete|destroy|drop|remove|archive|execute_write_query|execute_schema_query|bulk_insert)([_-]|$)/i;
|
|
53
|
+
function preview(value, max = 500) {
|
|
54
|
+
const normalized = value.trim().replace(/\s+/g, ' ');
|
|
55
|
+
return normalized.length > max
|
|
56
|
+
? `${normalized.slice(0, max - 1)}…`
|
|
57
|
+
: normalized;
|
|
58
|
+
}
|
|
59
|
+
function git(args, cwd) {
|
|
60
|
+
try {
|
|
61
|
+
return execFileSync('git', ['-C', cwd, ...args], {
|
|
62
|
+
encoding: 'utf-8',
|
|
63
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
64
|
+
}).trim();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function is_git_repo(cwd) {
|
|
71
|
+
return git(['rev-parse', '--is-inside-work-tree'], cwd) === 'true';
|
|
72
|
+
}
|
|
73
|
+
function get_git_recoverability(cwd, path) {
|
|
74
|
+
if (!is_git_repo(cwd))
|
|
75
|
+
return 'not-git';
|
|
76
|
+
const status = git(['status', '--porcelain=v1', '--', path], cwd);
|
|
77
|
+
if (status === undefined)
|
|
78
|
+
return 'not-git';
|
|
79
|
+
if (status.length > 0) {
|
|
80
|
+
return status.split('\n').some((line) => line.startsWith('??'))
|
|
81
|
+
? 'untracked'
|
|
82
|
+
: 'tracked-dirty';
|
|
83
|
+
}
|
|
84
|
+
const tracked = git(['ls-files', '--', path], cwd);
|
|
85
|
+
return tracked ? 'tracked-clean' : 'untracked';
|
|
86
|
+
}
|
|
87
|
+
function is_git_recoverable(cwd, path) {
|
|
88
|
+
return get_git_recoverability(cwd, path) === 'tracked-clean';
|
|
89
|
+
}
|
|
90
|
+
function parse_shell_words(command) {
|
|
91
|
+
const words = [];
|
|
92
|
+
const pattern = /"((?:\\.|[^"])*)"|'([^']*)'|(\S+)/g;
|
|
93
|
+
let match;
|
|
94
|
+
while ((match = pattern.exec(command))) {
|
|
95
|
+
words.push(match[1] ?? match[2] ?? match[3]);
|
|
96
|
+
}
|
|
97
|
+
return words;
|
|
98
|
+
}
|
|
99
|
+
function extract_command_paths(command, command_name) {
|
|
100
|
+
if (/[;&|`$()<>]/.test(command))
|
|
101
|
+
return undefined;
|
|
102
|
+
const words = parse_shell_words(command);
|
|
103
|
+
const command_index = command_name === 'rm'
|
|
104
|
+
? words.findIndex((word) => ['rm', 'rmdir', 'unlink', 'shred'].includes(word))
|
|
105
|
+
: words.findIndex((word, index) => word === 'rm' && words[index - 1] === 'git');
|
|
106
|
+
if (command_index === -1)
|
|
107
|
+
return undefined;
|
|
108
|
+
return words
|
|
109
|
+
.slice(command_index + 1)
|
|
110
|
+
.filter((word) => word !== '--' && !word.startsWith('-'));
|
|
111
|
+
}
|
|
112
|
+
function describe_path_risk(cwd, paths) {
|
|
113
|
+
const risky = paths.filter((path) => !is_git_recoverable(cwd, path));
|
|
114
|
+
if (risky.length === 0)
|
|
115
|
+
return 'Deletes git-recoverable files';
|
|
116
|
+
const risks = new Set(risky.map((path) => get_git_recoverability(cwd, path)));
|
|
117
|
+
if (risks.has('untracked')) {
|
|
118
|
+
return 'Deletes untracked files or directories that git cannot restore';
|
|
119
|
+
}
|
|
120
|
+
if (risks.has('tracked-dirty')) {
|
|
121
|
+
return 'Deletes files with uncommitted changes';
|
|
122
|
+
}
|
|
123
|
+
return 'Deletes files outside git recovery';
|
|
124
|
+
}
|
|
125
|
+
function assess_rm_command(command, cwd) {
|
|
126
|
+
if (!/(^|[;&|]\s*)(sudo\s+)?(rm|rmdir|unlink|shred)\b/.test(command)) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const paths = extract_command_paths(command, 'rm');
|
|
130
|
+
if (paths &&
|
|
131
|
+
paths.length > 0 &&
|
|
132
|
+
paths.every((path) => is_git_recoverable(cwd, path))) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
const reason = paths?.length
|
|
136
|
+
? describe_path_risk(cwd, paths)
|
|
137
|
+
: 'Deletes files or directories';
|
|
138
|
+
return {
|
|
139
|
+
title: 'Confirm destructive command?',
|
|
140
|
+
description: `${reason}: ${preview(command)}`,
|
|
141
|
+
reason,
|
|
142
|
+
allow_key: 'bash:rm-risky',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function assess_git_rm_command(command, cwd) {
|
|
146
|
+
if (!/(^|[;&|]\s*)git\s+rm\b/.test(command))
|
|
147
|
+
return undefined;
|
|
148
|
+
if (/\s-f\b|\s--force\b/.test(command)) {
|
|
149
|
+
return {
|
|
150
|
+
title: 'Confirm forced git removal?',
|
|
151
|
+
description: `Forced git removal can discard uncommitted file changes: ${preview(command)}`,
|
|
152
|
+
reason: 'Force-removes files from git',
|
|
153
|
+
allow_key: 'bash:git-rm-force',
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const paths = extract_command_paths(command, 'git-rm');
|
|
157
|
+
if (paths &&
|
|
158
|
+
paths.length > 0 &&
|
|
159
|
+
paths.every((path) => is_git_recoverable(cwd, path))) {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
const reason = paths?.length
|
|
163
|
+
? describe_path_risk(cwd, paths)
|
|
164
|
+
: 'Deletes tracked files from git';
|
|
165
|
+
return {
|
|
166
|
+
title: 'Confirm git removal?',
|
|
167
|
+
description: `${reason}: ${preview(command)}`,
|
|
168
|
+
reason,
|
|
169
|
+
allow_key: 'bash:git-rm-risky',
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function assess_git_reset_hard(command, cwd) {
|
|
173
|
+
if (!/(^|[;&|]\s*)git\s+reset\b[^;&|]*--hard\b/.test(command)) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
if (git(['status', '--porcelain=v1'], cwd) === '')
|
|
177
|
+
return undefined;
|
|
178
|
+
return {
|
|
179
|
+
title: 'Confirm hard reset?',
|
|
180
|
+
description: `This can discard uncommitted tracked changes: ${preview(command)}`,
|
|
181
|
+
reason: 'Discards uncommitted tracked changes',
|
|
182
|
+
allow_key: 'bash:git-reset-hard',
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export function assess_bash_command(command, cwd = process.cwd()) {
|
|
186
|
+
const normalized = command.trim();
|
|
187
|
+
if (!normalized)
|
|
188
|
+
return undefined;
|
|
189
|
+
const specific = assess_rm_command(normalized, cwd) ??
|
|
190
|
+
assess_git_rm_command(normalized, cwd) ??
|
|
191
|
+
assess_git_reset_hard(normalized, cwd);
|
|
192
|
+
if (specific)
|
|
193
|
+
return specific;
|
|
194
|
+
const match = DESTRUCTIVE_COMMAND_PATTERNS.find(({ pattern }) => pattern.test(normalized));
|
|
195
|
+
if (!match)
|
|
196
|
+
return undefined;
|
|
197
|
+
return {
|
|
198
|
+
title: 'Confirm destructive command?',
|
|
199
|
+
description: `${match.reason}: ${preview(normalized)}`,
|
|
200
|
+
reason: match.reason,
|
|
201
|
+
allow_key: match.allow_key,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function assess_file_write(cwd, path) {
|
|
205
|
+
if (typeof path !== 'string' || !path.trim())
|
|
206
|
+
return undefined;
|
|
207
|
+
const absolute = resolve(cwd, path);
|
|
208
|
+
if (!existsSync(absolute))
|
|
209
|
+
return undefined;
|
|
210
|
+
if (is_git_recoverable(cwd, path))
|
|
211
|
+
return undefined;
|
|
212
|
+
const reason = get_git_recoverability(cwd, path) === 'tracked-dirty'
|
|
213
|
+
? 'Overwrites a file with uncommitted changes'
|
|
214
|
+
: 'Overwrites an untracked file git cannot restore';
|
|
215
|
+
return {
|
|
216
|
+
title: 'Confirm file overwrite?',
|
|
217
|
+
description: `${reason}: ${path}`,
|
|
218
|
+
reason,
|
|
219
|
+
allow_key: 'write:risky-overwrite',
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function assess_file_edit(cwd, input) {
|
|
223
|
+
const path = typeof input.path === 'string' ? input.path : undefined;
|
|
224
|
+
const edits = Array.isArray(input.edits) ? input.edits : [];
|
|
225
|
+
let removed_chars = 0;
|
|
226
|
+
let added_chars = 0;
|
|
227
|
+
for (const edit of edits) {
|
|
228
|
+
if (!edit || typeof edit !== 'object')
|
|
229
|
+
continue;
|
|
230
|
+
const old_text = edit.oldText;
|
|
231
|
+
const new_text = edit.newText;
|
|
232
|
+
if (typeof old_text === 'string')
|
|
233
|
+
removed_chars += old_text.length;
|
|
234
|
+
if (typeof new_text === 'string')
|
|
235
|
+
added_chars += new_text.length;
|
|
236
|
+
}
|
|
237
|
+
if (removed_chars === 0 || removed_chars - added_chars < 200) {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
if (path && is_git_recoverable(cwd, path))
|
|
241
|
+
return undefined;
|
|
242
|
+
return {
|
|
243
|
+
title: 'Confirm large content removal?',
|
|
244
|
+
description: `This edit removes ${removed_chars - added_chars} more characters than it adds${path ? ` in ${path}` : ''}.`,
|
|
245
|
+
reason: path
|
|
246
|
+
? 'Removes substantial content from a file git cannot fully restore'
|
|
247
|
+
: 'Removes substantial file content',
|
|
248
|
+
allow_key: 'edit:large-removal-risky',
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function assess_custom_tool(event) {
|
|
252
|
+
if (!DESTRUCTIVE_CUSTOM_TOOL_NAME.test(event.toolName)) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
const input = event.input;
|
|
256
|
+
const query = typeof input.query === 'string'
|
|
257
|
+
? `\n\nQuery: ${preview(input.query)}`
|
|
258
|
+
: '';
|
|
259
|
+
return {
|
|
260
|
+
title: 'Confirm destructive tool call?',
|
|
261
|
+
description: `Tool ${event.toolName} appears destructive.${query}`,
|
|
262
|
+
reason: `Potentially destructive tool: ${event.toolName}`,
|
|
263
|
+
allow_key: `tool:${event.toolName}`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
export function assess_tool_call(event, cwd) {
|
|
267
|
+
if (event.toolName === 'bash') {
|
|
268
|
+
const command = event.input.command;
|
|
269
|
+
return typeof command === 'string'
|
|
270
|
+
? assess_bash_command(command, cwd)
|
|
271
|
+
: undefined;
|
|
272
|
+
}
|
|
273
|
+
if (event.toolName === 'write') {
|
|
274
|
+
return assess_file_write(cwd, event.input.path);
|
|
275
|
+
}
|
|
276
|
+
if (event.toolName === 'edit') {
|
|
277
|
+
return assess_file_edit(cwd, event.input);
|
|
278
|
+
}
|
|
279
|
+
return assess_custom_tool(event);
|
|
280
|
+
}
|
|
281
|
+
async function confirm_action(action, ctx) {
|
|
282
|
+
if (!ctx.hasUI)
|
|
283
|
+
return 'block';
|
|
284
|
+
const choice = await ctx.ui.select(`${action.title}\n${action.description}`, ['Allow once', 'Allow similar for this session', 'Block']);
|
|
285
|
+
if (choice === 'Allow once')
|
|
286
|
+
return 'allow';
|
|
287
|
+
if (choice === 'Allow similar for this session') {
|
|
288
|
+
return 'allow-similar';
|
|
289
|
+
}
|
|
290
|
+
ctx.ui.notify('Destructive action blocked', 'info');
|
|
291
|
+
return 'block';
|
|
292
|
+
}
|
|
293
|
+
function blocked_reason(action) {
|
|
294
|
+
return `Blocked destructive action: ${action.reason}`;
|
|
295
|
+
}
|
|
296
|
+
function blocked_bash_result(action) {
|
|
297
|
+
return {
|
|
298
|
+
output: `${blocked_reason(action)}\n`,
|
|
299
|
+
exitCode: 130,
|
|
300
|
+
cancelled: false,
|
|
301
|
+
truncated: false,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
export default async function confirm_destructive(pi) {
|
|
305
|
+
const allowed_for_session = new Set();
|
|
306
|
+
function is_allowed(action) {
|
|
307
|
+
return allowed_for_session.has(action.allow_key);
|
|
308
|
+
}
|
|
309
|
+
async function should_allow(action, ctx) {
|
|
310
|
+
if (is_allowed(action))
|
|
311
|
+
return true;
|
|
312
|
+
const decision = await confirm_action(action, ctx);
|
|
313
|
+
if (decision === 'allow-similar') {
|
|
314
|
+
allowed_for_session.add(action.allow_key);
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
return decision === 'allow';
|
|
318
|
+
}
|
|
319
|
+
pi.on('tool_call', async (event, ctx) => {
|
|
320
|
+
const action = assess_tool_call(event, ctx.cwd);
|
|
321
|
+
if (!action)
|
|
322
|
+
return;
|
|
323
|
+
if (await should_allow(action, ctx))
|
|
324
|
+
return;
|
|
325
|
+
return {
|
|
326
|
+
block: true,
|
|
327
|
+
reason: blocked_reason(action),
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
pi.on('user_bash', async (event, ctx) => {
|
|
331
|
+
const action = assess_bash_command(event.command, event.cwd);
|
|
332
|
+
if (!action)
|
|
333
|
+
return;
|
|
334
|
+
if (await should_allow(action, ctx))
|
|
335
|
+
return;
|
|
336
|
+
return { result: blocked_bash_result(action) };
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
//# 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,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spences10/pi-confirm-destructive",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Pi extension that confirms destructive actions before they run",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"confirm",
|
|
7
|
+
"destructive",
|
|
8
|
+
"guard",
|
|
9
|
+
"pi",
|
|
10
|
+
"pi-package",
|
|
11
|
+
"safety"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "Scott Spence <me@scottspence.com>",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/spences10/my-pi.git",
|
|
18
|
+
"directory": "packages/pi-confirm-destructive"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@mariozechner/pi-coding-agent": "^0.70.2"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^25.6.0",
|
|
35
|
+
"typescript": "^6.0.0",
|
|
36
|
+
"vitest": "^4.1.5"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=22.0.0"
|
|
40
|
+
},
|
|
41
|
+
"pi": {
|
|
42
|
+
"extensions": [
|
|
43
|
+
"./dist/index.js"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc -p tsconfig.build.json",
|
|
48
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest"
|
|
51
|
+
}
|
|
52
|
+
}
|