@shakudo/opencode-mattermost-control 0.3.45
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/.opencode/command/mattermost-connect.md +5 -0
- package/.opencode/command/mattermost-disconnect.md +5 -0
- package/.opencode/command/mattermost-monitor.md +12 -0
- package/.opencode/command/mattermost-status.md +5 -0
- package/.opencode/command/speckit.analyze.md +184 -0
- package/.opencode/command/speckit.checklist.md +294 -0
- package/.opencode/command/speckit.clarify.md +181 -0
- package/.opencode/command/speckit.constitution.md +82 -0
- package/.opencode/command/speckit.implement.md +135 -0
- package/.opencode/command/speckit.plan.md +89 -0
- package/.opencode/command/speckit.specify.md +258 -0
- package/.opencode/command/speckit.tasks.md +137 -0
- package/.opencode/command/speckit.taskstoissues.md +30 -0
- package/.opencode/plugin/mattermost-control/event-handlers/compaction.ts +61 -0
- package/.opencode/plugin/mattermost-control/event-handlers/file.ts +36 -0
- package/.opencode/plugin/mattermost-control/event-handlers/index.ts +14 -0
- package/.opencode/plugin/mattermost-control/event-handlers/message.ts +124 -0
- package/.opencode/plugin/mattermost-control/event-handlers/permission.ts +34 -0
- package/.opencode/plugin/mattermost-control/event-handlers/question.ts +92 -0
- package/.opencode/plugin/mattermost-control/event-handlers/session.ts +100 -0
- package/.opencode/plugin/mattermost-control/event-handlers/todo.ts +33 -0
- package/.opencode/plugin/mattermost-control/event-handlers/tool.ts +76 -0
- package/.opencode/plugin/mattermost-control/formatters.ts +202 -0
- package/.opencode/plugin/mattermost-control/index.ts +964 -0
- package/.opencode/plugin/mattermost-control/package.json +12 -0
- package/.opencode/plugin/mattermost-control/state.ts +180 -0
- package/.opencode/plugin/mattermost-control/timers.ts +96 -0
- package/.opencode/plugin/mattermost-control/tools/connect.ts +563 -0
- package/.opencode/plugin/mattermost-control/tools/file.ts +41 -0
- package/.opencode/plugin/mattermost-control/tools/index.ts +12 -0
- package/.opencode/plugin/mattermost-control/tools/monitor.ts +183 -0
- package/.opencode/plugin/mattermost-control/tools/schedule.ts +253 -0
- package/.opencode/plugin/mattermost-control/tools/session.ts +120 -0
- package/.opencode/plugin/mattermost-control/types.ts +107 -0
- package/LICENSE +21 -0
- package/README.md +1280 -0
- package/opencode-shared +359 -0
- package/opencode-shared-restart +495 -0
- package/opencode-shared-stop +90 -0
- package/package.json +65 -0
- package/src/clients/mattermost-client.ts +221 -0
- package/src/clients/websocket-client.ts +199 -0
- package/src/command-handler.ts +1035 -0
- package/src/config.ts +170 -0
- package/src/context-builder.ts +309 -0
- package/src/file-completion-handler.ts +521 -0
- package/src/file-handler.ts +242 -0
- package/src/guest-approval-handler.ts +223 -0
- package/src/logger.ts +73 -0
- package/src/merge-handler.ts +335 -0
- package/src/message-router.ts +151 -0
- package/src/models/index.ts +197 -0
- package/src/models/routing.ts +50 -0
- package/src/models/thread-mapping.ts +40 -0
- package/src/monitor-service.ts +222 -0
- package/src/notification-service.ts +118 -0
- package/src/opencode-session-registry.ts +370 -0
- package/src/persistence/team-store.ts +396 -0
- package/src/persistence/thread-mapping-store.ts +258 -0
- package/src/question-handler.ts +401 -0
- package/src/reaction-handler.ts +111 -0
- package/src/response-streamer.ts +364 -0
- package/src/scheduler/schedule-store.ts +261 -0
- package/src/scheduler/scheduler-service.ts +349 -0
- package/src/session-manager.ts +142 -0
- package/src/session-ownership-handler.ts +253 -0
- package/src/status-indicator.ts +279 -0
- package/src/thread-manager.ts +231 -0
- package/src/todo-manager.ts +162 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# opencode-shared-restart - Restart the shared OpenCode server with optional plugin version change
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./opencode-shared-restart [OPTIONS]
|
|
7
|
+
#
|
|
8
|
+
# Options:
|
|
9
|
+
# -v, --version VERSION Update Mattermost plugin to specified version before restart
|
|
10
|
+
# -r, --rollback VERSION Same as --version (alias for clarity when reverting)
|
|
11
|
+
# -c, --current Show current installed plugin version and exit
|
|
12
|
+
# -l, --list List recent available versions and exit
|
|
13
|
+
# -s, --status Show status of last restart operation
|
|
14
|
+
# -h, --help Show this help message
|
|
15
|
+
#
|
|
16
|
+
# Examples:
|
|
17
|
+
# ./opencode-shared-restart # Restart with current plugin version
|
|
18
|
+
# ./opencode-shared-restart -v 0.2.55 # Update to v0.2.55 and restart
|
|
19
|
+
# ./opencode-shared-restart --rollback 0.2.54 # Rollback to v0.2.54 and restart
|
|
20
|
+
# ./opencode-shared-restart --current # Show current version
|
|
21
|
+
# ./opencode-shared-restart --list # Show available versions
|
|
22
|
+
# ./opencode-shared-restart --status # Check last restart result
|
|
23
|
+
#
|
|
24
|
+
# Environment variables:
|
|
25
|
+
# OPENCODE_CONFIG_DIR - OpenCode config directory (default: ~/.config/opencode)
|
|
26
|
+
# VERDACCIO_REGISTRY - Verdaccio registry URL (default: http://verdaccio.hyperplane-verdaccio.svc.cluster.local:4873)
|
|
27
|
+
# OPENCODE_SERVER_PORT - Server port (default: 4096)
|
|
28
|
+
# OPENCODE_WORKING_DIR - Working directory for server (default: current directory)
|
|
29
|
+
#
|
|
30
|
+
# Note: This script runs the restart in a detached process so it survives
|
|
31
|
+
# the OpenCode server restart. Check --status or the log file for results.
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
set -euo pipefail
|
|
35
|
+
|
|
36
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
37
|
+
CONFIG_DIR="${OPENCODE_CONFIG_DIR:-$HOME/.config/opencode}"
|
|
38
|
+
WORKING_DIR="${OPENCODE_WORKING_DIR:-$(pwd)}"
|
|
39
|
+
REGISTRY="${VERDACCIO_REGISTRY:-http://verdaccio.hyperplane-verdaccio.svc.cluster.local:4873}"
|
|
40
|
+
PLUGIN_NAME="opencode-mattermost-control"
|
|
41
|
+
PORT="${OPENCODE_SERVER_PORT:-4096}"
|
|
42
|
+
|
|
43
|
+
PIDFILE="/tmp/opencode-server.pid"
|
|
44
|
+
SUPERVISOR_PIDFILE="/tmp/opencode-server.supervisor.pid"
|
|
45
|
+
STOP_FLAG="/tmp/opencode-server.stop"
|
|
46
|
+
LOCKDIR="/tmp/opencode-server.supervisor.lock"
|
|
47
|
+
|
|
48
|
+
RESTART_LOG="/tmp/opencode-restart.log"
|
|
49
|
+
RESTART_STATUS_FILE="/tmp/opencode-restart.status"
|
|
50
|
+
RESTART_PID_FILE="/tmp/opencode-restart.pid"
|
|
51
|
+
|
|
52
|
+
RED='\033[0;31m'
|
|
53
|
+
GREEN='\033[0;32m'
|
|
54
|
+
YELLOW='\033[1;33m'
|
|
55
|
+
BLUE='\033[0;34m'
|
|
56
|
+
NC='\033[0m'
|
|
57
|
+
|
|
58
|
+
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
|
59
|
+
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
60
|
+
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
|
61
|
+
log_step() { echo -e "${BLUE}[STEP]${NC} $*"; }
|
|
62
|
+
|
|
63
|
+
log_file() { echo "[$(date -Iseconds)] $*" >> "$RESTART_LOG"; }
|
|
64
|
+
|
|
65
|
+
show_help() {
|
|
66
|
+
head -35 "$0" | tail -33 | sed 's/^#//' | sed 's/^ //'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get_current_version() {
|
|
70
|
+
if [[ -f "$CONFIG_DIR/node_modules/$PLUGIN_NAME/package.json" ]]; then
|
|
71
|
+
grep '"version"' "$CONFIG_DIR/node_modules/$PLUGIN_NAME/package.json" | sed 's/.*"version": *"\([^"]*\)".*/\1/'
|
|
72
|
+
else
|
|
73
|
+
echo "not installed"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get_configured_version() {
|
|
78
|
+
if [[ -f "$CONFIG_DIR/package.json" ]]; then
|
|
79
|
+
grep "\"$PLUGIN_NAME\"" "$CONFIG_DIR/package.json" | sed 's/.*"'$PLUGIN_NAME'": *"\([^"]*\)".*/\1/' | tr -d '^~'
|
|
80
|
+
else
|
|
81
|
+
echo "not configured"
|
|
82
|
+
fi
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
list_versions() {
|
|
86
|
+
log_info "Fetching available versions from registry..."
|
|
87
|
+
local versions
|
|
88
|
+
versions=$(curl -s "$REGISTRY/$PLUGIN_NAME" 2>/dev/null | jq -r '.versions | keys[]' 2>/dev/null | sort -V | tail -10)
|
|
89
|
+
|
|
90
|
+
if [[ -z "$versions" ]]; then
|
|
91
|
+
log_error "Failed to fetch versions from registry"
|
|
92
|
+
return 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
local current
|
|
96
|
+
current=$(get_current_version)
|
|
97
|
+
|
|
98
|
+
echo ""
|
|
99
|
+
echo "Recent available versions:"
|
|
100
|
+
echo "=========================="
|
|
101
|
+
while IFS= read -r v; do
|
|
102
|
+
if [[ "$v" == "$current" ]]; then
|
|
103
|
+
echo -e " ${GREEN}$v${NC} (installed)"
|
|
104
|
+
else
|
|
105
|
+
echo " $v"
|
|
106
|
+
fi
|
|
107
|
+
done <<< "$versions"
|
|
108
|
+
echo ""
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
show_status() {
|
|
112
|
+
echo ""
|
|
113
|
+
if [[ -f "$RESTART_STATUS_FILE" ]]; then
|
|
114
|
+
echo "=== Last Restart Status ==="
|
|
115
|
+
cat "$RESTART_STATUS_FILE"
|
|
116
|
+
echo ""
|
|
117
|
+
else
|
|
118
|
+
echo "No restart status found."
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
if [[ -f "$RESTART_LOG" ]]; then
|
|
122
|
+
echo "=== Recent Restart Log ==="
|
|
123
|
+
tail -30 "$RESTART_LOG"
|
|
124
|
+
echo ""
|
|
125
|
+
echo "(Full log: $RESTART_LOG)"
|
|
126
|
+
else
|
|
127
|
+
echo "No restart log found."
|
|
128
|
+
fi
|
|
129
|
+
echo ""
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
update_plugin_version() {
|
|
133
|
+
local target_version="$1"
|
|
134
|
+
local current_version
|
|
135
|
+
current_version=$(get_current_version)
|
|
136
|
+
|
|
137
|
+
log_file "Updating plugin from v${current_version} to v${target_version}"
|
|
138
|
+
|
|
139
|
+
log_file "Updating package.json..."
|
|
140
|
+
cd "$CONFIG_DIR"
|
|
141
|
+
if [[ -f package.json ]]; then
|
|
142
|
+
jq ".dependencies[\"$PLUGIN_NAME\"] = \"$target_version\"" package.json > package.json.tmp
|
|
143
|
+
mv package.json.tmp package.json
|
|
144
|
+
else
|
|
145
|
+
log_file "ERROR: package.json not found in $CONFIG_DIR"
|
|
146
|
+
return 1
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
log_file "Clearing plugin cache..."
|
|
150
|
+
rm -rf "$CONFIG_DIR/node_modules/$PLUGIN_NAME"
|
|
151
|
+
rm -f "$CONFIG_DIR/bun.lock"
|
|
152
|
+
|
|
153
|
+
log_file "Installing plugin v${target_version}..."
|
|
154
|
+
if ! bun install --registry "$REGISTRY" >> "$RESTART_LOG" 2>&1; then
|
|
155
|
+
log_file "ERROR: Failed to install plugin"
|
|
156
|
+
return 1
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
local installed_version
|
|
160
|
+
installed_version=$(get_current_version)
|
|
161
|
+
if [[ "$installed_version" != "$target_version" ]]; then
|
|
162
|
+
log_file "ERROR: Version mismatch: expected $target_version, got $installed_version"
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
log_file "Plugin updated to v${installed_version}"
|
|
167
|
+
return 0
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
stop_opencode() {
|
|
171
|
+
log_file "Stopping OpenCode..."
|
|
172
|
+
|
|
173
|
+
touch "$STOP_FLAG"
|
|
174
|
+
|
|
175
|
+
if [[ -f "$SUPERVISOR_PIDFILE" ]]; then
|
|
176
|
+
local supervisor_pid
|
|
177
|
+
supervisor_pid=$(cat "$SUPERVISOR_PIDFILE" 2>/dev/null || true)
|
|
178
|
+
if [[ -n "${supervisor_pid:-}" ]] && kill -0 "$supervisor_pid" 2>/dev/null; then
|
|
179
|
+
log_file "Stopping supervisor (PID: ${supervisor_pid})..."
|
|
180
|
+
kill "$supervisor_pid" 2>/dev/null || true
|
|
181
|
+
sleep 0.5
|
|
182
|
+
kill -9 "$supervisor_pid" 2>/dev/null || true
|
|
183
|
+
fi
|
|
184
|
+
rm -f "$SUPERVISOR_PIDFILE"
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
[[ -d "$LOCKDIR" ]] && rmdir "$LOCKDIR" 2>/dev/null || true
|
|
188
|
+
|
|
189
|
+
if [[ -f "$PIDFILE" ]]; then
|
|
190
|
+
local pid
|
|
191
|
+
pid=$(cat "$PIDFILE" 2>/dev/null || true)
|
|
192
|
+
if [[ -n "${pid:-}" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
193
|
+
log_file "Stopping server (PID: ${pid})..."
|
|
194
|
+
kill "$pid" 2>/dev/null || true
|
|
195
|
+
sleep 1
|
|
196
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
197
|
+
fi
|
|
198
|
+
rm -f "$PIDFILE"
|
|
199
|
+
else
|
|
200
|
+
local pid
|
|
201
|
+
pid=$(lsof -ti :"$PORT" 2>/dev/null || true)
|
|
202
|
+
if [[ -n "${pid:-}" ]]; then
|
|
203
|
+
log_file "Stopping process on port ${PORT} (PID: ${pid})..."
|
|
204
|
+
kill "$pid" 2>/dev/null || true
|
|
205
|
+
sleep 1
|
|
206
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
sleep 2
|
|
211
|
+
log_file "OpenCode stopped"
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
start_opencode_server() {
|
|
215
|
+
log_file "Starting OpenCode server in directory: $WORKING_DIR"
|
|
216
|
+
|
|
217
|
+
rm -f "$STOP_FLAG"
|
|
218
|
+
|
|
219
|
+
cd "$WORKING_DIR"
|
|
220
|
+
nohup opencode serve --port "$PORT" >> /tmp/opencode-server.log 2>&1 &
|
|
221
|
+
local server_pid=$!
|
|
222
|
+
echo "$server_pid" > "$PIDFILE"
|
|
223
|
+
|
|
224
|
+
log_file "Server process started (PID: ${server_pid})"
|
|
225
|
+
return 0
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
verify_startup() {
|
|
229
|
+
local max_attempts=30
|
|
230
|
+
local attempt=0
|
|
231
|
+
|
|
232
|
+
log_file "Waiting for server to start..."
|
|
233
|
+
|
|
234
|
+
while [[ $attempt -lt $max_attempts ]]; do
|
|
235
|
+
if [[ -f "$PIDFILE" ]]; then
|
|
236
|
+
local pid
|
|
237
|
+
pid=$(cat "$PIDFILE" 2>/dev/null || true)
|
|
238
|
+
if [[ -n "${pid:-}" ]] && ! kill -0 "$pid" 2>/dev/null; then
|
|
239
|
+
log_file "ERROR: Server process died unexpectedly"
|
|
240
|
+
return 1
|
|
241
|
+
fi
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
if nc -z localhost "$PORT" 2>/dev/null; then
|
|
245
|
+
sleep 2
|
|
246
|
+
if nc -z localhost "$PORT" 2>/dev/null; then
|
|
247
|
+
log_file "Server is responding on port $PORT"
|
|
248
|
+
return 0
|
|
249
|
+
fi
|
|
250
|
+
fi
|
|
251
|
+
sleep 0.5
|
|
252
|
+
attempt=$((attempt + 1))
|
|
253
|
+
done
|
|
254
|
+
|
|
255
|
+
log_file "ERROR: Server failed to start within 15 seconds"
|
|
256
|
+
return 1
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
start_supervisor() {
|
|
260
|
+
log_file "Starting supervisor..."
|
|
261
|
+
|
|
262
|
+
if [[ -x "$SCRIPT_DIR/opencode-shared" ]]; then
|
|
263
|
+
nohup "$SCRIPT_DIR/opencode-shared" --supervise >> /tmp/opencode-server.supervisor.log 2>&1 &
|
|
264
|
+
elif command -v opencode-shared &>/dev/null; then
|
|
265
|
+
nohup opencode-shared --supervise >> /tmp/opencode-server.supervisor.log 2>&1 &
|
|
266
|
+
else
|
|
267
|
+
log_file "WARNING: opencode-shared not found, supervisor not started"
|
|
268
|
+
return 0
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
sleep 1
|
|
272
|
+
log_file "Supervisor started"
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
write_status() {
|
|
276
|
+
local status="$1"
|
|
277
|
+
local message="$2"
|
|
278
|
+
local version
|
|
279
|
+
version=$(get_current_version)
|
|
280
|
+
|
|
281
|
+
cat > "$RESTART_STATUS_FILE" << EOF
|
|
282
|
+
Status: $status
|
|
283
|
+
Time: $(date -Iseconds)
|
|
284
|
+
Plugin Version: $version
|
|
285
|
+
Working Directory: $WORKING_DIR
|
|
286
|
+
Message: $message
|
|
287
|
+
EOF
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
do_restart() {
|
|
291
|
+
local target_version="$1"
|
|
292
|
+
local previous_version="$2"
|
|
293
|
+
|
|
294
|
+
log_file "=========================================="
|
|
295
|
+
log_file "Starting restart process"
|
|
296
|
+
log_file "Previous version: $previous_version"
|
|
297
|
+
log_file "Target version: ${target_version:-same}"
|
|
298
|
+
log_file "Working directory: $WORKING_DIR"
|
|
299
|
+
log_file "=========================================="
|
|
300
|
+
|
|
301
|
+
stop_opencode
|
|
302
|
+
|
|
303
|
+
if [[ -n "$target_version" ]]; then
|
|
304
|
+
if ! update_plugin_version "$target_version"; then
|
|
305
|
+
log_file "Plugin update failed, attempting rollback to $previous_version"
|
|
306
|
+
|
|
307
|
+
if update_plugin_version "$previous_version"; then
|
|
308
|
+
log_file "Rolled back to $previous_version"
|
|
309
|
+
else
|
|
310
|
+
log_file "CRITICAL: Rollback failed!"
|
|
311
|
+
write_status "FAILED" "Plugin update failed and rollback failed. Manual intervention required."
|
|
312
|
+
return 1
|
|
313
|
+
fi
|
|
314
|
+
fi
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
local current_version
|
|
318
|
+
current_version=$(get_current_version)
|
|
319
|
+
log_file "Starting server with plugin v${current_version}"
|
|
320
|
+
|
|
321
|
+
if ! start_opencode_server; then
|
|
322
|
+
log_file "Failed to start server process"
|
|
323
|
+
write_status "FAILED" "Server process failed to start with v${current_version}"
|
|
324
|
+
return 1
|
|
325
|
+
fi
|
|
326
|
+
|
|
327
|
+
if ! verify_startup; then
|
|
328
|
+
log_file "Server not responding after startup"
|
|
329
|
+
|
|
330
|
+
if [[ -n "$target_version" && "$target_version" != "$previous_version" ]]; then
|
|
331
|
+
log_file "Attempting rollback to $previous_version"
|
|
332
|
+
|
|
333
|
+
stop_opencode
|
|
334
|
+
|
|
335
|
+
if update_plugin_version "$previous_version"; then
|
|
336
|
+
log_file "Rolled back to $previous_version, trying to start again"
|
|
337
|
+
|
|
338
|
+
if start_opencode_server && verify_startup; then
|
|
339
|
+
log_file "Rollback successful - running with v${previous_version}"
|
|
340
|
+
start_supervisor
|
|
341
|
+
write_status "ROLLBACK" "v${target_version} failed to start. Rolled back to v${previous_version}."
|
|
342
|
+
return 0
|
|
343
|
+
else
|
|
344
|
+
log_file "CRITICAL: Server won't start even after rollback!"
|
|
345
|
+
write_status "FAILED" "Server failed with v${target_version} and v${previous_version}. Manual intervention required."
|
|
346
|
+
return 1
|
|
347
|
+
fi
|
|
348
|
+
else
|
|
349
|
+
log_file "CRITICAL: Rollback failed!"
|
|
350
|
+
write_status "FAILED" "Server failed and rollback failed. Manual intervention required."
|
|
351
|
+
return 1
|
|
352
|
+
fi
|
|
353
|
+
else
|
|
354
|
+
write_status "FAILED" "Server failed to start with v${current_version}. Check /tmp/opencode-server.log"
|
|
355
|
+
return 1
|
|
356
|
+
fi
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
start_supervisor
|
|
360
|
+
|
|
361
|
+
log_file "=========================================="
|
|
362
|
+
log_file "Restart completed successfully"
|
|
363
|
+
log_file "Running version: $(get_current_version)"
|
|
364
|
+
log_file "=========================================="
|
|
365
|
+
|
|
366
|
+
write_status "SUCCESS" "Server running with v$(get_current_version)"
|
|
367
|
+
return 0
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
run_detached() {
|
|
371
|
+
local target_version="$1"
|
|
372
|
+
local previous_version
|
|
373
|
+
previous_version=$(get_current_version)
|
|
374
|
+
|
|
375
|
+
echo "$$" > "$RESTART_PID_FILE"
|
|
376
|
+
|
|
377
|
+
exec > "$RESTART_LOG" 2>&1
|
|
378
|
+
|
|
379
|
+
do_restart "$target_version" "$previous_version"
|
|
380
|
+
|
|
381
|
+
rm -f "$RESTART_PID_FILE"
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
main() {
|
|
385
|
+
local target_version=""
|
|
386
|
+
local show_current=false
|
|
387
|
+
local show_list=false
|
|
388
|
+
local show_status_flag=false
|
|
389
|
+
local run_detached_flag=false
|
|
390
|
+
|
|
391
|
+
while [[ $# -gt 0 ]]; do
|
|
392
|
+
case "$1" in
|
|
393
|
+
-v|--version|-r|--rollback)
|
|
394
|
+
target_version="$2"
|
|
395
|
+
shift 2
|
|
396
|
+
;;
|
|
397
|
+
-c|--current)
|
|
398
|
+
show_current=true
|
|
399
|
+
shift
|
|
400
|
+
;;
|
|
401
|
+
-l|--list)
|
|
402
|
+
show_list=true
|
|
403
|
+
shift
|
|
404
|
+
;;
|
|
405
|
+
-s|--status)
|
|
406
|
+
show_status_flag=true
|
|
407
|
+
shift
|
|
408
|
+
;;
|
|
409
|
+
--detached-run)
|
|
410
|
+
run_detached_flag=true
|
|
411
|
+
target_version="${2:-}"
|
|
412
|
+
shift
|
|
413
|
+
[[ -n "$target_version" ]] && shift
|
|
414
|
+
;;
|
|
415
|
+
--working-dir)
|
|
416
|
+
WORKING_DIR="$2"
|
|
417
|
+
shift 2
|
|
418
|
+
;;
|
|
419
|
+
-h|--help)
|
|
420
|
+
show_help
|
|
421
|
+
exit 0
|
|
422
|
+
;;
|
|
423
|
+
*)
|
|
424
|
+
log_error "Unknown option: $1"
|
|
425
|
+
show_help
|
|
426
|
+
exit 1
|
|
427
|
+
;;
|
|
428
|
+
esac
|
|
429
|
+
done
|
|
430
|
+
|
|
431
|
+
if $show_current; then
|
|
432
|
+
local current
|
|
433
|
+
current=$(get_current_version)
|
|
434
|
+
local configured
|
|
435
|
+
configured=$(get_configured_version)
|
|
436
|
+
echo "Installed version: $current"
|
|
437
|
+
echo "Configured version: $configured"
|
|
438
|
+
exit 0
|
|
439
|
+
fi
|
|
440
|
+
|
|
441
|
+
if $show_list; then
|
|
442
|
+
list_versions
|
|
443
|
+
exit 0
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
if $show_status_flag; then
|
|
447
|
+
show_status
|
|
448
|
+
exit 0
|
|
449
|
+
fi
|
|
450
|
+
|
|
451
|
+
if $run_detached_flag; then
|
|
452
|
+
run_detached "$target_version"
|
|
453
|
+
exit $?
|
|
454
|
+
fi
|
|
455
|
+
|
|
456
|
+
local previous_version
|
|
457
|
+
previous_version=$(get_current_version)
|
|
458
|
+
|
|
459
|
+
echo ""
|
|
460
|
+
log_info "OpenCode Shared Restart"
|
|
461
|
+
log_info "======================="
|
|
462
|
+
log_info "Current plugin version: $previous_version"
|
|
463
|
+
if [[ -n "$target_version" ]]; then
|
|
464
|
+
log_info "Target plugin version: $target_version"
|
|
465
|
+
fi
|
|
466
|
+
echo ""
|
|
467
|
+
|
|
468
|
+
log_info "Launching restart in background process..."
|
|
469
|
+
log_info "This will disconnect you from OpenCode temporarily."
|
|
470
|
+
log_info ""
|
|
471
|
+
log_info "Check restart status with:"
|
|
472
|
+
log_info " $0 --status"
|
|
473
|
+
log_info ""
|
|
474
|
+
log_info "Or view the log:"
|
|
475
|
+
log_info " tail -f $RESTART_LOG"
|
|
476
|
+
echo ""
|
|
477
|
+
|
|
478
|
+
> "$RESTART_LOG"
|
|
479
|
+
write_status "IN_PROGRESS" "Restart initiated at $(date -Iseconds)"
|
|
480
|
+
|
|
481
|
+
nohup "$0" --detached-run "$target_version" --working-dir "$WORKING_DIR" >> "$RESTART_LOG" 2>&1 &
|
|
482
|
+
local bg_pid=$!
|
|
483
|
+
|
|
484
|
+
log_info "Restart process started (PID: $bg_pid)"
|
|
485
|
+
log_info "Reconnect to OpenCode once restart completes."
|
|
486
|
+
|
|
487
|
+
sleep 2
|
|
488
|
+
|
|
489
|
+
if [[ -f "$RESTART_STATUS_FILE" ]]; then
|
|
490
|
+
echo ""
|
|
491
|
+
cat "$RESTART_STATUS_FILE"
|
|
492
|
+
fi
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
main "$@"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# opencode-shared-stop - Stop the shared OpenCode server and supervisor
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./opencode-shared-stop
|
|
7
|
+
#
|
|
8
|
+
# This script:
|
|
9
|
+
# 1. Creates a stop flag to prevent auto-restart
|
|
10
|
+
# 2. Stops the supervisor process
|
|
11
|
+
# 3. Stops the server process
|
|
12
|
+
# 4. Cleans up state files
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
set -e
|
|
16
|
+
|
|
17
|
+
PORT="${OPENCODE_SERVER_PORT:-4096}"
|
|
18
|
+
|
|
19
|
+
# State files (must match opencode-shared)
|
|
20
|
+
PIDFILE="/tmp/opencode-server.pid"
|
|
21
|
+
SUPERVISOR_PIDFILE="/tmp/opencode-server.supervisor.pid"
|
|
22
|
+
STOP_FLAG="/tmp/opencode-server.stop"
|
|
23
|
+
LOCKDIR="/tmp/opencode-server.supervisor.lock"
|
|
24
|
+
|
|
25
|
+
# Step 1: Create stop flag FIRST to prevent auto-restart
|
|
26
|
+
echo "Setting stop flag to prevent auto-restart..."
|
|
27
|
+
touch "$STOP_FLAG"
|
|
28
|
+
|
|
29
|
+
# Step 2: Stop supervisor if running
|
|
30
|
+
if [[ -f "$SUPERVISOR_PIDFILE" ]]; then
|
|
31
|
+
supervisor_pid=$(cat "$SUPERVISOR_PIDFILE" 2>/dev/null || true)
|
|
32
|
+
if [[ -n "${supervisor_pid:-}" ]] && kill -0 "$supervisor_pid" 2>/dev/null; then
|
|
33
|
+
echo "Stopping supervisor (PID: ${supervisor_pid})..."
|
|
34
|
+
kill "$supervisor_pid" 2>/dev/null || true
|
|
35
|
+
# Give it a moment to exit gracefully
|
|
36
|
+
sleep 0.5
|
|
37
|
+
# Force kill if still running
|
|
38
|
+
if kill -0 "$supervisor_pid" 2>/dev/null; then
|
|
39
|
+
kill -9 "$supervisor_pid" 2>/dev/null || true
|
|
40
|
+
fi
|
|
41
|
+
else
|
|
42
|
+
echo "Supervisor process not running (stale PID file)."
|
|
43
|
+
fi
|
|
44
|
+
rm -f "$SUPERVISOR_PIDFILE"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Clean up supervisor lock directory
|
|
48
|
+
if [[ -d "$LOCKDIR" ]]; then
|
|
49
|
+
rmdir "$LOCKDIR" 2>/dev/null || true
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Step 3: Stop server if running
|
|
53
|
+
if [[ -f "$PIDFILE" ]]; then
|
|
54
|
+
pid=$(cat "$PIDFILE" 2>/dev/null || true)
|
|
55
|
+
if [[ -n "${pid:-}" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
56
|
+
echo "Stopping OpenCode server (PID: ${pid})..."
|
|
57
|
+
kill "$pid" 2>/dev/null || true
|
|
58
|
+
# Wait for graceful shutdown
|
|
59
|
+
sleep 1
|
|
60
|
+
# Force kill if still running
|
|
61
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
62
|
+
echo "Server didn't stop gracefully, forcing..."
|
|
63
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
64
|
+
fi
|
|
65
|
+
echo "Server stopped."
|
|
66
|
+
else
|
|
67
|
+
echo "Server process not running (stale PID file)."
|
|
68
|
+
fi
|
|
69
|
+
rm -f "$PIDFILE"
|
|
70
|
+
else
|
|
71
|
+
# Try to find process by port as fallback
|
|
72
|
+
pid=$(lsof -ti :"$PORT" 2>/dev/null || true)
|
|
73
|
+
if [[ -n "${pid:-}" ]]; then
|
|
74
|
+
echo "Stopping process on port ${PORT} (PID: ${pid})..."
|
|
75
|
+
kill "$pid" 2>/dev/null || true
|
|
76
|
+
sleep 1
|
|
77
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
78
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
79
|
+
fi
|
|
80
|
+
echo "Server stopped."
|
|
81
|
+
else
|
|
82
|
+
echo "No OpenCode server running on port ${PORT}."
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Step 4: Clean up stop flag (optional - can leave for debugging)
|
|
87
|
+
# Uncomment next line to remove stop flag after stopping
|
|
88
|
+
# rm -f "$STOP_FLAG"
|
|
89
|
+
|
|
90
|
+
echo "Done. Stop flag left at ${STOP_FLAG} (will be cleared on next start)."
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shakudo/opencode-mattermost-control",
|
|
3
|
+
"version": "0.3.45",
|
|
4
|
+
"description": "OpenCode plugin for remote control via Mattermost DMs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": ".opencode/plugin/mattermost-control/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./.opencode/plugin/mattermost-control/index.ts",
|
|
9
|
+
"./plugin": "./.opencode/plugin/mattermost-control/index.ts"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
".opencode",
|
|
13
|
+
"src",
|
|
14
|
+
"opencode.json",
|
|
15
|
+
"README.md",
|
|
16
|
+
"opencode-shared",
|
|
17
|
+
"opencode-shared-stop",
|
|
18
|
+
"opencode-shared-restart"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"opencode-shared": "./opencode-shared",
|
|
22
|
+
"opencode-shared-stop": "./opencode-shared-stop",
|
|
23
|
+
"opencode-shared-restart": "./opencode-shared-restart"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "bun test",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "bun run typecheck"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"opencode",
|
|
32
|
+
"opencode-plugin",
|
|
33
|
+
"mattermost",
|
|
34
|
+
"remote-control",
|
|
35
|
+
"chat",
|
|
36
|
+
"ai",
|
|
37
|
+
"coding-assistant"
|
|
38
|
+
],
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/Shakudo-io/opencode-mattermost-plugin.git"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/Shakudo-io/opencode-mattermost-plugin#readme",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/Shakudo-io/opencode-mattermost-plugin/issues"
|
|
46
|
+
},
|
|
47
|
+
"author": "Shakudo <team@shakudo.io>",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@opencode-ai/plugin": "^1.1.25",
|
|
51
|
+
"node-cron": "^4.2.1",
|
|
52
|
+
"ws": "^8.18.0",
|
|
53
|
+
"zod": "^4.1.8"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.10.5",
|
|
57
|
+
"@types/node-cron": "^3.0.11",
|
|
58
|
+
"@types/ws": "^8.5.13",
|
|
59
|
+
"bun-types": "^1.3.6",
|
|
60
|
+
"typescript": "^5.7.2"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18.0.0"
|
|
64
|
+
}
|
|
65
|
+
}
|