@cyanautomation/kaseki-agent 1.36.10 → 1.36.11

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 CHANGED
@@ -604,6 +604,14 @@ ssh pi@192.168.1.100 'tmp=$(mktemp) && curl -fsSL https://raw.githubusercontent.
604
604
  ssh pi@192.168.1.100 '/agents/kaseki-agent/scripts/kaseki-setup-host.sh --fix'
605
605
  ```
606
606
 
607
+ If checkout freshness fails, remediation is now specific to the failure mode:
608
+
609
+ - `.git` access failures (for example: `permission denied`, `not a git repository`,
610
+ or inaccessible `.git`) keep permission-focused remediation.
611
+ - UID/GID impersonation failures (for example: unknown user/group or `sudo`/`runuser`
612
+ invocation errors) return remediation that asks you to configure a valid way to
613
+ execute as UID:GID `10000:10000` (or provide passwd/group mappings), then rerun setup.
614
+
607
615
  #### Local Activation (No SSH)
608
616
 
609
617
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanautomation/kaseki-agent",
3
- "version": "1.36.10",
3
+ "version": "1.36.11",
4
4
  "description": "Admin/helper/doctor toolbox and local API client for Kaseki diagnostics, setup, and API-backed coding-agent task workflows",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -100,6 +100,24 @@ check_writable() {
100
100
  fi
101
101
  }
102
102
 
103
+ resolve_uid_to_name() {
104
+ local uid="$1"
105
+ if ! command -v getent >/dev/null 2>&1; then
106
+ printf ''
107
+ return 0
108
+ fi
109
+ getent passwd "$uid" 2>/dev/null | awk -F: 'NR==1 && NF>=6 {print $1}'
110
+ }
111
+
112
+ resolve_gid_to_name() {
113
+ local gid="$1"
114
+ if ! command -v getent >/dev/null 2>&1; then
115
+ printf ''
116
+ return 0
117
+ fi
118
+ getent group "$gid" 2>/dev/null | awk -F: 'NR==1 && NF>=4 {print $1}'
119
+ }
120
+
103
121
  normalize_secrets_dir() {
104
122
  local secrets_dir="$1"
105
123
  if [ ! -d "$secrets_dir" ]; then
@@ -158,12 +176,25 @@ run_checkout_freshness_probe() {
158
176
 
159
177
  local probe_command=(git -C "$checkout_dir" rev-parse HEAD)
160
178
 
179
+ local resolved_user_name=""
180
+ local resolved_group_name=""
181
+ resolved_user_name="$(resolve_uid_to_name "$KASEKI_CONTAINER_UID")"
182
+ resolved_group_name="$(resolve_gid_to_name "$KASEKI_CONTAINER_GID")"
183
+
161
184
  if [ "$(id -u)" -eq "$KASEKI_CONTAINER_UID" ] && [ "$(id -g)" -eq "$KASEKI_CONTAINER_GID" ]; then
162
185
  "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
163
- elif command -v sudo >/dev/null 2>&1; then
164
- sudo -u "#${KASEKI_CONTAINER_UID}" -g "#${KASEKI_CONTAINER_GID}" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
165
- elif command -v runuser >/dev/null 2>&1 && [ "$(id -u)" -eq 0 ]; then
166
- runuser -u "#${KASEKI_CONTAINER_UID}" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
186
+ elif [ "$(id -u)" -eq 0 ] && command -v setpriv >/dev/null 2>&1; then
187
+ setpriv --reuid "$KASEKI_CONTAINER_UID" --regid "$KASEKI_CONTAINER_GID" --clear-groups -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
188
+ elif [ "$(id -u)" -eq 0 ] && command -v runuser >/dev/null 2>&1 && [ -n "$resolved_user_name" ] && [ -n "$resolved_group_name" ]; then
189
+ runuser -u "$resolved_user_name" -g "$resolved_group_name" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
190
+ elif [ "$(id -u)" -eq 0 ] && command -v sudo >/dev/null 2>&1; then
191
+ if [ -n "$resolved_user_name" ] && [ -n "$resolved_group_name" ]; then
192
+ sudo -u "$resolved_user_name" -g "$resolved_group_name" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
193
+ elif [ -n "$resolved_user_name" ]; then
194
+ sudo -u "$resolved_user_name" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
195
+ else
196
+ sudo -u "#${KASEKI_CONTAINER_UID}" -g "#${KASEKI_CONTAINER_GID}" -- "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
197
+ fi
167
198
  else
168
199
  "${probe_command[@]}" >/dev/null 2>"$stderr_file" || true
169
200
  fi
@@ -172,8 +203,13 @@ run_checkout_freshness_probe() {
172
203
  probe_status="failed"
173
204
  local stderr_tail
174
205
  stderr_tail="$(tail -n 1 "$stderr_file" | tr -d '\r')"
175
- probe_detail="Checkout freshness probe failed when running git metadata access as UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}: ${stderr_tail}"
176
- probe_remediation="Fix ownership/permissions so ${checkout_dir} and ${checkout_dir}/.git are readable by UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."
206
+ if printf '%s' "$stderr_tail" | grep -Eiq 'unknown user|unknown group|no passwd entry|user .* does not exist|group .* does not exist|sudo: .*unknown|sudo: .*invalid|runuser: .*does not exist|runuser: user .* does not exist|runuser: group .* does not exist|unable to initialize policy plugin|unable to set user context'; then
207
+ probe_detail="Checkout freshness probe failed: probe could not impersonate UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID} due to host user/group mapping or privilege-tool configuration issue: ${stderr_tail}"
208
+ probe_remediation="Configure a valid host method to run commands as UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID} (or ensure passwd/group mappings exist for that UID/GID), then rerun ./scripts/kaseki-setup-host.sh --fix."
209
+ else
210
+ probe_detail="Checkout freshness probe failed when running git metadata access as UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}: ${stderr_tail}"
211
+ probe_remediation="Fix ownership/permissions so ${checkout_dir} and ${checkout_dir}/.git are readable by UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."
212
+ fi
177
213
  else
178
214
  probe_status="ok"
179
215
  probe_detail="Checkout freshness probe passed for ${checkout_dir} as UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."