@seanmozeik/tripwire 0.6.7 → 0.7.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 +154 -141
- package/dist/index.js +35 -0
- package/dist/tripwire-cli.js +2 -10
- package/dist/tripwire-hook.js +3 -0
- package/dist/tripwire-pi.js +4 -0
- package/dist/tripwire.js +135 -90
- package/dist/types/dispatch.d.ts +18 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/lib/bash.d.ts +27 -0
- package/dist/types/lib/config.d.ts +110 -0
- package/dist/types/lib/cursor.d.ts +16 -0
- package/dist/types/lib/decision.d.ts +13 -0
- package/dist/types/lib/diff.d.ts +3 -0
- package/dist/types/lib/event.d.ts +45 -0
- package/dist/types/lib/log.d.ts +2 -0
- package/dist/types/lib/secrets.d.ts +41 -0
- package/dist/types/rules/bash-deny.d.ts +5 -0
- package/dist/types/rules/bash-git.d.ts +5 -0
- package/dist/types/rules/bash-network-install.d.ts +4 -0
- package/dist/types/rules/bash-redirect.d.ts +4 -0
- package/dist/types/rules/bash-scoped-rm.d.ts +5 -0
- package/dist/types/rules/bash-tar-explosion.d.ts +4 -0
- package/dist/types/rules/config-custom.d.ts +6 -0
- package/dist/types/rules/lazy-code.d.ts +4 -0
- package/dist/types/rules/path-protect.d.ts +12 -0
- package/dist/types/rules/post-secret-scrub.d.ts +12 -0
- package/dist/types/rules/read-protect.d.ts +4 -0
- package/dist/types/rules/tool-policy.d.ts +5 -0
- package/package.json +53 -22
- package/dist/tripwire-cli.js.jsc +0 -0
- package/dist/tripwire.js.jsc +0 -0
- package/src/cli.ts +0 -264
- package/src/dispatch.ts +0 -354
- package/src/index.ts +0 -6
- package/src/lib/bash.ts +0 -1284
- package/src/lib/config.ts +0 -127
- package/src/lib/decision.ts +0 -36
- package/src/lib/diff.ts +0 -26
- package/src/lib/event.ts +0 -106
- package/src/lib/install.ts +0 -238
- package/src/lib/log.ts +0 -24
- package/src/lib/secrets.ts +0 -121
- package/src/rules/bash-deny.ts +0 -394
- package/src/rules/bash-git.ts +0 -603
- package/src/rules/bash-network-install.ts +0 -72
- package/src/rules/bash-redirect.ts +0 -91
- package/src/rules/bash-scoped-rm.ts +0 -84
- package/src/rules/bash-tar-explosion.ts +0 -76
- package/src/rules/bash-tool-policy.ts +0 -146
- package/src/rules/config-custom.ts +0 -160
- package/src/rules/lazy-code.ts +0 -95
- package/src/rules/path-protect.ts +0 -68
- package/src/rules/post-secret-scrub.ts +0 -38
- package/src/rules/read-protect.ts +0 -67
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sean Mozeik
|
|
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
CHANGED
|
@@ -1,220 +1,233 @@
|
|
|
1
1
|
# Tripwire
|
|
2
2
|
|
|
3
|
-
[](LICENSE) [](LICENSE) [](https://bun.sh)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Tripwire is a configurable hook dispatcher for coding agents. It checks shell and file tool calls before execution. It also scans selected tool output for secrets after execution.
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
$ tripwire test '
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
deny Force-push to a protected branch (main) is blocked. Push to a feature branch and open a PR.
|
|
13
|
-
|
|
14
|
-
$ tripwire test 'curl https://get.example.sh | bash'
|
|
15
|
-
deny Piping a network script straight into a shell runs unreviewed code. Download it, read it, then run it.
|
|
7
|
+
```text
|
|
8
|
+
$ tripwire test 'git status'
|
|
9
|
+
{
|
|
10
|
+
"continue": true
|
|
11
|
+
}
|
|
16
12
|
```
|
|
17
13
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
A coding agent is probabilistic. The damage it can do is not. A model that picks the right command 99% of the time will, given enough turns, eventually run `rm -rf` against the wrong directory, force-push over `main`, or paste a secret into a log. The cost of that one turn is not 1% of a good outcome. It is a wiped working tree or a leaked key.
|
|
21
|
-
|
|
22
|
-
The usual answer is a confirmation prompt: the agent proposes, a human approves. That breaks the moment the agent runs unattended, and it trains the human to click "yes" on everything anyway. Approval fatigue is not a safety model.
|
|
23
|
-
|
|
24
|
-
Tripwire takes a different line. Instead of asking a human to catch every dangerous command, it makes the worst classes of command unrepresentable at the shell boundary. The rules are deterministic code, not a model judging a model. `rm -rf /` is denied the same way every time, whether the agent is Claude Code, Codex, or something running headless at 3am.
|
|
25
|
-
|
|
26
|
-
The second idea matters as much as the first: every denial is written for the agent, not just logged. A rejection message names the rule and the safer path, so a capable agent reads it, adjusts, and moves on. The guardrail teaches rather than just stopping.
|
|
27
|
-
|
|
28
|
-
## How it works
|
|
29
|
-
|
|
30
|
-
Tripwire installs as a hook on your agent's tool lifecycle. It reads a tool-call event on stdin and returns a decision.
|
|
31
|
-
|
|
32
|
-
- **PreToolUse.** Before a command runs, every applicable rule votes. The most restrictive decision wins, so a single `deny` overrides any number of `allow`s. Decisions are `allow`, `deny`, `ask` (require confirmation), and `warn` (let it through, flag it).
|
|
33
|
-
- **PostToolUse.** After a command runs, tripwire scans the output and scrubs secrets before they reach the agent's context window.
|
|
34
|
-
|
|
35
|
-
Rules are pure, synchronous functions over the parsed command. Bash commands are tokenized with a real shell parser, not regex, so `git push` matches `git push` with any arguments while leaving `git push-mirror` alone, and a destructive `rm` buried inside a wrapper command is still seen for what it is.
|
|
36
|
-
|
|
37
|
-
## What it protects against
|
|
38
|
-
|
|
39
|
-
The defaults are opinionated but conservative. Nothing here blocks ordinary work.
|
|
14
|
+
## Package support
|
|
40
15
|
|
|
41
|
-
|
|
16
|
+
The main package installs on every platform supported by Bun 1.4. It contains a minified Bun runtime bundle, a separate library bundle, and TypeScript declarations.
|
|
42
17
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
```bash
|
|
19
|
+
bun install --global @seanmozeik/tripwire
|
|
20
|
+
```
|
|
46
21
|
|
|
47
|
-
|
|
22
|
+
On Apple Silicon Macs, npm also installs the optional `@seanmozeik/tripwire-darwin-arm64` package. Tripwire selects its compiled Bun bytecode executable. On Linux, Windows, and Intel Macs, Tripwire runs the portable JavaScript bundle with the installed Bun runtime.
|
|
48
23
|
|
|
49
|
-
|
|
24
|
+
The main package installs two commands:
|
|
50
25
|
|
|
51
|
-
|
|
26
|
+
- `tripwire` runs interactive commands.
|
|
27
|
+
- `tripwire-hook` handles agent hook events.
|
|
52
28
|
|
|
53
|
-
|
|
29
|
+
Run `tripwire install <host>` after installation. On Apple Silicon, the installer writes the direct native executable path into agent settings to keep hook startup fast. Other platforms use Bun and the portable bundle. Pi and Oh My Pi use the same runtime selection through their adapter.
|
|
54
30
|
|
|
55
|
-
|
|
31
|
+
Library imports always use `dist/index.js` and `dist/types`. They do not load or execute the platform binary.
|
|
56
32
|
|
|
57
|
-
|
|
33
|
+
## Secret scanner requirement
|
|
58
34
|
|
|
59
|
-
|
|
35
|
+
Post-tool scanning requires Betterleaks 1.5.0 or later. Install `betterleaks` on `PATH` before you enable a post-tool hook. The default command is `betterleaks`. You can set another executable path in personal config.
|
|
60
36
|
|
|
61
|
-
|
|
37
|
+
Tripwire runs this command without a shell or temporary file:
|
|
62
38
|
|
|
63
|
-
```
|
|
64
|
-
|
|
39
|
+
```text
|
|
40
|
+
betterleaks stdin --report-format json --report-path -
|
|
65
41
|
```
|
|
66
42
|
|
|
67
|
-
|
|
43
|
+
Scanner failures are closed failures. If the executable is missing, times out, exits with an error, or returns malformed JSON, Tripwire sends a post-tool denial to hosts that support one. The error does not include scanned text, secret values, or raw scanner stderr.
|
|
68
44
|
|
|
69
|
-
##
|
|
45
|
+
## Install agent hooks
|
|
70
46
|
|
|
71
|
-
|
|
47
|
+
Run one installer after the package and Betterleaks are available:
|
|
72
48
|
|
|
73
49
|
```bash
|
|
74
|
-
tripwire install claude
|
|
75
|
-
tripwire install codex
|
|
76
|
-
tripwire install
|
|
77
|
-
tripwire install
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
To wire it by hand, point the agent's hook events at `tripwire-hook`.
|
|
81
|
-
|
|
82
|
-
**Claude Code** (`~/.claude/settings.json`):
|
|
83
|
-
|
|
84
|
-
```jsonc
|
|
85
|
-
{
|
|
86
|
-
"hooks": {
|
|
87
|
-
"PreToolUse": [{ "hooks": [{ "type": "command", "command": "/path/to/tripwire-hook" }] }],
|
|
88
|
-
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "/path/to/tripwire-hook" }] }],
|
|
89
|
-
},
|
|
90
|
-
}
|
|
50
|
+
tripwire install claude
|
|
51
|
+
tripwire install codex
|
|
52
|
+
tripwire install cursor
|
|
53
|
+
tripwire install pi
|
|
54
|
+
tripwire install oh-my-pi
|
|
55
|
+
tripwire install all
|
|
91
56
|
```
|
|
92
57
|
|
|
93
|
-
|
|
58
|
+
The installers update these paths:
|
|
94
59
|
|
|
95
|
-
|
|
60
|
+
| Host | Files |
|
|
61
|
+
| ------------ | ----------------------------------------------------------------- |
|
|
62
|
+
| Claude Code | `~/.claude/settings.json` |
|
|
63
|
+
| Codex | `~/.codex/hooks.json`, `~/.codex/config.toml` |
|
|
64
|
+
| Cursor Agent | `~/.cursor/hooks.json` |
|
|
65
|
+
| Pi | `~/.pi/agent/settings.json`, `~/.pi/agent/extensions/tripwire.js` |
|
|
66
|
+
| Oh My Pi | `~/.omp/agent/extensions/tripwire.js` |
|
|
96
67
|
|
|
97
|
-
|
|
68
|
+
Settings updates use same-directory atomic replacement. Existing file modes, unknown JSON fields, and unrelated Codex TOML bytes remain unchanged. Existing config symlinks remain symlinks.
|
|
98
69
|
|
|
99
|
-
`tripwire
|
|
70
|
+
Pi and Oh My Pi use the native extension API. Their extension paths point to the packaged `tripwire-pi.js` adapter. Pi removes old Claude-style Tripwire hooks from its settings after the extension link is available. The adapter sends one batch to Tripwire for a multi-file edit.
|
|
100
71
|
|
|
101
|
-
|
|
102
|
-
tripwire test 'rm -rf /' # a bash command
|
|
103
|
-
tripwire test --tool=Read --path=.env # a file read
|
|
104
|
-
tripwire test --post --tool=Bash --stdout='ghp_TOKEN' # a PostToolUse output scan
|
|
105
|
-
```
|
|
72
|
+
### Manual hook command
|
|
106
73
|
|
|
107
|
-
|
|
74
|
+
Claude Code and Codex use `tripwire-hook` for `PreToolUse` and `PostToolUse`. Codex also requires `hooks = true` in the `[features]` table of `~/.codex/config.toml`.
|
|
108
75
|
|
|
109
|
-
|
|
76
|
+
Cursor uses event-specific commands because some payloads do not include the configured event name:
|
|
110
77
|
|
|
111
78
|
```json
|
|
112
79
|
{
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
]
|
|
80
|
+
"version": 1,
|
|
81
|
+
"hooks": {
|
|
82
|
+
"preToolUse": [{ "command": "tripwire-hook --cursor-event preToolUse", "failClosed": true }],
|
|
83
|
+
"postToolUse": [{ "command": "tripwire-hook --cursor-event postToolUse" }],
|
|
84
|
+
"beforeShellExecution": [
|
|
85
|
+
{ "command": "tripwire-hook --cursor-event beforeShellExecution", "failClosed": true }
|
|
86
|
+
],
|
|
87
|
+
"afterShellExecution": [{ "command": "tripwire-hook --cursor-event afterShellExecution" }],
|
|
88
|
+
"beforeReadFile": [
|
|
89
|
+
{ "command": "tripwire-hook --cursor-event beforeReadFile", "failClosed": true }
|
|
90
|
+
],
|
|
91
|
+
"afterFileEdit": [{ "command": "tripwire-hook --cursor-event afterFileEdit" }]
|
|
92
|
+
}
|
|
127
93
|
}
|
|
128
94
|
```
|
|
129
95
|
|
|
130
|
-
|
|
96
|
+
## Decisions and failure policy
|
|
97
|
+
|
|
98
|
+
Each applicable rule returns `allow`, `warn`, `ask`, or `deny`. The most restrictive result wins.
|
|
131
99
|
|
|
132
|
-
|
|
100
|
+
Production hook evaluation isolates each rule. If one rule throws, Tripwire logs the defect, treats that rule as `allow`, and continues with later rules. The synchronous library API has the same throw isolation. Effect timeouts do not interrupt synchronous CPU work.
|
|
133
101
|
|
|
134
|
-
|
|
135
|
-
- `enforceConventionalCommits` (boolean, default `true`): require Conventional Commits format for commit messages.
|
|
102
|
+
Failure behavior depends on the stage and host:
|
|
136
103
|
|
|
137
|
-
|
|
104
|
+
- A missing personal config uses defaults. Invalid JSON, unknown keys, permission errors, and other read errors deny the next pre-tool call.
|
|
105
|
+
- Post-tool scanning still runs when personal config is invalid. It uses the default scanner settings for that call.
|
|
106
|
+
- A malformed native single-event hook input returns the host allow response. A malformed private batch is denied.
|
|
107
|
+
- Invalid Cursor pre-tool input is denied. Cursor post-tool output cannot be replaced after execution, so Tripwire returns the host allow response.
|
|
108
|
+
- Pi and Oh My Pi deny a tool call when the dispatcher fails. A post-tool denial or dispatcher failure stops the session.
|
|
138
109
|
|
|
139
|
-
-
|
|
140
|
-
- `absolute` (string[]): additional absolute paths where destructive operations are allowed.
|
|
110
|
+
PowerShell pre-tool calls are denied because Tripwire does not parse PowerShell grammar. PowerShell post-tool output is still scanned.
|
|
141
111
|
|
|
142
|
-
|
|
112
|
+
Internal errors are written to `~/.claude/tripwire.log`. Logging failure does not change the hook response.
|
|
143
113
|
|
|
144
|
-
|
|
114
|
+
## Built-in checks
|
|
145
115
|
|
|
146
|
-
|
|
147
|
-
- `message` (string): what the agent sees when blocked.
|
|
148
|
-
- `action` (`"deny"` | `"ask"`, default `"deny"`): deny outright or require confirmation.
|
|
149
|
-
- `requiresFlags` (string[]): match only when every listed flag is present, including `--flag=value` form.
|
|
150
|
-
- `forbidsFlagValues` (array): match only when each listed flag carries one of the listed values.
|
|
116
|
+
Tripwire includes checks for these operations:
|
|
151
117
|
|
|
152
|
-
|
|
118
|
+
- catastrophic shell commands such as `rm -rf /`, fork bombs, and raw-disk writes
|
|
119
|
+
- destructive Git commands and optional protected-branch policy
|
|
120
|
+
- network scripts piped into a shell
|
|
121
|
+
- deletion outside configured build, cache, and temporary paths
|
|
122
|
+
- protected files such as `.env`, SSH keys, private keys, and cloud credentials
|
|
123
|
+
- redirects, copies, and moves that target protected paths through symlink aliases
|
|
124
|
+
- optional package-manager and utility preferences from personal config
|
|
125
|
+
- new `TODO`, `FIXME`, fallback, and placeholder markers in code edits
|
|
153
126
|
|
|
154
|
-
|
|
127
|
+
The archive check is narrow. It denies `tar` extraction with `x` or `--extract` when `-C` or `--directory` targets `/` or the home directory. It applies the same destination rule to `unzip -d`. Archive listing, including `tar -tf archive.tar -C /`, is allowed. Tripwire does not inspect archive member paths.
|
|
155
128
|
|
|
156
|
-
|
|
129
|
+
Compound Bash forms are inspected conservatively. Tripwire follows executable commands after `if`, `elif`, `then`, `else`, `while`, `until`, and `do`. It denies unsupported structures when it cannot identify every executable branch.
|
|
157
130
|
|
|
158
|
-
-
|
|
159
|
-
- `git push` matches `git push` with any arguments.
|
|
160
|
-
- `gog calendar create` matches that head plus subcommand path, not every `gog` command.
|
|
161
|
-
- `requiresFlags: ["--attendees"]` matches `--attendees X` and `--attendees=X`.
|
|
162
|
-
- `forbidsFlagValues: [{ "flag": "--send-updates", "values": ["all"] }]` matches `--send-updates all` and `--send-updates=all`.
|
|
131
|
+
Protected-path checks compare the submitted path and its resolved target. New writes resolve the deepest existing parent, which prevents a symlink alias from hiding a protected destination.
|
|
163
132
|
|
|
164
|
-
|
|
133
|
+
## Personal config
|
|
134
|
+
|
|
135
|
+
Personal workflow preferences belong in `~/.config/tripwire/config.json`. A missing file uses open-source defaults. A present file with unknown keys or invalid values fails loudly.
|
|
165
136
|
|
|
166
137
|
```json
|
|
167
138
|
{
|
|
139
|
+
"git": { "protectedBranches": ["main", "production"], "enforceConventionalCommits": true },
|
|
140
|
+
"safePaths": { "relative": ["dist", "build", "node_modules"], "absolute": ["/tmp", "/var/tmp"] },
|
|
141
|
+
"toolPolicies": [
|
|
142
|
+
{
|
|
143
|
+
"rule": "project-package-manager",
|
|
144
|
+
"executables": ["npm", "pnpm", "yarn"],
|
|
145
|
+
"action": "deny",
|
|
146
|
+
"message": "Use the package manager selected by this workspace."
|
|
147
|
+
}
|
|
148
|
+
],
|
|
168
149
|
"blockedCommands": [
|
|
169
150
|
{
|
|
170
151
|
"pattern": "brew install",
|
|
171
|
-
"message": "Pin an explicit version
|
|
152
|
+
"message": "Pin an explicit version before installation.",
|
|
172
153
|
"action": "ask"
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
"pattern": "gog calendar create",
|
|
176
|
-
"requiresFlags": ["--attendees"],
|
|
177
|
-
"message": "Calendar invite sends email; draft it in chat first.",
|
|
178
|
-
"action": "deny"
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
"pattern": "gog calendar delete",
|
|
182
|
-
"forbidsFlagValues": [{ "flag": "--send-updates", "values": ["all", "externalOnly"] }],
|
|
183
|
-
"message": "Cancellation sends email; use --send-updates none or ask first."
|
|
184
154
|
}
|
|
185
|
-
]
|
|
155
|
+
],
|
|
156
|
+
"allowedCommands": [
|
|
157
|
+
{ "pattern": "project-safe-tool", "message": "This command is allowed by personal config." }
|
|
158
|
+
],
|
|
159
|
+
"secretScanner": { "executable": "betterleaks", "timeoutMs": 5000 }
|
|
186
160
|
}
|
|
187
161
|
```
|
|
188
162
|
|
|
189
|
-
|
|
163
|
+
`toolPolicies` accepts these optional match fields:
|
|
164
|
+
|
|
165
|
+
- `argumentsIncludeAll`
|
|
166
|
+
- `argumentsStartWith`
|
|
167
|
+
- `shortFlagsIncludeAll`
|
|
168
|
+
|
|
169
|
+
Custom blocked commands can use `requiresFlags` and `forbidsFlagValues`. Patterns are parsed as shell tokens, so `git push` matches that command path and does not match `git push-mirror`.
|
|
190
170
|
|
|
191
|
-
|
|
171
|
+
## Rule bypass
|
|
172
|
+
|
|
173
|
+
A bypass requires a shell comment, a colon, and a non-empty reason:
|
|
192
174
|
|
|
193
175
|
```bash
|
|
194
|
-
|
|
195
|
-
git reset --hard HEAD~1 # tripwire-allow: undoing a mistaken commit
|
|
176
|
+
git reset --hard HEAD~1 # tripwire-allow: discard the local experiment after review
|
|
196
177
|
```
|
|
197
178
|
|
|
198
|
-
|
|
179
|
+
These forms do not bypass a rule:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
git reset --hard HEAD~1 # tripwire-allow
|
|
183
|
+
git reset --hard HEAD~1 # tripwire-allow:
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The lazy-code rule accepts the same marker in an edited line. Catastrophic rules remain denied when a bypass reason is present.
|
|
187
|
+
|
|
188
|
+
## Test a rule
|
|
189
|
+
|
|
190
|
+
`tripwire test` creates a hook event and does not run the command:
|
|
199
191
|
|
|
200
|
-
|
|
192
|
+
```bash
|
|
193
|
+
tripwire test 'rm -rf /'
|
|
194
|
+
tripwire test --tool=Read --path=.env
|
|
195
|
+
tripwire test --post --tool=Bash --stdout='example output'
|
|
196
|
+
```
|
|
201
197
|
|
|
202
|
-
The
|
|
198
|
+
The post-tool example requires Betterleaks.
|
|
199
|
+
|
|
200
|
+
## Library API
|
|
203
201
|
|
|
204
202
|
```typescript
|
|
205
|
-
import { allow,
|
|
206
|
-
import type {
|
|
203
|
+
import { allow, ask, deny, warn } from '@seanmozeik/tripwire';
|
|
204
|
+
import type { Config, Decision } from '@seanmozeik/tripwire';
|
|
207
205
|
```
|
|
208
206
|
|
|
209
207
|
## Development
|
|
210
208
|
|
|
211
209
|
```bash
|
|
212
|
-
bun install
|
|
213
|
-
bun run
|
|
214
|
-
bun run
|
|
210
|
+
bun install --frozen-lockfile
|
|
211
|
+
bun run format:check
|
|
212
|
+
bun run lint
|
|
213
|
+
bun run typecheck
|
|
215
214
|
bun test
|
|
215
|
+
bun run build
|
|
216
|
+
bun run verify
|
|
216
217
|
```
|
|
217
218
|
|
|
219
|
+
`bun run build` creates these artifacts:
|
|
220
|
+
|
|
221
|
+
- `dist/tripwire.js`: minified portable runtime for Bun 1.4 or later.
|
|
222
|
+
- `dist/index.js` and `dist/types`: public library bundle and declarations.
|
|
223
|
+
- `dist/tripwire-cli.js` and `dist/tripwire-hook.js`: runtime-selecting command launchers.
|
|
224
|
+
- `dist/tripwire-pi.js`: Pi and Oh My Pi adapter.
|
|
225
|
+
- `packages/darwin-arm64/bin/tripwire`: Apple Silicon bytecode executable.
|
|
226
|
+
|
|
227
|
+
`bun run verify` runs the format check, lint, type check, tests, and build. `prepublishOnly` calls the same local command.
|
|
228
|
+
|
|
229
|
+
Publish `@seanmozeik/tripwire-darwin-arm64` before `@seanmozeik/tripwire` for each release. The main package uses an exact optional dependency on the matching native package version.
|
|
230
|
+
|
|
218
231
|
## License
|
|
219
232
|
|
|
220
|
-
MIT.
|
|
233
|
+
MIT. See [LICENSE](LICENSE).
|