Commit Graph

135 Commits

Author SHA1 Message Date
SaelixCode eb0c0263c7 fix: Distributed API UI & metrics polish + DEP0060 suppression
Add Node modal — type selector & state reset:
- Restored a Local/Remote <Select> dropdown in renderFormFields so users can
  explicitly choose the node type instead of it defaulting silently to 'remote'.
- Switching type clears api_url and api_token so no stale remote credentials
  carry over if a user switches from Remote to Local mid-form.
- Replaced the static "Add Remote Node" title with a dynamic one that reflects
  the currently selected type ("Add Local Node" / "Add Remote Node").
- onOpenChange now resets formData to defaultFormData whenever the dialog
  opens, preventing stale values from a previous session leaking in.

Remote connection details — real metrics:
- testRemoteConnection previously returned hard-coded '-' for containers,
  images, and cpus after a successful auth/check ping.
- Now fires three parallel requests (Promise.allSettled) after auth passes:
    /api/stats          → containers total + running count
    /api/system/stats   → cpu.cores
    /api/system/images  → image list length
- Each field falls back to '-' gracefully if an endpoint is unavailable,
  so a slow or older remote instance never breaks the connection test.

DEP0060 util._extend suppression:
- http-proxy@1.18.1 calls util._extend when createProxyServer() is first
  invoked at runtime (NOT at import time). A process.emitWarning override
  placed before the proxy instantiations intercepts only DEP0060 without
  suppressing any other warnings. No package version changes needed.

Also includes linter/formatter normalisation across multiple files.
2026-03-19 16:06:47 -04:00
Anso 9e6f72111d Merge pull request #32 from AnsoCode/fix/distributed-api-refinement
fix: Distributed API Proxy & Auth Refinement
2026-03-19 15:35:47 -04:00
SaelixCode fddd855624 fix: Distributed API proxy memory leak, node switcher refresh, and copy button
Proxy memory leak (MaxListenersExceededWarning + DEP0060):
createProxyMiddleware was instantiated inside the request handler on every
single API call. Each new instance registered fresh 'close' listeners on the
HTTP server and re-ran the http-proxy util._extend deprecated path. After ~10
requests the MaxListeners threshold was breached. Fix: declare ONE global
remoteNodeProxy at startup using the router option to dynamically resolve the
target URL per request. Listeners are registered once. ECONNREFUSED errors are
caught in the on.error handler and returned as structured 502 JSON.

Node switcher "nothing happens":
EditorLayout had a single useEffect([], []) that called refreshStacks() once
on mount. Changing the active node updated NodeContext state and localStorage
but nothing re-triggered the stack list fetch. Fix: split into two effects —
notifications polling (no dependency) and a stack-refresh effect keyed on
activeNode?.id. When the node changes, stale editor/container/file state is
cleared and the stacks for the new node are fetched.

Copy button silently failing:
navigator.clipboard.writeText() throws DOMException in non-HTTPS / non-localhost
contexts (e.g. http://192.168.x.x). The uncaught async exception silently
swallowed the success toast and state update. Fix: wrapped in try/catch with
an execCommand('copy') textarea fallback and a final error toast if both fail.
2026-03-19 15:34:04 -04:00
Anso 45a642014f Merge pull request #31 from AnsoCode/fix/distributed-api-auth
fix: Distributed API Auth
2026-03-19 15:14:45 -04:00
SaelixCode 5932bced36 fix: Distributed API auth hardening — Bearer tokens and URL normalization
- Extend WS upgrade handler to accept Authorization: Bearer tokens as a
  fallback to cookie auth. Remote Sencho instances receive proxied WS
  connections carrying Bearer (no cookie), so the previous cookie-only
  check caused immediate 401 rejections for all proxied log/terminal streams.
- Log token validation failures in authMiddleware (was silently swallowed,
  violating no-empty-catch directive).
- Normalize api_url by stripping trailing slashes in testRemoteConnection,
  the HTTP proxy target, and the WS proxy target to prevent double-slash URLs.
2026-03-19 15:11:57 -04:00
SaelixCode 67c7078128 fix: stop infinite page reload caused by premature NodeProvider mount and 401 hard-redirect
- Move NodeProvider inside the authenticated branch in App.tsx so it only
  mounts after auth is confirmed; previously it mounted on boot causing
  refreshNodes to fire before any session existed
- Replace window.location.href='/' on 401 in apiFetch with a
  sencho-unauthorized custom event; AuthContext listens and transitions
  appStatus to notAuthenticated without a full browser reload
2026-03-19 13:57:48 -04:00
Anso ac5032d363 Merge pull request #30 from AnsoCode/fix/memory-leak-and-reload
fix: Memory Leak & Reload Loop
2026-03-19 13:30:29 -04:00
SaelixCode fd07374956 fix: memory leak in SSE log accumulation and infinite reload loop in NodeContext
- Cap GlobalObservabilityView SSE log array at 10,000 entries to prevent
  unbounded memory growth during long dev-mode sessions
- Break NodeContext infinite re-fetch loop by replacing the activeNode
  closure dependency in refreshNodes with a useRef read, making the
  callback stable and preventing the useEffect -> setState -> useCallback
  -> useEffect cycle
2026-03-19 13:28:21 -04:00
Anso 880919fb78 Merge pull request #29 from AnsoCode/fix/monitor-service-skip-remote-nodes
fix: Skip remote nodes in MonitorService
2026-03-19 12:43:27 -04:00
SaelixCode b48cf62e5b fix: skip remote nodes in MonitorService to prevent direct Docker access errors
Remote nodes in the Distributed API model are self-monitoring — each
remote Sencho instance runs its own MonitorService against its local
Docker socket. The main instance must not attempt direct DockerController
access for remote nodes, which caused fatal crashes on every 30s tick.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:41:34 -04:00
SaelixCode 67d43bb3c6 chore: untrack .claude/ settings from git 2026-03-19 12:24:43 -04:00
Anso e585313f22 Merge pull request #28 from AnsoCode/feature/distributed-api-pivot
refactor: Distributed API Pivot
2026-03-19 12:23:25 -04:00
SaelixCode c91c9ed7fd refactor: pivot from ssh proxy to distributed api model
- Delete SSHFileAdapter, IFileAdapter, LocalFileAdapter (SSH/SFTP stack)
- Remove ssh2, ssh2-sftp-client dependencies; add http-proxy-middleware, http-proxy
- NodeRegistry: remote nodes no longer use Dockerode TCP; new getProxyTarget() returns {apiUrl, apiToken}
- NodeRegistry.testConnection: remote nodes use HTTP GET /api/auth/check instead of docker.info()
- DatabaseService: Node interface swaps SSH/TLS fields for api_url + api_token; legacy columns preserved for DB compat
- FileSystemService: reverted to clean local-only fs.promises; adapter pattern fully removed
- ComposeService: executeRemote() and SSH log streaming deleted; local-only execution remains
- index.ts: add /api/auth/generate-node-token endpoint (long-lived JWT, scope:node_proxy)
- index.ts: authMiddleware now accepts Bearer token in addition to cookie (Sencho-to-Sencho auth)
- index.ts: remote HTTP proxy middleware intercepts all /api/ requests for remote nodes, strips x-node-id, injects Authorization header, proxies to api_url
- index.ts: WS upgrade handler proxies WebSocket connections for remote nodes via http-proxy wsProxyServer
- NodeManager.tsx: form reduced to Name, API URL, API Token; Generate Node Token button added inline
- NodeContext.tsx: Node interface updated to api_url/api_token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:20:32 -04:00
Anso 23730430d7 Merge pull request #27 from AnsoCode/feature/remote-nodes-security-polish
feat: Remote Nodes Security & Polish
2026-03-19 10:09:26 -04:00
SaelixCode 96b1105343 fix: add tls_ca, tls_cert, tls_key to frontend Node interface
NodeContext.tsx was missing the three TLS fields that were already
present on the backend Node type, causing TS2339 build errors in
NodeManager.tsx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 10:08:27 -04:00
SaelixCode 2a37e114df feat: implement remote tls/ssh security, isolate system stats, and polish ux
- NodeRegistry: wire TLS ca/cert/key into Dockerode when present on node config
- index.ts: /api/system/stats now branches on node type — remote nodes use docker.info() for CPU/RAM, local keeps systeminformation; disk gracefully returns null for remote
- index.ts: POST /api/nodes now persists tls_ca, tls_cert, tls_key fields
- FileSystemService: throw clean error on missing/empty compose_dir instead of crashing path.join
- FileSystemService: guard getStacks() against falsy item.name entries
- SSHFileAdapter: filter undefined/non-string names from SFTP readdir before returning
- NodeManager: add SSH Authentication Type toggle (Password vs Private Key)
- NodeManager: add Enable TLS toggle with conditional CA/cert/key textarea fields
- NodeManager: auto-test connection immediately after node creation
- NodeManager: replace "Strategy B" copy with Docker TCP setup instructions
- NodeManager: add pr-8 to header and DialogHeader to prevent overlap with parent dialog X button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 09:40:03 -04:00
Anso 1fb0494e2e Merge pull request #26 from AnsoCode/fix/remote-nodes-remediation
fix: Remote Nodes Remediation — Port Routing, SSH Credentials & compose_dir
2026-03-18 21:07:07 -04:00
SaelixCode 26b8f62968 fix: separate Docker API port from SSH port, add SSH credential UI, fix compose_dir routing 2026-03-18 21:04:43 -04:00
Anso 792e977098 Merge pull request #25 from AnsoCode/fix/remote-nodes-telemetry-crashes
fix: Remote Nodes Telemetry Fixes
2026-03-18 20:33:51 -04:00
SaelixCode f1f8e34da5 fix: harden telemetry parsing and null node fallbacks 2026-03-18 20:31:57 -04:00
Anso 7f23c88c73 Merge pull request #24 from AnsoCode/fix/remote-nodes-hardening
fix: Remote Nodes Hardening
2026-03-18 14:14:16 -04:00
SaelixCode 4bd80e29bf fix: harden docker api validation, handle sftp errors, and fix node manager ui 2026-03-18 14:13:07 -04:00
SaelixCode 69e86a0a37 fix: Resolve DatabaseService SQL syntax error and add concrete IFileAdapter implementations 2026-03-18 13:13:56 -04:00
Anso 8a4f8874de Merge pull request #23 from AnsoCode/feature/remote-nodes-wiring
feat: Remote Nodes Wiring & SSH Adapters
2026-03-18 12:58:10 -04:00
SaelixCode 8c51198468 feat: Remote Nodes Wiring & SSH Adapters 2026-03-18 12:55:30 -04:00
Anso 457c9976bc Merge pull request #22 from AnsoCode/feature/remote-nodes-foundation
feat: Remote Nodes Foundation
2026-03-18 11:55:20 -04:00
SaelixCode d2c5b2de67 fix: cast req.params.id as string to resolve TS2345 type errors 2026-03-18 11:53:41 -04:00
SaelixCode 02e1ebe1b6 feat: Remote Nodes Foundation (Strategy B) - Add nodes table with auto-seeded default local node in DatabaseService - Create NodeRegistry service for multi-instance Docker daemon connections - Add 6 Node management API endpoints (CRUD + test connection) - Create NodeManager component with table UI and connection testing - Add NodeContext for frontend-wide active node state management - Add node switcher dropdown to sidebar (visible when >1 node) - Add Nodes tab to Settings Hub 2026-03-18 11:45:04 -04:00
Anso c324d987ea Merge pull request #21 from AnsoCode/feature/global-logs-classification
fix: replace naive log level detection with robust 3-tier regex class…
2026-03-10 16:12:35 -04:00
SaelixCode b7e6b5a21c fix: replace naive log level detection with robust 3-tier regex classification engine
Eliminates massive false-positive error misclassifications caused by Docker
containers writing standard INFO logs to STDERR. The new hierarchy:
1. INFO/DEBUG/TRACE indicators (overrides STDERR default)
2. WARN/WARNING indicators
3. ERROR/FATAL/CRIT/CRITICAL/PANIC + Exception: indicators

Supports common log formats: level=info, [INFO], and bare INFO tokens.
Applied to both /api/logs/global and /api/logs/global/stream endpoints.
2026-03-10 14:50:51 -04:00
Anso b32cf5490c Merge pull request #20 from AnsoCode/feature/enterprise-logs-dev-mode
feat: Enterprise Logs & Dev Mode
2026-03-09 14:03:30 -04:00
SaelixCode 448a64a10d feat: implement enterprise sse global logs and developer mode 2026-03-09 14:02:10 -04:00
Anso 7336ea896e Merge pull request #19 from AnsoCode/feature/global-logs-ux-polish
fix: Global Logs UX Polish
2026-03-09 12:26:07 -04:00
SaelixCode b2674080c4 fix: implement smart auto-scroll and definitive stack filtering in global logs 2026-03-09 12:21:12 -04:00
Anso f501fa4712 Merge pull request #18 from AnsoCode/feature/global-logs-polish
fix: Global Logs Polish
2026-03-06 23:08:22 -05:00
SaelixCode 9af0f85749 fix: refine log level parsing and implement bottom auto-scroll 2026-03-06 23:07:17 -05:00
Anso 1f544c6568 Merge pull request #17 from AnsoCode/feature/observability-remediation-v2
fix: Observability UI & TTY Parsing
2026-03-06 22:53:33 -05:00
SaelixCode 8203dd6a14 fix: tty parsing, timezone mapping, and floating action bar for global logs 2026-03-06 22:52:36 -05:00
Anso da5a74a424 Merge pull request #16 from AnsoCode/feature/observability-remediation
fix: Observability Polish & Normalization
2026-03-06 22:25:52 -05:00
SaelixCode 29b10150b4 fix: remediate observability dashboard and global logs parsing 2026-03-06 22:24:42 -05:00
Anso 935c2b016a Merge pull request #15 from AnsoCode/feature/unified-logs-metrics
feat: Unified Observability
2026-03-06 21:06:35 -05:00
SaelixCode a4a5365da1 feat: implement centralized logging and historical metrics dashboard 2026-03-06 21:05:23 -05:00
Anso 49cef7acfa Merge pull request #14 from AnsoCode/feature/live-container-logs
feat: implement real-time container log streaming via SSE
2026-03-06 15:43:28 -05:00
SaelixCode b765403dcf feat: implement real-time container log streaming via SSE 2026-03-06 15:41:06 -05:00
Anso 12aab3a5ae Merge pull request #13 from AnsoCode/feature/app-store-final-polish
feat: implement pre-deploy collision checks and universal two-stage t…
2026-03-06 14:55:27 -05:00
SaelixCode b97952567d feat: implement pre-deploy collision checks and universal two-stage teardown 2026-03-06 14:45:37 -05:00
Anso c4805a17ac Merge pull request #12 from AnsoCode/feature/two-stage-teardown
fix: implement two-stage teardown for reliable atomic rollbacks
2026-03-06 10:27:29 -05:00
SaelixCode fb3a28834e fix: implement two-stage teardown for reliable atomic rollbacks 2026-03-06 10:18:47 -05:00
Anso b90db0124c Merge pull request #11 from AnsoCode/feature/smart-error-parser
feat: Advanced Error Handling & Probes
2026-03-05 20:00:28 -05:00
SaelixCode 953049a45d feat: implement smart error parser and post-deploy health probe 2026-03-05 19:59:35 -05:00