Skip to content

feat(shell): PTY-based interactive command execution with SecureInput - #38640

Closed
ziuus wants to merge 5 commits into
anomalyco:devfrom
ziuus:feat/sudo-pty-interactive
Closed

ziuus wants to merge 5 commits into
anomalyco:devfrom
ziuus:feat/sudo-pty-interactive

Conversation

@ziuus

@ziuus ziuus commented Jul 24, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #9808

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds a SecureInput service that detects password prompts (sudo, ssh, etc.) in shell output and delegates user input via a deferred request/response pattern over the event bus.

The shell tool now checks if a command looks interactive (sudo, ssh -t, etc.) and runs it through a PTY instead of the normal subprocess path. Output is scanned for password prompts; when one is found, a secure-input request is emitted on the bus and the PTY waits for a response. The agent or UI can submit the password via the new HTTP routes under /secure-input.

The change is non-breaking: interactive mode only activates when an interactive parameter is passed or the command matches known patterns (sudo, ssh, etc.). All existing paths remain unchanged.

How did you verify your code works?

Ran the project typecheck (tsgo --noEmit) — passes clean. The SecureInput service is wired through the app layer and only resolves from context on demand, so it has no impact on boot path or existing tests.

Screenshots / recordings

N/A — not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

When OpenCode discovers skills from multiple scan paths (e.g. global ~/.agents/skills/ and project-level .agents/skills/), the same physical SKILL.md file can be found multiple times. The add() function would log a warning with identical existing and duplicate paths, then overwrite the same map entry.

This fix returns early when the same file path is encountered again, silencing the false-positive warning. If two different files share the same skill name, the warning is still shown as intended.

Fixes #26709
Add support for interactive commands (sudo, ssh -t, ansible -K) that
require password/secure input. Previously these commands would fail
because the tool used ChildProcessSpawner with stdin: 'ignore'.

Changes:
- Add SecureInput Effect service with:
  - Password prompt pattern detection (sudo, SSH, GPG, ansible, etc.)
  - Interactive command auto-detection
  - PTY-based command execution via bun-pty
  - Event-driven password request/submit/cancel/timeout flow
  - Password goes directly to PTY, never stored or logged
  - 60s timeout, output sanitization ([password supplied])
- Add 'interactive: boolean' parameter to ShellTool parameter schema
- Add PTY execution branch in ShellTool that activates on interactive
  flag or auto-detection
- Add SecureInputID identifier prefix (sec_)
- Add Hono API routes: GET /secure-input (list), POST /:id/submit,
  POST /:id/cancel
- Register SecureInput layer in AppRuntime
- Register routes in instance server
- Update shell.txt prompt template with interactive usage note

Output sanitization replaces detected password prompts with
'[password supplied]' before returning to the LLM.
@ziuus
ziuus force-pushed the feat/sudo-pty-interactive branch from fcff4f6 to 6f7c6b3 Compare July 25, 2026 17:50
- Add SecureInput service with PTY-based command execution
- Detect password prompts and create pending requests for user input
- Add interactive parameter to shell tool schema
- Route interactive commands through PTY with password support
- Register SecureInput HTTP API group (list, submit, cancel)
- Register SecureInput node in app-runtime
@Pancake2021

Copy link
Copy Markdown

Hey @ziuus, I've rebased and updated the feature to work with the current dev branch APIs:

What changed from your original:

  • Routes rewritten to use HttpApi (effect/unstable/httpapi) instead of Hono
  • SecureInputID uses branded strings (Schema.brand) instead of Newtype class
  • Layer registration uses AppNodeBuilderV1 + LayerNode instead of Layer.mergeAll
  • PTY import uses @opencode-ai/core/pty (static import) instead of dynamic import("#pty")
  • Removed Bus events (Bus module no longer exists in current dev)
  • Uses Duration.DurationInput instead of raw number for timeout

What I kept from your approach:

  • Same password/interactive command detection patterns
  • Same PTY execution architecture
  • Added the (yes/no.*)? pattern you had

Branch with combined work: Pancake2021/feat/sudo-pty-merged

Want me to open a new PR from this branch, or would you prefer to update your branch? Happy to collaborate either way.

- Merges pancake2021/feat/sudo-pty-merged to resolve conflicts
- SecureInput: uses branded strings, Effect.serviceOption, LayerNode
- Routes: HttpApi (effect/unstable/httpapi) replaces legacy Hono
- Removes Bus dependency (no longer exists in dev)
- Drops legacy Hono secure-input route file
@ziuus

ziuus commented Jul 26, 2026

Copy link
Copy Markdown
Author

@Pancake2021 merged your branch into this PR — thanks for doing the rebase. Your HttpApi routes, LayerNode setup, branded strings, and other updates are all live here now. PR is back to mergeable state.

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

@oleduc

oleduc commented Aug 26, 2026

Copy link
Copy Markdown

Hey we still need this, any chance this may get re-opened?

@ziuus

ziuus commented Aug 27, 2026

Copy link
Copy Markdown
Author

Hey @github-actions / maintainers — this PR was auto-closed but it's still needed. @oleduc commented 9 hours ago confirming the use case is active. The branch has the rebased commits from @Pancake2021 that are compatible with current dev APIs (HttpApi, LayerNode, branded strings). Can this be reopened?

@tmzhuang

tmzhuang commented Nov 6, 2026

Copy link
Copy Markdown

Please re-open this.

@ziuus

ziuus commented Nov 8, 2026

Copy link
Copy Markdown
Author

Thanks @tmzhuang! Since this PR was closed by repository automation, GitHub restricts reopening to repository maintainers. If maintainers are interested in reviving this feature, I'm happy to rebase the PTY/SecureInput implementation onto current dev or submit an updated PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Support for sudo and password-requiring commands in Bash tool

4 participants