agent-director 0.4.0 → 0.4.2

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.
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env bash
2
+ # uninstall.sh — reverse an agent-director install.
3
+ #
4
+ # Per SRD §16.2. By default:
5
+ # - Remove the two help hook entries from ~/.claude/settings.json
6
+ # (preserving any other user hooks).
7
+ # - Remove the canonical binary and any `.prior` rollback snapshot
8
+ # under ~/.agent-director/bin/.
9
+ # - Remove the PATH symlink (if found at any of the standard
10
+ # locations or at --symlink-dir).
11
+ # - Leave ~/.agent-director/ intact (the operator may want to
12
+ # keep their templates / state.db history).
13
+ #
14
+ # Flags:
15
+ # --purge Also rm -rf ~/.agent-director (templates +
16
+ # state.db). Requires --force or an interactive
17
+ # confirmation.
18
+ # --force Skip the --purge confirmation prompt.
19
+ # --mcp-also Also run `claude mcp remove agent-director`.
20
+ # --symlink-dir <dir> Look for the PATH symlink at <dir>; default
21
+ # is ~/.local/bin.
22
+
23
+ set -euo pipefail
24
+
25
+ readonly DEFAULT_INSTALL_ROOT="${HOME}/.agent-director"
26
+ readonly DEFAULT_BIN_DIR="${DEFAULT_INSTALL_ROOT}/bin"
27
+ readonly DEFAULT_SETTINGS_PATH="${HOME}/.claude/settings.json"
28
+
29
+ PURGE=0
30
+ FORCE=0
31
+ MCP_ALSO=0
32
+ SYMLINK_DIR="${HOME}/.local/bin"
33
+
34
+ while [[ $# -gt 0 ]]; do
35
+ case "$1" in
36
+ --purge) PURGE=1; shift ;;
37
+ --force) FORCE=1; shift ;;
38
+ --mcp-also) MCP_ALSO=1; shift ;;
39
+ --symlink-dir) SYMLINK_DIR="$2"; shift 2 ;;
40
+ -h|--help)
41
+ sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'
42
+ exit 0 ;;
43
+ *)
44
+ echo "uninstall.sh: unknown flag: $1" >&2
45
+ exit 2 ;;
46
+ esac
47
+ done
48
+
49
+ # --------------------------------------------------------------------
50
+ # Remove hook entries from ~/.claude/settings.json.
51
+ # Match by command suffix " help" + path prefix matching the install
52
+ # root, so the script only removes ITS entries — other user hooks
53
+ # survive verbatim.
54
+ # --------------------------------------------------------------------
55
+
56
+ if [[ -f "$DEFAULT_SETTINGS_PATH" ]]; then
57
+ if ! command -v jq >/dev/null 2>&1; then
58
+ echo "uninstall.sh: jq is required to safely edit settings.json" >&2
59
+ exit 2
60
+ fi
61
+ existing=$(<"$DEFAULT_SETTINGS_PATH")
62
+ if ! printf '%s' "$existing" | jq empty >/dev/null 2>&1; then
63
+ echo "uninstall.sh: ~/.claude/settings.json is not valid JSON; leaving it alone" >&2
64
+ else
65
+ new=$(printf '%s' "$existing" | jq \
66
+ --arg prefix "${DEFAULT_BIN_DIR}/agent-director" '
67
+ .hooks //= {}
68
+ | .hooks.SessionStart //= []
69
+ | .hooks.SessionEnd //= []
70
+ | .hooks.SessionStart |= [
71
+ .[] | select(
72
+ (.hooks | type) != "array"
73
+ or all(.hooks[]?; (.command // "") | startswith($prefix) | not)
74
+ )
75
+ ]
76
+ | .hooks.SessionEnd |= [
77
+ .[] | select(
78
+ (.hooks | type) != "array"
79
+ or all(.hooks[]?; (.command // "") | startswith($prefix) | not)
80
+ )
81
+ ]
82
+ ')
83
+ # Backup-before-edit (symmetric with install.sh) so a regressed
84
+ # jq filter is recoverable from a timestamped .bak.
85
+ backup_settings="${DEFAULT_SETTINGS_PATH}.bak.$(date +%Y%m%d-%H%M%S)"
86
+ cp -f "$DEFAULT_SETTINGS_PATH" "$backup_settings"
87
+ tmp="${DEFAULT_SETTINGS_PATH}.new"
88
+ printf '%s\n' "$new" > "$tmp"
89
+ mv -f "$tmp" "$DEFAULT_SETTINGS_PATH"
90
+ echo "uninstall.sh: backed up prior settings to $backup_settings"
91
+ echo "uninstall.sh: removed help hook entries from $DEFAULT_SETTINGS_PATH"
92
+ fi
93
+ fi
94
+
95
+ # --------------------------------------------------------------------
96
+ # Reverse install.sh's defaults.inject_help_hook merge: drop that key
97
+ # from config.toml. If [defaults] is left empty (no other keys, only
98
+ # blank lines or comments), drop the section header too. Symmetric
99
+ # with install.sh's Q4=yes config merge.
100
+ # --------------------------------------------------------------------
101
+
102
+ CONFIG_TOML="${DEFAULT_INSTALL_ROOT}/config.toml"
103
+ if [[ -f "$CONFIG_TOML" ]]; then
104
+ cleaned=$(awk '
105
+ function flush_defaults() {
106
+ has_content = 0
107
+ for (i = 1; i <= n; i++) {
108
+ stripped = lines[i]
109
+ sub(/^[[:space:]]+/, "", stripped)
110
+ if (stripped != "" && stripped !~ /^#/) {
111
+ has_content = 1
112
+ break
113
+ }
114
+ }
115
+ if (has_content) {
116
+ print header
117
+ for (i = 1; i <= n; i++) print lines[i]
118
+ }
119
+ delete lines
120
+ n = 0
121
+ header = ""
122
+ }
123
+ BEGIN { in_defaults = 0; n = 0; header = "" }
124
+ /^\[/ {
125
+ if (in_defaults) {
126
+ flush_defaults()
127
+ in_defaults = 0
128
+ }
129
+ if ($0 ~ /^\[defaults\][[:space:]]*$/) {
130
+ in_defaults = 1
131
+ header = $0
132
+ next
133
+ }
134
+ print
135
+ next
136
+ }
137
+ in_defaults {
138
+ if ($0 ~ /^[[:space:]]*inject_help_hook[[:space:]]*=/) {
139
+ next
140
+ }
141
+ lines[++n] = $0
142
+ next
143
+ }
144
+ { print }
145
+ END {
146
+ if (in_defaults) flush_defaults()
147
+ }
148
+ ' "$CONFIG_TOML")
149
+ original=$(<"$CONFIG_TOML")
150
+ if [[ "$cleaned" != "$original" ]]; then
151
+ backup_cfg="${CONFIG_TOML}.bak.$(date +%Y%m%d-%H%M%S)"
152
+ cp -f "$CONFIG_TOML" "$backup_cfg"
153
+ tmp_cfg="${CONFIG_TOML}.new"
154
+ printf '%s\n' "$cleaned" > "$tmp_cfg"
155
+ mv -f "$tmp_cfg" "$CONFIG_TOML"
156
+ echo "uninstall.sh: cleared inject_help_hook from $CONFIG_TOML (backup $backup_cfg)"
157
+ fi
158
+ fi
159
+
160
+ # --------------------------------------------------------------------
161
+ # Remove binaries (canonical + .prior snapshot + any legacy
162
+ # versioned-binary siblings from pre-b.43y installs).
163
+ # --------------------------------------------------------------------
164
+
165
+ if [[ -d "$DEFAULT_BIN_DIR" ]]; then
166
+ for f in "$DEFAULT_BIN_DIR"/agent-director "$DEFAULT_BIN_DIR"/agent-director.*; do
167
+ [[ -e "$f" || -L "$f" ]] || continue
168
+ rm -f "$f"
169
+ done
170
+ echo "uninstall.sh: removed binaries under $DEFAULT_BIN_DIR"
171
+ fi
172
+
173
+ # --------------------------------------------------------------------
174
+ # Remove PATH symlink (if any).
175
+ # --------------------------------------------------------------------
176
+
177
+ if [[ -L "${SYMLINK_DIR}/agent-director" ]]; then
178
+ rm -f "${SYMLINK_DIR}/agent-director"
179
+ echo "uninstall.sh: removed symlink ${SYMLINK_DIR}/agent-director"
180
+ fi
181
+
182
+ # --------------------------------------------------------------------
183
+ # Optional MCP deregistration.
184
+ # --------------------------------------------------------------------
185
+
186
+ if [[ "$MCP_ALSO" -eq 1 ]]; then
187
+ if command -v claude >/dev/null 2>&1; then
188
+ claude mcp remove agent-director 2>/dev/null || true
189
+ echo "uninstall.sh: deregistered agent-director from MCP"
190
+ fi
191
+ fi
192
+
193
+ # --------------------------------------------------------------------
194
+ # --purge: full directory removal.
195
+ # --------------------------------------------------------------------
196
+
197
+ if [[ "$PURGE" -eq 1 ]]; then
198
+ if [[ "$FORCE" -eq 0 ]]; then
199
+ printf "uninstall.sh: --purge will rm -rf %s — proceed? [y/N] " "$DEFAULT_INSTALL_ROOT"
200
+ read -r answer
201
+ case "$answer" in
202
+ y|Y|yes|YES) ;;
203
+ *) echo "uninstall.sh: --purge aborted"; exit 0 ;;
204
+ esac
205
+ fi
206
+ rm -rf "$DEFAULT_INSTALL_ROOT"
207
+ echo "uninstall.sh: purged $DEFAULT_INSTALL_ROOT"
208
+ fi
209
+
210
+ echo "uninstall.sh: done"