feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: add --config and --steps CLI flags for programmatic setup - #2545

Merged
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags
Mar 13, 2026
Merged

feat: add --config and --steps CLI flags for programmatic setup#2545
louisgv merged 8 commits into
OpenRouterLabs:mainfrom
AhmedTMM:feat/config-steps-flags

Conversation

@AhmedTMM

Copy link
Copy Markdown
Collaborator

Summary

  • Add --config <path> flag to load spawn options from a JSON config file (model, steps, name, setup data)
  • Add --steps <list> flag for comma-separated setup step control
  • Telegram setup reads TELEGRAM_BOT_TOKEN env var before falling back to interactive prompt
  • WhatsApp auto-skipped in headless mode with warning
  • Setup prompt skipped when SPAWN_ENABLED_STEPS is already set (from --steps or --config)
  • New spawn-config.ts module with valibot schema validation
  • OptionalStep interface extended with dataEnvVar and interactive metadata
  • validateStepNames() validates step names and warns about unknowns
  • E2E verify helpers for github, browser, and telegram setup artifacts
  • QA reference file (.claude/rules/agent-setup-options.md) documenting all setup options
  • Version bump to 0.17.0

Config file format

{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}

Priority order (highest wins):

  1. CLI flags (--model, --steps, --name)
  2. --config file
  3. Env vars / preferences
  4. Agent defaults

Test plan

  • bunx @biomejs/biome check src/ — 0 errors
  • bun test — 1397 tests pass
  • bash -n sh/e2e/lib/verify.sh — syntax OK
  • Manual: spawn codex gcp --config test.json --dry-run
  • Manual: spawn openclaw gcp --steps github,browser --headless --output json
  • Manual: TELEGRAM_BOT_TOKEN=xxx spawn openclaw gcp --steps telegram --headless

🤖 Generated with Claude Code

@AhmedTMM
AhmedTMM marked this pull request as ready for review March 12, 2026 22:46

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: CHANGES REQUESTED
Commit: 9d7932c

Findings

MEDIUM - packages/cli/src/shared/spawn-config.ts:35 — Null byte check occurs after path resolution
The null byte check happens after resolve(filePath) is called. While Node.js will reject null bytes in paths, the check should come before any filesystem operations for defense-in-depth. Move line 35-37 before line 32.

LOW - Multiple files — Missing input validation on model ID and steps
The --model and --steps flags accept arbitrary strings without validation. While this is non-critical (values are validated later or unused), consider adding basic format validation:

  • Model ID should match pattern: provider/model-name
  • Steps should be validated before being set in env vars (already done in orchestrate.ts, but could be earlier)

INFO - packages/cli/src/index.ts:846-850 — Credentials in environment variables
The PR correctly loads TELEGRAM_BOT_TOKEN and GITHUB_TOKEN from config files into env vars. This is acceptable for spawn's design (credentials are already in env vars), but the config file path should be validated to prevent directory traversal.

INFO - packages/cli/src/shared/agent-setup.ts:800-815 — Token escaping is correct
The code uses jsonEscape() (which calls JSON.stringify()) for the Telegram bot token before passing to shell. This is correct and prevents command injection.

Tests

  • bash -n: PASS (sh/e2e/lib/verify.sh syntax valid)
  • bun test: PASS (1405 tests pass, 0 fail)
  • curl|bash: OK (no violations found in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Additional Issues

  1. Merge conflicts: The PR shows mergeable: CONFLICTING status. Please rebase on main and resolve conflicts.
  2. Documentation file: The PR adds .claude/rules/agent-setup-options.md which violates the Documentation Policy in CLAUDE.md. Per the policy, only README.md, CLAUDE.md, and cloud-specific sh/{cloud}/README.md are allowed. Move this to .docs/ (git-ignored).

Recommendations

Required before merge:

  1. Rebase on main and resolve merge conflicts
  2. Move .claude/rules/agent-setup-options.md to .docs/agent-setup-options.md
  3. Move null byte check before path resolution (line 35 → before line 32)

Optional improvements:
4. Add model ID format validation in index.ts
5. Add early steps validation in index.ts (before orchestrate.ts)


-- security/pr-reviewer

@louisgvlouisgv added the security-review-required Security review found critical/high issues - changes required label Mar 12, 2026
@AhmedTMM
AhmedTMMforce-pushed the feat/config-steps-flags branch from 9d7932c to 4bb28f5CompareMarch 12, 2026 23:48
AhmedTMMand others added 8 commits March 12, 2026 23:55
Adds separate "Telegram" and "WhatsApp" checkboxes to the OpenClaw
setup screen:
- Telegram: prompts for bot token from @Botfather, injects into
OpenClaw config via `openclaw config set`
- WhatsApp: reminds user to scan QR code via the web dashboard
after launch (no CLI setup possible)
Updates USER.md with channel-specific guidance when either is selected.
Bump CLI version to 0.16.16.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of punting WhatsApp setup to "after launch", runs
`openclaw channels login --channel whatsapp` as an interactive SSH
session between gateway start and TUI launch. The user scans the
QR code with their phone during provisioning setup.
Flow: gateway starts → tunnel set up → WhatsApp QR scan → TUI launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --config <path> flag to load spawn options from a JSON config file
(model, steps, name, setup data like telegram_bot_token). Add --steps
<list> flag for comma-separated setup step control. Both enable the
web UI and headless automation to control which setup steps run.
Priority order: CLI flags > --config file > env vars > defaults.
- New spawn-config.ts module with valibot validation
- OptionalStep extended with dataEnvVar and interactive metadata
- validateStepNames() for step name validation with warnings
- Telegram setup reads TELEGRAM_BOT_TOKEN env var before prompting
- WhatsApp auto-skipped in headless mode with warning
- promptSetupOptions() skipped when SPAWN_ENABLED_STEPS already set
- E2E verify helpers for github, browser, telegram setup artifacts
- QA reference file documenting all agent setup options
- Version bump to 0.17.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --model <id> CLI flag that sets MODEL_ID env var
- --model is extracted before --config so it takes priority
- Add config-priority.test.ts with 8 tests verifying:
- --model overrides config model
- --steps overrides config steps
- --steps "" disables all steps
- --name overrides config name
- Config tokens apply as defaults
- Explicit env vars override config tokens
- Remove preferences.json from priority order docs (not needed)
- Add --model to help text and unknown-flag guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document config file format, setup steps table, and new CLI flags
in the commands table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move null byte check before path resolution (defense-in-depth)
- Move agent-setup-options.md from .claude/rules/ to .docs/ (git-ignored)
per documentation policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rebase on main introduced a duplicate --model flag extraction block
(one from the PR at line 804, one from main at line 941). Consolidated
into the single early extraction point with -m shorthand support.
Also removed duplicate --model entry from KNOWN_FLAGS set.
Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@la14-1
la14-1force-pushed the feat/config-steps-flags branch from 4bb28f5 to 5a48de2CompareMarch 12, 2026 23:59
@la14-1

Copy link
Copy Markdown
Collaborator

Rebase + conflict resolution

Rebased onto main and resolved merge conflicts:

  1. packages/cli/package.json — kept version 0.17.1 (from main, higher than PR's 0.16.16 / 0.17.0)
  2. packages/cli/src/shared/agent-setup.ts — merged import lists (both shellQuote from main and prompt from this PR's dependency)
  3. packages/cli/src/flags.ts — merged flag sets (kept --model, -m from main + added --config, --steps from this PR), removed duplicate --model entry
  4. packages/cli/src/index.ts — removed duplicate --model flag extraction block (main added one at line 941, PR had one at line 804). Consolidated into the PR's earlier position (before --config) with -m shorthand support from main's version.

Review feedback status

The existing commit 7e21bf35 (fix: address security review feedback) already addressed the required changes:

  • Null byte check moved before path resolution in spawn-config.ts
  • agent-setup-options.md moved from .claude/rules/ to .docs/

Verification

  • bunx @biomejs/biome check src/0 errors (121 files checked)
  • bun test1405 pass, 0 fail (3633 expect() calls)

-- refactor/pr-maintainer

@louisgvlouisgv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Verdict: APPROVED
Commit: 5a48de2

Summary

All security concerns from the previous review (commit 9d7932c) have been successfully addressed:

  1. ✓ Null byte check - Moved to line 33 in spawn-config.ts, BEFORE path resolution (defense-in-depth)
  2. ✓ Documentation policy - agent-setup-options.md removed from .claude/rules/ and moved to .docs/ (git-ignored)
  3. ✓ Merge conflicts - Resolved (mergeable: MERGEABLE)

Security Findings

No issues found. The PR implements secure credential handling:

  • Config file validation: Null byte check before filesystem ops, 1MB size limit, valibot schema validation
  • Token escaping: Telegram bot token uses jsonEscape() (JSON.stringify()) before shell injection - correct
  • Credentials in env vars: Follows spawn's existing pattern (TELEGRAM_BOT_TOKEN, GITHUB_TOKEN) - acceptable
  • Input validation: Model ID and steps are validated downstream in orchestrate.ts - adequate

Tests

  • bash -n: PASS (all .sh files have valid syntax)
  • bun test: PASS (1405 tests pass, 0 fail, 3633 expect() calls)
  • bunx @biomejs/biome lint: PASS (121 files checked, 0 errors)
  • curl|bash: OK (no violations in shell scripts)
  • macOS compat: OK (no bash 3.x incompatibilities)

Feature Validation

The PR adds two programmatic CLI flags:

  • --config : Load options from JSON (with proper security validation)
  • --steps : Control which setup steps run (github, browser, telegram, etc.)

Both features are well-tested (3 new test files with comprehensive coverage) and integrate cleanly with the existing architecture.


-- security/pr-reviewer

@louisgvlouisgv added the security-approved Security review approved label Mar 13, 2026
@louisgv
louisgv merged commit f683dd8 into OpenRouterLabs:mainMar 13, 2026
5 checks passed
@AhmedTMM
AhmedTMM deleted the feat/config-steps-flags branch April 7, 2026 00:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-approvedSecurity review approvedsecurity-review-requiredSecurity review found critical/high issues - changes required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@AhmedTMM@la14-1@louisgv