aibox-cli 0.4.1 → 0.4.2

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.
Files changed (2) hide show
  1. package/bin/aibox +32 -29
  2. package/package.json +1 -1
package/bin/aibox CHANGED
@@ -57,11 +57,25 @@ set -euo pipefail
57
57
 
58
58
  # ── Script identity ──────────────────────────────────────────────
59
59
  SCRIPT_NAME="$(basename "$0")"
60
- AIBOX_VERSION="6"
60
+ AIBOX_VERSION="7"
61
61
  CONFIG_DIR="${HOME}/.config/aibox"
62
62
  DEFAULT_IMAGE="aibox:latest"
63
63
  CONTAINER_PREFIX="aibox"
64
64
 
65
+ # ── Output helpers ─────────────────────────────────────────────
66
+ _step() {
67
+ local msg="$1"
68
+ local width=60
69
+ local pad
70
+ pad=$(( width - ${#msg} - 5 )) # 5 = "── " + " ─"
71
+ [[ $pad -lt 3 ]] && pad=3
72
+ local line
73
+ line=$(printf '─%.0s' $(seq 1 "$pad"))
74
+ echo ""
75
+ echo "── ${msg} ${line}"
76
+ echo ""
77
+ }
78
+
65
79
  # ── Machine-aware Colima start ───────────────────────────────────
66
80
  _colima_start() {
67
81
  local total_cpu total_mem_gb vm_cpu vm_mem vm_disk
@@ -384,7 +398,7 @@ if ! [[ "$INSTANCE_NAME" =~ ^[a-z0-9_-]+$ ]]; then
384
398
  exit 1
385
399
  fi
386
400
  CONTAINER_NAME="${BASE_CONTAINER_NAME}-${INSTANCE_NAME}"
387
- WORKSPACE_DIR="/workspace/${PROJECT_NAME}"
401
+ WORKSPACE_DIR="${PROJECT_DIR}"
388
402
 
389
403
  # ── Isolation mode setup ─────────────────────────────────────────
390
404
  COPY_VOLUME=""
@@ -422,7 +436,7 @@ ensure_dockerfile() {
422
436
 
423
437
  if [[ "$current_version" != "$AIBOX_VERSION" || ! -f "$dockerfile" ]]; then
424
438
  if [[ -f "$dockerfile" && "$current_version" != "$AIBOX_VERSION" ]]; then
425
- echo "Dockerfile outdated (v${current_version} → v${AIBOX_VERSION}). Regenerating..."
439
+ echo "Dockerfile outdated (v${current_version} → v${AIBOX_VERSION}). Regenerating (one-time)..."
426
440
  fi
427
441
  cat > "$dockerfile" << DOCKERFILE
428
442
  FROM node:20-alpine
@@ -473,16 +487,6 @@ set -e
473
487
  # Fix auth volume ownership (Docker creates volumes as root)
474
488
  chown -R aibox:aibox /home/aibox/.claude 2>/dev/null || true
475
489
 
476
- # ── IDE path symlink ─────────────────────────────────────────
477
- # Create symlink so container paths match host paths for IDE integration.
478
- # Claude Code reports cwd-based paths to the IDE plugin; if they don't
479
- # match host paths, diffs break (empty left side, wrong file path).
480
- if [[ -n "${AIBOX_HOST_DIR:-}" && -n "${AIBOX_WORKSPACE_DIR:-}" \
481
- && "$AIBOX_HOST_DIR" != "$AIBOX_WORKSPACE_DIR" ]]; then
482
- mkdir -p "$(dirname "$AIBOX_HOST_DIR")"
483
- ln -sfn "$AIBOX_WORKSPACE_DIR" "$AIBOX_HOST_DIR"
484
- fi
485
-
486
490
  # ── Mode-dependent setup ──────────────────────────────────────
487
491
  MODE="${AIBOX_MODE:-safe}"
488
492
 
@@ -582,14 +586,14 @@ _prepare_copy_volume() {
582
586
 
583
587
  # Check if volume already has content (--entrypoint bypasses su-exec drop)
584
588
  local has_content
585
- has_content=$(docker run --rm --entrypoint sh -v "${COPY_VOLUME}:${WORKSPACE_DIR}" "$IMAGE" -c "ls -A ${WORKSPACE_DIR} 2>/dev/null | head -1" 2>/dev/null || true)
589
+ has_content=$(docker run --rm --entrypoint sh -v "${COPY_VOLUME}:${WORKSPACE_DIR}" "$IMAGE" -c "ls -A '${WORKSPACE_DIR}' 2>/dev/null | head -1" 2>/dev/null || true)
586
590
 
587
591
  if [[ -n "$has_content" ]]; then
588
592
  echo "Copy volume already populated (${COPY_VOLUME}). Reusing."
589
593
  return
590
594
  fi
591
595
 
592
- echo "Copying project into isolated volume (branch: ${branch_name})..."
596
+ _step "Copying project into volume (branch: ${branch_name})"
593
597
 
594
598
  # Create bundle to a temp file first so we can check for failure
595
599
  local bundle_file
@@ -605,12 +609,12 @@ _prepare_copy_volume() {
605
609
  -v "${COPY_VOLUME}:${WORKSPACE_DIR}" \
606
610
  "$IMAGE" -c "
607
611
  cat > /tmp/repo.bundle
608
- mkdir -p ${WORKSPACE_DIR}
609
- cd ${WORKSPACE_DIR}
612
+ mkdir -p '${WORKSPACE_DIR}'
613
+ cd '${WORKSPACE_DIR}'
610
614
  git clone /tmp/repo.bundle .
611
615
  rm /tmp/repo.bundle
612
616
  git checkout -b '${branch_name}' 2>/dev/null || git checkout '${branch_name}'
613
- chown -R aibox:aibox ${WORKSPACE_DIR}
617
+ chown -R aibox:aibox '${WORKSPACE_DIR}'
614
618
  "; then
615
619
  rm -f "$bundle_file"
616
620
  docker volume rm "$COPY_VOLUME" 2>/dev/null || true
@@ -633,7 +637,7 @@ _prepare_worktree() {
633
637
 
634
638
  mkdir -p "${CONFIG_DIR}/worktrees"
635
639
 
636
- echo "Creating worktree (branch: ${branch_name})..."
640
+ _step "Creating worktree (branch: ${branch_name})"
637
641
 
638
642
  # Try creating with a new branch, fall back to existing branch
639
643
  if git -C "$PROJECT_DIR" worktree add "$WORKTREE_DIR" -b "$branch_name" 2>/dev/null; then
@@ -696,8 +700,6 @@ _environment_yaml() {
696
700
  echo "${indent}- CLAUDE_CONFIG_DIR=/home/aibox/.claude"
697
701
  echo "${indent}- AIBOX_MODE=\${AIBOX_MODE:-safe}"
698
702
  echo "${indent}- AIBOX_EXTRA_DOMAINS=\${AIBOX_EXTRA_DOMAINS:-}"
699
- echo "${indent}- AIBOX_HOST_DIR=${PROJECT_DIR}"
700
- echo "${indent}- AIBOX_WORKSPACE_DIR=${WORKSPACE_DIR}"
701
703
  }
702
704
 
703
705
  # Build -e flags for docker exec from current terminal environment
@@ -869,15 +871,16 @@ dc() {
869
871
  cmd_build() {
870
872
  _check_deps
871
873
  ensure_dockerfile
872
- echo "Building ${IMAGE}..."
874
+ _step "Building ${IMAGE}"
873
875
  docker build -t "$IMAGE" "$CONFIG_DIR"
874
- echo "Done. Image: ${IMAGE}"
876
+ echo "Done."
875
877
  }
876
878
 
877
879
  ensure_init() {
878
880
  if [[ ! -f "${PROJECT_DIR}/compose.dev.yaml" ]]; then
879
881
  _require_safe_dir
880
- echo "No ${SCRIPT_NAME} config found. Will create compose.dev.yaml, .aibox, and .idea/workspace.xml."
882
+ _step "Initializing project (one-time)"
883
+ echo "Will create compose.dev.yaml, .aibox, and .idea/workspace.xml."
881
884
  if _confirm_yes "Initialize?"; then
882
885
  _init_files
883
886
  echo ""
@@ -893,14 +896,14 @@ cmd_up() {
893
896
  ensure_init
894
897
 
895
898
  if ! docker image inspect "$IMAGE" &>/dev/null; then
896
- echo "Image '${IMAGE}' not found. Building..."
899
+ echo "Image '${IMAGE}' not found. Building (one-time)..."
897
900
  cmd_build
898
901
  else
899
902
  # Check if image version matches script version
900
903
  local img_version
901
904
  img_version=$(docker inspect "$IMAGE" --format '{{index .Config.Labels "aibox.version"}}' 2>/dev/null || echo "")
902
905
  if [[ "$img_version" != "$AIBOX_VERSION" ]]; then
903
- echo "Image outdated (v${img_version:-0} → v${AIBOX_VERSION}). Rebuilding..."
906
+ echo "Image outdated (v${img_version:-0} → v${AIBOX_VERSION}). Rebuilding (one-time)..."
904
907
  cmd_build
905
908
  fi
906
909
  fi
@@ -915,9 +918,9 @@ cmd_up() {
915
918
  if ! docker ps --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
916
919
  # Ensure shared auth volume exists (external: true requires it)
917
920
  docker volume create "$AUTH_VOLUME" &>/dev/null || true
918
- echo "Starting ${CONTAINER_NAME} (image: ${IMAGE})..."
921
+ _step "Starting ${CONTAINER_NAME}"
919
922
  dc up -d
920
- echo "Container running. Workspace: ${WORKSPACE_DIR}"
923
+ echo "Container running."
921
924
  else
922
925
  echo "${CONTAINER_NAME} is already running."
923
926
  fi
@@ -967,7 +970,7 @@ cmd_claude() {
967
970
  local current_mode
968
971
  current_mode=$(docker exec "$CONTAINER_NAME" sh -c 'echo ${AIBOX_MODE:-safe}' 2>/dev/null || echo "unknown")
969
972
  if [[ "$current_mode" != "$AIBOX_MODE" ]]; then
970
- echo "Restarting container in ${AIBOX_MODE} mode (was: ${current_mode})..."
973
+ _step "Restarting container in ${AIBOX_MODE} mode (was: ${current_mode})"
971
974
  dc down --remove-orphans >/dev/null
972
975
  fi
973
976
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aibox-cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Run AI coding agents in isolated Docker containers",
5
5
  "author": "repalash <palash@shaders.app>",
6
6
  "license": "MIT",