@devrouter/cli 0.0.38 → 0.0.39
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 +7 -0
- package/bin/devrouter-process +97 -9
- package/dist/devrouter.js +2303 -469
- package/package.json +2 -1
- package/upgrade-prompts/0.0.39.md +48 -0
package/README.md
CHANGED
|
@@ -70,6 +70,13 @@ devrouter ensure .
|
|
|
70
70
|
devrouter exec . -- pnpm seed
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Managed repositories may define independent profiles for routed apps, optional
|
|
74
|
+
Compose capabilities, and repository-owned processes. Use
|
|
75
|
+
`devrouter ensure . --profile <name>` for a task-specific environment; native
|
|
76
|
+
Dev Container clients still see the full source configuration. Check
|
|
77
|
+
`devrouter status` or `devrouter doctor` when you need the desired, active, and
|
|
78
|
+
drift state.
|
|
79
|
+
|
|
73
80
|
Use devrouter lifecycle commands for managed environments. Raw `devpod up`,
|
|
74
81
|
`stop`, or `delete` bypass ownership locks and exact checkout validation.
|
|
75
82
|
|
package/bin/devrouter-process
CHANGED
|
@@ -5,6 +5,8 @@ usage() {
|
|
|
5
5
|
cat <<'EOF'
|
|
6
6
|
Usage:
|
|
7
7
|
devrouter-process ensure --name <name> --match <regex> [options] -- <command> [args...]
|
|
8
|
+
devrouter-process stop --name <name>
|
|
9
|
+
devrouter-process status --name <name>
|
|
8
10
|
|
|
9
11
|
Options:
|
|
10
12
|
--fingerprint <value> Runtime identity. Defaults to command, workspace, adapter, and safe allowlisted environment identity.
|
|
@@ -25,11 +27,16 @@ require_value() {
|
|
|
25
27
|
[ "$#" -ge 2 ] || die "$1 requires a value."
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
action="${1:-}"
|
|
31
|
+
case "$action" in
|
|
32
|
+
ensure|stop|status)
|
|
33
|
+
shift
|
|
34
|
+
;;
|
|
35
|
+
*)
|
|
29
36
|
usage >&2
|
|
30
37
|
exit 1
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
;;
|
|
39
|
+
esac
|
|
33
40
|
|
|
34
41
|
name=""
|
|
35
42
|
process_match=""
|
|
@@ -44,16 +51,19 @@ while [ "$#" -gt 0 ]; do
|
|
|
44
51
|
shift 2
|
|
45
52
|
;;
|
|
46
53
|
--match)
|
|
54
|
+
[ "$action" = "ensure" ] || die "--match is only valid for ensure."
|
|
47
55
|
require_value "$@"
|
|
48
56
|
process_match="$2"
|
|
49
57
|
shift 2
|
|
50
58
|
;;
|
|
51
59
|
--fingerprint)
|
|
60
|
+
[ "$action" = "ensure" ] || die "--fingerprint is only valid for ensure."
|
|
52
61
|
require_value "$@"
|
|
53
62
|
fingerprint="$2"
|
|
54
63
|
shift 2
|
|
55
64
|
;;
|
|
56
65
|
--log)
|
|
66
|
+
[ "$action" = "ensure" ] || die "--log is only valid for ensure."
|
|
57
67
|
require_value "$@"
|
|
58
68
|
log_file="$2"
|
|
59
69
|
shift 2
|
|
@@ -73,17 +83,26 @@ while [ "$#" -gt 0 ]; do
|
|
|
73
83
|
done
|
|
74
84
|
|
|
75
85
|
[[ "$name" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]] || die "--name must be a safe identifier."
|
|
76
|
-
[ -n "$process_match" ] || die "--match is required."
|
|
77
|
-
[ "$#" -gt 0 ] || die "A command is required after --."
|
|
78
86
|
[ -r "/proc/$$/environ" ] || die "Linux /proc process metadata is required."
|
|
79
87
|
|
|
80
|
-
|
|
88
|
+
if [ "$action" = "ensure" ]; then
|
|
89
|
+
[ -n "$process_match" ] || die "--match is required."
|
|
90
|
+
[ "$#" -gt 0 ] || die "A command is required after --."
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
required_tools=(awk flock grep pgrep ps tr)
|
|
94
|
+
if [ "$action" = "ensure" ]; then
|
|
95
|
+
required_tools+=(setsid sha256sum sort)
|
|
96
|
+
fi
|
|
97
|
+
for tool in "${required_tools[@]}"; do
|
|
81
98
|
command -v "$tool" >/dev/null 2>&1 || die "Required command is unavailable: $tool"
|
|
82
99
|
done
|
|
83
100
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
101
|
+
if [ "$action" = "ensure" ]; then
|
|
102
|
+
match_status=0
|
|
103
|
+
pgrep -f -- "$process_match" >/dev/null 2>&1 || match_status=$?
|
|
104
|
+
[ "$match_status" -le 1 ] || die "--match is not a valid process regular expression."
|
|
105
|
+
fi
|
|
87
106
|
|
|
88
107
|
fingerprint_env_names=()
|
|
89
108
|
fingerprint_env_list="${DEVROUTER_PROCESS_FINGERPRINT_ENV:-}"
|
|
@@ -107,6 +126,10 @@ if [[ -v DEVROUTER_PROCESS_ADAPTER_SHA256 ]] &&
|
|
|
107
126
|
die "DEVROUTER_PROCESS_ADAPTER_SHA256 must be a SHA-256 digest."
|
|
108
127
|
fi
|
|
109
128
|
|
|
129
|
+
if [ "$action" != "ensure" ] && [ "$#" -gt 0 ]; then
|
|
130
|
+
die "Unexpected arguments for $action."
|
|
131
|
+
fi
|
|
132
|
+
|
|
110
133
|
emit_environment_field() {
|
|
111
134
|
local field="$1"
|
|
112
135
|
local variable="$2"
|
|
@@ -232,6 +255,10 @@ unknown_process_exists() {
|
|
|
232
255
|
marked_process_exists || matching_process_exists
|
|
233
256
|
}
|
|
234
257
|
|
|
258
|
+
report_status() {
|
|
259
|
+
printf '{"name":"%s","status":"%s"}\n' "$name" "$1"
|
|
260
|
+
}
|
|
261
|
+
|
|
235
262
|
stop_process_group() {
|
|
236
263
|
local pid="$1"
|
|
237
264
|
local pgid="$2"
|
|
@@ -263,6 +290,67 @@ mkdir -p "$state_dir" "$(dirname "$log_file")"
|
|
|
263
290
|
exec 9>"$lock_file"
|
|
264
291
|
flock -w "$lock_timeout" 9 || die "Timed out waiting for the '$name' process lock."
|
|
265
292
|
|
|
293
|
+
if [ "$action" = "status" ]; then
|
|
294
|
+
if [ ! -f "$state_file" ]; then
|
|
295
|
+
if marked_process_exists; then
|
|
296
|
+
report_status foreign
|
|
297
|
+
exit 2
|
|
298
|
+
fi
|
|
299
|
+
report_status stopped
|
|
300
|
+
exit 0
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
read -r pid pgid stored_fingerprint extra <"$state_file" || true
|
|
304
|
+
if [ -z "$stored_fingerprint" ] ||
|
|
305
|
+
! [[ "$pid" =~ ^[1-9][0-9]*$ ]] ||
|
|
306
|
+
! [[ "$pgid" =~ ^[1-9][0-9]*$ ]] ||
|
|
307
|
+
[ -n "$extra" ]; then
|
|
308
|
+
report_status drifted
|
|
309
|
+
exit 2
|
|
310
|
+
fi
|
|
311
|
+
if process_alive "$pid"; then
|
|
312
|
+
if process_owned "$pid" "$pgid" "$stored_fingerprint"; then
|
|
313
|
+
report_status running
|
|
314
|
+
else
|
|
315
|
+
report_status foreign
|
|
316
|
+
exit 2
|
|
317
|
+
fi
|
|
318
|
+
exit 0
|
|
319
|
+
fi
|
|
320
|
+
report_status drifted
|
|
321
|
+
exit 2
|
|
322
|
+
fi
|
|
323
|
+
|
|
324
|
+
if [ "$action" = "stop" ]; then
|
|
325
|
+
if [ ! -f "$state_file" ]; then
|
|
326
|
+
if marked_process_exists; then
|
|
327
|
+
die "Found an unowned '$name' process; refusing to stop it."
|
|
328
|
+
fi
|
|
329
|
+
echo "[devrouter-process] '$name' is already stopped."
|
|
330
|
+
exit 0
|
|
331
|
+
fi
|
|
332
|
+
|
|
333
|
+
read -r pid pgid stored_fingerprint extra <"$state_file" || true
|
|
334
|
+
if [ -z "$stored_fingerprint" ] ||
|
|
335
|
+
! [[ "$pid" =~ ^[1-9][0-9]*$ ]] ||
|
|
336
|
+
! [[ "$pgid" =~ ^[1-9][0-9]*$ ]] ||
|
|
337
|
+
[ -n "$extra" ]; then
|
|
338
|
+
die "Invalid state for '$name'; refusing to stop it."
|
|
339
|
+
fi
|
|
340
|
+
if process_alive "$pid"; then
|
|
341
|
+
process_owned "$pid" "$pgid" "$stored_fingerprint" ||
|
|
342
|
+
die "State points at an unowned '$name' process; refusing to stop it."
|
|
343
|
+
stop_process_group "$pid" "$pgid"
|
|
344
|
+
elif process_group_alive "$pgid"; then
|
|
345
|
+
die "State points at a live unowned '$name' process group; refusing to stop it."
|
|
346
|
+
elif marked_process_exists; then
|
|
347
|
+
die "Found an unowned '$name' process; refusing to stop it."
|
|
348
|
+
fi
|
|
349
|
+
rm -f "$state_file"
|
|
350
|
+
echo "[devrouter-process] '$name' is stopped."
|
|
351
|
+
exit 0
|
|
352
|
+
fi
|
|
353
|
+
|
|
266
354
|
pid=""
|
|
267
355
|
pgid=""
|
|
268
356
|
stored_fingerprint=""
|