@itc-steve/pi-ask-complete 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ First public release.
6
+
7
+ - Bottom-panel `ask_user` (multi-question, transcript stays visible)
8
+ - Permission gate for `bash` / `write` / `edit` with path wildcards
9
+ - `permission.json` rules (bash / tools / paths); seeds from example when missing
10
+ - Session / permanent allow; deny with reason
11
+ - Chain / substitution unit checks; path-deny on bash args; sudo → `sudo_run` redirect
12
+ - `/yolo` session mode: auto-approve every gate **ask** (including globs); **deny** and sudo redirect still enforced; `ask_user` untouched
13
+ - `/permissions` lists allows/denies and YOLO state
14
+ - Herdr attention: ding only when the pane is backgrounded
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 InfoTrust Corporation
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,147 @@
1
+ # pi-ask-complete
2
+
3
+ Bottom-panel **ask_user** + **permission gate** (bash / write / edit + path wildcards) for the [Pi coding agent](https://pi.dev).
4
+
5
+ ## Gate
6
+
7
+ | Tool | Behavior |
8
+ | --- | --- |
9
+ | `bash` | Every unit (segments, `$(...)`, backticks) is **checked**; path deny args block. **One prompt per tool call** (not per unit). Session/permanent allow applies to each unique base that needed approval |
10
+ | `write` / `edit` | Path rules first, then tool rule, else ask |
11
+ | `read` | Allowed by default; only auto-**deny** on matching path deny rules — never prompts for normal reads |
12
+
13
+ ### Default bash allows
14
+
15
+ Seeded `permission.json` allows non-destructive **explore / troubleshoot** commands
16
+ out of the box (listing, read/print text, search, process/system info, network
17
+ diagnostics, checksums, git read-only subcommands). `find`/`awk`/`curl`/`fd` etc are
18
+ **ask** (not allow) — they are general exec engines.
19
+ Path **deny** rules still block secret files even when the binary is allowed
20
+ (`cat .env` → deny).
21
+
22
+ Still **ask** (not pre-allowed): writers and mutators — `rm`, `mv`, `cp`, `mkdir`,
23
+ `touch`, `sed`, `tee`, `chmod`, package managers, `git push` / `commit` / `reset`,
24
+ shells (`bash`/`python`/`node`), etc. Catastrophic commands stay **deny**:
25
+ `mkfs`, `dd`, `shutdown`, `reboot`, `poweroff`, `halt`.
26
+
27
+ Panel options: **Allow this** · **Allow for this session** · **Allow permanently** · **Deny with reason**
28
+
29
+ - **Session** — in-memory until the agent session ends (not written to disk).
30
+ For a bash pipeline, remembers **every** real base that still needed approval.
31
+ - **Permanent** — live immediately + written to `permission.json`
32
+ - bash → **primary base only** (`herdr … | python3 … | sed …` → only `herdr`)
33
+ - write/edit → **exact file path** in `paths`
34
+
35
+ ## Path wildcards
36
+
37
+ ```
38
+ * any chars except /
39
+ ** any chars including /
40
+ ? one char except /
41
+ ```
42
+
43
+ **Most-specific pattern wins.** The pattern that pins more of the filename tail
44
+ takes precedence regardless of allow/deny, so `**/.env` **deny** beats a broad
45
+ `Projects/**` **allow** for `Projects/app/.env`. Exact-specificity ties → deny wins.
46
+
47
+ Bash commands are decomposed for **policy**: chains (`;` `|` `&&`) and substitutions
48
+ each become a unit that must independently pass. Path-like args are checked against
49
+ path deny rules — so `ls; rm -rf x` and `cat .env` no longer slip through an allowed
50
+ prefix. The user still sees **one** prompt for the whole line; choosing session or
51
+ permanent allow covers every base that still needed approval.
52
+ (Heuristic, not a full shell parser — `$VAR` expansion isn't resolved.)
53
+
54
+ | Path | With example config |
55
+ | --- | --- |
56
+ | `.env` | deny |
57
+ | `prod.env` | deny |
58
+ | `.env.example` | **allow** |
59
+ | `.ssh/id_rsa` | deny |
60
+ | `src/main.ts` | ask (no rule) |
61
+
62
+ ## permission.json
63
+
64
+ All policy is in JSON — **nothing is hard-blocked in code**.
65
+
66
+ `~/.pi/agent/permission.json` (or `$PI_CODING_AGENT_DIR/permission.json`).
67
+
68
+ If the file is **missing** (deleted or never created), load seeds it from
69
+ `permission.json.example` and re-creates the file on disk so you can edit it.
70
+ If the file is **present**, it is obeyed verbatim — even a single rule or an
71
+ empty `{}`. Existing files are never merged with, unioned against, or
72
+ overwritten by the example defaults.
73
+
74
+ `sudo_run` (from pix-sudo) is **not** gated here — its PAM password prompt is the
75
+ approve/deny step. Raw `sudo`/`doas` in bash is redirected to `sudo_run`.
76
+
77
+ ```json
78
+ {
79
+ "bash": {
80
+ "ls": "allow",
81
+ "cat": "allow",
82
+ "rg": "allow",
83
+ "git status*": "allow",
84
+ "dd": "deny"
85
+ },
86
+ "tools": {
87
+ "read": "allow",
88
+ "write": "ask"
89
+ },
90
+ "paths": {
91
+ "**/.env.example": "allow",
92
+ "**/*.env": "deny",
93
+ "/home/you/Projects/**": "allow"
94
+ }
95
+ }
96
+ ```
97
+
98
+ Full starter list: `permission.json.example`.
99
+
100
+ ## Install
101
+
102
+ ```bash
103
+ pi install npm:@itc-steve/pi-ask-complete
104
+ ```
105
+
106
+ Or from a local checkout:
107
+
108
+ ```bash
109
+ pi install /path/to/pi-ask-complete
110
+ # packages entry: "npm:@itc-steve/pi-ask-complete"
111
+ # or: "../../Projects/pi-ask-complete"
112
+ ```
113
+
114
+ `/reload` after changes. `/permissions` shows current allows.
115
+
116
+ ## `/yolo`
117
+
118
+ Session-scoped mode that auto-approves everything that would otherwise **ask**
119
+ (bash / write / edit / unresolved globs — the permission panel stays quiet).
120
+
121
+ - **Does:** skip the permission panel for every gate `ask` (including globs/`$VAR`).
122
+ - **Does not bypass:** path/bash/tool **deny** rules, or the `sudo`/`doas` → `sudo_run` redirect.
123
+ - **Does not touch:** `ask_user` (model questions still prompt you).
124
+ - **Dies with the session** — memory only; nothing written to `permission.json`. Cleared on `session_start`.
125
+
126
+ `/yolo` toggles · `/yolo on` · `/yolo off`. When on, `/permissions` shows the YOLO line.
127
+
128
+ ## ask_user
129
+
130
+ LLM-callable multi-question bottom panel (`overlay: false` — transcript stays visible). Prefer this over plain-text multi-choice.
131
+
132
+ ## Threat model / limits
133
+
134
+ This is a **heuristic agent gate**, not a sandbox or seccomp profile. The model is still the adversary; the gate reduces accidents and casual exfil, it does not stop a determined local process.
135
+
136
+ | Covered | Not a full guarantee |
137
+ | --- | --- |
138
+ | Chain / pipe / `&&` units each checked | Full shell AST / exotic quoting |
139
+ | `$(…)`, backticks, process subs as units | Nested quote mazes |
140
+ | Path deny on args, redirects, `if=`, `@file`, git `rev:path` | Paths only after real `$VAR` expansion |
141
+ | Glued operators (`cat .env;true`) cleaned | Every future shell metacharacter |
142
+ | Unresolved globs / braces / `$''` → **ask** | Interpreter `-c` payloads (permanent-allow `python3`/`bash` is high blast radius) |
143
+ | Any unit starting with `sudo`/`doas` → redirect | Root via other helpers |
144
+ | Corrupt / non-object `permission.json` keeps last good rules | First load of a corrupt file (everything asks) |
145
+ | Missing `permission.json` re-seeds from example (fail closed) | Broken install with no example (path deny-all via noPolicy) |
146
+
147
+ **Allow permanently** stores a **binary base** (e.g. all `cat`) or an **exact file path** for write/edit. Prefer session allow for interpreters.
package/index.ts ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * pi-ask-complete
3
+ *
4
+ * Bottom-panel ask_user (transcript stays visible) + bash permission gate
5
+ * that reuses the same panel for Allow / Allow permanently / Deny with reason.
6
+ */
7
+
8
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
9
+ import { registerAskUser } from "./src/ask-user.ts";
10
+ import { bindHerdrAttention } from "./src/herdr-attention.ts";
11
+ import { registerPermission } from "./src/permission.ts";
12
+ import { PermissionStore } from "./src/permission-store.ts";
13
+
14
+ export default function piCompleteAsk(pi: ExtensionAPI) {
15
+ const store = new PermissionStore();
16
+
17
+ // Herdr dings only when this pane is backgrounded (see herdr-attention.ts).
18
+ bindHerdrAttention(pi.events);
19
+ registerAskUser(pi);
20
+ registerPermission(pi, store);
21
+
22
+ // Nudge the model to use ask_user / sudo_run correctly.
23
+ pi.on("before_agent_start", async (event) => {
24
+ const tip =
25
+ "\n\n# User interaction tools\n" +
26
+ "- Use `ask_user` whenever you need the user to choose between options, confirm a decision, or answer a clarifying question. Do not present multi-choice questions as plain text when `ask_user` is available.\n" +
27
+ "- System shell commands are gated automatically; you do not need to call `ask_permission` for normal bash — the user will be prompted.\n" +
28
+ "- Never run `sudo`/`doas` via bash. Use `sudo_run` with the command (no sudo prefix) and a short reason; the user will approve and enter their password.\n";
29
+
30
+ return {
31
+ systemPrompt: (event.systemPrompt ?? "") + tip,
32
+ };
33
+ });
34
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@itc-steve/pi-ask-complete",
3
+ "version": "0.1.0",
4
+ "description": "Pi extension: bottom-panel ask_user + bash permission gate (Allow / Allow permanently / Deny with reason) writing ~/.pi/agent/permission.json",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi",
8
+ "pi-extension",
9
+ "pi-coding-agent",
10
+ "ask-user",
11
+ "permissions",
12
+ "yolo"
13
+ ],
14
+ "author": {
15
+ "name": "itc-steve",
16
+ "url": "https://github.com/itc-steve"
17
+ },
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/itc-steve/pi-ask-complete.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/itc-steve/pi-ask-complete/issues"
25
+ },
26
+ "homepage": "https://github.com/itc-steve/pi-ask-complete#readme",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "type": "module",
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "main": "./index.ts",
35
+ "files": [
36
+ "index.ts",
37
+ "src",
38
+ "permission.json.example",
39
+ "README.md",
40
+ "CHANGELOG.md",
41
+ "LICENSE"
42
+ ],
43
+ "scripts": {
44
+ "test": "node --experimental-strip-types --test test/*.test.ts",
45
+ "prepublishOnly": "npm test"
46
+ },
47
+ "pi": {
48
+ "extensions": ["./index.ts"]
49
+ },
50
+ "peerDependencies": {
51
+ "@earendil-works/pi-ai": "*",
52
+ "@earendil-works/pi-coding-agent": "*",
53
+ "@earendil-works/pi-tui": "*",
54
+ "typebox": "*"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "@earendil-works/pi-ai": { "optional": true },
58
+ "@earendil-works/pi-coding-agent": { "optional": true },
59
+ "@earendil-works/pi-tui": { "optional": true },
60
+ "typebox": { "optional": true }
61
+ }
62
+ }
@@ -0,0 +1,299 @@
1
+ {
2
+ "bash": {
3
+ "ls": "allow",
4
+ "dir": "allow",
5
+ "vdir": "allow",
6
+ "tree": "allow",
7
+ "eza": "allow",
8
+ "exa": "allow",
9
+ "lsd": "allow",
10
+ "pwd": "allow",
11
+ "cd": "allow",
12
+ "pushd": "allow",
13
+ "popd": "allow",
14
+ "dirs": "allow",
15
+ "locate": "allow",
16
+ "which": "allow",
17
+ "type": "allow",
18
+ "whereis": "allow",
19
+ "file": "allow",
20
+ "stat": "allow",
21
+ "namei": "allow",
22
+ "readlink": "allow",
23
+ "realpath": "allow",
24
+ "basename": "allow",
25
+ "dirname": "allow",
26
+ "pathchk": "allow",
27
+ "du": "allow",
28
+ "df": "allow",
29
+ "dust": "allow",
30
+ "duf": "allow",
31
+ "free": "allow",
32
+ "lsblk": "allow",
33
+ "blkid": "allow",
34
+ "lsattr": "allow",
35
+ "getfacl": "allow",
36
+ "findmnt": "allow",
37
+ "lscpu": "allow",
38
+ "lsmem": "allow",
39
+ "lsipc": "allow",
40
+ "lslogins": "allow",
41
+ "lspci": "allow",
42
+ "lsusb": "allow",
43
+ "lshw": "allow",
44
+ "ps": "allow",
45
+ "procs": "allow",
46
+ "pgrep": "allow",
47
+ "pidof": "allow",
48
+ "top": "allow",
49
+ "htop": "allow",
50
+ "btop": "allow",
51
+ "pstree": "allow",
52
+ "lsof": "allow",
53
+ "fuser": "allow",
54
+ "uname": "allow",
55
+ "hostname": "allow",
56
+ "arch": "allow",
57
+ "nproc": "allow",
58
+ "id": "allow",
59
+ "whoami": "allow",
60
+ "groups": "allow",
61
+ "who": "allow",
62
+ "w": "allow",
63
+ "last": "allow",
64
+ "lastlog": "allow",
65
+ "uptime": "allow",
66
+ "date": "allow",
67
+ "cal": "allow",
68
+ "vmstat": "allow",
69
+ "iostat": "allow",
70
+ "mpstat": "allow",
71
+ "sar": "allow",
72
+ "dmesg": "allow",
73
+ "journalctl": "allow",
74
+ "getconf": "allow",
75
+ "getent": "allow",
76
+ "locale": "allow",
77
+ "ss": "allow",
78
+ "netstat": "allow",
79
+ "ping": "allow",
80
+ "ping6": "allow",
81
+ "traceroute": "allow",
82
+ "traceroute6": "allow",
83
+ "tracepath": "allow",
84
+ "mtr": "allow",
85
+ "dig": "allow",
86
+ "nslookup": "allow",
87
+ "host": "allow",
88
+ "ip": "allow",
89
+ "cat": "allow",
90
+ "tac": "allow",
91
+ "head": "allow",
92
+ "tail": "allow",
93
+ "less": "allow",
94
+ "more": "allow",
95
+ "bat": "allow",
96
+ "batcat": "allow",
97
+ "wc": "allow",
98
+ "nl": "allow",
99
+ "od": "allow",
100
+ "hexdump": "allow",
101
+ "xxd": "allow",
102
+ "strings": "allow",
103
+ "grep": "allow",
104
+ "egrep": "allow",
105
+ "fgrep": "allow",
106
+ "rg": "allow",
107
+ "ag": "allow",
108
+ "ack": "allow",
109
+ "cut": "allow",
110
+ "sort": "allow",
111
+ "uniq": "allow",
112
+ "tr": "allow",
113
+ "column": "allow",
114
+ "paste": "allow",
115
+ "join": "allow",
116
+ "comm": "allow",
117
+ "diff": "allow",
118
+ "diff3": "allow",
119
+ "sdiff": "allow",
120
+ "cmp": "allow",
121
+ "colordiff": "allow",
122
+ "jq": "allow",
123
+ "yq": "allow",
124
+ "fold": "allow",
125
+ "fmt": "allow",
126
+ "expand": "allow",
127
+ "unexpand": "allow",
128
+ "rev": "allow",
129
+ "tput": "allow",
130
+ "printf": "allow",
131
+ "echo": "allow",
132
+ "true": "allow",
133
+ "false": "allow",
134
+ "test": "allow",
135
+ "expr": "allow",
136
+ "seq": "allow",
137
+ "md5sum": "allow",
138
+ "sha1sum": "allow",
139
+ "sha224sum": "allow",
140
+ "sha256sum": "allow",
141
+ "sha384sum": "allow",
142
+ "sha512sum": "allow",
143
+ "cksum": "allow",
144
+ "sum": "allow",
145
+ "b2sum": "allow",
146
+ "crc32": "allow",
147
+ "zcat": "allow",
148
+ "zless": "allow",
149
+ "zgrep": "allow",
150
+ "bzcat": "allow",
151
+ "bzgrep": "allow",
152
+ "xzcat": "allow",
153
+ "xzgrep": "allow",
154
+ "lzcat": "allow",
155
+ "zstdcat": "allow",
156
+ "zstdless": "allow",
157
+ "tar -t*": "allow",
158
+ "tar --list*": "allow",
159
+ "unzip -l*": "allow",
160
+ "gzip -l*": "allow",
161
+ "env": "allow",
162
+ "printenv": "allow",
163
+ "export": "allow",
164
+ "set": "allow",
165
+ "declare": "allow",
166
+ "alias": "allow",
167
+ "history": "allow",
168
+ "help": "allow",
169
+ "man": "allow",
170
+ "info": "allow",
171
+ "whatis": "allow",
172
+ "apropos": "allow",
173
+ "compgen": "allow",
174
+ "strace": "allow",
175
+ "ltrace": "allow",
176
+ "nm": "allow",
177
+ "objdump": "allow",
178
+ "readelf": "allow",
179
+ "ldd": "allow",
180
+ "git status*": "allow",
181
+ "git log*": "allow",
182
+ "git diff*": "allow",
183
+ "git show*": "allow",
184
+ "git rev-parse*": "allow",
185
+ "git rev-list*": "allow",
186
+ "git ls-files*": "allow",
187
+ "git ls-tree*": "allow",
188
+ "git ls-remote*": "allow",
189
+ "git blame*": "allow",
190
+ "git describe*": "allow",
191
+ "git remote -v": "allow",
192
+ "git remote show*": "allow",
193
+ "git branch": "allow",
194
+ "git branch -a": "allow",
195
+ "git branch -v*": "allow",
196
+ "git branch --show-current": "allow",
197
+ "git stash list*": "allow",
198
+ "git config --get*": "allow",
199
+ "git config --list*": "allow",
200
+ "git config -l*": "allow",
201
+ "git tag": "allow",
202
+ "git tag -l*": "allow",
203
+ "git shortlog*": "allow",
204
+ "git reflog*": "allow",
205
+ "git cat-file*": "allow",
206
+ "git name-rev*": "allow",
207
+ "git symbolic-ref*": "allow",
208
+ "git check-ignore*": "allow",
209
+ "mkfs": "deny",
210
+ "mkfs.fat": "deny",
211
+ "mkfs.vfat": "deny",
212
+ "mkfs.exfat": "deny",
213
+ "mkfs.ext2": "deny",
214
+ "mkfs.ext3": "deny",
215
+ "mkfs.ext4": "deny",
216
+ "mkfs.xfs": "deny",
217
+ "mkfs.btrfs": "deny",
218
+ "mkfs.ntfs": "deny",
219
+ "mkfs.f2fs": "deny",
220
+ "mkfs.minix": "deny",
221
+ "dd": "deny",
222
+ "shutdown": "deny",
223
+ "reboot": "deny",
224
+ "poweroff": "deny",
225
+ "halt": "deny",
226
+ "fdisk": "deny",
227
+ "parted": "deny",
228
+ "sgdisk": "deny",
229
+ "wipefs": "deny",
230
+ "shred": "deny",
231
+ "mkswap": "deny",
232
+ "blkdiscard": "deny"
233
+ },
234
+ "tools": {
235
+ "read": "allow",
236
+ "write": "ask",
237
+ "edit": "ask"
238
+ },
239
+ "paths": {
240
+ "**/.env.example": "allow",
241
+ "**/*.env.example": "allow",
242
+ "**/.env.sample": "allow",
243
+ "**/.env.template": "allow",
244
+ "**/.env.sample.*": "allow",
245
+ "**/env.example": "allow",
246
+ "**/id_rsa.pub": "allow",
247
+ "**/id_ed25519.pub": "allow",
248
+ "**/id_ecdsa.pub": "allow",
249
+ "**/id_dsa.pub": "allow",
250
+ "**/.env": "deny",
251
+ "**/*.env": "deny",
252
+ "**/.env.local": "deny",
253
+ "**/.env.development": "deny",
254
+ "**/.env.production": "deny",
255
+ "**/.env.staging": "deny",
256
+ "**/.env.test": "deny",
257
+ "**/.env.rc": "deny",
258
+ "**/.env.*.local": "deny",
259
+ "**/*.pem": "deny",
260
+ "**/*.key": "deny",
261
+ "**/*.p12": "deny",
262
+ "**/*.pfx": "deny",
263
+ "**/*.jks": "deny",
264
+ "**/id_rsa": "deny",
265
+ "**/id_ed25519": "deny",
266
+ "**/id_ecdsa": "deny",
267
+ "**/id_dsa": "deny",
268
+ "**/.ssh/**": "deny",
269
+ "**/.aws/**": "deny",
270
+ "**/.gnupg/**": "deny",
271
+ "**/.netrc": "deny",
272
+ "**/.npmrc": "deny",
273
+ "**/.pypirc": "deny",
274
+ "**/credentials.json": "deny",
275
+ "**/credentials.yml": "deny",
276
+ "**/credentials.yaml": "deny",
277
+ "**/service-account*.json": "deny",
278
+ "**/secrets.json": "deny",
279
+ "**/secrets.yml": "deny",
280
+ "**/secrets.yaml": "deny",
281
+ "**/*-credentials.json": "deny",
282
+ "/etc/shadow": "deny",
283
+ "/etc/gshadow": "deny",
284
+ "/etc/sudoers": "deny",
285
+ "/etc/sudoers.d/**": "deny",
286
+ "/etc/ssh/ssh_host_*_key": "deny",
287
+ "**/.docker/config.json": "deny",
288
+ "**/kubeconfig": "deny",
289
+ "**/.kube/config": "deny",
290
+ "**/*.tfstate": "deny",
291
+ "**/.git-credentials": "deny",
292
+ "**/.config/gh/hosts.yml": "deny",
293
+ "**/.bash_history": "deny",
294
+ "**/.zsh_history": "deny",
295
+ "**/.mysql_history": "deny",
296
+ "**/.psql_history": "deny",
297
+ "**/.python_history": "deny"
298
+ }
299
+ }