@cyanautomation/kaseki-agent 1.36.11 → 1.37.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanautomation/kaseki-agent",
3
- "version": "1.36.11",
3
+ "version": "1.37.0",
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,19 @@ check_writable() {
100
100
  fi
101
101
  }
102
102
 
103
+ fix_checkout_permissions_if_exists() {
104
+ # If checkout directory exists with potentially problematic ownership,
105
+ # try to fix it to match container UID:GID (only when --fix is set)
106
+ if [ "$KASEKI_FIX" != "1" ]; then
107
+ return 0
108
+ fi
109
+ if [ ! -d "$KASEKI_CHECKOUT_DIR" ]; then
110
+ return 0
111
+ fi
112
+ # Attempt to fix ownership to container UID:GID for consistency
113
+ run_privileged chown -R "$KASEKI_CONTAINER_UID:$KASEKI_CONTAINER_GID" "$KASEKI_CHECKOUT_DIR" 2>/dev/null || true
114
+ }
115
+
103
116
  resolve_uid_to_name() {
104
117
  local uid="$1"
105
118
  if ! command -v getent >/dev/null 2>&1; then
@@ -151,12 +164,20 @@ run_checkout_freshness_probe() {
151
164
  local probe_status="skipped"
152
165
  local probe_detail="Checkout freshness probe skipped because setup did not run bootstrap."
153
166
  local probe_remediation=""
167
+ local stderr_file=""
168
+
169
+ cleanup_probe_stderr_file() {
170
+ if [ -n "$stderr_file" ]; then
171
+ rm -f "$stderr_file"
172
+ fi
173
+ }
154
174
 
155
175
  if [ ! -d "$checkout_dir" ]; then
156
176
  probe_status="failed"
157
177
  probe_detail="Checkout freshness probe failed: expected checkout path ${checkout_dir} does not exist."
158
178
  probe_remediation="Fix ownership/permissions so ${checkout_dir} and ${checkout_dir}/.git are readable by UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."
159
179
  printf '%s|%s|%s\n' "$probe_status" "$probe_detail" "$probe_remediation"
180
+ cleanup_probe_stderr_file
160
181
  return 0
161
182
  fi
162
183
 
@@ -165,15 +186,12 @@ run_checkout_freshness_probe() {
165
186
  probe_detail="Checkout freshness probe failed: ${checkout_dir}/.git is missing or inaccessible."
166
187
  probe_remediation="Fix ownership/permissions so ${checkout_dir} and ${checkout_dir}/.git are readable by UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."
167
188
  printf '%s|%s|%s\n' "$probe_status" "$probe_detail" "$probe_remediation"
189
+ cleanup_probe_stderr_file
168
190
  return 0
169
191
  fi
170
192
 
171
- local stderr_file
172
193
  stderr_file="$(mktemp)"
173
-
174
- # Ensure cleanup on exit
175
- trap 'rm -f "$stderr_file"' EXIT INT TERM
176
-
194
+
177
195
  local probe_command=(git -C "$checkout_dir" rev-parse HEAD)
178
196
 
179
197
  local resolved_user_name=""
@@ -214,7 +232,7 @@ run_checkout_freshness_probe() {
214
232
  probe_status="ok"
215
233
  probe_detail="Checkout freshness probe passed for ${checkout_dir} as UID:GID ${KASEKI_CONTAINER_UID}:${KASEKI_CONTAINER_GID}."
216
234
  fi
217
- rm -f "$stderr_file"
235
+ cleanup_probe_stderr_file
218
236
 
219
237
  printf '%s|%s|%s\n' "$probe_status" "$probe_detail" "$probe_remediation"
220
238
  }
@@ -324,6 +342,94 @@ bootstrap_checkout_if_possible() {
324
342
  return 1
325
343
  }
326
344
 
345
+ ensure_git_safe_directory() {
346
+ if ! command -v git >/dev/null 2>&1; then
347
+ printf 'warning: git is unavailable; skipping safe.directory preflight for %s\n' "$KASEKI_CHECKOUT_DIR"
348
+ return 0
349
+ fi
350
+
351
+ if [ ! -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
352
+ printf 'warning: %s/.git is missing; skipping safe.directory preflight\n' "$KASEKI_CHECKOUT_DIR"
353
+ return 0
354
+ fi
355
+
356
+ local status_code=0
357
+
358
+ # Configure safe.directory for current context (usually root when run via sudo)
359
+ local existing_safe_dirs
360
+ existing_safe_dirs="$(git config --global --get-all safe.directory 2>/dev/null || true)"
361
+ if printf '%s\n' "$existing_safe_dirs" | grep -Fxq "$KASEKI_CHECKOUT_DIR"; then
362
+ printf 'ok: git safe.directory already present for current user context\n'
363
+ else
364
+ if git config --global --add safe.directory "$KASEKI_CHECKOUT_DIR" >/dev/null 2>&1; then
365
+ printf 'ok: configured git safe.directory for current user context\n'
366
+ else
367
+ printf 'warning: failed to configure git safe.directory for current user context\n'
368
+ status_code=1
369
+ fi
370
+ fi
371
+
372
+ # If running via sudo, also configure safe.directory for the invoking user
373
+ if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
374
+ local invoking_user_config
375
+ invoking_user_config="$(sudo -u "$SUDO_USER" git config --global --get-all safe.directory 2>/dev/null || true)"
376
+ if printf '%s\n' "$invoking_user_config" | grep -Fxq "$KASEKI_CHECKOUT_DIR"; then
377
+ printf 'ok: git safe.directory already present for invoking user (%s)\n' "$SUDO_USER"
378
+ else
379
+ if sudo -u "$SUDO_USER" git config --global --add safe.directory "$KASEKI_CHECKOUT_DIR" >/dev/null 2>&1; then
380
+ printf 'ok: configured git safe.directory for invoking user (%s)\n' "$SUDO_USER"
381
+ else
382
+ printf 'warning: failed to configure git safe.directory for invoking user (%s)\n' "$SUDO_USER"
383
+ status_code=1
384
+ fi
385
+ fi
386
+ fi
387
+
388
+ if [ "$status_code" -ne 0 ]; then
389
+ printf 'remediation: if you see dubious ownership errors, try manually running as the invoking user:\n'
390
+ if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
391
+ printf ' sudo -u %s git config --global --add safe.directory "%s"\n' "$SUDO_USER" "$KASEKI_CHECKOUT_DIR"
392
+ fi
393
+ printf ' And as root: git config --global --add safe.directory "%s"\n' "$KASEKI_CHECKOUT_DIR"
394
+ fi
395
+
396
+ return 0
397
+ }
398
+
399
+ verify_git_safe_directory() {
400
+ # Verify that safe.directory is actually configured before bootstrap
401
+ if ! command -v git >/dev/null 2>&1; then
402
+ return 0
403
+ fi
404
+
405
+ if [ ! -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
406
+ return 0
407
+ fi
408
+
409
+ local existing_safe_dirs
410
+ existing_safe_dirs="$(git config --global --get-all safe.directory 2>/dev/null || true)"
411
+ if printf '%s\n' "$existing_safe_dirs" | grep -Fxq "$KASEKI_CHECKOUT_DIR"; then
412
+ return 0
413
+ fi
414
+
415
+ # Not configured in current context; check if sudo user context has it
416
+ if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
417
+ local invoking_user_config
418
+ invoking_user_config="$(sudo -u "$SUDO_USER" git config --global --get-all safe.directory 2>/dev/null || true)"
419
+ if printf '%s\n' "$invoking_user_config" | grep -Fxq "$KASEKI_CHECKOUT_DIR"; then
420
+ return 0
421
+ fi
422
+ fi
423
+
424
+ # Safe.directory not configured anywhere; warn but don't fail (bootstrap might still work)
425
+ printf 'warning: git safe.directory not found for checkout. If bootstrap fails with "dubious ownership", run:\n'
426
+ if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
427
+ printf ' sudo -u %s git config --global --add safe.directory "%s"\n' "$SUDO_USER" "$KASEKI_CHECKOUT_DIR"
428
+ fi
429
+ printf ' git config --global --add safe.directory "%s"\n' "$KASEKI_CHECKOUT_DIR"
430
+ return 0
431
+ }
432
+
327
433
  recreate_api_if_requested() {
328
434
  if [ "$KASEKI_RECREATE_API" != "1" ]; then
329
435
  return 0
@@ -358,6 +464,9 @@ check_writable "$KASEKI_ROOT/kaseki-results" || status=1
358
464
  printf 'using host secrets directory: %s\n' "$KASEKI_HOST_SECRETS_DIR"
359
465
  normalize_secrets_dir "$KASEKI_HOST_SECRETS_DIR"
360
466
 
467
+ fix_checkout_permissions_if_exists
468
+ ensure_git_safe_directory
469
+ verify_git_safe_directory
361
470
  bootstrap_checkout_if_possible || status=$?
362
471
 
363
472
  probe_payload="$(run_checkout_freshness_probe "$KASEKI_CHECKOUT_DIR")"
@@ -383,7 +492,19 @@ fi
383
492
  recreate_api_if_requested || status=$?
384
493
 
385
494
  if [ "$status" -ne 0 ]; then
386
- printf 'kaseki host setup incomplete. Re-run with --fix to create directories and bootstrap when possible.\n' >&2
495
+ printf 'kaseki host setup incomplete. Details above. Common remediation steps:\n' >&2
496
+ printf '\n' >&2
497
+ printf '1. Ensure git safe.directory is configured:\n' >&2
498
+ if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
499
+ printf ' sudo -u %s git config --global --add safe.directory "%s"\n' "$SUDO_USER" "$KASEKI_CHECKOUT_DIR" >&2
500
+ fi
501
+ printf ' git config --global --add safe.directory "%s"\n' "$KASEKI_CHECKOUT_DIR" >&2
502
+ printf '\n' >&2
503
+ printf '2. Fix directory permissions/ownership:\n' >&2
504
+ printf ' sudo chown -R %d:%d "%s"\n' "$KASEKI_CONTAINER_UID" "$KASEKI_CONTAINER_GID" "$KASEKI_ROOT" >&2
505
+ printf '\n' >&2
506
+ printf '3. Retry setup:\n' >&2
507
+ printf ' sudo kaseki-agent host setup --fix\n' >&2
387
508
  fi
388
509
 
389
510
  exit "$status"