Class: Harnex::Adapters::Base
- Inherits:
-
Object
- Object
- Harnex::Adapters::Base
show all
- Defined in:
- lib/harnex/adapters/base.rb
Constant Summary
collapse
- PROMPT_PREFIXES =
[">", "\u203A", "\u276F"].freeze
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Adapter contract — subclasses MUST implement: base_command -> Array CLI args to spawn.
Instance Method Summary
collapse
-
#base_command ⇒ Object
-
#build_command ⇒ Object
-
#build_send_payload(text:, submit:, enter_only:, screen_text:, force: false) ⇒ Object
-
#describe ⇒ Object
-
#infer_repo_path(_argv) ⇒ Object
-
#initialize(key, extra_args = []) ⇒ Base
constructor
-
#inject_exit(writer, delay_ms: 0) ⇒ Object
-
#input_state(screen_text) ⇒ Object
-
#parse_session_summary(_transcript_tail) ⇒ Object
-
#send_wait_seconds(submit:, enter_only:) ⇒ Object
-
#transport ⇒ Object
-
#wait_for_sendable(screen_snapshot_fn, submit:, enter_only:, force:) ⇒ Object
-
#wait_for_sendable_state?(_state, submit:, enter_only:) ⇒ Boolean
Constructor Details
#initialize(key, extra_args = []) ⇒ Base
Returns a new instance of Base.
18
19
20
21
|
# File 'lib/harnex/adapters/base.rb', line 18
def initialize(key, = [])
@key = key
@extra_args = .dup
end
|
Instance Attribute Details
#key ⇒ Object
Adapter contract — subclasses MUST implement:
base_command -> Array[String] CLI args to spawn
Subclasses MAY override:
input_state(text) -> Hash Parse screen for state
build_send_payload -> Hash Build injection payload
inject_exit(writer) -> void Send a stop/exit sequence
infer_repo_path(argv) -> String Extract repo path from CLI args
wait_for_sendable -> String Wait for a send-ready snapshot
16
17
18
|
# File 'lib/harnex/adapters/base.rb', line 16
def key
@key
end
|
Instance Method Details
#base_command ⇒ Object
37
38
39
|
# File 'lib/harnex/adapters/base.rb', line 37
def base_command
raise NotImplementedError, "#{self.class} must define #base_command"
end
|
#build_command ⇒ Object
33
34
35
|
# File 'lib/harnex/adapters/base.rb', line 33
def build_command
base_command + @extra_args
end
|
#build_send_payload(text:, submit:, enter_only:, screen_text:, force: false) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/harnex/adapters/base.rb', line 84
def build_send_payload(text:, submit:, enter_only:, screen_text:, force: false)
state = input_state(screen_text)
if !force && blocked_state?(state, enter_only: enter_only)
raise ArgumentError, blocked_message(state, enter_only: enter_only)
end
payload = enter_only ? "" : text.to_s
payload << submit_bytes if submit || enter_only
{
text: payload,
newline: false,
input_state: state,
force: force
}
end
|
#describe ⇒ Object
29
30
31
|
# File 'lib/harnex/adapters/base.rb', line 29
def describe
{ transport: transport }
end
|
#infer_repo_path(_argv) ⇒ Object
41
42
43
|
# File 'lib/harnex/adapters/base.rb', line 41
def infer_repo_path(_argv)
Dir.pwd
end
|
#inject_exit(writer, delay_ms: 0) ⇒ Object
101
102
103
104
105
106
107
|
# File 'lib/harnex/adapters/base.rb', line 101
def inject_exit(writer, delay_ms: 0)
writer.write("/exit")
writer.flush
sleep(delay_ms / 1000.0) if delay_ms.positive?
writer.write(submit_bytes)
writer.flush
end
|
45
46
47
48
49
50
|
# File 'lib/harnex/adapters/base.rb', line 45
def input_state(screen_text)
{
state: "unknown",
input_ready: nil
}
end
|
#parse_session_summary(_transcript_tail) ⇒ Object
52
53
54
|
# File 'lib/harnex/adapters/base.rb', line 52
def parse_session_summary(_transcript_tail)
{}
end
|
#send_wait_seconds(submit:, enter_only:) ⇒ Object
56
57
58
|
# File 'lib/harnex/adapters/base.rb', line 56
def send_wait_seconds(submit:, enter_only:)
0.0
end
|
#transport ⇒ Object
Default transport. Adapters speaking JSON-RPC override to :stdio_jsonrpc; Session#run uses this to pick the I/O path.
25
26
27
|
# File 'lib/harnex/adapters/base.rb', line 25
def transport
:pty
end
|
#wait_for_sendable(screen_snapshot_fn, submit:, enter_only:, force:) ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/harnex/adapters/base.rb', line 64
def wait_for_sendable(screen_snapshot_fn, submit:, enter_only:, force:)
snapshot = screen_snapshot_fn.call
return snapshot if force
wait_secs = send_wait_seconds(submit: submit, enter_only: enter_only).to_f
return snapshot unless wait_secs.positive?
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + wait_secs
state = input_state(snapshot)
while Process.clock_gettime(Process::CLOCK_MONOTONIC) < deadline &&
wait_for_sendable_state?(state, submit: submit, enter_only: enter_only)
sleep 0.05
snapshot = screen_snapshot_fn.call
state = input_state(snapshot)
end
snapshot
end
|
#wait_for_sendable_state?(_state, submit:, enter_only:) ⇒ Boolean
60
61
62
|
# File 'lib/harnex/adapters/base.rb', line 60
def wait_for_sendable_state?(_state, submit:, enter_only:)
false
end
|