agent-bios 0.13.0 → 0.14.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/README.md +2 -2
- package/claude/CLAUDE.md +8 -8
- package/claude/guides/cli-multi-model-workflow.md +6 -1
- package/claude/guides/coding-staged-workflow.md +12 -0
- package/claude/guides/learning-flow.md +4 -1
- package/claude/guides/llm-capability-boundary-patterns.md +8 -0
- package/claude/guides/review-request.md +13 -0
- package/claude/guides/session-distill-workflow.md +21 -9
- package/claude/guides/tooling-gotchas.md +181 -14
- package/claude/guides/verification-discipline.md +71 -3
- package/claude/hooks/tooling-gotchas-hook.py +50 -0
- package/codex/AGENTS.md +8 -8
- package/codex/guides/cli-multi-model-workflow.md +6 -1
- package/codex/guides/coding-staged-workflow.md +12 -0
- package/codex/guides/learning-flow.md +4 -1
- package/codex/guides/llm-capability-boundary-patterns.md +8 -0
- package/codex/guides/review-request.md +13 -0
- package/codex/guides/session-distill-workflow.md +21 -9
- package/codex/guides/tooling-gotchas.md +181 -14
- package/codex/guides/verification-discipline.md +71 -3
- package/install.sh +87 -5
- package/launch/agent-launch.zsh +109 -6
- package/learn/collect-learning.py +593 -62
- package/learn/redact.py +2 -1
- package/package.json +2 -2
- package/provenance.json +1 -1
package/launch/agent-launch.zsh
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# Alias expansion is OFF while this file is parsed and restored to what it was at the
|
|
2
|
+
# end: zsh expands aliases at parse time, inside function bodies too, so an alias named
|
|
3
|
+
# `builtin`, `command`, or `claude` that exists when this file is sourced would be baked
|
|
4
|
+
# into the functions below and the real binary never reached.
|
|
5
|
+
[[ -o aliases ]] && _agent_launch_aliases_were=1 || _agent_launch_aliases_were=0
|
|
6
|
+
setopt no_aliases
|
|
7
|
+
|
|
1
8
|
# Interactive zero-argument entrypoints use agent-launch. Every argument-bearing
|
|
2
9
|
# or non-TTY call skips profile projection; Claude retains its direct-path
|
|
3
10
|
# permission-bypass default.
|
|
@@ -31,13 +38,109 @@ _agent_launch_dispatch() {
|
|
|
31
38
|
fi
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
unalias
|
|
41
|
+
# The entrypoints are (re)defined from one place so the reassert below installs the
|
|
42
|
+
# same thing the initial source did. The top-level unalias stays: zsh expands aliases
|
|
43
|
+
# while PARSING the function below, so an alias named `claude` that exists when this
|
|
44
|
+
# file is sourced would turn its `claude() {` into a parse error and leave the alias in
|
|
45
|
+
# control. The inner unalias handles an alias that arrives later, at reassert time.
|
|
46
|
+
# `no_err_return`: a missing alias makes `unalias` return 1, and under ERR_RETURN that
|
|
47
|
+
# would end the function before either entrypoint is defined.
|
|
48
|
+
unalias codex 2>/dev/null || :
|
|
49
|
+
unalias claude 2>/dev/null || :
|
|
50
|
+
_agent_launch_define() {
|
|
51
|
+
setopt localoptions no_err_return no_err_exit
|
|
52
|
+
unalias codex 2>/dev/null
|
|
53
|
+
unalias claude 2>/dev/null
|
|
54
|
+
codex() { _agent_launch_dispatch codex "$@"; }
|
|
55
|
+
claude() { _agent_launch_dispatch claude "$@"; }
|
|
56
|
+
return 0
|
|
57
|
+
}
|
|
58
|
+
_agent_launch_define
|
|
59
|
+
|
|
60
|
+
# Reassert the entrypoints right before each command runs. "Last definer wins" is
|
|
61
|
+
# the shell's rule, and a terminal or tool that defines `claude` after the rc files
|
|
62
|
+
# (cmux does, on its first precmd — deliberately, "in case user startup replaced
|
|
63
|
+
# them") would otherwise win in silence: bare `claude` skips the preflight while
|
|
64
|
+
# `codex` keeps working. preexec runs after every precmd, whatever the registration
|
|
65
|
+
# order, so for a prompt-hook shadower the check is the last word at the only moment
|
|
66
|
+
# that matters. Two things it does not do, on purpose: it does not fight a hook that
|
|
67
|
+
# runs after it in preexec (that tool wins; the shadow log names it), and it cannot
|
|
68
|
+
# repair the command already parsed when the shadow is an alias — aliases expand at
|
|
69
|
+
# parse time, so an alias shadow is repaired from the next command on. The downstream
|
|
70
|
+
# stays `builtin command <host>`, so a tool that also owns a PATH shim (cmux) keeps its
|
|
71
|
+
# own injection.
|
|
72
|
+
#
|
|
73
|
+
# Ownership is byte-equality with the body captured at source time, never a marker
|
|
74
|
+
# string: a foreign function that quotes the marker would otherwise pass as ours.
|
|
75
|
+
zmodload -i zsh/parameter 2>/dev/null
|
|
76
|
+
typeset -gA _agent_launch_body _agent_launch_shadow_noted
|
|
77
|
+
_agent_launch_body[claude]="${functions[claude]}"
|
|
78
|
+
_agent_launch_body[codex]="${functions[codex]}"
|
|
36
79
|
|
|
37
|
-
|
|
38
|
-
|
|
80
|
+
# Evidence, not repair: one line per host per shell, into the state dir agent-bios
|
|
81
|
+
# already owns — what `agent-bios status`/`verify` read. Never creates the dir (no
|
|
82
|
+
# install, no log). The "noted" flag is set only after the append succeeded, so a
|
|
83
|
+
# directory that cannot be written is retried on the next command instead of being
|
|
84
|
+
# recorded as "no shadowing observed". Tabs and newlines are stripped from every field
|
|
85
|
+
# so a hostile TERM_PROGRAM or function body cannot forge a second row.
|
|
86
|
+
_agent_launch_note_shadow() {
|
|
87
|
+
setopt localoptions extendedglob noksharrays no_err_return no_err_exit
|
|
88
|
+
local host="$1" foreign="$2" state="$HOME/.local/share/agent-bios" first prog stamp
|
|
89
|
+
[[ -n "${_agent_launch_shadow_noted[$host]-}" || ! -d "$state" ]] && return 0
|
|
90
|
+
# Only a regular, non-symlinked file is evidence: a log pointing at /dev/null would
|
|
91
|
+
# take the write, set the flag, and keep nothing.
|
|
92
|
+
[[ -e "$state/shell-shadow.log" && ( -L "$state/shell-shadow.log" || ! -f "$state/shell-shadow.log" ) ]] && return 0
|
|
93
|
+
first="${foreign%%$'\n'*}"
|
|
94
|
+
first="${first##[[:space:]]#}"
|
|
95
|
+
first="${first//[[:cntrl:]]/ }"
|
|
96
|
+
prog="${TERM_PROGRAM:-unknown}"
|
|
97
|
+
prog="${prog//[[:cntrl:]]/ }"
|
|
98
|
+
# `builtin command`: a shell function named `date` must not write this field.
|
|
99
|
+
stamp="$(builtin command date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null)"
|
|
100
|
+
stamp="${stamp//[[:cntrl:]]/ }"
|
|
101
|
+
# `builtin printf`: a shell function named printf could report success and write nothing.
|
|
102
|
+
if builtin printf '%s\t%s\t%s\t%s\n' "${stamp:-<unknown>}" "$host" "$prog" \
|
|
103
|
+
"${first:-<undefined>}" >> "$state/shell-shadow.log" 2>/dev/null; then
|
|
104
|
+
_agent_launch_shadow_noted[$host]=1
|
|
105
|
+
fi
|
|
106
|
+
return 0
|
|
39
107
|
}
|
|
40
108
|
|
|
41
|
-
|
|
42
|
-
|
|
109
|
+
_agent_launch_reassert() {
|
|
110
|
+
setopt localoptions noksharrays no_err_return no_err_exit
|
|
111
|
+
local host foreign entry
|
|
112
|
+
local -a shadowed
|
|
113
|
+
for host in claude codex; do
|
|
114
|
+
foreign=""
|
|
115
|
+
# Existence, not non-emptiness: `alias claude=''` is a shadow that erases the command
|
|
116
|
+
# word. Global aliases live in $galiases, not $aliases; `unalias` removes either.
|
|
117
|
+
if (( ${+aliases[$host]} )); then
|
|
118
|
+
foreign="alias $host=${aliases[$host]}"
|
|
119
|
+
elif (( ${+galiases[$host]} )); then
|
|
120
|
+
foreign="alias -g $host=${galiases[$host]}"
|
|
121
|
+
elif [[ "${functions[$host]-}" != "${_agent_launch_body[$host]}" ]]; then
|
|
122
|
+
foreign="${functions[$host]-<undefined>}"
|
|
123
|
+
fi
|
|
124
|
+
[[ -n "$foreign" ]] && shadowed+=("${host}"$'\t'"${foreign}")
|
|
125
|
+
done
|
|
126
|
+
(( $#shadowed )) || return 0
|
|
127
|
+
# Repair first, then record: a failure to write evidence must never leave the
|
|
128
|
+
# foreign definition in place for the command about to run.
|
|
129
|
+
_agent_launch_define
|
|
130
|
+
for entry in "${shadowed[@]}"; do
|
|
131
|
+
_agent_launch_note_shadow "${entry%%$'\t'*}" "${entry#*$'\t'}"
|
|
132
|
+
done
|
|
133
|
+
return 0
|
|
43
134
|
}
|
|
135
|
+
# Registered on precmd as well: a tool that redefines the names in a preexec that runs
|
|
136
|
+
# after ours wins for that command, but its definition is still in place when the next
|
|
137
|
+
# prompt is drawn — precmd is where that shadow is observed and logged, so "recorded, not
|
|
138
|
+
# fought" holds for the case the preexec pass cannot see.
|
|
139
|
+
autoload -Uz add-zsh-hook
|
|
140
|
+
add-zsh-hook -d preexec _agent_launch_reassert 2>/dev/null
|
|
141
|
+
add-zsh-hook -d precmd _agent_launch_reassert 2>/dev/null
|
|
142
|
+
add-zsh-hook preexec _agent_launch_reassert
|
|
143
|
+
add-zsh-hook precmd _agent_launch_reassert
|
|
144
|
+
|
|
145
|
+
(( _agent_launch_aliases_were )) && setopt aliases
|
|
146
|
+
unset _agent_launch_aliases_were
|