mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-07 09:10:55 +00:00
refactor: extract helper functions to reduce complexity in discovery and commands (#1172)
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 <refactor@openrouter.ai> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
df96db3499
commit
2fbe225855
2 changed files with 58 additions and 35 deletions
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<void> {
|
||||
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<boolean> {
|
||||
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<void> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue