darman and Claude Opus 4.8
39d62348d8
harness-providers: auth.json credential storage (M3)
...
- auth.rs: AuthRecord (OAuth {access, refresh, expires} | Api {key}) with
is_expired(now, skew) honoring expires==0 = never; AuthStorage keyed by
provider id over ~/.local/share/ai-harness/auth.json.
- Read-modify-write on every op so concurrent refresh/login don't clobber;
writes go through a temp-file rename set to 0600 (unix) to avoid truncated
auth files.
- 6 tempdir tests: missing→empty, set/get/overwrite, multi-provider coexist,
scoped remove (+ no-op on absent), expiry skew/never, 0600 perms.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-08 23:37:34 +02:00
darman and Claude Opus 4.8
e2706a1560
harness-providers: OpenAI chat + responses codecs, provider, registry wiring (M3)
...
- codec/openai_chat.rs: /chat/completions request builder (flat messages,
tool_calls, system → leading system message, reasoning_effort) + SSE decoder
(content/tool_calls-by-index/reasoning_content accumulation, [DONE] sentinel,
include_usage). Also the fallback codec for OpenAI-compatible endpoints.
- codec/openai_responses.rs: /responses request builder (input items, tool calls
and results as top-level function_call/function_call_output, instructions,
reasoning {effort, summary}) + SSE decoder (output_item add/done, output_text
and reasoning_summary deltas, function_call_arguments, response.completed usage
with separate reasoning_tokens).
- openai.rs: OpenAiProvider routing gpt-*/o-* → responses, else chat; Bearer auth;
error classification incl. 400 context_length_exceeded → ContextOverflow.
- Registered in harness-app from config.providers["openai"] (api_key + optional
base_url), sourced from OPENAI_API_KEY by the existing config loader.
- 21 codec/provider unit tests (decode fixtures + request-builder assertions).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-08 23:35:49 +02:00
darman
0812f6d94c
M2 TUI: EngineHandle, ratatui app, markdown renderer, permission modal, session picker, snapshot tests
...
harness-app:
- EngineHandle: non-blocking multi-turn API (prompt/abort/permission_reply/
list_sessions/session_messages/message_parts), persistent SQLite store,
no auto-approve — TUI handles permission asks via real oneshot path
- App refactored to wrap EngineHandle; headless run -p keeps auto-approve
harness-tui:
- Terminal guard (raw mode, alternate screen, panic hook, Drop restore)
- Event loop: tokio::select! over crossterm events, bus events, 33ms render tick
- AppState with MessageView/PartView (cached Vec<Line> field), ModalState
- pulldown-cmark → ratatui markdown renderer (headings, bold, italic, code
blocks, lists, blockquotes, links, manual word-wrap)
- Layout: header, chat viewport, input (tui-textarea), status bar
- Permission modal (y/a/n) wired to EngineHandle::permission_reply
- Session picker (Ctrl+S) with resume
- Abort (Esc), Ctrl+C×2 quit, slash commands (/new /model /agent /sessions)
- 7 TestBackend snapshot tests (empty, messages, tool cards, modals)
2026-07-08 23:35:40 +02:00