diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9227c43..aa565d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,8 +2,8 @@ name: release on: push: - tags: - - 'v*' + branches: + - main permissions: contents: write @@ -24,84 +24,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Initialize - run: | - pacman -Syuu --noconfirm base-devel archiso docker git nodejs bc - git clone https://gitlab.archlinux.org/archlinux/archiso - cp -rf ./cfg/profiledef.sh /usr/share/archiso/configs/releng/ - cp -rf ./cfg/profiledef.sh ./archiso/configs/releng/profiledef.sh - cp -rf ./cfg/profiledef.sh ./archiso/configs/baseline/profiledef.sh - cp -rf ./scpt/mkarchiso ./archiso/archiso/mkarchiso - ./archiso/archiso/mkarchiso -v -o ./ ./archiso/configs/releng/ - tar xf aios-bootstrap*.tar.gz - mkdir -p root.x86_64/var/lib/machines/arch - pacstrap -c root.x86_64/var/lib/machines/arch base - echo -e 'Server = http://mirrors.cat.net/archlinux/$repo/os/$arch - Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch' >> ./root.x86_64/var/lib/machines/arch/etc/pacman.d/mirrorlist - sed -i s/CheckSpace/#CheckeSpace/ root.x86_64/var/lib/machines/arch/etc/pacman.conf - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman-key --init' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman-key --populate archlinux' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman -Syu --noconfirm base base-devel linux vim git zsh rust openssh openssl jq go nodejs npm docker podman bc sqlite' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /etc/containers/registries.conf.d' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'curl -sL -o /etc/containers/registries.conf.d/ai.conf https://git.syui.ai/ai/os/raw/branch/main/cfg/ai.conf' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chsh -s /bin/zsh' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'npm i -g @anthropic-ai/claude-code' - cp -rf ./cfg/os-release root.x86_64/var/lib/machines/arch/etc/os-release - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'useradd -m -G wheel -s /bin/zsh ai' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'echo "ai:root" | chpasswd' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'echo "%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/pacman -Syu --noconfirm, /usr/bin/rm -rf /var/lib/pacman/db.lck, /usr/bin/poweroff, /usr/bin/reboot, /usr/bin/machinectl" >> /etc/sudoers' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /etc/systemd/system/getty@tty1.service.d' - cat > root.x86_64/var/lib/machines/arch/etc/systemd/system/getty@tty1.service.d/override.conf <<'EOF' - [Service] - ExecStart= - ExecStart=-/usr/bin/agetty --autologin ai --noclear %I $TERM - EOF - cp -rf ./cfg/zshrc root.x86_64/var/lib/machines/arch/root/.zshrc - cp -rf ./cfg/zshrc root.x86_64/var/lib/machines/arch/home/ai/.zshrc - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown ai:ai /home/ai/.zshrc' - cp -rf ./cfg/aios.zsh root.x86_64/var/lib/machines/arch/usr/local/bin/aios-startup - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chmod +x /usr/local/bin/aios-startup' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/os' - cat > root.x86_64/var/lib/machines/arch/home/ai/.config/syui/ai/os/config.json <<'EOF' - { - "shell": false - } - EOF - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown -R ai:ai /home/ai/.config' - cat >> root.x86_64/var/lib/machines/arch/home/ai/.zshrc <<'EOF' - # aios startup - source /usr/local/bin/aios-startup - EOF - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'git clone https://git.syui.ai/ai/gpt && cd gpt && cargo build --release && cp -rf ./target/release/aigpt /bin/' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /root/.config/syui/ai/claude' - cat > root.x86_64/var/lib/machines/arch/root/.config/syui/ai/claude/claude_desktop_config.json <<'EOF' - { - "mcpServers": { - "aigpt": { - "command": "aigpt", - "args": ["server", "--enable-layer4"] - } - } - } - EOF - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'ln -sf /root/.config/syui/ai/claude /root/.config/claude' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/claude' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'cp /root/.config/syui/ai/claude/claude_desktop_config.json /home/ai/.config/syui/ai/claude/' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'ln -sf /home/ai/.config/syui/ai/claude /home/ai/.config/claude' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown -R ai:ai /home/ai/.config/syui' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'git clone https://git.syui.ai/ai/bot && cd bot && cargo build && cp -rf ./target/debug/ai /bin/ && ai ai' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /root/.config/syui/ai/gpt' - cp -rf ./cfg/mcp.json root.x86_64/var/lib/machines/arch/root/.config/syui/ai/mcp.json - cp -rf ./cfg/config.toml root.x86_64/var/lib/machines/arch/root/.config/syui/ai/config.toml - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'aigpt server --enable-layer4 &' - sleep 2 - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pkill aigpt' - arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'if command -v sqlite3 &>/dev/null; then sqlite3 /root/.config/syui/ai/gpt/memory.db "PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;"; fi' - cp -rf ./cfg/aios-ctl.zsh root.x86_64/var/lib/machines/arch/opt/aios-ctl.zsh - cp -rf ./cfg/install.sh ./install.sh - chmod +x ./install.sh - tar -zcvf aios-bootstrap.tar.gz root.x86_64/ install.sh + - name: Build aios + run: bash ./build.zsh + + - name: Create Docker images + run: | tar -C ./root.x86_64 -c . | docker import - ${{ env.IMAGE_NAME }} echo "${{ env.DOCKER_TOKEN }}" | docker login -u syui --password-stdin docker push ${{ env.IMAGE_NAME }} diff --git a/build.zsh b/build.zsh index babd919..f98598c 100755 --- a/build.zsh +++ b/build.zsh @@ -1,119 +1,119 @@ #!/bin/zsh +# aios build script +# 1. Build minimal Arch Linux base +# 2. Setup user (ai) and shell +# 3. Setup Claude Code and aigpt + +echo "=== aios build ===" +echo "" + +# Clean up previous build artifacts +echo "Cleaning up previous build..." +rm -rf root.x86_64/ archiso/ install.sh +rm -f aios-bootstrap*.tar.gz 2>/dev/null || true + +# ============================================ +# 1. Arch Linux Base Construction +# ============================================ + +echo "=== Step 1: Arch Linux Base ===" + +# Install build dependencies pacman -Syuu --noconfirm base-devel archiso docker git nodejs bc + +# Clone archiso git clone https://gitlab.archlinux.org/archlinux/archiso + +# Copy configuration cp -rf ./cfg/profiledef.sh /usr/share/archiso/configs/releng/ cp -rf ./cfg/profiledef.sh ./archiso/configs/releng/profiledef.sh cp -rf ./cfg/profiledef.sh ./archiso/configs/baseline/profiledef.sh cp -rf ./scpt/mkarchiso ./archiso/archiso/mkarchiso + +# Build bootstrap ./archiso/archiso/mkarchiso -v -o ./ ./archiso/configs/releng/ + +# Extract and prepare tar xf aios-bootstrap*.tar.gz -mkdir -p root.x86_64/var/lib/machines/arch -pacstrap -c root.x86_64/var/lib/machines/arch base +mkdir -p root.x86_64/var/lib/machines/aios +pacstrap -c root.x86_64/var/lib/machines/aios base + +# Configure pacman echo -e 'Server = http://mirrors.cat.net/archlinux/$repo/os/$arch -Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch' >> ./root.x86_64/var/lib/machines/arch/etc/pacman.d/mirrorlist -sed -i s/CheckSpace/#CheckeSpace/ root.x86_64/var/lib/machines/arch/etc/pacman.conf -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman-key --init' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman-key --populate archlinux' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pacman -Syu --noconfirm base base-devel linux vim git zsh rust openssh openssl jq go nodejs npm docker podman bc sqlite' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /etc/containers/registries.conf.d' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'curl -sL -o /etc/containers/registries.conf.d/ai.conf https://git.syui.ai/ai/os/raw/branch/main/cfg/ai.conf' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chsh -s /bin/zsh' +Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch' >> ./root.x86_64/var/lib/machines/aios/etc/pacman.d/mirrorlist +sed -i s/CheckSpace/#CheckeSpace/ root.x86_64/var/lib/machines/aios/etc/pacman.conf + +# Initialize pacman keys +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'pacman-key --init' +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'pacman-key --populate archlinux' + +# Install base packages (including systemd-container for machinectl) +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'pacman -Syu --noconfirm base base-devel linux vim git zsh rust openssh openssl jq go nodejs npm docker podman bc sqlite systemd arch-install-scripts' + +# Configure containers +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'mkdir -p /etc/containers/registries.conf.d' +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'curl -sL -o /etc/containers/registries.conf.d/ai.conf https://git.syui.ai/ai/os/raw/branch/main/cfg/ai.conf' + +# Set default shell +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'chsh -s /bin/zsh' # Install Claude Code -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'npm i -g @anthropic-ai/claude-code' +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'npm i -g @anthropic-ai/claude-code' # Copy os-release -cp -rf ./cfg/os-release root.x86_64/var/lib/machines/arch/etc/os-release +cp -rf ./cfg/os-release root.x86_64/var/lib/machines/aios/etc/os-release -# Create default user 'ai' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'useradd -m -G wheel -s /bin/zsh ai' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'echo "ai:root" | chpasswd' +# Configure sudoers for wheel group +echo "Configuring sudoers..." +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'echo "%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/pacman, /usr/bin/pacstrap, /usr/bin/arch-chroot, /usr/bin/rm, /usr/bin/mkdir, /usr/bin/mv, /usr/bin/cp, /usr/bin/poweroff, /usr/bin/reboot, /usr/bin/machinectl, /bin/bash" >> /etc/sudoers' -# Enable wheel group for sudo (specific commands without password) -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'echo "%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/pacman -Syu --noconfirm, /usr/bin/rm -rf /var/lib/pacman/db.lck, /usr/bin/poweroff, /usr/bin/reboot, /usr/bin/machinectl" >> /etc/sudoers' +# Install aigpt (aios core package) +echo "Installing aigpt..." +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'git clone https://git.syui.ai/ai/gpt && cd gpt && cargo build --release && cp -rf ./target/release/aigpt /bin/' -# Setup auto-login for user 'ai' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /etc/systemd/system/getty@tty1.service.d' -cat > root.x86_64/var/lib/machines/arch/etc/systemd/system/getty@tty1.service.d/override.conf <<'EOF' -[Service] -ExecStart= -ExecStart=-/usr/bin/agetty --autologin ai --noclear %I $TERM -EOF +# Install aibot (aios core package) +echo "Installing aibot..." +arch-chroot root.x86_64/var/lib/machines/aios /bin/sh -c 'git clone https://git.syui.ai/ai/bot && cd bot && cargo build && cp -rf ./target/debug/aibot /bin/ && aibot ai' -# Copy .zshrc for root -cp -rf ./cfg/zshrc root.x86_64/var/lib/machines/arch/root/.zshrc +echo "✓ Arch Linux base complete" +echo "" -# Copy .zshrc for user 'ai' -cp -rf ./cfg/zshrc root.x86_64/var/lib/machines/arch/home/ai/.zshrc -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown ai:ai /home/ai/.zshrc' +# ============================================ +# 2. User Setup +# ============================================ -# Copy aios startup script -cp -rf ./cfg/aios.zsh root.x86_64/var/lib/machines/arch/usr/local/bin/aios-startup -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chmod +x /usr/local/bin/aios-startup' +bash ./cfg/setup-user.sh +echo "" -# Create default config directory and file for user 'ai' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/os' -cat > root.x86_64/var/lib/machines/arch/home/ai/.config/syui/ai/os/config.json <<'EOF' -{ - "shell": false -} -EOF -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown -R ai:ai /home/ai/.config' +# ============================================ +# 3. Claude & aigpt Setup +# ============================================ -# Update .zshrc to source startup script -cat >> root.x86_64/var/lib/machines/arch/home/ai/.zshrc <<'EOF' +bash ./cfg/setup-claude.sh +echo "" -# aios startup -source /usr/local/bin/aios-startup -EOF +# ============================================ +# Finalize +# ============================================ -# Install aigpt (AI memory system) -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'git clone https://git.syui.ai/ai/gpt && cd gpt && cargo build --release && cp -rf ./target/release/aigpt /bin/' - -# Setup Claude Code MCP configuration (shared via symlink) -# Create actual config in syui/ai/claude (bind-mounted) -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /root/.config/syui/ai/claude' -cat > root.x86_64/var/lib/machines/arch/root/.config/syui/ai/claude/claude_desktop_config.json <<'EOF' -{ - "mcpServers": { - "aigpt": { - "command": "aigpt", - "args": ["server", "--enable-layer4"] - } - } -} -EOF - -# Create symlink for root -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'ln -sf /root/.config/syui/ai/claude /root/.config/claude' - -# Setup for ai user too -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/claude' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'cp /root/.config/syui/ai/claude/claude_desktop_config.json /home/ai/.config/syui/ai/claude/' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'ln -sf /home/ai/.config/syui/ai/claude /home/ai/.config/claude' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'chown -R ai:ai /home/ai/.config/syui' - -# Install ai/bot (optional, for backward compatibility) -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'git clone https://git.syui.ai/ai/bot && cd bot && cargo build && cp -rf ./target/debug/ai /bin/ && ai ai' - -# Create config directory -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'mkdir -p /root/.config/syui/ai/gpt' - -# Copy MCP and aios configuration -cp -rf ./cfg/mcp.json root.x86_64/var/lib/machines/arch/root/.config/syui/ai/mcp.json -cp -rf ./cfg/config.toml root.x86_64/var/lib/machines/arch/root/.config/syui/ai/config.toml - -# Initialize aigpt database with WAL mode -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'aigpt server --enable-layer4 &' -sleep 2 -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'pkill aigpt' -arch-chroot root.x86_64/var/lib/machines/arch /bin/sh -c 'if command -v sqlite3 &>/dev/null; then sqlite3 /root/.config/syui/ai/gpt/memory.db "PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;"; fi' +echo "=== Finalizing ===" # Copy aios-ctl.zsh for host machine control -cp -rf ./cfg/aios-ctl.zsh root.x86_64/var/lib/machines/arch/opt/aios-ctl.zsh +cp -rf ./cfg/aios-ctl.zsh root.x86_64/var/lib/machines/aios/opt/aios-ctl.zsh -# Copy install script to root for easy access +# Prepare directory for child containers (ai user will create them as needed) +echo "Preparing directory for child containers..." +mkdir -p root.x86_64/var/lib/machines/aios/var/lib/machines + +# Copy install script cp -rf ./cfg/install.sh ./install.sh chmod +x ./install.sh +# Create tarball with aios (ready for child containers) +echo "Creating tarball..." tar -zcvf aios-bootstrap.tar.gz root.x86_64/ install.sh + +echo "" +echo "=== Build Complete ===" +echo "Output: aios-bootstrap.tar.gz" +echo "" diff --git a/cfg/aios-ctl.zsh b/cfg/aios-ctl.zsh index 41cfd30..05bef2b 100644 --- a/cfg/aios-ctl.zsh +++ b/cfg/aios-ctl.zsh @@ -21,9 +21,9 @@ function aios-shell() { sudo machinectl shell $NAME } -# Login to aios container +# Login to aios container as ai user function aios-login() { - sudo machinectl login $NAME + sudo machinectl shell $NAME /bin/su - ai } # Create backup of current aios diff --git a/cfg/init-containers.sh b/cfg/init-containers.sh new file mode 100644 index 0000000..8a8dac8 --- /dev/null +++ b/cfg/init-containers.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Initialize child containers for ai user +# This script runs once on first login + +echo "=== Initializing workspace containers ===" +echo "This may take a few minutes..." + +# Create workspace directory +mkdir -p /tmp/workspace-init + +# Create base workspace +echo "Creating workspace container..." +sudo pacstrap -c /tmp/workspace-init base + +# Configure workspace +sudo arch-chroot /tmp/workspace-init /bin/sh -c 'pacman -Syu --noconfirm vim git zsh openssh nodejs npm sqlite' + +# Add securetty for pts login +sudo bash -c 'cat >> /tmp/workspace-init/etc/securetty < /etc/systemd/nspawn/$NAME.nspawn <<'EOF' -[Exec] -Boot=yes -PrivateUsers=pick -ResolvConf=copy-host - -[Files] -Bind=/root/.config/syui/ai:/root/.config/syui/ai - -[Network] -VirtualEthernet=no -EOF - -# Create aiosback.nspawn -cat > /etc/systemd/nspawn/$BACKUP.nspawn <<'EOF' -[Exec] -Boot=yes -PrivateUsers=pick -ResolvConf=copy-host - -[Files] -Bind=/root/.config/syui/ai:/root/.config/syui/ai - -[Network] -VirtualEthernet=no -EOF - -# Create workspace.nspawn -cat > /etc/systemd/nspawn/workspace.nspawn <<'EOF' -[Exec] -Boot=yes -PrivateUsers=pick -ResolvConf=copy-host - -[Files] -Bind=/root/.config/syui/ai:/root/.config/syui/ai - -[Network] -VirtualEthernet=no -EOF - -# Create bind mount directory -mkdir -p /root/.config/syui/ai - -# Enable systemd-machined -echo "4. Enabling systemd-machined..." -systemctl enable --now systemd-machined - -# Remove existing images if they exist -echo "5. Checking for existing images..." -for img in $BACKUP workspace; do - if machinectl list-images | grep -q "^$img"; then - echo " Removing existing image: $img" - machinectl poweroff $img 2>/dev/null || true - sleep 1 - machinectl terminate $img 2>/dev/null || true - sleep 1 - machinectl remove $img - fi -done - -# Create initial backup -echo "6. Creating initial backup image..." -machinectl clone $NAME $BACKUP - -# Create workspace container for AI operations -echo "7. Creating workspace container..." -machinectl clone $NAME workspace - -echo "" echo "=== Installation complete ===" echo "" -echo "Next steps for each user:" -echo " 1. Copy control script to your home:" -echo " cp /var/lib/machines/$NAME/opt/aios-ctl.zsh ~/.aios-ctl.zsh" -echo "" -echo " 2. Add to your .zshrc:" -echo " echo 'source ~/.aios-ctl.zsh' >> ~/.zshrc" -echo " source ~/.zshrc" -echo "" -echo " 3. Start aios:" -echo " aios-start" -echo "" -echo " 4. Login to aios:" -echo " aios-login" -echo "" -echo "Available commands:" -echo " aios-start, aios-stop, aios-shell, aios-login" -echo " aios-backup, aios-reset, aios-update" -echo " aios-help for full list" +echo "Usage:" +echo " sudo machinectl start $NAME" +echo " sudo machinectl shell $NAME /bin/su - ai" echo "" diff --git a/cfg/setup-claude.sh b/cfg/setup-claude.sh new file mode 100755 index 0000000..a0a2981 --- /dev/null +++ b/cfg/setup-claude.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Claude Code MCP setup for aios +# Configures MCP, sets up shared memory + +ROOTFS="root.x86_64/var/lib/machines/aios" + +echo "=== Claude MCP Setup ===" + +# Setup Claude Code MCP configuration (shared via symlink) +echo "Configuring MCP..." +# Create actual config in syui/ai/claude (bind-mounted) +arch-chroot $ROOTFS /bin/sh -c 'mkdir -p /root/.config/syui/ai/claude' +cat > $ROOTFS/root/.config/syui/ai/claude/claude_desktop_config.json <<'EOF' +{ + "mcpServers": { + "aigpt": { + "command": "aigpt", + "args": ["server", "--enable-layer4"] + } + } +} +EOF + +# Create symlink for root +arch-chroot $ROOTFS /bin/sh -c 'ln -sf /root/.config/syui/ai/claude /root/.config/claude' + +# Setup for ai user too +arch-chroot $ROOTFS /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/claude' +arch-chroot $ROOTFS /bin/sh -c 'cp /root/.config/syui/ai/claude/claude_desktop_config.json /home/ai/.config/syui/ai/claude/' +arch-chroot $ROOTFS /bin/sh -c 'ln -sf /home/ai/.config/syui/ai/claude /home/ai/.config/claude' +arch-chroot $ROOTFS /bin/sh -c 'chown -R ai:ai /home/ai/.config/syui' + +# Create config directory +arch-chroot $ROOTFS /bin/sh -c 'mkdir -p /root/.config/syui/ai/gpt' + +# Copy MCP and aios configuration +echo "Copying configuration files..." +cp -rf ./cfg/mcp.json $ROOTFS/root/.config/syui/ai/mcp.json +cp -rf ./cfg/config.toml $ROOTFS/root/.config/syui/ai/config.toml + +# Initialize aigpt database with WAL mode +echo "Initializing aigpt database..." +arch-chroot $ROOTFS /bin/sh -c 'aigpt server --enable-layer4 &' +sleep 2 +arch-chroot $ROOTFS /bin/sh -c 'pkill aigpt' +arch-chroot $ROOTFS /bin/sh -c 'if command -v sqlite3 &>/dev/null; then sqlite3 /root/.config/syui/ai/gpt/memory.db "PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;"; fi' + +echo "✓ Claude MCP setup complete" diff --git a/cfg/setup-user.sh b/cfg/setup-user.sh new file mode 100755 index 0000000..583faf7 --- /dev/null +++ b/cfg/setup-user.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# User setup for aios +# Creates ai user, configures auto-login, sudo, zshrc + +ROOTFS="root.x86_64/var/lib/machines/aios" + +echo "=== User Setup ===" + +# Create default user 'ai' +echo "Creating user 'ai'..." +arch-chroot $ROOTFS /bin/sh -c 'useradd -m -G wheel -s /bin/zsh ai' +arch-chroot $ROOTFS /bin/sh -c 'echo "ai:root" | chpasswd' + +# Configure securetty for pts login (required for systemd-nspawn) +echo "Configuring securetty..." +cat >> $ROOTFS/etc/securetty <<'EOF' +pts/0 +pts/1 +pts/2 +pts/3 +pts/4 +pts/5 +pts/6 +pts/7 +pts/8 +pts/9 +EOF + +# Enable systemd-machined for container management +echo "Enabling systemd-machined..." +arch-chroot $ROOTFS /bin/sh -c 'systemctl enable systemd-machined' + +# Setup auto-login for user 'ai' +echo "Setting up auto-login..." +arch-chroot $ROOTFS /bin/sh -c 'mkdir -p /etc/systemd/system/getty@tty1.service.d' +cat > $ROOTFS/etc/systemd/system/getty@tty1.service.d/override.conf <<'EOF' +[Service] +ExecStart= +ExecStart=-/usr/bin/agetty --autologin ai --noclear %I $TERM +EOF + +# Copy .zshrc for root +echo "Copying zshrc..." +cp -rf ./cfg/zshrc $ROOTFS/root/.zshrc + +# Copy .zshrc for user 'ai' +cp -rf ./cfg/zshrc $ROOTFS/home/ai/.zshrc + +# Copy container initialization script +cp -rf ./cfg/init-containers.sh $ROOTFS/usr/local/bin/init-containers.sh +arch-chroot $ROOTFS /bin/sh -c 'chmod +x /usr/local/bin/init-containers.sh' + +# Add initialization, MCP auto-setup and claude auto-start for ai user (login shell only) +cat >> $ROOTFS/home/ai/.zshrc <<'EOF' + +# Initialize workspace containers on first login +if [ ! -f ~/.aios-initialized ]; then + echo "First login detected. Initializing workspace containers..." + if command -v sudo &>/dev/null && [ -x /usr/local/bin/init-containers.sh ]; then + /usr/local/bin/init-containers.sh && touch ~/.aios-initialized + fi +fi + +# MCP auto-setup (run once after .claude.json is created) +if [[ -f ~/.claude.json ]] && ! grep -q '"aigpt"' ~/.claude.json 2>/dev/null; then + if command -v claude &>/dev/null && command -v aigpt &>/dev/null; then + claude mcp add aigpt aigpt server &>/dev/null || true + fi +fi + +# Auto-start claude in interactive login shell +if [[ -o login ]] && [[ -o interactive ]]; then + if command -v claude &>/dev/null; then + claude + fi +fi +EOF + +arch-chroot $ROOTFS /bin/sh -c 'chown ai:ai /home/ai/.zshrc' + +# Copy aios startup script +cp -rf ./cfg/aios.zsh $ROOTFS/usr/local/bin/aios-startup +arch-chroot $ROOTFS /bin/sh -c 'chmod +x /usr/local/bin/aios-startup' + +# Create default config directory and file for user 'ai' +arch-chroot $ROOTFS /bin/sh -c 'mkdir -p /home/ai/.config/syui/ai/os' +cat > $ROOTFS/home/ai/.config/syui/ai/os/config.json <<'EOF' +{ + "shell": false +} +EOF +arch-chroot $ROOTFS /bin/sh -c 'chown -R ai:ai /home/ai/.config' + +# Update .zshrc to source startup script +cat >> $ROOTFS/home/ai/.zshrc <<'EOF' + +# aios startup +source /usr/local/bin/aios-startup +EOF + +echo "✓ User setup complete" diff --git a/scpt/mkarchiso b/scpt/mkarchiso index 5b08ab0..c6f8d55 100755 --- a/scpt/mkarchiso +++ b/scpt/mkarchiso @@ -1335,17 +1335,19 @@ _validate_requirements_buildmode_bootstrap() { local bootstrap_pkg_list_from_file=() # Check if packages for the bootstrap image are specified - if [[ -e "${bootstrap_packages}" ]]; then - mapfile -t bootstrap_pkg_list_from_file < \ - <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}") - bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}") - if (( ${#bootstrap_pkg_list_from_file[@]} < 1 )); then + if [[ -n "${bootstrap_packages}" ]]; then + if [[ -e "${bootstrap_packages}" ]]; then + mapfile -t bootstrap_pkg_list_from_file < \ + <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}") + bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}") + if (( ${#bootstrap_pkg_list_from_file[@]} < 1 )); then + (( validation_error=validation_error+1 )) + _msg_error "No package specified in '${bootstrap_packages}'." 0 + fi + else (( validation_error=validation_error+1 )) - _msg_error "No package specified in '${bootstrap_packages}'." 0 + _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0 fi - else - (( validation_error=validation_error+1 )) - _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0 fi _validate_common_requirements_buildmode_all