Commit graph

287 commits

Author SHA1 Message Date
Snider
3012703763 feat(gui): ToolCallHandler + manifest injection in chat
New pkg/chat/tool_handler.go: ToolCallHandler interface + ToolCall
type + BuildToolManifest helper + Core-action dispatch adapter +
inline {"tool_call": ...} JSON parser. Service.Send now detects
inline tool calls during stream, invokes OnToolCall, persists a
'tool' result message, and continues the completion loop. Manifest
is prepended to system prompt when a handler is registered
(no-op when unregistered — back-compat).

Good/Bad/Ugly coverage in tool_handler_test.go: valid tool_call
dispatches through mock executor and lands in history; unknown
tool name surfaces error into conversation (not a silent drop);
malformed inline JSON does NOT dispatch — stream continues, no
executor call, assistant message preserves the raw tool_call
fragment for audit.

go vet + go test ./pkg/chat/... clean (codex 0.124.0, gpt-5.5,
LEK AGENTS.md loaded).

Closes tasks.lthn.sh/view.php?id=22

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 07:47:54 +01:00
Snider
8abfca31e7 feat(gui): 4 smart layout helpers + Good/Bad/Ugly coverage
Added layout primitives to pkg/window/tiling.go:
- BesideEditor — position a window beside an editor, same height,
  on the side with more empty space
- SuggestLayout — layout N windows on screen (golden-ratio split
  for 2, grid for 3+)
- FindEmptySpace — find the largest rectangular empty region that
  fits a minimum size; return (rect, ok)
- ArrangePair — 60/40 or 50/50 split based on aspect ratios

Plus Rect/Size aliases and a WindowPlacement type. Good/Bad/Ugly
test coverage + godoc examples.

pkg/mcp/tools_layout.go left unchanged — this branch already
registers layout_beside_editor / layout_suggest / screen_find_space
/ window_arrange_pair on top of the new helpers.

go vet clean. go test pkg/window/... passes under HOME override
(legacy layout-save tests need writeable ~/Library on non-sandbox).

Closes tasks.lthn.sh/view.php?id=30

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 07:26:22 +01:00
Snider
7976b579a4 feat(gui): pkg/chat + gui.chat.* IPC actions (MVP chat surface)
pkg/chat/service.go + messages.go implement the RFC §15.1–§15.8
chat service with the full IPC surface:
- gui.chat.send — streams assistant reply, returns message id
- gui.chat.history — []Message for a conversation
- gui.chat.models — []Model (name, size, status)
- gui.chat.selectModel — sets active model
- gui.chat.conversations.list/load/delete
- gui.chat.thinking.start/stop — explicit thinking-state tracking

MCP tool registrations in pkg/mcp/tools_chat.go mirror the IPC
surface (chat_send, chat_history, chat_models, etc). WS bridge in
pkg/display/display.go wires chat:conversations:load and
chat🤔stop, keeping legacy chat:conversations:get and
chat🤔end paths pointed at the new handlers for compat.

Good/Bad/Ugly tests per action in service_test.go + godoc example
in service_example_test.go. go vet + go test ./pkg/chat/... +
./pkg/... all clean.

Closes tasks.lthn.sh/view.php?id=14

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 07:26:22 +01:00
Snider
dfff893f16 feat(gui): webview devtools open/close MCP tools
display.go: menu builder now consults menu.Service.ShowDevTools()
and, when enabled, adds Developer > Open DevTools + Close DevTools
menu items. Handlers route to the focused window (or the only open
window) via the existing webview.devtoolsOpen /
webview.devtoolsClose actions — which already land on Wails
WebviewWindow.OpenDevTools / CloseDevTools.

Tests: Good/Bad/Ugly coverage for both MCP tool handlers in
tools_webview_test.go plus a menu-level test in display_test.go
that clicks the built items and verifies mock devtools state flips
open/closed, with a disabled-config case.

tools_webview.go already had the handlers + registration on this
branch; locked down with tests instead of re-implementing.

Closes tasks.lthn.sh/view.php?id=31

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 06:17:34 +01:00
Snider
fa4168e380 feat(gui): InjectPreload — storage polyfills + Electron shim + app preloads
New pkg/preload package:
- preload.go — InjectPreload(webview, origin) entry point; builds
  three-step preload: storage polyfills, Electron shim (origin-
  filtered), app preloads from .core/view.yaml manifest.preloads.
- assets/storage_polyfills.js — localStorage/sessionStorage/
  IndexedDB bridges.
- assets/electron_shim.js — minimal ipcRenderer.send/invoke
  mapping to core.QUERY/ACTION.
- Adds a minimal window.core.ml.generate shim — gates the
  AI-native browser path (RFC §11a).

pkg/window/wails.go wires into Wails OnPageLoad via reflection when
the runtime exposes the hook, with a clean fallback for the
stubbed/test runtime. Legacy display-preload code detected and
skipped when the new package is in play.

Good/Bad/Ugly tests in pkg/preload/preload_test.go. go vet + go
test clean.

Closes tasks.lthn.sh/view.php?id=16

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 06:17:34 +01:00
Snider
d3858dcd26 feat(gui): core:// scheme handler + 7 route dispatches
display.Service now exposes a SchemeHandler interface; new
scheme_handler.go implements the core:// dispatcher covering the
7 RFC routes:
- settings, store, network, models → core.QUERY dispatch
- agent, wallet, identity → core.ACTION dispatch

Validates URL shape (rejects paths beyond the scheme host, malformed
URLs), unknown routes return a named error. Good/Bad/Ugly tests +
godoc example.

AssetServer startup wiring deferred — no tracked Wails bootstrap
(application.New / wails.Run / AssetServer config) exists in this
worktree yet; handler is ready for wiring when that lands.

Closes tasks.lthn.sh/view.php?id=15

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 06:17:33 +01:00
Snider
09432017ef fix(display): race-safe WSEventManager.broadcaster eventBuffer read
Guard eventBuffer access under RLock inside broadcaster() so a
concurrent buffer swap can't trip a nil-ref crash.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-24 06:02:26 +01:00
Snider
6e62d4a20c feat(lifecycle): add AppMode type + DetectMode()
Some checks failed
Security Scan / security (push) Has been cancelled
Test / test (push) Has been cancelled
New pkg/lifecycle/mode.go introduces AppMode (Manager | Worker) and
DetectMode() that returns:
- Manager by default (explicit or empty env)
- Worker when CORE_APP_MODE=worker, or when empty env + CI=true signals
  a headless/compute context

Prerequisite for the BugSETI compute worker pattern (core/gui RFC.md §9.1) —
manager GUI runs the full app UI, workers run headless compute with only an
RPC surface.

Tests follow the core/go {Good,Bad,Ugly} naming convention; go test
./pkg/lifecycle/... passes.

Co-authored-by: Codex <noreply@openai.com>

Closes tasks.lthn.sh/view.php?id=32
2026-04-23 13:12:12 +01:00
Snider
6a4edb0090 Harden layout persistence path handling
Some checks failed
Security Scan / security (push) Has been cancelled
Test / test (push) Has been cancelled
2026-04-18 08:55:14 +01:00
Snider
db535805a1 Harden window state path configuration
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-18 08:49:04 +01:00
Snider
1705e6ef57 Harden websocket nil handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-18 08:36:49 +01:00
Snider
6f9285a48d Harden menu builder against nil handles
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 21:02:34 +01:00
Snider
99cfa72fa1 Harden nil event handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 21:01:05 +01:00
Snider
917930e7eb Harden context menu MCP JSON bridge
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:54:37 +01:00
Snider
0b20658612 Harden menu nil handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:53:14 +01:00
Snider
127ece75dd Harden preload origin trust
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:50:24 +01:00
Snider
7a9a96c0a0 Tighten WebSocket origin checks
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:44:20 +01:00
Snider
07c65655fe Harden manifest path resolution
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:42:37 +01:00
Snider
90d7bfd9a4 Harden websocket and marketplace failure paths
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:38:57 +01:00
Snider
d47d143201 Harden sidecar auto-start fallback
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:33:56 +01:00
Snider
f5821a64e5 Harden websocket numeric field validation
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:32:24 +01:00
Snider
b2b28e1fe5 Harden manifest cache access
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:29:26 +01:00
Snider
18437891e7 fix(display): initialize p2p bridge after events
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:27:05 +01:00
Snider
9eb87cdc68 Harden p2p bridge cleanup
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:12:18 +01:00
Snider
17fd6e9cdf Harden P2P publish fan-out
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:09:38 +01:00
Snider
5e2a49002e Harden sidecar startup failure handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:07:19 +01:00
Snider
6931d9d2b6 Harden display and MCP menu failures
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:05:33 +01:00
Snider
f5cee5adaf Harden context menu nil backend paths
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:01:58 +01:00
Snider
4365248c86 Harden screen state boundaries
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 20:00:27 +01:00
Snider
69e1fbe7e3 Validate websocket layout numeric fields
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:52:26 +01:00
Snider
7301932257 Harden environment file manager path handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:49:52 +01:00
Snider
fb43e9a729 Add display wrapper coverage
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:47:15 +01:00
Snider
86d0a5d525 Add display API coverage
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:42:52 +01:00
Snider
dca4842c94 Harden context menu rollback handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:36:08 +01:00
Snider
8fd4da836f Fix display storage error wrappers
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:31:10 +01:00
Snider
bd1063a102 Harden display API return semantics
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:21:53 +01:00
Snider
908eab58b6 Harden events service nil platform handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:18:53 +01:00
Snider
7efba121a9 Harden websocket handler nil-safety
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:10:24 +01:00
Snider
8174d1c481 Harden display window service nil safety
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:07:51 +01:00
Snider
f1ccbf4270 Harden storage store initialization
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 19:05:15 +01:00
Snider
115064490a Harden websocket and event validation
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:51:42 +01:00
Snider
4649ee104a Return empty screen lists
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:49:26 +01:00
Snider
90b6531e81 Add MCP hardening tests
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:47:28 +01:00
Snider
e120c25da0 Harden screen list query failures
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:45:43 +01:00
Snider
4b8a534920 Harden screen query failure handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:44:19 +01:00
Snider
2d2f965bbe Harden display query failures
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:42:21 +01:00
Snider
cb1c0654bb Harden event listener shutdown
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:33:08 +01:00
Snider
4e0911b682 Surface display config persistence errors
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:30:42 +01:00
Snider
2dfdb0c0ee Harden context menu websocket payloads
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:25:49 +01:00
Snider
3c06621999 Harden display collection returns
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
2026-04-17 18:22:33 +01:00