Commit Graph
16 Commits
Author SHA1 Message Date
Luan VuandLuvu182 0e2282be8f fix: use errors.Is() for sentinel comparisons + remove unused @xyflow/react (#727)
Replace direct sentinel error comparisons (==, !=) with errors.Is()
across the codebase. Direct comparison breaks when errors are wrapped
with fmt.Errorf("...: %w", err), which can cause missed matches for
sql.ErrNoRows, io.EOF, context.DeadlineExceeded, and context.Canceled.

Affected packages:
- store/pg: sql.ErrNoRows in secure_cli, agents_export_team_*, mcp_export_queries
- store/sqlitestore: sql.ErrNoRows in schema migration
- tools: context.DeadlineExceeded in shell, credentialed_exec
- mcp: context.DeadlineExceeded in bridge_tool
- providers: context.Canceled in acp_provider, anthropic_stream_test
- updater: io.EOF in tar extraction

Also removes unused @xyflow/react dependency from web UI — it was
replaced by react-force-graph-2d but never cleaned up from package.json.

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-04-07 12:16:45 +07:00
viettranx 7a6a944622 refactor(ui): Phase 3 — Zod schemas + React Hook Form for 6 form dialogs
Add zod@4.3.6, react-hook-form@7.72.1, @hookform/resolvers@5.2.2.

Create src/schemas/ with 6 validation schemas:
- agent.schema.ts, provider.schema.ts, cron.schema.ts
- channel.schema.ts, credential.schema.ts, heartbeat.schema.ts

Refactor 6 form dialogs from manual useState chains to RHF + Zod:
- agent-create-dialog: 12 → 2 useState
- provider-form-dialog: 8 → 0 useState
- cron-form-dialog: 7 → 0 useState
- channel-instance-form-dialog: 11 → 6 useState
- cli-credential-form-dialog: 18 → 9 useState
- heartbeat-config-dialog: 19 → 4 useState

Total: 75 useState removed, replaced with type-safe form state.
Async side-effects kept as hooks. No behavior changes.
2026-04-03 22:35:06 +07:00
viettranx 7850ccea01 feat(kg): replace ReactFlow SVG with react-force-graph-2d Canvas renderer
- Replace ReactFlow (SVG, lags at 80+ nodes) with react-force-graph-2d
  (Canvas/WebGL, handles 500+ nodes at 60fps)
- Custom nodeCanvasObject: colored circle by entity type + name label
- Single click: highlight node + neighbors + connected edges with
  directional particles; dim unconnected nodes to 20% opacity
- Double click (timer-based 280ms): open entity detail modal
- Edge labels shown only for selected node's connections (background pill)
- Increase GRAPH_LIMIT from 80 to 150 (Canvas renderer handles it)
- ResizeObserver for responsive container sizing
- Zoom-to-fit button in stats bar
- Auto zoom-to-fit on engine stop
- Dark/light theme support via isDark conditional colors
- Remove ReactFlow + D3 force imports (packages kept in package.json)
2026-04-03 19:41:44 +07:00
viettranx b59a623649 fix(deps): upgrade major packages across web and desktop UIs
Web UI:
- i18next 25→26, react-i18next 16→17
- lucide-react 0.468→1.7 (no brand icons used)
- tailwind-merge 2→3 (Tailwind CSS 4 compat)
- typescript 5.7→6.0 (remove deprecated baseUrl from tsconfig)

Desktop UI:
- i18next 25→26, react-i18next 16→17
- immer 10→11 (internal perf improvements)
- react-markdown 9→10, react-syntax-highlighter 15→16
- typescript 5.9→6.0
- Fix MarkdownRenderer: wrap ReactMarkdown in div for className (v10 removed prop)

Both: build verified, pnpm audit 0 vulnerabilities
2026-03-29 13:03:39 +07:00
viettranx c5cd1ad412 fix(deps): upgrade Vite 6→8, plugin-react 4→6, and patch/minor updates
Desktop + Web UI:
- @vitejs/plugin-react ^4.3.4 → ^6.0.1 (Vite 8 compat)
- vite ^6.0.0 → ^8.0.3 (CVE: Rollup path traversal, Picomatch ReDoS)
- tailwindcss/vite 4.2.0 → 4.2.2, tailwindcss 4.2.0 → 4.2.2

Web UI patch/minor:
- @tanstack/react-query 5.90→5.95, react-router 7.13.0→7.13.2
- recharts 3.8.0→3.8.1, zustand 5.0.11→5.0.12, ws 8.19→8.20
- i18next 25.8→25.10, react-i18next 16.5→16.6, framer-motion 12.34→12.38

Both: pnpm audit reports 0 vulnerabilities
2026-03-29 12:59:04 +07:00
viettranx db41e58319 fix(security): SSRF validation, path hardening, and dependency CVE fixes (#525)
Provider SSRF prevention:
- Add validateProviderURL() blocking internal/private network targets
- Whitelist http/https schemes only (blocks file://, gopher://, etc.)
- Normalize IPv6-mapped IPv4 (::ffff:127.0.0.1) before private IP check
- Validate both api_base and base_url fields on create and update

Path hardening:
- Symlink resolution in DooD workspace resolver (resolve-then-match)
- Strict regex for media ID validation (replaces ad-hoc string checks)

Dependency CVE fixes:
- Upgrade Vite 6→8 (Rollup path traversal, Picomatch ReDoS)
2026-03-29 12:54:12 +07:00
Goon c25e770d43 feat(ui): multi-skill upload with client-side validation (#149)
* feat(ui): multi-skill upload with client-side validation

Allow uploading multiple skill ZIP files at once with pre-upload
validation. JSZip parses each ZIP client-side to verify SKILL.md
presence, frontmatter format, and slug validity before upload.

- Add JSZip dependency (lazy-loaded, code-split ~30KB gzip)
- Create validate-skill-zip.ts mirroring server-side checks
- Rewrite skill-upload-dialog for multi-file with status badges
- Add concurrent validation, sequential upload with per-file progress
- Add empty SKILL.md check to backend upload handler
- Add i18n keys for all new UI strings (en/vi/zh)

* fix(ui): duplicate entries and validation hang in multi-skill upload

- Move pending list construction to assignment inside updater return
  to prevent StrictMode double-invoke from pushing duplicates
- Wrap per-file validateSkillZip in try/catch so one failure doesn't
  block Promise.all and leave entries stuck in "validating" state

* fix(ui): use static import for JSZip instead of dynamic import

Dynamic import("jszip") fails in browser - bare module specifiers
don't resolve at runtime. Use static import which Vite handles
via its module graph and code-splits automatically.

* feat(ui): add inline visibility toggle on skills table

Click the visibility badge on managed skills to cycle through
private → internal → public. File-based skills stay read-only.

* fix(ui): move dedup logic outside state updater in upload dialog

Avoids reading stale entries inside functional updater. Builds
pending list from current entries state before calling setEntries.

* fix(ui): auto-select first active agent when current agent unavailable

When agents load from API, if the current selected agent is not in the active agents list, automatically select the first available active agent instead of remaining unset. Prevents chat page from being unable to send messages when default agent selection is invalid.

* feat(ui): make agent display name editable in setup wizard

Allow users to customize the agent display name during onboarding instead of keeping it hardcoded to "GoClaw". Removed read-only state from the display name input and added a placeholder for guidance.

* feat: add document path enrichment and media filename support

Backend changes:
- enrichDocumentPaths() in agent/media.go: injects persisted file paths into <media:document> tags
- Document paths allow skills (e.g. pdf skill via exec) to access files directly
- chat.go: support new media format {path, filename} alongside legacy string paths
- Updated read_document tool description to guide agent on using path attribute
- Docker: add pypdf to Python dependencies for PDF processing
- Softened MUST language in read_* tool descriptions (changed to Call this)

Frontend changes:
- chat-input.tsx: attach filename with each uploaded file in media payload
- use-chat-send.ts: send media as {path, filename} objects instead of just paths
- i18n: add "uploaded_files" text in en, vi, zh locales
- chat-page.tsx: minor adjustment for media handling

Enables skills to process uploaded documents directly without intermediate copying.
2026-03-11 16:59:03 +07:00
Viet Tran 73389d2715 fix(ui): align usage data contracts, add timezone setting, and fix empty usage page (#146)
- Fix 6 data contract mismatches between Go backend JSON tags and React
  frontend TypeScript interfaces (field renames, response envelope changes)
- Add timezone selector to topbar with 12 common timezone options
- Replace date-fns formatting with native Intl.DateTimeFormat for
  timezone-aware chart labels (reduces bundle ~20KB)
- Add missing SnapshotTimeSeries fields (memory_docs, memory_chunks,
  kg_entities, kg_relations) that caused empty usage page
- Add error banner to usage page for API error visibility
- Sanitize backend error messages in usage HTTP handlers
- Add batch chunking (max 3000 rows) for snapshot upserts
- Remove userId display from topbar
- Add usage analytics i18n strings for en/vi/zh
2026-03-11 14:22:03 +07:00
viettranx 344e2ac7d1 feat(i18n): add full i18n support for backend and web UI
- Add i18next + react-i18next with namespace-split locale files (27 namespaces x 3 languages)
- Add language switcher in topbar (EN/VI/ZH) with localStorage persistence
- Replace hardcoded strings in 160+ React components with t() translations
- Add Go message catalog (internal/i18n) with T(locale, key, args...) function
- Replace 81 hardcoded error strings in gateway methods and HTTP handlers
- Add locale context propagation: WS connect param + HTTP Accept-Language header
- Keep technical terms in English: Agent, Session, Channel, Provider, Skill, Team, MCP, Cron
- Update CLAUDE.md and review-pr skill with i18n compliance checks
2026-03-09 22:22:42 +07:00
viettranx 63eff188ad feat(kg): add knowledge graph with LLM extraction, traversal, and graph visualization
- KnowledgeGraphStore interface + PostgreSQL implementation (recursive CTE traversal, 5s timeout)
- LLM entity extraction pipeline triggered on memory writes (background goroutine)
- knowledge_graph_search agent tool with search + traversal modes
- HTTP API: CRUD entities, traverse, extract, stats, graph endpoints
- Web UI: KG tab on memory page with table/graph toggle, entity detail, manual extraction
- Force-directed graph visualization using @xyflow/react + d3-force
- Builtin tool seed with configurable provider/model/confidence settings
2026-03-09 17:11:20 +07:00
viettranx 157d09c021 feat(ui): sortable provider chain with drag-and-drop and portal combobox
Replace simple JSON settings modal with sortable provider chain cards for
media tools. Each card supports provider/model selection, timeout, retries,
and typed provider-specific params via schema.

- Add @dnd-kit/core + @dnd-kit/sortable for drag-and-drop reordering
- New media-provider-chain-form.tsx: sortable card list with DnD
- New media-provider-params-schema.ts: typed params per tool x provider_type
- Combobox: add portalContainer prop to escape dialog overflow clipping
- Title Case formatting for dialog titles
2026-03-08 20:10:20 +07:00
viettranx 85e7198f6b feat(skills): add syntax highlighting, CSV tables, responsive layout
- Add highlight.js with tree-shaken language imports for code viewer
- Add CSV file rendering as styled table with sticky headers
- Add resizable file tree panel with drag handle
- Add mobile stacked layout with back navigation
- Strip frontmatter from .md files in file viewer
- Add responsive dialog breakpoints (sm/md/lg/xl/2xl)
- Split skill-detail-dialog into 4 focused modules (<200 lines each)
- Add highlight.js CSS with dark mode overrides
2026-03-08 10:47:42 +07:00
viettranxandClaude Opus 4.6 813c602bca feat(ui): migrate to TanStack Query, add server-side pagination, and improve error handling
- Add @tanstack/react-query with shared cache and centralized query keys
- Migrate all 14 CRUD hooks from manual useState/useCallback to useQuery/useMutation
- Add WS event-driven query invalidation (sessions, traces auto-refresh on run completion)
- Consolidate LlmConfigSection to delegate provider/model UI to ProviderModelSelect
- Add server-side pagination for custom-tools and channel-instances (Go store + HTTP handler)
- Extract shared types into dedicated files (provider, custom-tool, mcp, channel, skill, trace)
- Add network error handling in HTTP client and connectivity check on login
- Add disconnect banner in app layout when gateway connection is lost

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:25:59 +07:00
viettranx 08ced252b2 feat: Introduce agent summoning flow with a dedicated modal and updated bootstrap process for predefined agents. 2026-02-24 10:19:49 +07:00
viettranx abaaf8fc83 feat: Implement dynamic model selection for agents using a new backend API and a reusable combobox component. 2026-02-23 19:17:34 +07:00
Viet TranandClaude Opus 4.6 f3f4c67b36 Initial commit: GoClaw AI agent gateway
Multi-agent AI gateway with WebSocket RPC, HTTP API, and messaging channel integrations.
Go port of OpenClaw with multi-tenant PostgreSQL, per-user isolation, security hardening,
and production observability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 14:58:07 +07:00