21 Commits

Author SHA1 Message Date
fe6261598b feat: DevPanel render logging — unknown widgets, placeholders, and urlwidget failures
Add comprehensive logging to BricksRenderer for DevPanel visibility:

1. Unknown widgettypes: WARN log with full JSON dump in DevPanel Logs tab.
   Also shows [? WidgetType] orange placeholder on screen when no subwidgets.
2. Placeholder widgets (Html, MarkdownViewer, etc.): INFO log with widget summary.
3. urlwidget load failures: ERROR log with full widget JSON and error message.
4. widgetSummary(): compact one-line summary (type, id, options keys, counts).
5. widgetJsonDump(): pretty-printed JSON for deep inspection in DevPanel.

Previously: unknown widgets silently fell through to subwidget rendering.
Now: every unrecognized widget is visible in DevPanel with full context.
2026-05-21 15:51:20 +08:00
5ba33b9e18 fix: urlwidget subwidgets replace entire page instead of rendering in-place
Bug: index.ui has VBox with 3 urlwidget subwidgets (top.ui, center.ui, bottom.ui).
When RenderUrlWidget dispatched through ActionDispatcher, loadWidget called
onWidgetLoaded which replaced the ENTIRE root widget. The last urlwidget to
finish loading (bottom.ui) overwrote top.ui and center.ui.

Fix: RenderUrlWidget now maintains local state (loadedWidget) and renders
loaded content in-place. Added ActionDispatcher.loadWidgetInPlace() that loads
via callbacks without calling onWidgetLoaded. Each urlwidget replaces only
itself, preserving sibling widgets in the parent container.
2026-05-21 14:27:34 +08:00
2b3dd84a13 fix: isWebBricksBackendResource() must extract path from full URLs before matching /public
Bug: when fetchUi('/public') resolves to http://host:port/public, the
isWebBricksBackendResource() check compared the full URL string against
'/public' and always returned false, so _webbricks_=1 was never added.

Fix: extract the path component from full URLs (strip scheme+host) before
running the .ui/.dspy/public/root detection logic. All HTTP methods
(getText/getJson/postJson/postForm) delegate to withBackendContextIfNeeded
which calls isWebBricksBackendResource, so this fix covers all code paths.
2026-05-20 22:54:59 +08:00
d4f7e39834 fix: ensure _webbricks_=1 is sent for all backend resource paths including /public
- isWebBricksBackendResource() now matches /public and / as WebBricks backend resources
- BricksHttp.kt switched from manual URL query string to Ktor parameter() API
- Added test/generic-client/build.sh for one-click build/run/package
2026-05-20 08:18:58 +08:00
43f416a6f0 feat: add DevMode with logging, HTTP interception, and debug panel
- DevLogStore: centralized log store with Flow-based observation (INFO/WARN/ERROR/EXCEPTION levels)
- DevHttpInterceptor: capture request/response pairs with timing and body details
- DevPanel: bottom panel with Logs/Network/Errors tabs, expandable entries, JSON formatting
- Integrated into BricksHttp (all HTTP methods), BricksParser, ActionDispatcher, Main
- Move Main.kt from shared/ to test/generic-client/ (library module should not have main)
- Add test/generic-client/ as generic bricks-mp desktop host with DevMode toggle
- Add kotlinx-datetime dependency for timestamp handling
- Add materialIconsExtended for DevPanel icons
2026-05-19 23:15:37 +08:00
39727f87f9 fix: preserve webbricks params for startup ui requests 2026-05-19 00:04:43 +08:00
388272b4ed fix: resolve redirects without encodedPath 2026-05-18 23:36:41 +08:00
4993e550db refactor: move Sage client bootstrap to app example 2026-05-18 23:18:57 +08:00
9d3593f810 fix: use correct login endpoint up_login.dspy with password param
- Endpoint was /rbac/user/userpassword_login.dspy (401), changed to /rbac/user/up_login.dspy
- Form param was passwd (500 error), changed to password (matches login.ui form field name)
2026-05-18 10:00:21 +08:00
a0a4b5698d fix: add User-Agent/Referer headers, GET index first for session cookie, handle non-JSON login response 2026-05-18 09:40:22 +08:00
26ebfe132c fix: use java.net.URLEncoder for form encoding (removes Ktor FormDataContent dependency), simplify postForm to use Map<String, String> 2026-05-18 09:36:13 +08:00
b342ae85c6 fix: rewrite SageClient and BricksHttp to use URL-encoded string body instead of FormDataContent (not available in Ktor common) 2026-05-18 09:31:34 +08:00
e4f35ec39c fix: use FormDataContent for form POST requests (Ktor CIO engine requirement) 2026-05-18 09:28:10 +08:00
605b5200ef fix: weight scope issue (use simple spacer), add CoroutineScope import 2026-05-18 09:20:31 +08:00
b80d607d51 fix: resolve all compilation errors (weight import, asStateFlow, getCookies->get, CoroutineScope import, JsonPrimitive form values, ExperimentalMaterial3Api) 2026-05-18 09:16:37 +08:00
7b881747d3 fix: move Main.kt into shared/src/jvmMain, remove broken desktopApp module, add root repositories 2026-05-18 09:10:41 +08:00
ceaadf39a8 fix: change packageVersion from 0.1.0 to 1.0.0 (MAJOR must be > 0 for DMG) 2026-05-18 09:08:51 +08:00
03c8a8a59f fix: change jvm("desktop") to jvm() and desktopMain to jvmMain to fix Gradle type-safe accessor issue 2026-05-18 09:07:27 +08:00
45abb011db fix: comment out android/iOS targets to fix build on macOS (desktop-only) 2026-05-18 08:55:03 +08:00
82c2b89ecd feat: macOS Sage desktop client with login, UI rendering, and DMG packaging
- SageClient: HTTP client with cookie-based login, session management, UI fetching
- Main.kt: Full macOS desktop app with login screen, main window, loading/error states
- BricksRenderer: Complete inline rendering for VBox/HBox/Button/Form/Menu/TabPanel/Modal/Scroll/Image/Svg
- BricksHttp: Ktor CIO engine with cookie storage, Bearer token auth, form POST
- BricksContext: currentWidget state flow, resolveTemplates for entire_url
- ActionDispatcher: SageClient integration, urlwidget loading, event callbacks
- BricksWidget: Added options field to BricksBind
- BricksParser: Parse bind options from JSON
- Build: Added ktor-client-cio, content-negotiation deps; DMG packaging configured
- .gitignore: Standard Kotlin/Gradle/IDE patterns
2026-05-18 08:42:34 +08:00
b9c585699c initial commit: bricks-mp project 2026-05-18 08:17:44 +08:00