Skip to content

Commit 3e03f3a

Browse files
committed
Prepare local install release updates
1 parent 45bd96c commit 3e03f3a

4 files changed

Lines changed: 96 additions & 39 deletions

File tree

Docs/INSTALLATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ git pull --ff-only
305305
./scripts/install_local.sh --prefix "$HOME/Library/Application Support/AgenticSecrets/LocalInstall" --load
306306
```
307307

308-
The installer replaces the app bundle, refreshes command symlinks, validates the package, and rewrites the install manifest.
308+
The installer stops any running Agentic Secrets UI before replacing the app bundle, refreshes command symlinks, validates the package, rewrites the install manifest, restarts the broker daemon when it was already loaded, and reopens the installed UI copy unless `--no-open` is used.
309309

310310
## Uninstall
311311

Docs/OPERATIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Install from the current checkout:
3535
./scripts/install_local.sh --prefix "$HOME/Library/Application Support/AgenticSecrets/LocalInstall"
3636
```
3737

38-
Update by running the install command again from the desired commit. The script rebuilds, ad-hoc signs, validates, copies the app bundle, refreshes command symlinks, rewrites the install manifest, waits for broker IPC health when loading the LaunchAgent, and opens the installed app when using the default user-local prefix. Use `--no-open` for scripted updates.
38+
Update by running the install command again from the desired commit. The script rebuilds, ad-hoc signs, validates, stops any running Agentic Secrets UI, copies the app bundle, refreshes command symlinks, rewrites the install manifest, restarts the broker daemon when it was already loaded or `--load` is passed, waits for broker IPC health after restart, and opens the installed app when using the default user-local prefix or when the UI was running before the update. Use `--no-open` for scripted updates.
3939

4040
Smoke-test installed IPC:
4141

Sources/App/Views/ManagementViews.swift

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ struct CLISecretsView: View {
6565
@State private var pendingUnregister: CLIRegistrationSummary?
6666
@State private var deleteSecrets = false
6767
@State private var showingPolicyEditor = false
68-
@State private var editingCLIName: String?
6968

7069
var body: some View {
7170
ControlPlanePageFrame(
@@ -87,9 +86,14 @@ struct CLISecretsView: View {
8786
} else if store.filteredCLIRegistrations.isEmpty {
8887
NoMatchingCLIView(store: store)
8988
} else {
90-
CLIRegistrationTable(store: store) { cliName in
91-
store.selectedCLI = cliName
92-
editingCLIName = cliName
89+
HSplitView {
90+
CLIRegistrationTable(store: store)
91+
.frame(minWidth: 560, idealWidth: 700)
92+
CLIRegistrationDetail(
93+
store: store,
94+
pendingUnregister: $pendingUnregister
95+
)
96+
.frame(minWidth: 460)
9397
}
9498
.frame(minHeight: 460)
9599
}
@@ -98,16 +102,6 @@ struct CLISecretsView: View {
98102
CLIDeliveryPolicyEditorSheet(store: store)
99103
.frame(width: 900, height: 720)
100104
}
101-
.sheet(isPresented: Binding(
102-
get: { editingCLIName != nil },
103-
set: { if !$0 { editingCLIName = nil } }
104-
)) {
105-
CLIRegistrationEditorSheet(
106-
store: store,
107-
pendingUnregister: $pendingUnregister
108-
)
109-
.frame(width: 760, height: 760)
110-
}
111105
.confirmationDialog("Unregister CLI?", isPresented: Binding(
112106
get: { pendingUnregister != nil },
113107
set: {
@@ -205,7 +199,6 @@ private struct CLIDeliveryPolicyMetric: View {
205199

206200
private struct CLIRegistrationTable: View {
207201
@Bindable var store: ControlPlaneStore
208-
var edit: (String) -> Void
209202

210203
var body: some View {
211204
Table(store.filteredCLIRegistrations, selection: $store.selectedCLI) {
@@ -254,15 +247,16 @@ private struct CLIRegistrationTable: View {
254247

255248
TableColumn("") { item in
256249
Button {
257-
edit(item.name)
250+
store.selectedCLI = item.name
258251
} label: {
259-
Label("Edit", systemImage: "slider.horizontal.3")
252+
Label("Details", systemImage: "sidebar.right")
253+
.labelStyle(.iconOnly)
260254
}
261255
.buttonStyle(.borderless)
262-
.help("Edit delivery settings for \(item.name)")
263-
.accessibilityLabel("Edit \(item.name)")
256+
.help("Show details for \(item.name)")
257+
.accessibilityLabel("Show details for \(item.name)")
264258
}
265-
.width(min: 86, ideal: 96)
259+
.width(44)
266260
}
267261
.accessibilityLabel("Registered CLI delivery table")
268262
}
@@ -272,18 +266,6 @@ private struct CLIRegistrationTable: View {
272266
}
273267
}
274268

275-
private struct CLIRegistrationEditorSheet: View {
276-
@Bindable var store: ControlPlaneStore
277-
@Binding var pendingUnregister: CLIRegistrationSummary?
278-
279-
var body: some View {
280-
CLIRegistrationDetail(
281-
store: store,
282-
pendingUnregister: $pendingUnregister
283-
)
284-
}
285-
}
286-
287269
private struct CLIDeliveryPolicyEditorSheet: View {
288270
@Bindable var store: ControlPlaneStore
289271
@Environment(\.dismiss) private var dismiss

scripts/install_local.sh

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ SOCKET_DIR="/tmp/agentic-secrets-$(id -u)"
6666
SOCKET_PATH="$SOCKET_DIR/core.sock"
6767
LAUNCH_DIR="$PREFIX/Library/LaunchAgents"
6868
MANIFEST_PATH="$STATE_DIR/install-manifest.json"
69+
BROKER_LABEL="com.agenticsecrets.broker"
70+
CORE_PLIST="$LAUNCH_DIR/$BROKER_LABEL.plist"
6971

7072
bundle_id_at() {
7173
[ -d "$1" ] || return 1
@@ -90,6 +92,75 @@ remove_managed_app_bundle() {
9092
exit 73
9193
}
9294

95+
running_ui_pids() {
96+
/usr/bin/pgrep -x "$APP_EXECUTABLE_NAME" 2>/dev/null || true
97+
}
98+
99+
wait_for_ui_exit() {
100+
attempt=1
101+
while [ "$attempt" -le 25 ]; do
102+
if [ -z "$(running_ui_pids)" ]; then
103+
return 0
104+
fi
105+
sleep 0.2
106+
attempt=$((attempt + 1))
107+
done
108+
return 1
109+
}
110+
111+
terminate_running_ui() {
112+
pids="$(running_ui_pids)"
113+
[ -n "$pids" ] || return 1
114+
115+
printf 'Stopping running Agentic Secrets app before replacing it...\n'
116+
/usr/bin/osascript -e "tell application id \"$BUNDLE_ID\" to quit" >/dev/null 2>&1 || true
117+
if wait_for_ui_exit; then
118+
return 0
119+
fi
120+
121+
pids="$(running_ui_pids)"
122+
if [ -n "$pids" ]; then
123+
# shellcheck disable=SC2086
124+
/bin/kill -TERM $pids >/dev/null 2>&1 || true
125+
fi
126+
if wait_for_ui_exit; then
127+
return 0
128+
fi
129+
130+
pids="$(running_ui_pids)"
131+
if [ -n "$pids" ]; then
132+
printf 'Agentic Secrets app did not exit cleanly; forcing shutdown.\n'
133+
# shellcheck disable=SC2086
134+
/bin/kill -KILL $pids >/dev/null 2>&1 || true
135+
fi
136+
wait_for_ui_exit || true
137+
return 0
138+
}
139+
140+
broker_is_loaded() {
141+
launchctl print "gui/$(id -u)/$BROKER_LABEL" >/dev/null 2>&1
142+
}
143+
144+
bootout_existing_broker() {
145+
if [ -f "$CORE_PLIST" ]; then
146+
launchctl bootout "gui/$(id -u)" "$CORE_PLIST" >/dev/null 2>&1 || true
147+
else
148+
launchctl bootout "gui/$(id -u)/$BROKER_LABEL" >/dev/null 2>&1 || true
149+
fi
150+
}
151+
152+
UI_WAS_RUNNING=0
153+
if terminate_running_ui; then
154+
UI_WAS_RUNNING=1
155+
fi
156+
157+
BROKER_WAS_LOADED=0
158+
if broker_is_loaded; then
159+
BROKER_WAS_LOADED=1
160+
printf 'Stopping running broker daemon before replacing it...\n'
161+
bootout_existing_broker
162+
fi
163+
93164
remove_managed_app_bundle "$APP_DEST"
94165
remove_managed_app_bundle "$LEGACY_APP_DEST"
95166
mkdir -p "$(dirname "$APP_DEST")" "$BIN_DIR" "$STATE_DIR" "$RUN_DIR" "$SOCKET_DIR" "$LAUNCH_DIR"
@@ -100,7 +171,6 @@ for executable in AgenticSecrets agentic-secrets agentic-secrets-shim agentic-se
100171
ln -sf "$APP_DEST/Contents/MacOS/$executable" "$BIN_DIR/$executable"
101172
done
102173

103-
CORE_PLIST="$LAUNCH_DIR/com.agenticsecrets.broker.plist"
104174
cat >"$CORE_PLIST" <<PLIST
105175
<?xml version="1.0" encoding="UTF-8"?>
106176
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -244,8 +314,10 @@ if [ "$CONFIGURE_SHELL" -eq 1 ]; then
244314
fi
245315

246316
DAEMON_READY=0
247-
if [ "$LOAD_LAUNCHD" -eq 1 ]; then
248-
launchctl bootout "gui/$(id -u)" "$CORE_PLIST" >/dev/null 2>&1 || true
317+
DAEMON_START_REQUESTED=0
318+
if [ "$LOAD_LAUNCHD" -eq 1 ] || [ "$BROKER_WAS_LOADED" -eq 1 ]; then
319+
DAEMON_START_REQUESTED=1
320+
bootout_existing_broker
249321
launchctl bootstrap "gui/$(id -u)" "$CORE_PLIST"
250322
printf 'Waiting for broker daemon...\n'
251323
if wait_for_daemon_health; then
@@ -256,9 +328,12 @@ if [ "$LOAD_LAUNCHD" -eq 1 ]; then
256328
fi
257329
fi
258330

259-
if [ "$PREFIX" != "$DEFAULT_PREFIX" ] && [ "$OPEN_EXPLICIT" -eq 0 ]; then
331+
if [ "$PREFIX" != "$DEFAULT_PREFIX" ] && [ "$OPEN_EXPLICIT" -eq 0 ] && [ "$UI_WAS_RUNNING" -eq 0 ]; then
260332
OPEN_APP=0
261333
fi
334+
if [ "$UI_WAS_RUNNING" -eq 1 ] && [ "$OPEN_EXPLICIT" -eq 0 ]; then
335+
OPEN_APP=1
336+
fi
262337

263338
printf '%s\n' "$PREFIX"
264339
printf '\nInstalled Agentic Secrets app:\n %s\n' "$APP_DEST"
@@ -279,7 +354,7 @@ NEXT_STEPS
279354
fi
280355
fi
281356

282-
if [ "$OPEN_APP" -eq 1 ] && [ "$LOAD_LAUNCHD" -eq 1 ] && [ "$DAEMON_READY" -eq 0 ]; then
357+
if [ "$OPEN_APP" -eq 1 ] && [ "$DAEMON_START_REQUESTED" -eq 1 ] && [ "$DAEMON_READY" -eq 0 ]; then
283358
OPEN_APP=0
284359
printf '\nBroker daemon did not become reachable yet; leaving the app closed.\n'
285360
printf 'Check daemon status with:\n launchctl print "gui/%s/com.agenticsecrets.broker"\n' "$(id -u)"

0 commit comments

Comments
 (0)