Skip to content

feat(run): headless mode and no-auto-skills flag#294

Merged
rubenmarcus merged 3 commits intomainfrom
feat/headless-no-auto-skills-main
Mar 13, 2026
Merged

feat(run): headless mode and no-auto-skills flag#294
rubenmarcus merged 3 commits intomainfrom
feat/headless-no-auto-skills-main

Conversation

@rubenmarcus
Copy link
Copy Markdown
Member

@rubenmarcus rubenmarcus commented Mar 13, 2026

Summary

This PR adds two runtime controls to ralph-starter run so embedding tools (like autoresearcher) can run cleaner, non-interactive backend iterations.

Problem

When autoresearcher invokes ralph-starter once per benchmark iteration, users currently see repeated startup/UI noise and skills auto-install checks. That makes loop logs hard to read and can add avoidable churn.

What Changed

  1. Added --headless to suppress non-essential CLI output in run mode.
  2. Added --no-auto-skills to disable automatic skills.sh installation checks in run mode.
  3. Wired these options into loop execution (headless, enableSkills) so behavior is enforced at executor level, not just hidden.
  4. Updated package version to 0.4.5.

Why This Helps autoresearcher

  1. Prevents banner/startup UX output from leaking into embedded iteration logs.
  2. Stops repeated auto-skill installation behavior between iterations.
  3. Keeps loop execution focused on task + validation signals.

Validation

  1. pnpm build
  2. pnpm test
  3. pnpm typecheck
  4. pnpm lint (existing repo-wide warnings only; no new errors introduced by this change)

Notes

This PR does not introduce a persistent multi-iteration backend session; each invocation is still a fresh run process. It is intended to make repeated one-iteration embedding significantly cleaner and more predictable.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions
Copy link
Copy Markdown
Contributor

Issue Linking Reminder

This PR doesn't appear to have a linked issue. Consider linking to:

  • This repo: Closes #123
  • ralph-ideas: Closes multivmlabs/ralph-ideas#123

Using Closes, Fixes, or Resolves will auto-close the issue when this PR is merged.


If this PR doesn't need an issue, you can ignore this message.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 13, 2026

✔️ Bundle Size Analysis

Metric Value
Base 2635.67 KB
PR 2638.70 KB
Diff 3.03 KB (0%)
Bundle breakdown
156K	dist/auth
80K	dist/automation
4.0K	dist/cli.d.ts
4.0K	dist/cli.d.ts.map
20K	dist/cli.js
12K	dist/cli.js.map
584K	dist/commands
28K	dist/config
4.0K	dist/index.d.ts
4.0K	dist/index.d.ts.map
4.0K	dist/index.js
4.0K	dist/index.js.map
896K	dist/integrations
100K	dist/llm
1.2M	dist/loop
188K	dist/mcp
60K	dist/presets
92K	dist/setup
40K	dist/skills
392K	dist/sources
76K	dist/ui
144K	dist/utils
336K	dist/wizard

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR adds two runtime flags — --headless and --no-auto-skills — to ralph-starter run to support cleaner embedded/automated invocations (e.g. from autoresearcher). The enableSkills option is correctly threaded all the way from CLI → RunCommandOptionsLoopOptionsrunLoop (and fully propagated through all three swarm strategies), and --no-auto-skills correctly skips both autoInstallSkillsFromTask and detectClaudeSkills. The version is bumped to 0.4.5.

Key changes and findings:

  • --headless correctly suppresses showWelcome(), the swarm startup banner, and the final result summary, and replaces the real ora() spinner with a no-op in both run.ts and executor.ts.
  • --no-auto-skills correctly prevents both the upfront autoInstallSkillsFromTask call and the per-loop detectClaudeSkills call from running.
  • enableSkills is now properly threaded through SwarmConfigStrategyOptionsmakeLoopOptions for all three swarm strategies (race, consensus, pipeline), addressing the gap noted in a previous review thread.
  • Incomplete headless suppression: Several standard informational console.log calls — most notably Using agent: {name} (line 1003) and the Max iterations: N (reason) block (lines 1241–1245), which fire on virtually every invocation — are not gated on !headless. This undermines the stated goal of clean automation logs and is the main issue to resolve before merging.

Confidence Score: 3/5

  • Safe to merge with low risk, but the headless output suppression is incomplete — standard diagnostic lines still leak into automation logs.
  • The core logic (enableSkills threading, noopSpinner, early returns in headless mode) is correct and the previous swarm threading gap has been fixed. The one real behavioral shortfall is that several unconditional console.log calls (agent name, iteration count, validation warmup) in runCommand are not gated on !headless, which means the flag does not fully achieve its stated purpose of suppressing non-essential CLI output. No data-integrity, security, or crash-risk issues were found.
  • src/commands/run.ts — multiple informational console.log calls not gated on headless

Important Files Changed

Filename Overview
src/commands/run.ts Adds headless and enableSkills options with correct gating for showWelcome, swarm output, and final result summary, but leaves several standard informational console.log calls (agent name, max iterations, validation warmup, Ralph Playbook detection) ungated — these will still leak into embedding tool logs despite --headless.
src/loop/executor.ts Adds enableSkills option to LoopOptions; correctly short-circuits detectClaudeSkills when enableSkills === false. Headless handling via noopSpinner and log suppression was already present and remains correct.
src/loop/swarm.ts Correctly threads headless and enableSkills through SwarmConfig → StrategyOptions → makeLoopOptions → runLoop for all three strategies (race, consensus, pipeline). All onProgress calls already use optional chaining, so undefined onProgress in headless mode is safe.
src/cli.ts Adds --headless and --no-auto-skills flags to the CLI. Commander.js negated-flag semantics correctly sets autoSkills to false when --no-auto-skills is provided and true otherwise.
package.json Version bump from 0.4.4 to 0.4.5 — expected for a feature release.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ralph-starter run] --> B{--headless?}
    B -->|yes| C[skip showWelcome]
    B -->|no| D[showWelcome]
    C --> E{--no-auto-skills?}
    D --> E
    E -->|yes, autoSkills=false| F[skip autoInstallSkillsFromTask]
    E -->|no, autoSkills=true| G[autoInstallSkillsFromTask]
    F --> H[build loopOptions\nheadless=true\nenableSkills=false]
    G --> H2[build loopOptions\nheadless=false\nenableSkills=true]
    H --> I{--swarm?}
    H2 --> I
    I -->|yes| J[runSwarm\nheadless + enableSkills\nthreaded through]
    I -->|no| K[runLoop\nenableSkills===false?\nskip detectClaudeSkills]
    J --> L{headless?}
    K --> M{headless?}
    L -->|yes, no winner| N[throw Error]
    L -->|yes, winner| O[return early — no summary output]
    L -->|no| P[print swarm summary]
    M -->|yes, failure| Q[throw Error with exitReason]
    M -->|yes, success| R[return early — no summary output]
    M -->|no| S[print loop summary]

    style C fill:#f9a,stroke:#f66
    style F fill:#f9a,stroke:#f66
    style N fill:#f66,stroke:#c00,color:#fff
    style Q fill:#f66,stroke:#c00,color:#fff
Loading

Comments Outside Diff (1)

  1. src/commands/run.ts, line 1003-1245 (link)

    Several informational console.log calls bypass the headless gate

    The --headless flag's stated purpose is to suppress non-essential CLI output so embedding tools (e.g. autoresearcher) get clean logs. However, several unconditional console.log calls that fire on every normal invocation are not gated on !headless:

    • Line 1003: Using agent: {agent.name} — always emits
    • Line 1124: Using fetched specification as task — emits on every --from invocation
    • Lines 1130-1132: Ralph Playbook detected / Using build mode from IMPLEMENTATION_PLAN.md — emits whenever a playbook is present
    • Lines 1241-1245: Tasks: N pending, N completed / Max iterations: N (reason) — emits on virtually every run unless --max-iterations is explicitly set
    • Lines 1252-1255: Validation warm-up: skipping until N tasks completed — emits when greenfield warmup fires
    • Line 1349: Model: {model} — emits when model selector runs

    Because lines 1003 and 1241-1245 fire on nearly every invocation, autoresearcher will still see agent-name and iteration-count noise in its embedded logs despite passing --headless.

    The fix is to guard these with if (!headless) (or the log helper already used in executor.ts). For example:

    if (!headless) {
      console.log(chalk.dim(`Using agent: ${agent.name}`));
    }

    and

    if (!headless && !options.maxIterations && !preset?.maxIterations) {
      if (taskCount.total > 0) {
        console.log(chalk.dim(`Tasks: ${taskCount.pending} pending, ${taskCount.completed} completed`));
      }
      console.log(chalk.dim(`Max iterations: ${smartIterations} (${reason})`));
    }
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/commands/run.ts
Line: 1003-1245

Comment:
**Several informational `console.log` calls bypass the headless gate**

The `--headless` flag's stated purpose is to suppress non-essential CLI output so embedding tools (e.g. `autoresearcher`) get clean logs. However, several unconditional `console.log` calls that fire on every normal invocation are not gated on `!headless`:

- **Line 1003**: `Using agent: {agent.name}` — always emits
- **Line 1124**: `Using fetched specification as task` — emits on every `--from` invocation
- **Lines 1130-1132**: `Ralph Playbook detected` / `Using build mode from IMPLEMENTATION_PLAN.md` — emits whenever a playbook is present
- **Lines 1241-1245**: `Tasks: N pending, N completed` / `Max iterations: N (reason)` — emits on virtually every run unless `--max-iterations` is explicitly set
- **Lines 1252-1255**: `Validation warm-up: skipping until N tasks completed` — emits when greenfield warmup fires
- **Line 1349**: `Model: {model}` — emits when model selector runs

Because lines 1003 and 1241-1245 fire on nearly every invocation, `autoresearcher` will still see agent-name and iteration-count noise in its embedded logs despite passing `--headless`.

The fix is to guard these with `if (!headless)` (or the `log` helper already used in `executor.ts`). For example:

```typescript
if (!headless) {
  console.log(chalk.dim(`Using agent: ${agent.name}`));
}
```

and

```typescript
if (!headless && !options.maxIterations && !preset?.maxIterations) {
  if (taskCount.total > 0) {
    console.log(chalk.dim(`Tasks: ${taskCount.pending} pending, ${taskCount.completed} completed`));
  }
  console.log(chalk.dim(`Max iterations: ${smartIterations} (${reason})`));
}
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: ae56979

@rubenmarcus
Copy link
Copy Markdown
Member Author

@greptileai

@rubenmarcus
Copy link
Copy Markdown
Member Author

@greptileai

@rubenmarcus rubenmarcus merged commit 5d05569 into main Mar 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant