@spences10/pi-confirm-destructive 0.0.14 → 0.0.16

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 CHANGED
@@ -5,6 +5,8 @@
5
5
  [![npm version](https://img.shields.io/npm/v/@spences10/pi-confirm-destructive?color=CB3837&logo=npm&logoColor=white)](https://www.npmjs.com/package/@spences10/pi-confirm-destructive)
6
6
  [![license](https://img.shields.io/npm/l/@spences10/pi-confirm-destructive)](https://www.npmjs.com/package/@spences10/pi-confirm-destructive)
7
7
 
8
+ ![my-pi package preview](https://raw.githubusercontent.com/spences10/my-pi/main/assets/pi-package-preview.png)
9
+
8
10
  Stop destructive shell commands before they surprise you.
9
11
  `pi-confirm-destructive` adds a Git-aware confirmation layer for
10
12
  deletes, resets, force pushes, and other risky actions so agents pause
@@ -0,0 +1,4 @@
1
+ import type { ToolCallEvent } from '@earendil-works/pi-coding-agent';
2
+ import type { DestructiveAction } from './types.js';
3
+ export declare function assess_bash_command(command: string, cwd?: string, session_created_paths?: ReadonlySet<string>): DestructiveAction | undefined;
4
+ export declare function assess_tool_call(event: ToolCallEvent, cwd: string, session_created_paths?: ReadonlySet<string>): DestructiveAction | undefined;
@@ -0,0 +1,228 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { get_git_recoverability, git, is_git_recoverable, } from './git.js';
4
+ import { describe_path_risk, is_agent_temp_path } from './paths.js';
5
+ import { extract_command_paths } from './shell.js';
6
+ const DESTRUCTIVE_COMMAND_PATTERNS = [
7
+ {
8
+ 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)/,
9
+ reason: 'Runs a potentially destructive Prisma database operation',
10
+ allow_key: 'bash:prisma-destructive',
11
+ },
12
+ {
13
+ pattern: /(^|[;&|]\s*)(psql|mysql|mariadb|sqlite3)\b[^;&|]*\b(drop|delete\s+from|truncate|alter\s+table|update\s+\S+\s+set)\b/i,
14
+ reason: 'Runs destructive SQL through a database CLI',
15
+ allow_key: 'bash:db-cli-destructive-sql',
16
+ },
17
+ {
18
+ pattern: /(^|[;&|]\s*)find\b[^;&|]*(\s-delete\b|-exec\s+(sudo\s+)?rm\b)/,
19
+ reason: 'Deletes files found by find',
20
+ allow_key: 'bash:find-delete',
21
+ },
22
+ {
23
+ pattern: /(^|[;&|]\s*)git\s+clean\b[^;&|]*-[a-zA-Z]*[fdx][a-zA-Z]*/,
24
+ reason: 'Deletes untracked files or directories',
25
+ allow_key: 'bash:git-clean',
26
+ },
27
+ {
28
+ pattern: /(^|[;&|]\s*)git\s+(checkout|restore)\b[^;&|]*(\s--\s+\.\s*$|\s\.\s*$)/,
29
+ reason: 'Discards working tree changes',
30
+ allow_key: 'bash:git-discard-all',
31
+ },
32
+ {
33
+ pattern: /(^|[;&|]\s*)rsync\b[^;&|]*\s--delete\b/,
34
+ reason: 'Deletes destination files during sync',
35
+ allow_key: 'bash:rsync-delete',
36
+ },
37
+ {
38
+ pattern: /(^|[;&|]\s*)truncate\b[^;&|]*(\s-s\s*0\b|\s--size\s*=?\s*0\b)/,
39
+ reason: 'Empties file contents',
40
+ allow_key: 'bash:truncate-zero',
41
+ },
42
+ {
43
+ pattern: /(^|[;&|]\s*)dd\b[^;&|]*\bof=/,
44
+ reason: 'Overwrites a device or file with dd',
45
+ allow_key: 'bash:dd-output',
46
+ },
47
+ {
48
+ pattern: /(^|[;&|]\s*)(mkfs|fdisk|parted|wipefs)\b/,
49
+ reason: 'Modifies disks or filesystems',
50
+ allow_key: 'bash:disk-tool',
51
+ },
52
+ ];
53
+ const DESTRUCTIVE_CUSTOM_TOOL_NAME = /(^|[_-])(delete|destroy|drop|remove|archive|execute_write_query|execute_schema_query|bulk_insert)([_-]|$)/i;
54
+ function preview(value, max = 500) {
55
+ const normalized = value.trim().replace(/\s+/g, ' ');
56
+ return normalized.length > max
57
+ ? `${normalized.slice(0, max - 1)}…`
58
+ : normalized;
59
+ }
60
+ function assess_rm_command(command, cwd, session_created_paths = new Set()) {
61
+ if (!/(^|[;&|]\s*)(sudo\s+)?(rm|rmdir|unlink|shred)\b/.test(command)) {
62
+ return undefined;
63
+ }
64
+ const paths = extract_command_paths(command, 'rm');
65
+ if (paths && paths.length > 0) {
66
+ if (paths.every((path) => {
67
+ const absolute = resolve(cwd, path);
68
+ return (session_created_paths.has(absolute) ||
69
+ is_agent_temp_path(absolute));
70
+ })) {
71
+ return undefined;
72
+ }
73
+ if (paths.every((path) => is_git_recoverable(cwd, path))) {
74
+ return undefined;
75
+ }
76
+ }
77
+ const reason = paths?.length
78
+ ? describe_path_risk(cwd, paths)
79
+ : 'Deletes files or directories';
80
+ return {
81
+ title: 'Confirm destructive command?',
82
+ description: `${reason}: ${preview(command)}`,
83
+ reason,
84
+ allow_key: 'bash:rm-risky',
85
+ };
86
+ }
87
+ function assess_git_rm_command(command, cwd) {
88
+ if (!/(^|[;&|]\s*)git\s+rm\b/.test(command))
89
+ return undefined;
90
+ if (/\s-f\b|\s--force\b/.test(command)) {
91
+ return {
92
+ title: 'Confirm forced git removal?',
93
+ description: `Forced git removal can discard uncommitted file changes: ${preview(command)}`,
94
+ reason: 'Force-removes files from git',
95
+ allow_key: 'bash:git-rm-force',
96
+ };
97
+ }
98
+ const paths = extract_command_paths(command, 'git-rm');
99
+ if (paths &&
100
+ paths.length > 0 &&
101
+ paths.every((path) => is_git_recoverable(cwd, path))) {
102
+ return undefined;
103
+ }
104
+ const reason = paths?.length
105
+ ? describe_path_risk(cwd, paths)
106
+ : 'Deletes tracked files from git';
107
+ return {
108
+ title: 'Confirm git removal?',
109
+ description: `${reason}: ${preview(command)}`,
110
+ reason,
111
+ allow_key: 'bash:git-rm-risky',
112
+ };
113
+ }
114
+ function assess_git_reset_hard(command, cwd) {
115
+ if (!/(^|[;&|]\s*)git\s+reset\b[^;&|]*--hard\b/.test(command)) {
116
+ return undefined;
117
+ }
118
+ if (git(['status', '--porcelain=v1'], cwd) === '')
119
+ return undefined;
120
+ return {
121
+ title: 'Confirm hard reset?',
122
+ description: `This can discard uncommitted tracked changes: ${preview(command)}`,
123
+ reason: 'Discards uncommitted tracked changes',
124
+ allow_key: 'bash:git-reset-hard',
125
+ };
126
+ }
127
+ export function assess_bash_command(command, cwd = process.cwd(), session_created_paths = new Set()) {
128
+ const normalized = command.trim();
129
+ if (!normalized)
130
+ return undefined;
131
+ const specific = assess_rm_command(normalized, cwd, session_created_paths) ??
132
+ assess_git_rm_command(normalized, cwd) ??
133
+ assess_git_reset_hard(normalized, cwd);
134
+ if (specific)
135
+ return specific;
136
+ const match = DESTRUCTIVE_COMMAND_PATTERNS.find(({ pattern }) => pattern.test(normalized));
137
+ if (!match)
138
+ return undefined;
139
+ return {
140
+ title: 'Confirm destructive command?',
141
+ description: `${match.reason}: ${preview(normalized)}`,
142
+ reason: match.reason,
143
+ allow_key: match.allow_key,
144
+ };
145
+ }
146
+ function assess_file_write(cwd, path, session_created_paths = new Set()) {
147
+ if (typeof path !== 'string' || !path.trim())
148
+ return undefined;
149
+ const absolute = resolve(cwd, path);
150
+ if (!existsSync(absolute))
151
+ return undefined;
152
+ if (session_created_paths.has(absolute))
153
+ return undefined;
154
+ if (is_git_recoverable(cwd, path))
155
+ return undefined;
156
+ const reason = get_git_recoverability(cwd, path) === 'tracked-dirty'
157
+ ? 'Overwrites a file with uncommitted changes'
158
+ : 'Overwrites an untracked file git cannot restore';
159
+ return {
160
+ title: 'Confirm file overwrite?',
161
+ description: `${reason}: ${path}`,
162
+ reason,
163
+ allow_key: 'write:risky-overwrite',
164
+ };
165
+ }
166
+ function assess_file_edit(cwd, input, session_created_paths = new Set()) {
167
+ const path = typeof input.path === 'string' ? input.path : undefined;
168
+ const edits = Array.isArray(input.edits) ? input.edits : [];
169
+ let removed_chars = 0;
170
+ let added_chars = 0;
171
+ for (const edit of edits) {
172
+ if (!edit || typeof edit !== 'object')
173
+ continue;
174
+ const old_text = edit.oldText;
175
+ const new_text = edit.newText;
176
+ if (typeof old_text === 'string')
177
+ removed_chars += old_text.length;
178
+ if (typeof new_text === 'string')
179
+ added_chars += new_text.length;
180
+ }
181
+ if (removed_chars === 0 || removed_chars - added_chars < 200) {
182
+ return undefined;
183
+ }
184
+ if (path && session_created_paths.has(resolve(cwd, path))) {
185
+ return undefined;
186
+ }
187
+ if (path && is_git_recoverable(cwd, path))
188
+ return undefined;
189
+ return {
190
+ title: 'Confirm large content removal?',
191
+ description: `This edit removes ${removed_chars - added_chars} more characters than it adds${path ? ` in ${path}` : ''}.`,
192
+ reason: path
193
+ ? 'Removes substantial content from a file git cannot fully restore'
194
+ : 'Removes substantial file content',
195
+ allow_key: 'edit:large-removal-risky',
196
+ };
197
+ }
198
+ function assess_custom_tool(event) {
199
+ if (!DESTRUCTIVE_CUSTOM_TOOL_NAME.test(event.toolName)) {
200
+ return undefined;
201
+ }
202
+ const input = event.input;
203
+ const query = typeof input.query === 'string'
204
+ ? `\n\nQuery: ${preview(input.query)}`
205
+ : '';
206
+ return {
207
+ title: 'Confirm destructive tool call?',
208
+ description: `Tool ${event.toolName} appears destructive.${query}`,
209
+ reason: `Potentially destructive tool: ${event.toolName}`,
210
+ allow_key: `tool:${event.toolName}`,
211
+ };
212
+ }
213
+ export function assess_tool_call(event, cwd, session_created_paths = new Set()) {
214
+ if (event.toolName === 'bash') {
215
+ const command = event.input.command;
216
+ return typeof command === 'string'
217
+ ? assess_bash_command(command, cwd, session_created_paths)
218
+ : undefined;
219
+ }
220
+ if (event.toolName === 'write') {
221
+ return assess_file_write(cwd, event.input.path, session_created_paths);
222
+ }
223
+ if (event.toolName === 'edit') {
224
+ return assess_file_edit(cwd, event.input, session_created_paths);
225
+ }
226
+ return assess_custom_tool(event);
227
+ }
228
+ //# sourceMappingURL=assessors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assessors.js","sourceRoot":"","sources":["../../src/destructive/assessors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { GitRecoverability } from './types.js';
2
+ export declare function git(args: string[], cwd: string): string | undefined;
3
+ export declare function get_git_recoverability(cwd: string, path: string): GitRecoverability;
4
+ export declare function is_git_recoverable(cwd: string, path: string): boolean;
@@ -0,0 +1,33 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ export function git(args, cwd) {
3
+ try {
4
+ return execFileSync('git', ['-C', cwd, ...args], {
5
+ encoding: 'utf-8',
6
+ stdio: ['ignore', 'pipe', 'ignore'],
7
+ }).trim();
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ function is_git_repo(cwd) {
14
+ return git(['rev-parse', '--is-inside-work-tree'], cwd) === 'true';
15
+ }
16
+ export function get_git_recoverability(cwd, path) {
17
+ if (!is_git_repo(cwd))
18
+ return 'not-git';
19
+ const status = git(['status', '--porcelain=v1', '--', path], cwd);
20
+ if (status === undefined)
21
+ return 'not-git';
22
+ if (status.length > 0) {
23
+ return status.split('\n').some((line) => line.startsWith('??'))
24
+ ? 'untracked'
25
+ : 'tracked-dirty';
26
+ }
27
+ const tracked = git(['ls-files', '--', path], cwd);
28
+ return tracked ? 'tracked-clean' : 'untracked';
29
+ }
30
+ export function is_git_recoverable(cwd, path) {
31
+ return get_git_recoverability(cwd, path) === 'tracked-clean';
32
+ }
33
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/destructive/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,GAAW;IAC9C,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;YAChD,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACnC,CAAC,CAAC,IAAI,EAAE,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,GAAW,EACX,IAAY;IAEZ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAExC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IAClE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9D,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,eAAe,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CACjC,GAAW,EACX,IAAY;IAEZ,OAAO,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,eAAe,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function is_temp_path(path: string): boolean;
2
+ export declare function is_agent_temp_path(path: string): boolean;
3
+ export declare function describe_path_risk(cwd: string, paths: string[]): string;
@@ -0,0 +1,33 @@
1
+ import { tmpdir } from 'node:os';
2
+ import { isAbsolute, relative, resolve } from 'node:path';
3
+ import { get_git_recoverability, is_git_recoverable } from './git.js';
4
+ function is_path_within(parent, child) {
5
+ const rel = relative(parent, child);
6
+ return Boolean(rel) && !rel.startsWith('..') && !isAbsolute(rel);
7
+ }
8
+ export function is_temp_path(path) {
9
+ const temp_root = resolve(tmpdir());
10
+ const absolute = resolve(path);
11
+ return (absolute === temp_root || is_path_within(temp_root, absolute));
12
+ }
13
+ export function is_agent_temp_path(path) {
14
+ if (!is_temp_path(path))
15
+ return false;
16
+ const temp_root = resolve(tmpdir());
17
+ const first_segment = relative(temp_root, resolve(path)).split(/[\\/]+/)[0];
18
+ return /^my-pi-(audit|sandbox|temp|tmp|work|session)-/.test(first_segment);
19
+ }
20
+ export function describe_path_risk(cwd, paths) {
21
+ const risky = paths.filter((path) => !is_git_recoverable(cwd, path));
22
+ if (risky.length === 0)
23
+ return 'Deletes git-recoverable files';
24
+ const risks = new Set(risky.map((path) => get_git_recoverability(cwd, path)));
25
+ if (risks.has('untracked')) {
26
+ return 'Deletes untracked files or directories that git cannot restore';
27
+ }
28
+ if (risks.has('tracked-dirty')) {
29
+ return 'Deletes files with uncommitted changes';
30
+ }
31
+ return 'Deletes files outside git recovery';
32
+ }
33
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/destructive/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEtE,SAAS,cAAc,CAAC,MAAc,EAAE,KAAa;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CACN,QAAQ,KAAK,SAAS,IAAI,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAC7D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAC7D,QAAQ,CACR,CAAC,CAAC,CAAC,CAAC;IACL,OAAO,+CAA+C,CAAC,IAAI,CAC1D,aAAa,CACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CACjC,GAAW,EACX,KAAe;IAEf,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CACzB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CACxC,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,+BAA+B,CAAC;IAE/D,MAAM,KAAK,GAAG,IAAI,GAAG,CACpB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CACtD,CAAC;IACF,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,gEAAgE,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QAChC,OAAO,wCAAwC,CAAC;IACjD,CAAC;IACD,OAAO,oCAAoC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ToolResultEvent } from '@earendil-works/pi-coding-agent';
2
+ export declare function extract_command_paths(command: string, command_name: 'rm' | 'git-rm'): string[] | undefined;
3
+ export declare function extract_bash_create_paths(command: string, cwd: string): string[];
4
+ export declare function command_may_create_temp_path(command: string): boolean;
5
+ export declare function extract_created_temp_paths_from_result(event: ToolResultEvent): string[];
@@ -0,0 +1,97 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { is_temp_path } from './paths.js';
4
+ function parse_shell_words(command) {
5
+ const words = [];
6
+ const pattern = /"((?:\\.|[^"])*)"|'([^']*)'|(\S+)/g;
7
+ let match;
8
+ while ((match = pattern.exec(command))) {
9
+ words.push(match[1] ?? match[2] ?? match[3]);
10
+ }
11
+ return words;
12
+ }
13
+ export function extract_command_paths(command, command_name) {
14
+ if (/[;&|`$()<>]/.test(command))
15
+ return undefined;
16
+ const words = parse_shell_words(command);
17
+ const command_index = command_name === 'rm'
18
+ ? words.findIndex((word) => ['rm', 'rmdir', 'unlink', 'shred'].includes(word))
19
+ : words.findIndex((word, index) => word === 'rm' && words[index - 1] === 'git');
20
+ if (command_index === -1)
21
+ return undefined;
22
+ return words
23
+ .slice(command_index + 1)
24
+ .filter((word) => word !== '--' && !word.startsWith('-'));
25
+ }
26
+ function option_takes_value(command_name, option) {
27
+ const value_options = {
28
+ mkdir: ['-m', '--mode', '-Z', '--context'],
29
+ touch: ['-r', '--reference', '-d', '--date', '-t'],
30
+ };
31
+ return value_options[command_name]?.includes(option) ?? false;
32
+ }
33
+ function extract_simple_create_paths(command, cwd) {
34
+ if (/[;&|`$()<>]/.test(command))
35
+ return [];
36
+ const words = parse_shell_words(command);
37
+ const command_name = words[0];
38
+ if (!['mkdir', 'touch'].includes(command_name))
39
+ return [];
40
+ const paths = [];
41
+ for (let index = 1; index < words.length; index += 1) {
42
+ const word = words[index];
43
+ if (!word || word === '--')
44
+ continue;
45
+ if (word.startsWith('-')) {
46
+ if (option_takes_value(command_name, word))
47
+ index += 1;
48
+ continue;
49
+ }
50
+ const absolute = resolve(cwd, word);
51
+ if (is_temp_path(absolute) && !existsSync(absolute)) {
52
+ paths.push(absolute);
53
+ }
54
+ }
55
+ return paths;
56
+ }
57
+ function extract_redirect_create_paths(command, cwd) {
58
+ const paths = [];
59
+ const pattern = /(?:^|\s)(?:[12]>>|>>|&>|[12]?>)(?:\s*)("[^"]+"|'[^']+'|\S+)/g;
60
+ let match;
61
+ while ((match = pattern.exec(command))) {
62
+ const raw = match[1];
63
+ const path = raw.replace(/^(['"])(.*)\1$/, '$2');
64
+ const absolute = resolve(cwd, path);
65
+ if (is_temp_path(absolute) && !existsSync(absolute)) {
66
+ paths.push(absolute);
67
+ }
68
+ }
69
+ return paths;
70
+ }
71
+ export function extract_bash_create_paths(command, cwd) {
72
+ return [
73
+ ...extract_simple_create_paths(command, cwd),
74
+ ...extract_redirect_create_paths(command, cwd),
75
+ ];
76
+ }
77
+ export function command_may_create_temp_path(command) {
78
+ return /^\s*mktemp\b/.test(command);
79
+ }
80
+ function text_content(event) {
81
+ return event.content
82
+ .map((part) => {
83
+ if ('text' in part && typeof part.text === 'string') {
84
+ return part.text;
85
+ }
86
+ return '';
87
+ })
88
+ .join('');
89
+ }
90
+ export function extract_created_temp_paths_from_result(event) {
91
+ return text_content(event)
92
+ .split(/\r?\n/)
93
+ .map((line) => line.trim())
94
+ .filter((line) => line && is_temp_path(line) && existsSync(line))
95
+ .map((line) => resolve(line));
96
+ }
97
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/destructive/shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface DestructiveAction {
2
+ title: string;
3
+ description: string;
4
+ reason: string;
5
+ allow_key: string;
6
+ }
7
+ export interface DestructiveCommandPattern {
8
+ pattern: RegExp;
9
+ reason: string;
10
+ allow_key: string;
11
+ }
12
+ export type GitRecoverability = 'tracked-clean' | 'tracked-dirty' | 'untracked' | 'not-git';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/destructive/types.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,5 @@
1
- import type { ExtensionAPI, ToolCallEvent } from '@earendil-works/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, session_created_paths?: ReadonlySet<string>): DestructiveAction | undefined;
9
- export declare function assess_tool_call(event: ToolCallEvent, cwd: string, session_created_paths?: ReadonlySet<string>): DestructiveAction | undefined;
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { assess_bash_command, assess_tool_call } from './destructive/assessors.js';
3
+ export type { DestructiveAction } from './destructive/types.js';
4
+ export { assess_bash_command, assess_tool_call };
10
5
  export default function confirm_destructive(pi: ExtensionAPI): Promise<void>;
package/dist/index.js CHANGED
@@ -1,383 +1,9 @@
1
1
  // Confirm destructive tool calls before they run.
2
- import { execFileSync } from 'node:child_process';
3
2
  import { existsSync } from 'node:fs';
4
- import { tmpdir } from 'node:os';
5
- import { isAbsolute, relative, resolve } from 'node:path';
6
- const DESTRUCTIVE_COMMAND_PATTERNS = [
7
- {
8
- 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)/,
9
- reason: 'Runs a potentially destructive Prisma database operation',
10
- allow_key: 'bash:prisma-destructive',
11
- },
12
- {
13
- pattern: /(^|[;&|]\s*)(psql|mysql|mariadb|sqlite3)\b[^;&|]*\b(drop|delete\s+from|truncate|alter\s+table|update\s+\S+\s+set)\b/i,
14
- reason: 'Runs destructive SQL through a database CLI',
15
- allow_key: 'bash:db-cli-destructive-sql',
16
- },
17
- {
18
- pattern: /(^|[;&|]\s*)find\b[^;&|]*(\s-delete\b|-exec\s+(sudo\s+)?rm\b)/,
19
- reason: 'Deletes files found by find',
20
- allow_key: 'bash:find-delete',
21
- },
22
- {
23
- pattern: /(^|[;&|]\s*)git\s+clean\b[^;&|]*-[a-zA-Z]*[fdx][a-zA-Z]*/,
24
- reason: 'Deletes untracked files or directories',
25
- allow_key: 'bash:git-clean',
26
- },
27
- {
28
- pattern: /(^|[;&|]\s*)git\s+(checkout|restore)\b[^;&|]*(\s--\s+\.\s*$|\s\.\s*$)/,
29
- reason: 'Discards working tree changes',
30
- allow_key: 'bash:git-discard-all',
31
- },
32
- {
33
- pattern: /(^|[;&|]\s*)rsync\b[^;&|]*\s--delete\b/,
34
- reason: 'Deletes destination files during sync',
35
- allow_key: 'bash:rsync-delete',
36
- },
37
- {
38
- pattern: /(^|[;&|]\s*)truncate\b[^;&|]*(\s-s\s*0\b|\s--size\s*=?\s*0\b)/,
39
- reason: 'Empties file contents',
40
- allow_key: 'bash:truncate-zero',
41
- },
42
- {
43
- pattern: /(^|[;&|]\s*)dd\b[^;&|]*\bof=/,
44
- reason: 'Overwrites a device or file with dd',
45
- allow_key: 'bash:dd-output',
46
- },
47
- {
48
- pattern: /(^|[;&|]\s*)(mkfs|fdisk|parted|wipefs)\b/,
49
- reason: 'Modifies disks or filesystems',
50
- allow_key: 'bash:disk-tool',
51
- },
52
- ];
53
- const DESTRUCTIVE_CUSTOM_TOOL_NAME = /(^|[_-])(delete|destroy|drop|remove|archive|execute_write_query|execute_schema_query|bulk_insert)([_-]|$)/i;
54
- function preview(value, max = 500) {
55
- const normalized = value.trim().replace(/\s+/g, ' ');
56
- return normalized.length > max
57
- ? `${normalized.slice(0, max - 1)}…`
58
- : normalized;
59
- }
60
- function git(args, cwd) {
61
- try {
62
- return execFileSync('git', ['-C', cwd, ...args], {
63
- encoding: 'utf-8',
64
- stdio: ['ignore', 'pipe', 'ignore'],
65
- }).trim();
66
- }
67
- catch {
68
- return undefined;
69
- }
70
- }
71
- function is_git_repo(cwd) {
72
- return git(['rev-parse', '--is-inside-work-tree'], cwd) === 'true';
73
- }
74
- function get_git_recoverability(cwd, path) {
75
- if (!is_git_repo(cwd))
76
- return 'not-git';
77
- const status = git(['status', '--porcelain=v1', '--', path], cwd);
78
- if (status === undefined)
79
- return 'not-git';
80
- if (status.length > 0) {
81
- return status.split('\n').some((line) => line.startsWith('??'))
82
- ? 'untracked'
83
- : 'tracked-dirty';
84
- }
85
- const tracked = git(['ls-files', '--', path], cwd);
86
- return tracked ? 'tracked-clean' : 'untracked';
87
- }
88
- function is_git_recoverable(cwd, path) {
89
- return get_git_recoverability(cwd, path) === 'tracked-clean';
90
- }
91
- function is_path_within(parent, child) {
92
- const rel = relative(parent, child);
93
- return Boolean(rel) && !rel.startsWith('..') && !isAbsolute(rel);
94
- }
95
- function is_temp_path(path) {
96
- const temp_root = resolve(tmpdir());
97
- const absolute = resolve(path);
98
- return (absolute === temp_root || is_path_within(temp_root, absolute));
99
- }
100
- function is_agent_temp_path(path) {
101
- if (!is_temp_path(path))
102
- return false;
103
- const temp_root = resolve(tmpdir());
104
- const first_segment = relative(temp_root, resolve(path)).split(/[\\/]+/)[0];
105
- return /^my-pi-(audit|sandbox|temp|tmp|work|session)-/.test(first_segment);
106
- }
107
- function parse_shell_words(command) {
108
- const words = [];
109
- const pattern = /"((?:\\.|[^"])*)"|'([^']*)'|(\S+)/g;
110
- let match;
111
- while ((match = pattern.exec(command))) {
112
- words.push(match[1] ?? match[2] ?? match[3]);
113
- }
114
- return words;
115
- }
116
- function extract_command_paths(command, command_name) {
117
- if (/[;&|`$()<>]/.test(command))
118
- return undefined;
119
- const words = parse_shell_words(command);
120
- const command_index = command_name === 'rm'
121
- ? words.findIndex((word) => ['rm', 'rmdir', 'unlink', 'shred'].includes(word))
122
- : words.findIndex((word, index) => word === 'rm' && words[index - 1] === 'git');
123
- if (command_index === -1)
124
- return undefined;
125
- return words
126
- .slice(command_index + 1)
127
- .filter((word) => word !== '--' && !word.startsWith('-'));
128
- }
129
- function option_takes_value(command_name, option) {
130
- const value_options = {
131
- mkdir: ['-m', '--mode', '-Z', '--context'],
132
- touch: ['-r', '--reference', '-d', '--date', '-t'],
133
- };
134
- return value_options[command_name]?.includes(option) ?? false;
135
- }
136
- function extract_simple_create_paths(command, cwd) {
137
- if (/[;&|`$()<>]/.test(command))
138
- return [];
139
- const words = parse_shell_words(command);
140
- const command_name = words[0];
141
- if (!['mkdir', 'touch'].includes(command_name))
142
- return [];
143
- const paths = [];
144
- for (let index = 1; index < words.length; index += 1) {
145
- const word = words[index];
146
- if (!word || word === '--')
147
- continue;
148
- if (word.startsWith('-')) {
149
- if (option_takes_value(command_name, word))
150
- index += 1;
151
- continue;
152
- }
153
- const absolute = resolve(cwd, word);
154
- if (is_temp_path(absolute) && !existsSync(absolute)) {
155
- paths.push(absolute);
156
- }
157
- }
158
- return paths;
159
- }
160
- function extract_redirect_create_paths(command, cwd) {
161
- const paths = [];
162
- const pattern = /(?:^|\s)(?:[12]>>|>>|&>|[12]?>)(?:\s*)("[^"]+"|'[^']+'|\S+)/g;
163
- let match;
164
- while ((match = pattern.exec(command))) {
165
- const raw = match[1];
166
- const path = raw.replace(/^(['"])(.*)\1$/, '$2');
167
- const absolute = resolve(cwd, path);
168
- if (is_temp_path(absolute) && !existsSync(absolute)) {
169
- paths.push(absolute);
170
- }
171
- }
172
- return paths;
173
- }
174
- function extract_bash_create_paths(command, cwd) {
175
- return [
176
- ...extract_simple_create_paths(command, cwd),
177
- ...extract_redirect_create_paths(command, cwd),
178
- ];
179
- }
180
- function command_may_create_temp_path(command) {
181
- return /^\s*mktemp\b/.test(command);
182
- }
183
- function text_content(event) {
184
- return event.content
185
- .map((part) => {
186
- if ('text' in part && typeof part.text === 'string') {
187
- return part.text;
188
- }
189
- return '';
190
- })
191
- .join('');
192
- }
193
- function extract_created_temp_paths_from_result(event) {
194
- return text_content(event)
195
- .split(/\r?\n/)
196
- .map((line) => line.trim())
197
- .filter((line) => line && is_temp_path(line) && existsSync(line))
198
- .map((line) => resolve(line));
199
- }
200
- function describe_path_risk(cwd, paths) {
201
- const risky = paths.filter((path) => !is_git_recoverable(cwd, path));
202
- if (risky.length === 0)
203
- return 'Deletes git-recoverable files';
204
- const risks = new Set(risky.map((path) => get_git_recoverability(cwd, path)));
205
- if (risks.has('untracked')) {
206
- return 'Deletes untracked files or directories that git cannot restore';
207
- }
208
- if (risks.has('tracked-dirty')) {
209
- return 'Deletes files with uncommitted changes';
210
- }
211
- return 'Deletes files outside git recovery';
212
- }
213
- function assess_rm_command(command, cwd, session_created_paths = new Set()) {
214
- if (!/(^|[;&|]\s*)(sudo\s+)?(rm|rmdir|unlink|shred)\b/.test(command)) {
215
- return undefined;
216
- }
217
- const paths = extract_command_paths(command, 'rm');
218
- if (paths && paths.length > 0) {
219
- if (paths.every((path) => {
220
- const absolute = resolve(cwd, path);
221
- return (session_created_paths.has(absolute) ||
222
- is_agent_temp_path(absolute));
223
- })) {
224
- return undefined;
225
- }
226
- if (paths.every((path) => is_git_recoverable(cwd, path))) {
227
- return undefined;
228
- }
229
- }
230
- const reason = paths?.length
231
- ? describe_path_risk(cwd, paths)
232
- : 'Deletes files or directories';
233
- return {
234
- title: 'Confirm destructive command?',
235
- description: `${reason}: ${preview(command)}`,
236
- reason,
237
- allow_key: 'bash:rm-risky',
238
- };
239
- }
240
- function assess_git_rm_command(command, cwd) {
241
- if (!/(^|[;&|]\s*)git\s+rm\b/.test(command))
242
- return undefined;
243
- if (/\s-f\b|\s--force\b/.test(command)) {
244
- return {
245
- title: 'Confirm forced git removal?',
246
- description: `Forced git removal can discard uncommitted file changes: ${preview(command)}`,
247
- reason: 'Force-removes files from git',
248
- allow_key: 'bash:git-rm-force',
249
- };
250
- }
251
- const paths = extract_command_paths(command, 'git-rm');
252
- if (paths &&
253
- paths.length > 0 &&
254
- paths.every((path) => is_git_recoverable(cwd, path))) {
255
- return undefined;
256
- }
257
- const reason = paths?.length
258
- ? describe_path_risk(cwd, paths)
259
- : 'Deletes tracked files from git';
260
- return {
261
- title: 'Confirm git removal?',
262
- description: `${reason}: ${preview(command)}`,
263
- reason,
264
- allow_key: 'bash:git-rm-risky',
265
- };
266
- }
267
- function assess_git_reset_hard(command, cwd) {
268
- if (!/(^|[;&|]\s*)git\s+reset\b[^;&|]*--hard\b/.test(command)) {
269
- return undefined;
270
- }
271
- if (git(['status', '--porcelain=v1'], cwd) === '')
272
- return undefined;
273
- return {
274
- title: 'Confirm hard reset?',
275
- description: `This can discard uncommitted tracked changes: ${preview(command)}`,
276
- reason: 'Discards uncommitted tracked changes',
277
- allow_key: 'bash:git-reset-hard',
278
- };
279
- }
280
- export function assess_bash_command(command, cwd = process.cwd(), session_created_paths = new Set()) {
281
- const normalized = command.trim();
282
- if (!normalized)
283
- return undefined;
284
- const specific = assess_rm_command(normalized, cwd, session_created_paths) ??
285
- assess_git_rm_command(normalized, cwd) ??
286
- assess_git_reset_hard(normalized, cwd);
287
- if (specific)
288
- return specific;
289
- const match = DESTRUCTIVE_COMMAND_PATTERNS.find(({ pattern }) => pattern.test(normalized));
290
- if (!match)
291
- return undefined;
292
- return {
293
- title: 'Confirm destructive command?',
294
- description: `${match.reason}: ${preview(normalized)}`,
295
- reason: match.reason,
296
- allow_key: match.allow_key,
297
- };
298
- }
299
- function assess_file_write(cwd, path, session_created_paths = new Set()) {
300
- if (typeof path !== 'string' || !path.trim())
301
- return undefined;
302
- const absolute = resolve(cwd, path);
303
- if (!existsSync(absolute))
304
- return undefined;
305
- if (session_created_paths.has(absolute))
306
- return undefined;
307
- if (is_git_recoverable(cwd, path))
308
- return undefined;
309
- const reason = get_git_recoverability(cwd, path) === 'tracked-dirty'
310
- ? 'Overwrites a file with uncommitted changes'
311
- : 'Overwrites an untracked file git cannot restore';
312
- return {
313
- title: 'Confirm file overwrite?',
314
- description: `${reason}: ${path}`,
315
- reason,
316
- allow_key: 'write:risky-overwrite',
317
- };
318
- }
319
- function assess_file_edit(cwd, input, session_created_paths = new Set()) {
320
- const path = typeof input.path === 'string' ? input.path : undefined;
321
- const edits = Array.isArray(input.edits) ? input.edits : [];
322
- let removed_chars = 0;
323
- let added_chars = 0;
324
- for (const edit of edits) {
325
- if (!edit || typeof edit !== 'object')
326
- continue;
327
- const old_text = edit.oldText;
328
- const new_text = edit.newText;
329
- if (typeof old_text === 'string')
330
- removed_chars += old_text.length;
331
- if (typeof new_text === 'string')
332
- added_chars += new_text.length;
333
- }
334
- if (removed_chars === 0 || removed_chars - added_chars < 200) {
335
- return undefined;
336
- }
337
- if (path && session_created_paths.has(resolve(cwd, path))) {
338
- return undefined;
339
- }
340
- if (path && is_git_recoverable(cwd, path))
341
- return undefined;
342
- return {
343
- title: 'Confirm large content removal?',
344
- description: `This edit removes ${removed_chars - added_chars} more characters than it adds${path ? ` in ${path}` : ''}.`,
345
- reason: path
346
- ? 'Removes substantial content from a file git cannot fully restore'
347
- : 'Removes substantial file content',
348
- allow_key: 'edit:large-removal-risky',
349
- };
350
- }
351
- function assess_custom_tool(event) {
352
- if (!DESTRUCTIVE_CUSTOM_TOOL_NAME.test(event.toolName)) {
353
- return undefined;
354
- }
355
- const input = event.input;
356
- const query = typeof input.query === 'string'
357
- ? `\n\nQuery: ${preview(input.query)}`
358
- : '';
359
- return {
360
- title: 'Confirm destructive tool call?',
361
- description: `Tool ${event.toolName} appears destructive.${query}`,
362
- reason: `Potentially destructive tool: ${event.toolName}`,
363
- allow_key: `tool:${event.toolName}`,
364
- };
365
- }
366
- export function assess_tool_call(event, cwd, session_created_paths = new Set()) {
367
- if (event.toolName === 'bash') {
368
- const command = event.input.command;
369
- return typeof command === 'string'
370
- ? assess_bash_command(command, cwd, session_created_paths)
371
- : undefined;
372
- }
373
- if (event.toolName === 'write') {
374
- return assess_file_write(cwd, event.input.path, session_created_paths);
375
- }
376
- if (event.toolName === 'edit') {
377
- return assess_file_edit(cwd, event.input, session_created_paths);
378
- }
379
- return assess_custom_tool(event);
380
- }
3
+ import { resolve } from 'node:path';
4
+ import { assess_bash_command, assess_tool_call, } from './destructive/assessors.js';
5
+ import { command_may_create_temp_path, extract_bash_create_paths, extract_created_temp_paths_from_result, } from './destructive/shell.js';
6
+ export { assess_bash_command, assess_tool_call };
381
7
  async function confirm_action(action, ctx) {
382
8
  if (!ctx.hasUI)
383
9
  return 'block';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spences10/pi-confirm-destructive",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Git-aware Pi guardrail that asks for confirmation before destructive shell actions can change or lose work",
5
5
  "keywords": [
6
6
  "confirm",
@@ -29,10 +29,10 @@
29
29
  "access": "public"
30
30
  },
31
31
  "devDependencies": {
32
- "@earendil-works/pi-coding-agent": "^0.74.1",
32
+ "@earendil-works/pi-coding-agent": "0.75.4",
33
33
  "@types/node": "^25.8.0",
34
34
  "typescript": "^6.0.3",
35
- "vitest": "4.1.5"
35
+ "vitest": "4.1.6"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@earendil-works/pi-coding-agent": "*"