From 2fbe225855b83812ebff89e4ae43030f87017cbd Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Sat, 14 Feb 2026 20:23:26 -0800 Subject: [PATCH] refactor: extract helper functions to reduce complexity in discovery and commands (#1172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduced complexity in 2 functions by extracting focused helpers: 1. preflightCredentialCheck (42 → 30 lines): - collectMissingCredentials(): validate env vars - getCredentialGuidance(): context-specific messaging - confirmContinueWithMissingCreds(): user confirmation logic 2. build_single_prompt (54 → 14 lines): - _find_first_gap(): extract matrix gap lookup - _print_gap_implementation_steps(): format implementation guidance - _print_matrix_full_guidance(): format discovery guidance Improves testability and readability while preserving behavior. Agent: complexity-hunter Co-authored-by: spawn-refactor-bot Co-authored-by: Claude Sonnet 4.5 --- .claude/skills/setup-agent-team/discovery.sh | 43 +++++++++++------ cli/src/commands.ts | 50 ++++++++++++-------- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/.claude/skills/setup-agent-team/discovery.sh b/.claude/skills/setup-agent-team/discovery.sh index c467e2fd..d99ff3a0 100755 --- a/.claude/skills/setup-agent-team/discovery.sh +++ b/.claude/skills/setup-agent-team/discovery.sh @@ -250,9 +250,8 @@ build_team_prompt() { cat "$prompt_template" } -build_single_prompt() { - local gap - gap=$(python3 - "${MANIFEST}" <<'PYEOF' +_find_first_gap() { + python3 - "${MANIFEST}" <<'PYEOF' import json, sys m = json.load(open(sys.argv[1])) for key, status in m.get('matrix', {}).items(): @@ -260,24 +259,26 @@ for key, status in m.get('matrix', {}).items(): print(key) break PYEOF -) +} - if [[ -n "${gap}" ]]; then - local cloud="${gap%%/*}" - local agent="${gap##*/}" - printf 'Read CLAUDE.md and manifest.json. Implement "%s/%s.sh":\n' "${cloud}" "${agent}" - printf '1. Read %s/lib/common.sh for cloud primitives\n' "${cloud}" - printf '2. Read an existing %s.sh on another cloud for the install pattern\n' "${agent}" - printf '3. Write %s/%s.sh combining the two\n' "${cloud}" "${agent}" - printf '4. Update manifest.json to mark "%s/%s" as "implemented"\n' "${cloud}" "${agent}" - cat <<'EOF' +_print_gap_implementation_steps() { + local cloud="$1" + local agent="$2" + printf 'Read CLAUDE.md and manifest.json. Implement "%s/%s.sh":\n' "${cloud}" "${agent}" + printf '1. Read %s/lib/common.sh for cloud primitives\n' "${cloud}" + printf '2. Read an existing %s.sh on another cloud for the install pattern\n' "${agent}" + printf '3. Write %s/%s.sh combining the two\n' "${cloud}" "${agent}" + printf '4. Update manifest.json to mark "%s/%s" as "implemented"\n' "${cloud}" "${agent}" + cat <<'EOF' 5. Update the cloud's README.md 6. bash -n syntax check 7. Commit OpenRouter injection is mandatory. Follow CLAUDE.md Shell Script Rules. EOF - else - cat <<'EOF' +} + +_print_matrix_full_guidance() { + cat <<'EOF' Read CLAUDE.md and manifest.json. The matrix is full. Your priority: find a NEW cloud/sandbox provider to add. Search for cheap CPU compute @@ -302,6 +303,18 @@ Also check `gh issue list --repo OpenRouterTeam/spawn --state open` for user req Follow CLAUDE.md Shell Script Rules. Commit when done. EOF +} + +build_single_prompt() { + local gap + gap=$(_find_first_gap) + + if [[ -n "${gap}" ]]; then + local cloud="${gap%%/*}" + local agent="${gap##*/}" + _print_gap_implementation_steps "${cloud}" "${agent}" + else + _print_matrix_full_guidance fi } diff --git a/cli/src/commands.ts b/cli/src/commands.ts index 0a42a5b8..ca6500bf 100644 --- a/cli/src/commands.ts +++ b/cli/src/commands.ts @@ -603,13 +603,8 @@ function getAuthHint(manifest: Manifest, cloud: string): string | undefined { /** Check for missing credentials before running a script and warn the user. * In interactive mode, asks for confirmation. In non-interactive mode, just warns. */ -export async function preflightCredentialCheck(manifest: Manifest, cloud: string): Promise { - const cloudAuth = manifest.clouds[cloud].auth; - if (cloudAuth.toLowerCase() === "none") return; - - const authVars = parseAuthEnvVars(cloudAuth); +function collectMissingCredentials(authVars: string[]): string[] { const missing: string[] = []; - if (!process.env.OPENROUTER_API_KEY) { missing.push("OPENROUTER_API_KEY"); } @@ -618,29 +613,44 @@ export async function preflightCredentialCheck(manifest: Manifest, cloud: string missing.push(v); } } + return missing; +} +function getCredentialGuidance(cloud: string, onlyOpenRouter: boolean): string { + if (onlyOpenRouter) { + return "The script will open your browser to authenticate with OpenRouter."; + } + return `Run ${pc.cyan(`spawn ${cloud}`)} for setup instructions.`; +} + +async function confirmContinueWithMissingCreds(onlyOpenRouter: boolean): Promise { + const confirmMsg = onlyOpenRouter + ? "Continue? You'll authenticate via browser." + : "Continue anyway? The script will prompt for missing credentials."; + const shouldContinue = await p.confirm({ + message: confirmMsg, + initialValue: true, + }); + return !p.isCancel(shouldContinue) && shouldContinue; +} + +export async function preflightCredentialCheck(manifest: Manifest, cloud: string): Promise { + const cloudAuth = manifest.clouds[cloud].auth; + if (cloudAuth.toLowerCase() === "none") return; + + const authVars = parseAuthEnvVars(cloudAuth); + const missing = collectMissingCredentials(authVars); if (missing.length === 0) return; const cloudName = manifest.clouds[cloud].name; p.log.warn(`Missing credentials for ${cloudName}: ${missing.map(v => pc.cyan(v)).join(", ")}`); - // Give context-specific guidance const onlyOpenRouter = missing.length === 1 && missing[0] === "OPENROUTER_API_KEY"; - if (onlyOpenRouter) { - p.log.info(`The script will open your browser to authenticate with OpenRouter.`); - } else { - p.log.info(`Run ${pc.cyan(`spawn ${cloud}`)} for setup instructions.`); - } + p.log.info(getCredentialGuidance(cloud, onlyOpenRouter)); if (isInteractiveTTY()) { - const confirmMsg = onlyOpenRouter - ? "Continue? You'll authenticate via browser." - : "Continue anyway? The script will prompt for missing credentials."; - const shouldContinue = await p.confirm({ - message: confirmMsg, - initialValue: true, - }); - if (p.isCancel(shouldContinue) || !shouldContinue) { + const shouldContinue = await confirmContinueWithMissingCreds(onlyOpenRouter); + if (!shouldContinue) { handleCancel(); } }