@cyanautomation/kaseki-agent 1.28.0 → 1.29.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.28.0",
3
+ "version": "1.29.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",
@@ -1,6 +1,19 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # === Docker Entrypoint for Kaseki Agent ===
5
+ # Responsible for:
6
+ # 1. Running init container (if applicable) to fix /agents permissions
7
+ # 2. Running early startup checks
8
+ # 3. Dispatching to the appropriate command handler (api, agent, setup, etc.)
9
+
10
+ # Phase 1: Check if init container already ran (for debugging)
11
+ # The init container is a separate service in docker-compose and runs before this.
12
+ # If you're seeing permission errors here, the init container either:
13
+ # - Failed to fix permissions (expected in restricted environments)
14
+ # - Hasn't run yet (check depends_on conditions)
15
+ # - Ran but the issue is fundamental to the environment
16
+
4
17
  # Phase 2: Run early startup checks to catch permission and config issues
5
18
  # This runs before any kaseki operation to prevent silent failures
6
19
  if [ "${KASEKI_SKIP_STARTUP_CHECKS:-0}" != "1" ]; then
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # kaseki-init-container.sh — Initialize /agents directory permissions for API service
4
+ #
5
+ # This script runs in an init container (before the main kaseki-api service)
6
+ # to ensure the /agents directory is properly configured with correct ownership.
7
+ #
8
+ # Exit codes:
9
+ # 0 = success (directory is ready or was fixed)
10
+ # 1 = failure (directory not writable; manual intervention required)
11
+ #
12
+ # This approach allows graceful fallback: if init fails, the main API service
13
+ # still starts but logs clear instructions for Dockhand/Portainer users.
14
+
15
+ set -euo pipefail
16
+
17
+ # Configuration
18
+ KASEKI_ROOT="${KASEKI_ROOT:-/agents}"
19
+ CONTAINER_UID="${CONTAINER_UID:-10000}"
20
+ CONTAINER_GID="${CONTAINER_GID:-10000}"
21
+
22
+ # Color codes for output
23
+ RED='\033[0;31m'
24
+ YELLOW='\033[0;33m'
25
+ GREEN='\033[0;32m'
26
+ BLUE='\033[0;34m'
27
+ NC='\033[0m' # No Color
28
+
29
+ # Logging functions
30
+ log_pass() {
31
+ echo -e "${GREEN}✓${NC} $*" >&2
32
+ }
33
+
34
+ log_warn() {
35
+ echo -e "${YELLOW}⚠${NC} $*" >&2
36
+ }
37
+
38
+ log_error() {
39
+ echo -e "${RED}✗${NC} $*" >&2
40
+ }
41
+
42
+ log_info() {
43
+ echo -e "${BLUE}ℹ${NC} $*" >&2
44
+ }
45
+
46
+ # --- Main initialization logic ---
47
+
48
+ main() {
49
+ log_info "Init container: Initializing $KASEKI_ROOT"
50
+
51
+ # Check if /agents exists
52
+ if [ ! -d "$KASEKI_ROOT" ]; then
53
+ log_info " Creating $KASEKI_ROOT..."
54
+ if mkdir -p "$KASEKI_ROOT" 2>/dev/null; then
55
+ log_pass "Created $KASEKI_ROOT"
56
+ else
57
+ log_error "Failed to create $KASEKI_ROOT (parent directory not writable)"
58
+ log_error "Fix: Run on host: sudo mkdir -p $KASEKI_ROOT"
59
+ return 1
60
+ fi
61
+ fi
62
+
63
+ # Verify it's writable by container UID
64
+ if [ ! -w "$KASEKI_ROOT" ]; then
65
+ log_warn "$KASEKI_ROOT exists but is not writable by container"
66
+ log_info " Attempting to fix permissions..."
67
+
68
+ # Try to make it readable and executable for all (755)
69
+ if chmod 755 "$KASEKI_ROOT" 2>/dev/null; then
70
+ log_pass "Fixed permissions on $KASEKI_ROOT (chmod 755)"
71
+ return 0
72
+ else
73
+ log_error "Failed to fix permissions on $KASEKI_ROOT (chmod failed)"
74
+ log_error "This is expected in restricted environments (e.g., read-only volumes)"
75
+ log_error ""
76
+ log_error "Manual fix required. In your container platform (Dockhand/Portainer):"
77
+ log_error " 1. Run on the host: sudo chown $CONTAINER_UID:$CONTAINER_GID $KASEKI_ROOT"
78
+ log_error " 2. Run on the host: sudo chmod 755 $KASEKI_ROOT"
79
+ log_error " 3. Restart the kaseki-api service"
80
+ log_error ""
81
+ log_error "Alternative: Use init container with elevated privileges (not recommended)"
82
+ return 1
83
+ fi
84
+ fi
85
+
86
+ log_pass "$KASEKI_ROOT is writable by container"
87
+ log_pass "Init complete. API service can now proceed."
88
+ return 0
89
+ }
90
+
91
+ # Execute main and report result
92
+ if main; then
93
+ exit 0
94
+ else
95
+ # Graceful failure: exit 1 but don't block the main API service from starting
96
+ # The main service will detect the issue via startup-checks.sh and provide
97
+ # actionable error messages to users
98
+ exit 1
99
+ fi
@@ -49,6 +49,98 @@ log_info() {
49
49
  echo -e "${BLUE}ℹ${NC} $*" >&2
50
50
  }
51
51
 
52
+ # Check if we're running in a container managed by Docker (but not necessarily Docker Compose)
53
+ is_in_container() {
54
+ [ -f /.dockerenv ] || [ -f /run/.containerenv ]
55
+ }
56
+
57
+ # Detect container management platform (Dockhand, Portainer, Kubernetes, etc.)
58
+ detect_container_platform() {
59
+ if [ -S /var/run/docker.sock ] 2>/dev/null; then
60
+ # We have access to docker socket
61
+ if command -v docker &>/dev/null; then
62
+ # Check if running on Portainer (has specific env vars or config)
63
+ if [ -n "${PORTAINER_VERSION:-}" ] || [ -f /.portainer ]; then
64
+ echo "portainer"
65
+ return 0
66
+ fi
67
+ # Check for Dockhand patterns (typically running in restricted mode)
68
+ if grep -q "dockhand" /proc/self/cgroup 2>/dev/null || [ -n "${DOCKHAND_MODE:-}" ]; then
69
+ echo "dockhand"
70
+ return 0
71
+ fi
72
+ fi
73
+ fi
74
+ # Kubernetes detection
75
+ if [ -d /var/run/secrets/kubernetes.io ]; then
76
+ echo "kubernetes"
77
+ return 0
78
+ fi
79
+ echo "docker"
80
+ return 0
81
+ }
82
+
83
+ # Generate platform-specific remediation instructions
84
+ suggest_platform_setup() {
85
+ local platform="${1:-docker}"
86
+
87
+ case "$platform" in
88
+ portainer)
89
+ echo ""
90
+ echo "📦 Running on Portainer — Setup Instructions:"
91
+ echo ""
92
+ echo " 1. In Portainer UI, navigate to Stacks → kaseki-agent"
93
+ echo " 2. Edit the stack and modify the 'services' section:"
94
+ echo ""
95
+ echo " Before docker-compose up, run on the HOST:"
96
+ echo " sudo mkdir -p /agents"
97
+ echo " sudo chown 10000:10000 /agents"
98
+ echo " sudo chmod 755 /agents"
99
+ echo ""
100
+ echo " 3. Or, use an init container (already added in latest version)"
101
+ echo " Wait 10 seconds after deploy for init container to complete"
102
+ echo ""
103
+ echo " See: docs/DEPLOYMENT.md#container-management-platforms"
104
+ ;;
105
+ dockhand)
106
+ echo ""
107
+ echo "🔧 Running on Dockhand — Setup Instructions:"
108
+ echo ""
109
+ echo " 1. SSH into the Dockhand host"
110
+ echo " 2. Run the following commands:"
111
+ echo " sudo mkdir -p /agents"
112
+ echo " sudo chown 10000:10000 /agents"
113
+ echo " sudo chmod 755 /agents"
114
+ echo ""
115
+ echo " 3. Restart the kaseki-api service in Dockhand UI"
116
+ echo ""
117
+ echo " See: docs/DEPLOYMENT.md#container-management-platforms"
118
+ ;;
119
+ kubernetes)
120
+ echo ""
121
+ echo "☸️ Running on Kubernetes — Setup Instructions:"
122
+ echo ""
123
+ echo " 1. Ensure /agents PersistentVolume is properly mounted"
124
+ echo " 2. The PV must be writable by UID 10000"
125
+ echo ""
126
+ echo " Example: kubectl patch pv agents-pv -p '{\"spec\":{\"owner\":\"10000:10000\"}}'"
127
+ echo ""
128
+ echo " See: docs/DEPLOYMENT.md#kubernetes-deployment"
129
+ ;;
130
+ *)
131
+ echo ""
132
+ echo "💡 Setup Instructions:"
133
+ echo ""
134
+ echo " Run on the host where /agents is mounted:"
135
+ echo " sudo mkdir -p /agents"
136
+ echo " sudo chown 10000:10000 /agents"
137
+ echo " sudo chmod 755 /agents"
138
+ echo ""
139
+ echo " Then restart the kaseki-api service."
140
+ ;;
141
+ esac
142
+ }
143
+
52
144
  # Check if a directory is writable (even if it doesn't exist yet)
53
145
  is_writable_or_creatable() {
54
146
  local target_dir="$1"
@@ -102,6 +194,13 @@ check_kaseki_root() {
102
194
  if [ ! -w "$KASEKI_ROOT" ]; then
103
195
  log_error "$KASEKI_ROOT exists but is not writable by UID $CONTAINER_UID"
104
196
  log_error "Fix: Run on host: sudo chown $CONTAINER_UID:$CONTAINER_GID $KASEKI_ROOT"
197
+
198
+ # Provide platform-specific instructions if in container
199
+ if is_in_container; then
200
+ local platform
201
+ platform=$(detect_container_platform)
202
+ suggest_platform_setup "$platform"
203
+ fi
105
204
  return 2
106
205
  fi
107
206