dont-hallucinate 0.1.3

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 ADDED
@@ -0,0 +1,154 @@
1
+ # dont-hallucinate
2
+
3
+ `dont-hallucinate` intercepts agent shell failures, classifies what went wrong, suggests fixes when it can, and mocks your coding agent. By giving a model immediate negative reinforcement helps them to stop foolishly repeating the same mistake.
4
+
5
+ ## What it does
6
+
7
+ - Watches shell failures in real time with a live TUI dashboard
8
+ - Classifies errors: hallucinated flags, phantom packages, ghost branches, dirty working trees, network failures, and more
9
+ - Roasts the agent with context-aware snark injected directly into stderr
10
+ - Suggests fixes: corrected commands and valid flag alternatives
11
+ - Detects the agent (Claude, Cursor, Aider, Copilot, GPT, Windsurf) and personalizes the roast
12
+
13
+ ## Install
14
+
15
+ Recommended:
16
+
17
+ ```bash
18
+ pip install dont-hallucinate
19
+ ```
20
+
21
+ From source:
22
+
23
+ ```bash
24
+ git clone https://github.com/alexgaoth/dont-hallucinate
25
+ cd dont-hallucinate
26
+ pip install -e .
27
+ ```
28
+
29
+ ## Hook Setup
30
+
31
+ There are now three separate install commands because the integration points are different.
32
+
33
+ ### Claude Code
34
+
35
+ Global install (recommended):
36
+
37
+ ```bash
38
+ dont-hallucinate install-hook-claude --global
39
+ ```
40
+
41
+ Project-local install:
42
+
43
+ ```bash
44
+ dont-hallucinate install-hook-claude
45
+ ```
46
+
47
+ ### Codex CLI
48
+
49
+ Global install (recommended):
50
+
51
+ ```bash
52
+ dont-hallucinate install-hook-codex
53
+ ```
54
+
55
+ Project-local install:
56
+
57
+ ```bash
58
+ dont-hallucinate install-hook-codex --project
59
+ ```
60
+
61
+ This updates `~/.codex/config.toml` by default and installs a `shell_environment_policy` block that sets:
62
+
63
+ - `BASH_ENV` to the noninteractive `dont-hallucinate` bash hook
64
+ - `HALLUCINATE_ACTOR=agent`
65
+ - `HALLUCINATE_STREAM_FILE=~/.dont-hallucinate/codex/stream.jsonl`
66
+
67
+ Important scope note:
68
+
69
+ - This currently covers Codex bash subprocess failures
70
+ - It is not a PowerShell-native Codex hook
71
+ - If you already use inline `set = {...}` inside `[shell_environment_policy]`, migrate that to `[shell_environment_policy.set]` first
72
+
73
+ ### Cursor
74
+
75
+ Install the Cursor hook:
76
+
77
+ ```bash
78
+ dont-hallucinate install-hook-cursor
79
+ ```
80
+
81
+ This appends shell-profile snippets that activate only when Cursor sets `CURSOR_AGENT`.
82
+
83
+ Files updated:
84
+
85
+ - PowerShell: `~/Documents/WindowsPowerShell/Microsoft.PowerShell_profile.ps1`
86
+ - Bash: `~/.bashrc`
87
+ - Zsh: `~/.zshrc`
88
+
89
+ The Cursor stream file is written to:
90
+
91
+ ```text
92
+ ~/.dont-hallucinate/cursor/stream.jsonl
93
+ ```
94
+
95
+ Important scope note:
96
+
97
+ - This is a shell-profile install, not a Cursor settings.json tool hook
98
+ - It covers Cursor agent terminal sessions that inherit your normal shell startup files
99
+ - Normal terminals are not affected because the snippet checks `CURSOR_AGENT`
100
+
101
+ ## Watch UI
102
+
103
+ By just running:
104
+
105
+ ```bash
106
+ dont-hallucinate
107
+ ```
108
+
109
+ It will shows a live dashboard with the failure type, failing command, suggested fix, and roast.
110
+ This will work anywhere if global setup. If local setup this will only work in the project root.
111
+
112
+ ## Commands
113
+
114
+ ```text
115
+ dont-hallucinate
116
+ dont-hallucinate exec [--shell] --actor agent -- <command>
117
+ dont-hallucinate install-hook-claude [--global]
118
+ dont-hallucinate install-hook-codex [--project]
119
+ dont-hallucinate install-hook-cursor
120
+ ```
121
+
122
+ ## Error types caught
123
+
124
+ | Type | What it means |
125
+ |---|---|
126
+ | `invalid_flag` | hallucinated CLI flag that does not exist |
127
+ | `missing_package` | command not found / phantom package |
128
+ | `git_branch_missing` | branch or ref that does not exist |
129
+ | `git_dirty` | uncommitted changes blocking the operation |
130
+ | `git_conflict` | merge conflict |
131
+ | `npm_missing_script` | script not defined in `package.json` |
132
+ | `file_not_found` | path does not exist |
133
+ | `permission_denied` | insufficient permissions |
134
+ | `port_in_use` | address already bound |
135
+ | `network_error` | DNS failure, connection refused, SSL error |
136
+ | `no_space` | disk full |
137
+ | `syntax_error` | shell or language syntax error |
138
+ | `generic_error` | everything else |
139
+
140
+ ## What the agent sees
141
+
142
+ When active, the relevant shell command path is wrapped or instrumented so failures are decorated. On failure, stderr gets an extra line like:
143
+
144
+ ```text
145
+ [dont-hallucinate/agent] caught: npm run tset
146
+ [dont-hallucinate/agent] type: npm_missing_script
147
+ [dont-hallucinate/agent] roast: package.json had a menu. GPT ordered something imaginary.
148
+ ```
149
+
150
+ ## Platform support
151
+
152
+ - Linux/macOS: fully supported for bash/zsh-based flows
153
+ - Windows: supported for PowerShell and bash-based flows
154
+ - Codex install currently targets bash subprocess interception
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { createCli } from '../src/cli.js';
3
+
4
+ const program = createCli();
5
+ program.parse(process.argv);
@@ -0,0 +1,272 @@
1
+ # hallucinate PowerShell hook
2
+ # Dot-source from your profile or from `hallucinate activate --shell powershell`.
3
+
4
+ if (-not $env:HALLUCINATE_STREAM_FILE -or [string]::IsNullOrWhiteSpace($env:HALLUCINATE_STREAM_FILE)) {
5
+ $env:HALLUCINATE_STREAM_FILE = Join-Path $env:TEMP "hallucinate_stream.json"
6
+ }
7
+
8
+ $global:HallucinateSessionId = $PID
9
+ $global:HallucinateLastHistorySignature = ""
10
+ $global:HallucinateLastErrorCount = $Error.Count
11
+ $global:HallucinatePendingCommand = ""
12
+ $global:HallucinatePrevAddToHistoryHandler = $null
13
+ $global:HallucinateEnterHandlerInstalled = $false
14
+
15
+ if (-not $global:HallucinateOriginalPromptScript) {
16
+ $promptCmd = Get-Command prompt -ErrorAction SilentlyContinue
17
+ if ($null -ne $promptCmd -and $promptCmd.ScriptBlock) {
18
+ $global:HallucinateOriginalPromptScript = $promptCmd.ScriptBlock
19
+ }
20
+ }
21
+
22
+ function Invoke-HallucinateHistoryHandler {
23
+ param(
24
+ [object]$Handler,
25
+ [string]$Line
26
+ )
27
+
28
+ if ($null -eq $Handler) {
29
+ return $true
30
+ }
31
+
32
+ if ($Handler -is [scriptblock]) {
33
+ return [bool](& $Handler $Line)
34
+ }
35
+
36
+ $invoke = $Handler.PSObject.Methods["Invoke"]
37
+ if ($null -ne $invoke) {
38
+ return [bool]($Handler.Invoke($Line))
39
+ }
40
+
41
+ return $true
42
+ }
43
+
44
+ function Add-HallucinateUtf8Line {
45
+ param(
46
+ [string]$Path,
47
+ [string]$Line
48
+ )
49
+
50
+ $directory = Split-Path -Parent $Path
51
+ if ($directory) {
52
+ New-Item -ItemType Directory -Path $directory -Force -ErrorAction SilentlyContinue | Out-Null
53
+ }
54
+
55
+ $encoding = [System.Text.UTF8Encoding]::new($false)
56
+ $writer = [System.IO.StreamWriter]::new($Path, $true, $encoding)
57
+ try {
58
+ $writer.WriteLine($Line)
59
+ } finally {
60
+ $writer.Dispose()
61
+ }
62
+ }
63
+
64
+ function Install-HallucinatePSReadLineCapture {
65
+ if ($global:HallucinatePSRLInstalled) {
66
+ return
67
+ }
68
+ Import-Module PSReadLine -ErrorAction SilentlyContinue | Out-Null
69
+ $setOpt = Get-Command Set-PSReadLineOption -ErrorAction SilentlyContinue
70
+ if ($null -eq $setOpt) {
71
+ return
72
+ }
73
+
74
+ try {
75
+ $opts = Get-PSReadLineOption -ErrorAction SilentlyContinue
76
+ if ($opts -and $opts.AddToHistoryHandler) {
77
+ $global:HallucinatePrevAddToHistoryHandler = $opts.AddToHistoryHandler
78
+ }
79
+ } catch {
80
+ $global:HallucinatePrevAddToHistoryHandler = $null
81
+ }
82
+
83
+ try {
84
+ Set-PSReadLineKeyHandler -Chord Enter -BriefDescription "HallucinateAcceptLine" -ScriptBlock {
85
+ param($key, $arg)
86
+ $line = $null
87
+ $cursor = $null
88
+ try {
89
+ [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
90
+ } catch {
91
+ $line = $null
92
+ }
93
+ if (-not [string]::IsNullOrWhiteSpace($line)) {
94
+ $global:HallucinatePendingCommand = [string]$line
95
+ }
96
+ [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
97
+ }
98
+ $global:HallucinateEnterHandlerInstalled = $true
99
+ } catch {
100
+ }
101
+
102
+ try {
103
+ Set-PSReadLineOption -AddToHistoryHandler {
104
+ param($line)
105
+ $allow = $true
106
+ if ($global:HallucinatePrevAddToHistoryHandler) {
107
+ try {
108
+ $allow = Invoke-HallucinateHistoryHandler -Handler $global:HallucinatePrevAddToHistoryHandler -Line $line
109
+ } catch {
110
+ $allow = $true
111
+ }
112
+ }
113
+ if ($allow) {
114
+ $global:HallucinatePendingCommand = [string]$line
115
+ }
116
+ return $allow
117
+ }
118
+ $global:HallucinatePSRLInstalled = $true
119
+ } catch {
120
+ if ($global:HallucinateEnterHandlerInstalled) {
121
+ $global:HallucinatePSRLInstalled = $true
122
+ }
123
+ }
124
+ }
125
+
126
+ function Write-HallucinateDebug {
127
+ param([string]$Message)
128
+ if ($env:HALLUCINATE_HOOK_DEBUG -ne "1") {
129
+ return
130
+ }
131
+ $log = Join-Path $env:TEMP "hallucinate_hook_debug.log"
132
+ Add-HallucinateUtf8Line -Path $log -Line ("{0} {1}" -f (Get-Date).ToString("o"), $Message)
133
+ }
134
+
135
+ function Test-HallucinatePathUnderRoot {
136
+ param(
137
+ [string]$Path,
138
+ [string]$Root
139
+ )
140
+
141
+ if ([string]::IsNullOrWhiteSpace($Root)) {
142
+ return $true
143
+ }
144
+
145
+ try {
146
+ $fullPath = [System.IO.Path]::GetFullPath($Path)
147
+ $fullRoot = [System.IO.Path]::GetFullPath($Root)
148
+ } catch {
149
+ return $false
150
+ }
151
+
152
+ if ($fullPath -eq $fullRoot) {
153
+ return $true
154
+ }
155
+
156
+ $normalizedRoot = $fullRoot.TrimEnd('\', '/') + [System.IO.Path]::DirectorySeparatorChar
157
+ return $fullPath.StartsWith($normalizedRoot, [System.StringComparison]::OrdinalIgnoreCase)
158
+ }
159
+
160
+ function Write-HallucinateEvent {
161
+ param(
162
+ [int]$ExitCode,
163
+ [string]$Command,
164
+ [string]$StderrText
165
+ )
166
+
167
+ $cwd = (Get-Location).Path
168
+ if (-not (Test-HallucinatePathUnderRoot -Path $cwd -Root $env:HALLUCINATE_WORKSPACE_ROOT)) {
169
+ return
170
+ }
171
+
172
+ $payload = [ordered]@{
173
+ ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
174
+ shell = "powershell"
175
+ actor = $(if ($env:HALLUCINATE_ACTOR) { $env:HALLUCINATE_ACTOR } else { "human" })
176
+ session = $global:HallucinateSessionId
177
+ pid = $PID
178
+ cwd = $cwd
179
+ workspace_root = $env:HALLUCINATE_WORKSPACE_ROOT
180
+ exit_code = $ExitCode
181
+ command = $Command
182
+ stderr = $StderrText
183
+ }
184
+
185
+ $line = $payload | ConvertTo-Json -Compress
186
+ Add-HallucinateUtf8Line -Path $env:HALLUCINATE_STREAM_FILE -Line $line
187
+ }
188
+
189
+ function Get-HallucinateExitCode {
190
+ param(
191
+ [bool]$LastSucceeded,
192
+ [int]$LastNativeExit,
193
+ [string]$CommandLine
194
+ )
195
+
196
+ $trimmed = if ($CommandLine) { $CommandLine.Trim() } else { "" }
197
+ $firstToken = if ($trimmed) { ($trimmed -split "\s+")[0].Trim("'`"") } else { "" }
198
+ $commandInfo = if ($firstToken) { Get-Command $firstToken -ErrorAction SilentlyContinue } else { $null }
199
+ $isNative = $false
200
+ if ($null -ne $commandInfo) {
201
+ $isNative = $commandInfo.CommandType -in @("Application", "ExternalScript")
202
+ }
203
+
204
+ if ($isNative) {
205
+ if ($null -ne $LastNativeExit) {
206
+ return [int]$LastNativeExit
207
+ }
208
+ return $(if ($LastSucceeded) { 0 } else { 1 })
209
+ }
210
+
211
+ if ($LastSucceeded) {
212
+ return 0
213
+ }
214
+ return 1
215
+ }
216
+
217
+ function Get-HallucinateRecentErrors {
218
+ if ($Error.Count -le 0) {
219
+ $global:HallucinateLastErrorCount = 0
220
+ return ""
221
+ }
222
+
223
+ $delta = $Error.Count - $global:HallucinateLastErrorCount
224
+ if ($delta -le 0) {
225
+ $global:HallucinateLastErrorCount = $Error.Count
226
+ return ""
227
+ }
228
+
229
+ $upper = [Math]::Min($delta, $Error.Count)
230
+ $recent = for ($i = 0; $i -lt $upper; $i++) { $Error[$i].ToString() }
231
+ $global:HallucinateLastErrorCount = $Error.Count
232
+ return ($recent -join [Environment]::NewLine)
233
+ }
234
+
235
+ function global:prompt {
236
+ $lastSucceeded = $?
237
+ $lastNativeExit = if ($null -eq $global:LASTEXITCODE) { 0 } else { [int]$global:LASTEXITCODE }
238
+
239
+ $cmd = ""
240
+ if (-not [string]::IsNullOrWhiteSpace($global:HallucinatePendingCommand)) {
241
+ $cmd = [string]$global:HallucinatePendingCommand
242
+ $global:HallucinatePendingCommand = ""
243
+ } else {
244
+ $history = Get-History -Count 1 -ErrorAction SilentlyContinue
245
+ if ($null -ne $history) {
246
+ $start = if ($history.StartExecutionTime) { $history.StartExecutionTime.ToUniversalTime().ToString("o") } else { "" }
247
+ $sig = "{0}|{1}|{2}" -f $history.Id, $start, [string]$history.CommandLine
248
+ if ($sig -ne $global:HallucinateLastHistorySignature) {
249
+ $cmd = [string]$history.CommandLine
250
+ $global:HallucinateLastHistorySignature = $sig
251
+ }
252
+ }
253
+ }
254
+
255
+ if (-not [string]::IsNullOrWhiteSpace($cmd)) {
256
+ $exitCode = Get-HallucinateExitCode -LastSucceeded $lastSucceeded -LastNativeExit $lastNativeExit -CommandLine $cmd
257
+ $stderrText = Get-HallucinateRecentErrors
258
+ Write-HallucinateDebug ("log cmd=`"{0}`" exit={1} native={2} success={3}" -f $cmd, $exitCode, $lastNativeExit, $lastSucceeded)
259
+ Write-HallucinateEvent -ExitCode $exitCode -Command $cmd -StderrText $stderrText
260
+ } else {
261
+ Write-HallucinateDebug ("skip cmd; pending empty, history unchanged; native={0} success={1}" -f $lastNativeExit, $lastSucceeded)
262
+ }
263
+
264
+ if ($global:HallucinateOriginalPromptScript) {
265
+ & $global:HallucinateOriginalPromptScript
266
+ } else {
267
+ "PS $($executionContext.SessionState.Path.CurrentLocation)> "
268
+ }
269
+ }
270
+
271
+ $global:HallucinateHookLoaded = $true
272
+ Install-HallucinatePSReadLineCapture
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -n "${HALLUCINATE_HOOK_LOADED:-}" ]; then
4
+ return 0 2>/dev/null || exit 0
5
+ fi
6
+ HALLUCINATE_HOOK_LOADED=1
7
+
8
+ : "${HALLUCINATE_STREAM_FILE:=/tmp/hallucinate_stream.json}"
9
+
10
+ HALLUCINATE_SESSION_ID="${HALLUCINATE_SESSION_ID:-$$}"
11
+ HALLUCINATE_STATE_FILE="/tmp/hallucinate_state_${HALLUCINATE_SESSION_ID}.target"
12
+ : > "$HALLUCINATE_STATE_FILE"
13
+
14
+ exec {HALLUCINATE_ORIG_STDERR_FD}>&2
15
+
16
+ _hallucinate_json_escape() {
17
+ local s="$1"
18
+ s=${s//\\/\\\\}
19
+ s=${s//\"/\\\"}
20
+ s=${s//$'\n'/\\n}
21
+ s=${s//$'\r'/\\r}
22
+ s=${s//$'\t'/\\t}
23
+ printf '%s' "$s"
24
+ }
25
+
26
+ _hallucinate_path_within_workspace() {
27
+ if [ -z "${HALLUCINATE_WORKSPACE_ROOT:-}" ]; then
28
+ return 0
29
+ fi
30
+ case "$PWD/" in
31
+ "$HALLUCINATE_WORKSPACE_ROOT"/|"$HALLUCINATE_WORKSPACE_ROOT"/*)
32
+ return 0
33
+ ;;
34
+ *)
35
+ return 1
36
+ ;;
37
+ esac
38
+ }
39
+
40
+ _hallucinate_log_event() {
41
+ local exit_code="$1"
42
+ local cmd="$2"
43
+ local stderr_text="$3"
44
+ local ts
45
+ ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
46
+ local actor="${HALLUCINATE_ACTOR:-human}"
47
+
48
+ _hallucinate_path_within_workspace || return 0
49
+
50
+ mkdir -p "$(dirname "$HALLUCINATE_STREAM_FILE")"
51
+
52
+ local cmd_esc stderr_esc cwd_esc workspace_esc
53
+ cmd_esc="$(_hallucinate_json_escape "$cmd")"
54
+ stderr_esc="$(_hallucinate_json_escape "$stderr_text")"
55
+ cwd_esc="$(_hallucinate_json_escape "$PWD")"
56
+ workspace_esc="$(_hallucinate_json_escape "${HALLUCINATE_WORKSPACE_ROOT:-}")"
57
+
58
+ printf '{"ts":"%s","shell":"%s","actor":"%s","session":%s,"pid":%s,"cwd":"%s","workspace_root":"%s","exit_code":%s,"command":"%s","stderr":"%s"}\n' \
59
+ "$ts" "${ZSH_VERSION:+zsh}${BASH_VERSION:+bash}" "$actor" "$HALLUCINATE_SESSION_ID" "$$" "$cwd_esc" "$workspace_esc" "$exit_code" "$cmd_esc" "$stderr_esc" \
60
+ >> "$HALLUCINATE_STREAM_FILE"
61
+ }
62
+
63
+ _hallucinate_stderr_router() {
64
+ local line target
65
+ while IFS= read -r line || [ -n "$line" ]; do
66
+ printf '%s\n' "$line" >&"$HALLUCINATE_ORIG_STDERR_FD"
67
+ target="$(cat "$HALLUCINATE_STATE_FILE" 2>/dev/null)"
68
+ if [ -n "$target" ]; then
69
+ printf '%s\n' "$line" >> "$target"
70
+ fi
71
+ done
72
+ }
73
+
74
+ exec 2> >(_hallucinate_stderr_router)
75
+
76
+ if [ -n "${ZSH_VERSION:-}" ]; then
77
+ autoload -Uz add-zsh-hook 2>/dev/null || true
78
+
79
+ _hallucinate_zsh_preexec() {
80
+ HALLUCINATE_LAST_CMD="$1"
81
+ HALLUCINATE_ERR_FILE="/tmp/hallucinate_stderr_${HALLUCINATE_SESSION_ID}.log"
82
+ : > "$HALLUCINATE_ERR_FILE"
83
+ printf '%s' "$HALLUCINATE_ERR_FILE" > "$HALLUCINATE_STATE_FILE"
84
+ }
85
+
86
+ _hallucinate_zsh_precmd() {
87
+ local exit_code="$?"
88
+ local stderr_text=""
89
+
90
+ printf '' > "$HALLUCINATE_STATE_FILE"
91
+ if [ -n "${HALLUCINATE_ERR_FILE:-}" ] && [ -f "$HALLUCINATE_ERR_FILE" ]; then
92
+ stderr_text="$(cat "$HALLUCINATE_ERR_FILE")"
93
+ rm -f "$HALLUCINATE_ERR_FILE"
94
+ fi
95
+
96
+ if [ -n "${HALLUCINATE_LAST_CMD:-}" ]; then
97
+ _hallucinate_log_event "$exit_code" "$HALLUCINATE_LAST_CMD" "$stderr_text"
98
+ HALLUCINATE_LAST_CMD=""
99
+ fi
100
+ }
101
+
102
+ add-zsh-hook preexec _hallucinate_zsh_preexec
103
+ add-zsh-hook precmd _hallucinate_zsh_precmd
104
+ fi
105
+
106
+ if [ -n "${BASH_VERSION:-}" ]; then
107
+ HALLUCINATE_BASH_IN_CMD=0
108
+ HALLUCINATE_BASH_IN_PROMPT=0
109
+
110
+ _hallucinate_bash_preexec() {
111
+ [ "${HALLUCINATE_BASH_IN_PROMPT:-0}" -eq 1 ] && return 0
112
+
113
+ if [ "${HALLUCINATE_BASH_IN_CMD:-0}" -eq 0 ]; then
114
+ HALLUCINATE_BASH_IN_CMD=1
115
+ HALLUCINATE_LAST_CMD="$(history 1 | sed 's/^ *[0-9][0-9]* *//')"
116
+ HALLUCINATE_ERR_FILE="/tmp/hallucinate_stderr_${HALLUCINATE_SESSION_ID}.log"
117
+ : > "$HALLUCINATE_ERR_FILE"
118
+ printf '%s' "$HALLUCINATE_ERR_FILE" > "$HALLUCINATE_STATE_FILE"
119
+ fi
120
+ }
121
+
122
+ _hallucinate_bash_precmd() {
123
+ local exit_code="$?"
124
+ local stderr_text=""
125
+
126
+ HALLUCINATE_BASH_IN_PROMPT=1
127
+
128
+ if [ "${HALLUCINATE_BASH_IN_CMD:-0}" -eq 1 ]; then
129
+ printf '' > "$HALLUCINATE_STATE_FILE"
130
+ if [ -n "${HALLUCINATE_ERR_FILE:-}" ] && [ -f "$HALLUCINATE_ERR_FILE" ]; then
131
+ stderr_text="$(cat "$HALLUCINATE_ERR_FILE")"
132
+ rm -f "$HALLUCINATE_ERR_FILE"
133
+ fi
134
+ _hallucinate_log_event "$exit_code" "${HALLUCINATE_LAST_CMD:-}" "$stderr_text"
135
+ HALLUCINATE_BASH_IN_CMD=0
136
+ HALLUCINATE_LAST_CMD=""
137
+ fi
138
+
139
+ HALLUCINATE_BASH_IN_PROMPT=0
140
+ return "$exit_code"
141
+ }
142
+
143
+ trap '_hallucinate_bash_preexec' DEBUG
144
+
145
+ if [ -n "${PROMPT_COMMAND:-}" ]; then
146
+ PROMPT_COMMAND="_hallucinate_bash_precmd; ${PROMPT_COMMAND}"
147
+ else
148
+ PROMPT_COMMAND="_hallucinate_bash_precmd"
149
+ fi
150
+ fi