From f41a8ff3d3bd536bbb1bfd86db67dcc065bb23b4 Mon Sep 17 00:00:00 2001 From: egg Date: Mon, 16 Mar 2026 04:29:57 +0000 Subject: [PATCH 1/6] Add setup skill for guided egg onboarding and config updates --- skills/setup/SKILL.md | 377 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 skills/setup/SKILL.md diff --git a/skills/setup/SKILL.md b/skills/setup/SKILL.md new file mode 100644 index 0000000000..5f8c4a0407 --- /dev/null +++ b/skills/setup/SKILL.md @@ -0,0 +1,377 @@ +--- +name: setup +description: Walk the user through initial egg setup or update an existing configuration — checks dependencies, configures secrets, repositories, and validates the installation. +disable-model-invocation: true +argument-hint: "[--check | --update secrets | --update repos | --update config]" +--- + +# Setup + +You are guiding the user through egg setup or configuration updates. Walk through the phases below, adapting based on whether this is a fresh install or an update. + +## Argument Parsing + +Parse arguments after `/setup`: + +| Input | Interpretation | +|-------|---------------| +| `/setup` | Full setup — run all phases in order | +| `/setup --check` | Health check only — verify dependencies and config, report status | +| `/setup --update secrets` | Update secrets only (Phase 3) | +| `/setup --update repos` | Update repository configuration only (Phase 4) | +| `/setup --update config` | Update general config only (Phase 5) | + +## Phase 1 — Dependency Check + +Verify all required dependencies are installed and meet minimum versions. Run these checks using Bash commands: + +### Required Dependencies + +| Dependency | Check command | Minimum version | Install guidance | +|------------|--------------|-----------------|------------------| +| **Python** | `python3 --version` | 3.13+ | python.org or system package manager | +| **Docker** | `docker --version` | 20.10+ | docker.com/get-docker | +| **Docker Compose** | `docker compose version` | 2.0+ | Included with Docker Desktop; Linux: install docker-compose-plugin | +| **Git** | `git --version` | 2.30+ | git-scm.com | +| **GitHub CLI** | `gh --version` | 2.0+ | cli.github.com | +| **uv** (optional) | `uv --version` | any | For development; `curl -LsSf https://astral.sh/uv/install.sh \| sh` | + +### Additional Checks + +- **Docker running**: `docker info >/dev/null 2>&1` — if this fails, Docker daemon is not running +- **gh authenticated**: `gh auth status` — if not authenticated, guide user to run `gh auth login` +- **egg CLI installed**: `egg --version 2>/dev/null || which egg` — if missing, advise `pip install -e ./sandbox` + +### Reporting + +Present results as a compact checklist: + +``` +## Dependency Check + +- [x] Python 3.13.2 +- [x] Docker 27.5.1 +- [x] Docker Compose v2.32.4 +- [x] Git 2.48.1 +- [x] GitHub CLI 2.67.0 +- [x] Docker daemon running +- [x] gh authenticated as +- [ ] egg CLI not found — run: pip install -e ./sandbox +- [ ] uv not found (optional) — install for development +``` + +If any **required** dependency is missing or below minimum version, use `AskUserQuestion`: +- **Question**: "Some required dependencies are missing or outdated. Would you like help installing them?" +- **Header**: "Dependencies" +- **Options**: + - **"Show install instructions"** — description: "Display install commands for each missing dependency" + - **"Skip and continue"** — description: "Proceed with setup anyway (may fail later)" + - **"Abort setup"** — description: "Exit setup to install dependencies manually" + +If "Show install instructions", detect the platform and show appropriate commands: +- **macOS**: `brew install` commands +- **Linux (Debian/Ubuntu)**: `apt` commands +- **Linux (Fedora/RHEL)**: `dnf` commands +- **Generic**: Direct download links + +After showing instructions, ask if the user has installed the dependencies and wants to re-check. + +If running `/setup --check`, stop here after reporting the results. Do not proceed to other phases. + +## Phase 2 — Existing Configuration Detection + +Check for existing configuration at `~/.config/egg/`: + +```bash +ls -la ~/.config/egg/ 2>/dev/null +``` + +If the directory exists and contains configuration files, present a summary: + +``` +## Existing Configuration Found + +| File | Status | +|------|--------| +| config.yaml | Present (last modified: ) | +| repositories.yaml | Present | +| secrets.env | Present | +| github-app.pem | Not found | +| launcher-secret | Present | +``` + +Then use `AskUserQuestion`: +- **Question**: "Existing egg configuration found. What would you like to do?" +- **Header**: "Config" +- **Options**: + - **"Update existing"** — description: "Keep current config and update specific sections" + - **"Fresh setup"** — description: "Start from scratch (backs up existing config first)" + - **"Validate only"** — description: "Check current config for errors without changing anything" + +If "Update existing" → ask which section to update (secrets, repos, or general config), then jump to the relevant phase. +If "Fresh setup" → back up existing config to `~/.config/egg/backup-/`, then proceed through all phases. +If "Validate only" → run Phase 6 (Validation) and report results. + +If no existing configuration is found, proceed directly to Phase 3. + +## Phase 3 — Secrets Configuration + +Configure credentials in `~/.config/egg/secrets.env`. For each secret category, check if already configured and only prompt for missing or explicitly updated values. + +### Step 1: Anthropic Authentication + +Use `AskUserQuestion`: +- **Question**: "How do you authenticate with Claude?" +- **Header**: "Auth" +- **Options**: + - **"OAuth Token (Recommended)"** — description: "Uses your Claude.ai account. Run: claude auth status --json | jq -r '.oauthToken'" + - **"API Key"** — description: "Direct Anthropic API access. Get from console.anthropic.com/settings/keys" + +Based on selection: +- **OAuth**: Guide user to run `claude auth status --json | jq -r '.oauthToken'` and paste the token. Validate it starts with `sk-ant-oat`. +- **API Key**: Ask for the key. Validate it starts with `sk-ant-api`. + +### Step 2: GitHub Authentication + +Use `AskUserQuestion`: +- **Question**: "How should egg authenticate with GitHub?" +- **Header**: "GitHub" +- **Options**: + - **"GitHub App (Recommended)"** — description: "Bot identity for PRs and pushes. Requires App ID, Installation ID, and .pem file" + - **"Personal Access Token"** — description: "Uses your personal GitHub identity. Simpler setup but PRs are attributed to you" + - **"Both"** — description: "GitHub App for bot repos + PAT for personal repos (auth_mode: user)" + +Based on selection: + +**GitHub App flow**: +1. Ask for GitHub App ID (validate it's numeric) +2. Ask for Installation ID (validate it's numeric) +3. Ask for path to the `.pem` private key file. Validate the file exists and ends with `.pem`. Copy it to `~/.config/egg/github-app.pem` with `chmod 600`. +4. Ask for the bot name (must match the GitHub App name exactly) +5. Ask for the branch prefix (default: same as bot name, typically `egg`) + +**PAT flow**: +1. Ask for the GitHub PAT. Validate it starts with `ghp_` or `github_pat_`. +2. Set `GITHUB_USER_TOKEN` in secrets.env. +3. Set `GATEWAY_BOT_NAME=egg` and `GATEWAY_BOT_BRANCH_PREFIX=egg` as defaults. +4. Ask for the user's GitHub username for `GATEWAY_TRUSTED_USERS`. + +**Both flow**: Run GitHub App flow first, then PAT flow for `GITHUB_USER_TOKEN`. + +### Step 3: Optional Integrations + +Use `AskUserQuestion` (multiSelect): +- **Question**: "Which optional integrations do you want to configure?" +- **Header**: "Integrations" +- **multiSelect**: true +- **Options**: + - **"Slack"** — description: "Bot notifications and task requests (requires Slack App)" + - **"Confluence"** — description: "Sync ADRs, runbooks, and best practices" + - **"JIRA"** — description: "Sync tickets, requirements, and sprint info" + - **"None"** — description: "Skip optional integrations" + +For each selected integration, collect the required credentials (see `config/secrets.template.env` for the fields). + +### Step 4: Generate Launcher Secret + +Automatically generate the launcher secret if it doesn't exist: + +```bash +python3 -c "import secrets; print(secrets.token_urlsafe(32))" > ~/.config/egg/launcher-secret +chmod 600 ~/.config/egg/launcher-secret +``` + +### Step 5: Write secrets.env + +Write all collected secrets to `~/.config/egg/secrets.env` with `chmod 600`. Group by category with comments. Never overwrite values the user chose to keep. + +## Phase 4 — Repository Configuration + +Configure `~/.config/egg/repositories.yaml`. + +### Step 1: GitHub Username + +Ask for the user's GitHub username. Try to auto-detect from `gh api user --jq .login` first. + +### Step 2: Local Repositories + +Ask the user to provide paths to local git repositories to mount into the container: + +- **Question**: "Enter paths to local git repositories (these will be mounted into the egg container). Type each path and press Enter. Type 'done' when finished." +- Validate each path exists and is a git repo (has `.git/` directory) +- Auto-detect the remote URL to determine `owner/repo` format + +Present the detected repos: +``` +## Detected Repositories + +| Local Path | Remote | Owner/Repo | +|------------|--------|------------| +| /home/user/projects/my-app | github.com | user/my-app | +| /home/user/work/api-service | github.com | org/api-service | +``` + +### Step 3: Writable vs Read-only + +For each detected repo, use `AskUserQuestion`: +- **Question**: "What access level should egg have for ?" +- **Header**: "Access" +- **Options**: + - **"Writable"** — description: "Can push code, create PRs, respond to comments" + - **"Read-only"** — description: "Can monitor and analyze, but not modify" + +### Step 4: Per-repo Settings + +For each writable repo, ask about optional settings: + +Use `AskUserQuestion` (multiSelect): +- **Question**: "Configure optional settings for ?" +- **Header**: "Settings" +- **multiSelect**: true +- **Options**: + - **"Custom check commands"** — description: "Specify lint/test commands for SDLC pipeline (default: auto-discover)" + - **"User auth mode"** — description: "Use personal PAT instead of bot identity for this repo" + - **"None"** — description: "Use defaults" + +If "Custom check commands": collect name/command pairs for each check. +If "User auth mode": set `auth_mode: user` for this repo. + +### Step 5: Default Reviewer + +Set the default PR reviewer to the GitHub username collected in Step 1. + +### Step 6: Write repositories.yaml + +Write the configuration to `~/.config/egg/repositories.yaml`. + +## Phase 5 — General Configuration + +Create or update `~/.config/egg/config.yaml` with system-detected defaults. + +Auto-detect these values (do not prompt unless detection fails): +- `host_home`: from `$HOME` +- `host_uid`: from `id -u` +- `host_gid`: from `id -g` +- `anthropic_auth_method`: based on which credential was configured in Phase 3 + +Set sensible defaults for: +- `git_name`: "egg" +- `git_email`: "egg@localhost" +- `compose_project_name`: "egg" +- `gateway_api_port`: 9848 +- `gateway_proxy_port`: 3129 +- `orchestrator_api_port`: 9849 +- `mcp_server_port`: 9850 +- `mcp_rate_limit`: 30 + +Write to `~/.config/egg/config.yaml`. + +## Phase 6 — Validation + +Run a comprehensive validation of the setup. Check each component and report results. + +### Configuration Validation + +```bash +# Check all required config files exist +ls ~/.config/egg/config.yaml +ls ~/.config/egg/repositories.yaml +ls ~/.config/egg/secrets.env +ls ~/.config/egg/launcher-secret +``` + +### Secrets Validation + +Read `~/.config/egg/secrets.env` and verify: +- At least one Anthropic credential is set (OAuth token or API key) +- GitHub credentials are configured (App or PAT) +- `GATEWAY_BOT_NAME` is set +- `GATEWAY_BOT_BRANCH_PREFIX` is set +- File permissions are 600 + +### Repository Validation + +Parse `~/.config/egg/repositories.yaml` and verify: +- `github_username` is set +- At least one entry in `writable_repos` or `local_repos.paths` +- All local repo paths exist and are git repositories +- For repos with `auth_mode: user`, verify `GITHUB_USER_TOKEN` is set in secrets.env + +### Docker Validation + +```bash +# Check images can build (dry-run is not available, so just check Dockerfile exists) +ls Dockerfile 2>/dev/null || ls sandbox/Dockerfile 2>/dev/null + +# Check for port conflicts +ss -tlnp 2>/dev/null | grep -E ':(9848|9849|9850|3129) ' || echo "Ports available" +``` + +### Report + +Present a final validation report: + +``` +## Setup Validation + +### Configuration Files +- [x] config.yaml — valid +- [x] repositories.yaml — valid +- [x] secrets.env — valid (permissions: 600) +- [x] launcher-secret — valid + +### Credentials +- [x] Anthropic: OAuth token configured +- [x] GitHub: App configured (App ID: 12345) +- [x] Gateway: bot_name=my-bot, branch_prefix=egg + +### Repositories +- [x] user/my-app — writable, local path valid +- [x] org/api-service — read-only + +### Infrastructure +- [x] Docker daemon running +- [x] Ports 9848, 9849, 9850, 3129 available +``` + +If any validation fails, highlight the issue and offer to fix it (jump back to the relevant phase). + +## Phase 7 — Next Steps + +After successful setup or validation, show: + +``` +## Setup Complete + +Your egg configuration is ready. Here's what to do next: + +### First Run + egg --compose # Start gateway + orchestrator (builds images on first run) + egg # Start an interactive Claude Code session + +### Quick Commands + egg --compose --down # Stop gateway + orchestrator + egg --private # Run in private mode (Anthropic API only) + egg --exec "cmd" # Run a command in an ephemeral container + +### SDLC Pipeline + Inside the sandbox, run: + /sdlc # Prompt-driven pipeline + /sdlc -r -i # Issue-driven pipeline + +### Update Configuration Later + /setup --update secrets # Update API keys and tokens + /setup --update repos # Add or modify repositories + /setup --update config # Update general settings + /setup --check # Verify your setup is healthy +``` + +## Critical Rules + +- **Never expose secrets** — mask tokens when displaying (show first 8 and last 4 chars only) +- **Always validate input** — check token formats, file existence, path validity before writing +- **Back up before overwriting** — when updating existing config, create a timestamped backup first +- **Respect existing values** — when updating, only change what the user explicitly asks to change +- **Use chmod 600** for secrets.env, .pem files, and launcher-secret +- **Auto-detect when possible** — minimize questions by detecting platform, username, repo info automatically +- **Keep output concise** — use checklists and tables, not verbose paragraphs From f2040c3b6ae84e58402a6ff80503a373ee50b532 Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 04:44:31 +0000 Subject: [PATCH 2/6] Address review feedback on setup skill Fix all 5 blocking issues: - Python version: 3.13+ -> 3.11+ (matches pyproject.toml requires-python) - Specify CLAUDE_CODE_OAUTH_TOKEN as preferred variable name - Add GITHUB_APP_ID and GITHUB_APP_INSTALLATION_ID to App flow - PAT flow now sets both GITHUB_TOKEN and GITHUB_USER_TOKEN - Add complete secrets.env variable name mapping table Fix non-blocking issues: - Add bot_username step in repository configuration - Write read-only repos to readable_repos section - Use AskUserQuestion pattern for local repo collection - Cross-platform port check (ss/lsof/Python fallback) - Secrets validation: never display raw values - Reference config/secrets.template.env as source of truth --- skills/setup/SKILL.md | 89 ++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/skills/setup/SKILL.md b/skills/setup/SKILL.md index 5f8c4a0407..50836d5b3f 100644 --- a/skills/setup/SKILL.md +++ b/skills/setup/SKILL.md @@ -29,7 +29,7 @@ Verify all required dependencies are installed and meet minimum versions. Run th | Dependency | Check command | Minimum version | Install guidance | |------------|--------------|-----------------|------------------| -| **Python** | `python3 --version` | 3.13+ | python.org or system package manager | +| **Python** | `python3 --version` | 3.11+ | python.org or system package manager | | **Docker** | `docker --version` | 20.10+ | docker.com/get-docker | | **Docker Compose** | `docker compose version` | 2.0+ | Included with Docker Desktop; Linux: install docker-compose-plugin | | **Git** | `git --version` | 2.30+ | git-scm.com | @@ -128,8 +128,8 @@ Use `AskUserQuestion`: - **"API Key"** — description: "Direct Anthropic API access. Get from console.anthropic.com/settings/keys" Based on selection: -- **OAuth**: Guide user to run `claude auth status --json | jq -r '.oauthToken'` and paste the token. Validate it starts with `sk-ant-oat`. -- **API Key**: Ask for the key. Validate it starts with `sk-ant-api`. +- **OAuth**: Guide user to run `claude auth status --json | jq -r '.oauthToken'` and paste the token. Validate it starts with `sk-ant-oat`. Write to `CLAUDE_CODE_OAUTH_TOKEN` in secrets.env (this is the preferred variable name — the gateway checks it first before the legacy `ANTHROPIC_OAUTH_TOKEN`). +- **API Key**: Ask for the key. Validate it starts with `sk-ant-api`. Write to `ANTHROPIC_API_KEY` in secrets.env. ### Step 2: GitHub Authentication @@ -144,17 +144,17 @@ Use `AskUserQuestion`: Based on selection: **GitHub App flow**: -1. Ask for GitHub App ID (validate it's numeric) -2. Ask for Installation ID (validate it's numeric) +1. Ask for GitHub App ID (validate it's numeric). Write to `GITHUB_APP_ID` in secrets.env. +2. Ask for Installation ID (validate it's numeric). Write to `GITHUB_APP_INSTALLATION_ID` in secrets.env. 3. Ask for path to the `.pem` private key file. Validate the file exists and ends with `.pem`. Copy it to `~/.config/egg/github-app.pem` with `chmod 600`. -4. Ask for the bot name (must match the GitHub App name exactly) -5. Ask for the branch prefix (default: same as bot name, typically `egg`) +4. Ask for the bot name (must match the GitHub App name exactly). Write to `GATEWAY_BOT_NAME` in secrets.env. +5. Ask for the branch prefix (default: same as bot name, typically `egg`). Write to `GATEWAY_BOT_BRANCH_PREFIX` in secrets.env. **PAT flow**: 1. Ask for the GitHub PAT. Validate it starts with `ghp_` or `github_pat_`. -2. Set `GITHUB_USER_TOKEN` in secrets.env. -3. Set `GATEWAY_BOT_NAME=egg` and `GATEWAY_BOT_BRANCH_PREFIX=egg` as defaults. -4. Ask for the user's GitHub username for `GATEWAY_TRUSTED_USERS`. +2. Set both `GITHUB_TOKEN` and `GITHUB_USER_TOKEN` to the provided PAT in secrets.env. (`GITHUB_TOKEN` is used by the gateway for all repos by default; `GITHUB_USER_TOKEN` is used for repos with `auth_mode: user`.) +3. Set `GATEWAY_BOT_NAME=egg` and `GATEWAY_BOT_BRANCH_PREFIX=egg` as defaults in secrets.env. +4. Ask for the user's GitHub username for `GATEWAY_TRUSTED_USERS` in secrets.env. **Both flow**: Run GitHub App flow first, then PAT flow for `GITHUB_USER_TOKEN`. @@ -185,6 +185,30 @@ chmod 600 ~/.config/egg/launcher-secret Write all collected secrets to `~/.config/egg/secrets.env` with `chmod 600`. Group by category with comments. Never overwrite values the user chose to keep. +Reference `config/secrets.template.env` for the complete list of supported variables and their formats. The required variable names are: + +| Category | Variable Name | Source | +|----------|--------------|--------| +| Anthropic OAuth | `CLAUDE_CODE_OAUTH_TOKEN` | Phase 3 Step 1 (preferred over legacy `ANTHROPIC_OAUTH_TOKEN`) | +| Anthropic API key | `ANTHROPIC_API_KEY` | Phase 3 Step 1 | +| GitHub App ID | `GITHUB_APP_ID` | Phase 3 Step 2 | +| GitHub App Install ID | `GITHUB_APP_INSTALLATION_ID` | Phase 3 Step 2 | +| GitHub default token | `GITHUB_TOKEN` | Phase 3 Step 2 (PAT flow) | +| GitHub user PAT | `GITHUB_USER_TOKEN` | Phase 3 Step 2 (PAT or Both flow) | +| Gateway bot name | `GATEWAY_BOT_NAME` | Phase 3 Step 2 | +| Gateway branch prefix | `GATEWAY_BOT_BRANCH_PREFIX` | Phase 3 Step 2 | +| Gateway trusted users | `GATEWAY_TRUSTED_USERS` | Phase 3 Step 2 | +| Slack bot token | `SLACK_TOKEN` | Phase 3 Step 3 | +| Slack app token | `SLACK_APP_TOKEN` | Phase 3 Step 3 | +| Confluence base URL | `CONFLUENCE_BASE_URL` | Phase 3 Step 3 | +| Confluence username | `CONFLUENCE_USERNAME` | Phase 3 Step 3 | +| Confluence API token | `CONFLUENCE_API_TOKEN` | Phase 3 Step 3 | +| Confluence space keys | `CONFLUENCE_SPACE_KEYS` | Phase 3 Step 3 | +| JIRA base URL | `JIRA_BASE_URL` | Phase 3 Step 3 | +| JIRA username | `JIRA_USERNAME` | Phase 3 Step 3 | +| JIRA API token | `JIRA_API_TOKEN` | Phase 3 Step 3 | +| JIRA JQL query | `JIRA_JQL_QUERY` | Phase 3 Step 3 | + ## Phase 4 — Repository Configuration Configure `~/.config/egg/repositories.yaml`. @@ -195,11 +219,12 @@ Ask for the user's GitHub username. Try to auto-detect from `gh api user --jq .l ### Step 2: Local Repositories -Ask the user to provide paths to local git repositories to mount into the container: +Collect paths to local git repositories to mount into the container. Use `AskUserQuestion` iteratively: -- **Question**: "Enter paths to local git repositories (these will be mounted into the egg container). Type each path and press Enter. Type 'done' when finished." -- Validate each path exists and is a git repo (has `.git/` directory) -- Auto-detect the remote URL to determine `owner/repo` format +1. Ask: "Enter a path to a local git repository to mount into the egg container (or 'done' if finished)." +2. Validate the path exists and is a git repo (has `.git/` directory). +3. Auto-detect the remote URL to determine `owner/repo` format. +4. Ask: "Add another repository?" with options **"Yes"** / **"No, done adding repos"**. If "Yes", repeat from step 1. Present the detected repos: ``` @@ -236,13 +261,17 @@ Use `AskUserQuestion` (multiSelect): If "Custom check commands": collect name/command pairs for each check. If "User auth mode": set `auth_mode: user` for this repo. -### Step 5: Default Reviewer +### Step 5: Bot Username + +Set `bot_username` in repositories.yaml. Default to the `GATEWAY_BOT_NAME` value from Phase 3. This is used by the gateway for bot PR identification. + +### Step 6: Default Reviewer Set the default PR reviewer to the GitHub username collected in Step 1. -### Step 6: Write repositories.yaml +### Step 7: Write repositories.yaml -Write the configuration to `~/.config/egg/repositories.yaml`. +Write the configuration to `~/.config/egg/repositories.yaml`. Repos marked "Writable" go under `writable_repos`, repos marked "Read-only" go under `readable_repos`. ## Phase 5 — General Configuration @@ -282,9 +311,11 @@ ls ~/.config/egg/launcher-secret ### Secrets Validation -Read `~/.config/egg/secrets.env` and verify: -- At least one Anthropic credential is set (OAuth token or API key) -- GitHub credentials are configured (App or PAT) +Parse `~/.config/egg/secrets.env` and verify each required variable is set to a non-empty value. **Never display raw secret values** — only check for presence and validate prefixes (e.g., `sk-ant-oat`, `ghp_`). Do not `cat` or print the file contents. + +Verify: +- At least one Anthropic credential is set (`CLAUDE_CODE_OAUTH_TOKEN` or `ANTHROPIC_API_KEY`) +- GitHub credentials are configured (`GITHUB_APP_ID` + `GITHUB_APP_INSTALLATION_ID` for App, or `GITHUB_TOKEN` for PAT) - `GATEWAY_BOT_NAME` is set - `GATEWAY_BOT_BRANCH_PREFIX` is set - File permissions are 600 @@ -303,8 +334,22 @@ Parse `~/.config/egg/repositories.yaml` and verify: # Check images can build (dry-run is not available, so just check Dockerfile exists) ls Dockerfile 2>/dev/null || ls sandbox/Dockerfile 2>/dev/null -# Check for port conflicts -ss -tlnp 2>/dev/null | grep -E ':(9848|9849|9850|3129) ' || echo "Ports available" +# Check for port conflicts (cross-platform) +# Linux: +ss -tlnp 2>/dev/null | grep -E ':(9848|9849|9850|3129) ' || \ +# macOS: +lsof -i :9848 -i :9849 -i :9850 -i :3129 2>/dev/null || \ +# Fallback (cross-platform Python): +python3 -c " +import socket +for port in [9848, 9849, 9850, 3129]: + s = socket.socket() + try: + s.bind(('', port)) + s.close() + except OSError: + print(f'Port {port} in use') +" 2>/dev/null || echo "Ports available" ``` ### Report From 0905a37fd1b20e17c7cbcbdebfce8ef7e88dff01 Mon Sep 17 00:00:00 2001 From: egg Date: Mon, 16 Mar 2026 04:52:27 +0000 Subject: [PATCH 3/6] Rename setup skill to egg-setup --- skills/{setup => egg-setup}/SKILL.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) rename skills/{setup => egg-setup}/SKILL.md (95%) diff --git a/skills/setup/SKILL.md b/skills/egg-setup/SKILL.md similarity index 95% rename from skills/setup/SKILL.md rename to skills/egg-setup/SKILL.md index 50836d5b3f..90aa0b73f5 100644 --- a/skills/setup/SKILL.md +++ b/skills/egg-setup/SKILL.md @@ -1,5 +1,5 @@ --- -name: setup +name: egg-setup description: Walk the user through initial egg setup or update an existing configuration — checks dependencies, configures secrets, repositories, and validates the installation. disable-model-invocation: true argument-hint: "[--check | --update secrets | --update repos | --update config]" @@ -11,15 +11,15 @@ You are guiding the user through egg setup or configuration updates. Walk throug ## Argument Parsing -Parse arguments after `/setup`: +Parse arguments after `/egg-setup`: | Input | Interpretation | |-------|---------------| -| `/setup` | Full setup — run all phases in order | -| `/setup --check` | Health check only — verify dependencies and config, report status | -| `/setup --update secrets` | Update secrets only (Phase 3) | -| `/setup --update repos` | Update repository configuration only (Phase 4) | -| `/setup --update config` | Update general config only (Phase 5) | +| `/egg-setup` | Full setup — run all phases in order | +| `/egg-setup --check` | Health check only — verify dependencies and config, report status | +| `/egg-setup --update secrets` | Update secrets only (Phase 3) | +| `/egg-setup --update repos` | Update repository configuration only (Phase 4) | +| `/egg-setup --update config` | Update general config only (Phase 5) | ## Phase 1 — Dependency Check @@ -76,7 +76,7 @@ If "Show install instructions", detect the platform and show appropriate command After showing instructions, ask if the user has installed the dependencies and wants to re-check. -If running `/setup --check`, stop here after reporting the results. Do not proceed to other phases. +If running `/egg-setup --check`, stop here after reporting the results. Do not proceed to other phases. ## Phase 2 — Existing Configuration Detection @@ -405,10 +405,10 @@ Your egg configuration is ready. Here's what to do next: /sdlc -r -i # Issue-driven pipeline ### Update Configuration Later - /setup --update secrets # Update API keys and tokens - /setup --update repos # Add or modify repositories - /setup --update config # Update general settings - /setup --check # Verify your setup is healthy + /egg-setup --update secrets # Update API keys and tokens + /egg-setup --update repos # Add or modify repositories + /egg-setup --update config # Update general settings + /egg-setup --check # Verify your setup is healthy ``` ## Critical Rules From cc58d0ab1ff90218ee5aa53e183d77227f123ad0 Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 05:06:12 +0000 Subject: [PATCH 4/6] Address review feedback: fix Both flow, add mkdir, specify integration fields --- skills/egg-setup/SKILL.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/skills/egg-setup/SKILL.md b/skills/egg-setup/SKILL.md index 90aa0b73f5..d82f88cc4b 100644 --- a/skills/egg-setup/SKILL.md +++ b/skills/egg-setup/SKILL.md @@ -116,6 +116,12 @@ If no existing configuration is found, proceed directly to Phase 3. ## Phase 3 — Secrets Configuration +Create the configuration directory if it doesn't exist: + +```bash +mkdir -p ~/.config/egg/ +``` + Configure credentials in `~/.config/egg/secrets.env`. For each secret category, check if already configured and only prompt for missing or explicitly updated values. ### Step 1: Anthropic Authentication @@ -149,6 +155,7 @@ Based on selection: 3. Ask for path to the `.pem` private key file. Validate the file exists and ends with `.pem`. Copy it to `~/.config/egg/github-app.pem` with `chmod 600`. 4. Ask for the bot name (must match the GitHub App name exactly). Write to `GATEWAY_BOT_NAME` in secrets.env. 5. Ask for the branch prefix (default: same as bot name, typically `egg`). Write to `GATEWAY_BOT_BRANCH_PREFIX` in secrets.env. +6. Ask for the user's GitHub username for `GATEWAY_TRUSTED_USERS` in secrets.env (comma-separated list of GitHub usernames allowed to interact with the bot). **PAT flow**: 1. Ask for the GitHub PAT. Validate it starts with `ghp_` or `github_pat_`. @@ -156,7 +163,11 @@ Based on selection: 3. Set `GATEWAY_BOT_NAME=egg` and `GATEWAY_BOT_BRANCH_PREFIX=egg` as defaults in secrets.env. 4. Ask for the user's GitHub username for `GATEWAY_TRUSTED_USERS` in secrets.env. -**Both flow**: Run GitHub App flow first, then PAT flow for `GITHUB_USER_TOKEN`. +**Both flow**: +1. Run GitHub App flow steps 1–6. +2. Ask for a GitHub PAT. Validate it starts with `ghp_` or `github_pat_`. +3. Set `GITHUB_USER_TOKEN` to the provided PAT in secrets.env. Do **NOT** set `GITHUB_TOKEN` — the App's token refresher manages default authentication at runtime via `GITHUB_APP_ID` and the `.pem` key. +4. Verify `GATEWAY_TRUSTED_USERS` was set in step 1 (App flow step 6). If not, ask for the user's GitHub username. ### Step 3: Optional Integrations @@ -170,7 +181,13 @@ Use `AskUserQuestion` (multiSelect): - **"JIRA"** — description: "Sync tickets, requirements, and sprint info" - **"None"** — description: "Skip optional integrations" -For each selected integration, collect the required credentials (see `config/secrets.template.env` for the fields). +For each selected integration, collect the required credentials: + +- **Slack**: Collect `SLACK_TOKEN` (bot token, starts with `xoxb-`) and `SLACK_APP_TOKEN` (app-level token, starts with `xapp-`). +- **Confluence**: Collect `CONFLUENCE_BASE_URL` (e.g., `https://yoursite.atlassian.net`), `CONFLUENCE_USERNAME` (email), `CONFLUENCE_API_TOKEN`, and `CONFLUENCE_SPACE_KEYS` (comma-separated space keys). +- **JIRA**: Collect `JIRA_BASE_URL` (e.g., `https://yoursite.atlassian.net`), `JIRA_USERNAME` (email), `JIRA_API_TOKEN`, and `JIRA_JQL_QUERY` (default: `project = AND status != Done`). + +See `config/secrets.template.env` for additional details on field formats. ### Step 4: Generate Launcher Secret @@ -195,6 +212,7 @@ Reference `config/secrets.template.env` for the complete list of supported varia | GitHub App Install ID | `GITHUB_APP_INSTALLATION_ID` | Phase 3 Step 2 | | GitHub default token | `GITHUB_TOKEN` | Phase 3 Step 2 (PAT flow) | | GitHub user PAT | `GITHUB_USER_TOKEN` | Phase 3 Step 2 (PAT or Both flow) | +| GitHub read-only token | `GITHUB_READONLY_TOKEN` | Phase 3 Step 2 (optional — for separate read-only credentials) | | Gateway bot name | `GATEWAY_BOT_NAME` | Phase 3 Step 2 | | Gateway branch prefix | `GATEWAY_BOT_BRANCH_PREFIX` | Phase 3 Step 2 | | Gateway trusted users | `GATEWAY_TRUSTED_USERS` | Phase 3 Step 2 | @@ -221,7 +239,7 @@ Ask for the user's GitHub username. Try to auto-detect from `gh api user --jq .l Collect paths to local git repositories to mount into the container. Use `AskUserQuestion` iteratively: -1. Ask: "Enter a path to a local git repository to mount into the egg container (or 'done' if finished)." +1. Ask: "Enter a path to a local git repository to mount into the egg container." 2. Validate the path exists and is a git repo (has `.git/` directory). 3. Auto-detect the remote URL to determine `owner/repo` format. 4. Ask: "Add another repository?" with options **"Yes"** / **"No, done adding repos"**. If "Yes", repeat from step 1. From 6aaf5142c3704c5e9401bb03d09b1addb8699e46 Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 05:17:48 +0000 Subject: [PATCH 5/6] Fix --check to run validation, fix port check, add mkdir to phases 4/5 --- skills/egg-setup/SKILL.md | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/skills/egg-setup/SKILL.md b/skills/egg-setup/SKILL.md index d82f88cc4b..9236cfd610 100644 --- a/skills/egg-setup/SKILL.md +++ b/skills/egg-setup/SKILL.md @@ -76,7 +76,7 @@ If "Show install instructions", detect the platform and show appropriate command After showing instructions, ask if the user has installed the dependencies and wants to re-check. -If running `/egg-setup --check`, stop here after reporting the results. Do not proceed to other phases. +If running `/egg-setup --check`, skip to Phase 6 (Validation) after reporting dependency results. Do not run Phases 2–5. ## Phase 2 — Existing Configuration Detection @@ -229,6 +229,12 @@ Reference `config/secrets.template.env` for the complete list of supported varia ## Phase 4 — Repository Configuration +Ensure the configuration directory exists: + +```bash +mkdir -p ~/.config/egg/ +``` + Configure `~/.config/egg/repositories.yaml`. ### Step 1: GitHub Username @@ -293,6 +299,12 @@ Write the configuration to `~/.config/egg/repositories.yaml`. Repos marked "Writ ## Phase 5 — General Configuration +Ensure the configuration directory exists: + +```bash +mkdir -p ~/.config/egg/ +``` + Create or update `~/.config/egg/config.yaml` with system-detected defaults. Auto-detect these values (do not prompt unless detection fails): @@ -352,22 +364,24 @@ Parse `~/.config/egg/repositories.yaml` and verify: # Check images can build (dry-run is not available, so just check Dockerfile exists) ls Dockerfile 2>/dev/null || ls sandbox/Dockerfile 2>/dev/null -# Check for port conflicts (cross-platform) -# Linux: -ss -tlnp 2>/dev/null | grep -E ':(9848|9849|9850|3129) ' || \ -# macOS: -lsof -i :9848 -i :9849 -i :9850 -i :3129 2>/dev/null || \ -# Fallback (cross-platform Python): +# Check for port conflicts (cross-platform Python): python3 -c " -import socket +import socket, sys +conflicts = [] for port in [9848, 9849, 9850, 3129]: s = socket.socket() try: s.bind(('', port)) s.close() except OSError: - print(f'Port {port} in use') -" 2>/dev/null || echo "Ports available" + conflicts.append(port) +if conflicts: + for p in conflicts: + print(f'Port {p} in use') + sys.exit(1) +else: + print('All ports available') +" ``` ### Report From 44c365aa554f60042015072f71b95e4bb4151954 Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 05:30:09 +0000 Subject: [PATCH 6/6] Close socket on error path in port conflict check --- skills/egg-setup/SKILL.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skills/egg-setup/SKILL.md b/skills/egg-setup/SKILL.md index 9236cfd610..706884df63 100644 --- a/skills/egg-setup/SKILL.md +++ b/skills/egg-setup/SKILL.md @@ -372,9 +372,10 @@ for port in [9848, 9849, 9850, 3129]: s = socket.socket() try: s.bind(('', port)) - s.close() except OSError: conflicts.append(port) + finally: + s.close() if conflicts: for p in conflicts: print(f'Port {p} in use')