feat: add shell interface, registry, and bash shell emulator
Implement Phase 1.4: replaces the hardcoded banner/timeout stub with a proper shell system. Adds a Shell interface with weighted registry for shell selection, a RecordingChannel wrapper (pass-through for now, prep for Phase 2.3 replay), and a bash-like shell with fake filesystem, terminal line reader, and command handling (pwd, ls, cd, cat, whoami, hostname, id, uname, exit). Sessions now log command/output pairs to the store and record the shell name. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
19
internal/shell/recorder.go
Normal file
19
internal/shell/recorder.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package shell
|
||||
|
||||
import "io"
|
||||
|
||||
// RecordingChannel wraps an io.ReadWriteCloser. In Phase 1.4 it is a
|
||||
// pass-through; Phase 2.3 will add byte-level keystroke recording here
|
||||
// without changing any shell code.
|
||||
type RecordingChannel struct {
|
||||
inner io.ReadWriteCloser
|
||||
}
|
||||
|
||||
// NewRecordingChannel returns a RecordingChannel wrapping rw.
|
||||
func NewRecordingChannel(rw io.ReadWriteCloser) *RecordingChannel {
|
||||
return &RecordingChannel{inner: rw}
|
||||
}
|
||||
|
||||
func (r *RecordingChannel) Read(p []byte) (int, error) { return r.inner.Read(p) }
|
||||
func (r *RecordingChannel) Write(p []byte) (int, error) { return r.inner.Write(p) }
|
||||
func (r *RecordingChannel) Close() error { return r.inner.Close() }
|
||||
Reference in New Issue
Block a user