New sets up a new reconnecting pty that wraps the provided command. Any errors with starting are returned on Attach(). The reconnecting pty will close itself (and all connections to it) if nothing is attached for the duration of the timeout, if the context ends, or the process exits (buffered back
(ctx context.Context, logger slog.Logger, execer agentexec.Execer, cmd *pty.Cmd, options *Options)
| 122 | // duration of the timeout, if the context ends, or the process exits (buffered |
| 123 | // backend only). |
| 124 | func New(ctx context.Context, logger slog.Logger, execer agentexec.Execer, cmd *pty.Cmd, options *Options) ReconnectingPTY { |
| 125 | if options.Timeout == 0 { |
| 126 | options.Timeout = 5 * time.Minute |
| 127 | } |
| 128 | // Screen seems flaky on Darwin. Locally the tests pass 100% of the time (100 |
| 129 | // runs) but in CI screen often incorrectly claims the session name does not |
| 130 | // exist even though screen -list shows it. For now, restrict screen to |
| 131 | // Linux. |
| 132 | autoBackendType := "buffered" |
| 133 | if runtime.GOOS == "linux" { |
| 134 | _, err := exec.LookPath("screen") |
| 135 | if err == nil { |
| 136 | autoBackendType = "screen" |
| 137 | } |
| 138 | } |
| 139 | var backendType string |
| 140 | switch options.BackendType { |
| 141 | case "": |
| 142 | backendType = autoBackendType |
| 143 | default: |
| 144 | backendType = options.BackendType |
| 145 | } |
| 146 | |
| 147 | logger.Info(ctx, "start reconnecting pty", slog.F("backend_type", backendType)) |
| 148 | |
| 149 | switch backendType { |
| 150 | case "screen": |
| 151 | return newScreen(ctx, logger, execer, cmd, options) |
| 152 | default: |
| 153 | return newBuffered(ctx, logger, execer, cmd, options) |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | // heartbeat resets timer before timeout elapses and blocks until ctx ends. |
| 158 | func heartbeat(ctx context.Context, timer *time.Timer, timeout time.Duration) { |
no test coverage detected