Commit graph

49 commits

Author SHA1 Message Date
Naiyuan Qing
bc39abc6ed feat: inbox actor tracking, issue detail extraction, UI polish
- Add actor_type/actor_id to inbox items for proper attribution
- Extract issue detail into features/issues/components/issue-detail.tsx
- Inbox page and store updates for actor-based notifications
- Sidebar, layout, and actor-avatar refinements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 12:36:12 +08:00
Naiyuan Qing
655aa40732 feat: issue detail extraction, inbox enhancements, misc UI polish
- Extract IssueDetail into reusable component
- Inbox: add body/type fields, bulk actions, read state
- Pages: consistent layout patterns
- Workspace avatar, markdown, realtime sync improvements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:57:58 +08:00
Naiyuan Qing
8983a9fefa feat(logging): add structured logging across server and SDK
Replace raw fmt/log calls with structured slog logger (Go) and
console-based logger (TypeScript). Add request logging middleware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:57:11 +08:00
yushen
a5aedf5dfe fix(test): gracefully skip DB tests when database is unreachable
pgxpool.New is lazy and doesn't connect immediately. Add pool.Ping()
after creation so CI environments without PostgreSQL skip cleanly
instead of failing with os.Exit(1).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:44:36 +08:00
LinYushen
04997b4011
Merge pull request #254 from multica-ai/feat/homebrew-release
feat(release): add GoReleaser config and Homebrew tap support
2026-03-25 17:39:07 +08:00
yushen
3b3d2c48b9 refactor(release): rename multica-cli to multica
Rename the binary and all references from multica-cli to multica for a
cleaner command-line experience.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:34:29 +08:00
Naiyuan Qing
97fa09156d fix(test): register event bus listeners in integration test setup
TestWebSocketIntegration was timing out because registerListeners()
was never called — events published via bus had no listeners, so
WS broadcasts never happened.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:19:58 +08:00
Naiyuan Qing
0a5dd068b1 fix(test): add sleep after WS connect for Hub register timing
The Hub processes client registration asynchronously via a channel.
Without a short delay, the issue creation can fire before the client
is added to the workspace room, so the broadcast has no recipients.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:15:23 +08:00
Naiyuan Qing
77141cf0a7 fix(test): use correct var name testToken (not testAuthToken)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:06:50 +08:00
Naiyuan Qing
ae6abc2fc2 fix(test): pass JWT token and workspace_id in WS integration test
HandleWebSocket now requires auth — update test to include
token and workspace_id query params in the WebSocket URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:00:59 +08:00
Naiyuan Qing
a5a5febdf6 fix(test): events.NewBus → events.New (correct function name)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:54:18 +08:00
Naiyuan Qing
fc3dc39b82 fix(test): update tests for event bus + room-based Hub signatures
- integration_test: pass events.Bus to NewRouter
- handler_test: pass events.Bus to handler.New
- hub_test: add mock MembershipChecker, JWT token generation,
  replace hub.clients with totalClients() helper for room-based Hub

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:49:45 +08:00
Naiyuan Qing
06122dfe9e merge: resolve conflicts with main (skills feature)
Merge origin/main which added the skills system (structured skills
with meta skill runtime injection). Resolve 4 conflicts:

- workspace/store.ts: keep both skills state + issue/inbox fetch
- types/index.ts: keep Skill types + our event exports
- handler/agent.go: merge visibility filtering + skills batch loading
- pnpm-lock.yaml: accept main's lockfile with skills deps

Also fix skill.go: migrate h.broadcast → h.publish (event bus)
to match our architecture where all WS events go through the bus.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:43:21 +08:00
Naiyuan Qing
b0b4c1c31a chore: remove server binary from tracking
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:37:27 +08:00
Naiyuan Qing
66b1defab7 refactor: migrate stores to features/, remove dead packages, add modals + workspace sync
## Store migration (packages → features)
- Delete `packages/store/` — stores moved into web app's feature modules
- Delete `packages/hooks/` — replaced by feature-level hooks
- `features/issues/store.ts` — useIssueStore (was packages/store/issue-store)
- `features/inbox/store.ts` — useInboxStore (was packages/store/inbox-store)
- `features/workspace/store.ts` — absorbs agent state (was packages/store/agent-store)
- All imports updated from `@multica/store` → `@/features/*/store`

## Global modal system
- `features/modals/store.ts` — useModalStore (zustand)
- `features/modals/registry.tsx` — ModalRegistry renders active modal
- Mounted in app/layout.tsx alongside Toaster
- Create Workspace dialog now works (was broken: DropdownMenu ate click)

## Workspace real-time sync
- useRealtimeSync subscribes to workspace:updated, member:removed
- Member removal → auto-switch to another workspace
- Workspace settings update → sidebar reflects name change
- Workspace switch → parallel fetch issues + inbox + agents

## Bug fixes
- theme-provider: guard event.key for IME composition (isComposing check)
- task.go: publish comment:created + inbox:new events on task complete/fail
- listeners.go: broadcast comment:created, workspace:updated, member events
- events.go: add EventCommentUpdated, EventCommentDeleted constants

## Cleanup
- Remove _features/ tracking files (dev-only, not for main)
- Remove server/server binary from worktree
- Update CLAUDE.md to reflect new architecture

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:37:22 +08:00
Jiayuan Zhang
42aef6e13e fix: address review issues in skills system
- Fix authorization bypass in DeleteSkillFile (missing workspace/role check)
- Extract skills page into features/skills/ module (thin route shell)
- Fix skill files disappearing after save (use API return values + merge in refreshSkills)
- Fix silently swallowed DB errors in ListAgents/GetAgent skill queries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:37:08 +08:00
Jiayuan Zhang
fb709ff143 fix(test): remove skills column from integration test fixtures
Migration 008 drops agent.skills column, so test fixtures inserting
into the agent table must no longer reference it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:27:50 +08:00
Jiayuan Zhang
02df33803a feat: structured skills system with meta skill runtime injection
Replace agent.skills TEXT field with structured skill/skill_file/agent_skill
tables. Skills are workspace-level entities with supporting files, reusable
across agents via many-to-many bindings.

Backend: migration 008, sqlc queries, CRUD handler, agent-skill junction,
structured skill loading in task context snapshot.

Daemon: meta skill injection via runtime-native config (.claude/CLAUDE.md
for Claude, AGENTS.md for Codex) so agents discover .agent_context/ skills
through their native mechanism. Lean prompt without inlined skill content.

Frontend: Skills management page, agent Skills tab picker, SDK methods,
TypeScript types, workspace store integration.

Also removes auto-creation of init issues when creating agents.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:17:59 +08:00
Jiayuan Zhang
678266ec87 feat(daemon): add per-task isolated execution environments
Introduce the `execenv` package that creates isolated working directories
for each agent task. Supports git worktree mode (code tasks) and plain
directory mode (non-code tasks), with `.agent_context/issue_context.md`
injected into the workdir for Claude Code to discover.

Key changes:
- New `server/internal/daemon/execenv/` package (Prepare/Cleanup)
- `runTask()` now creates isolated env instead of using shared reposRoot
- Prompt updated to reference `.agent_context/` files
- Add `WorkspacesRoot` config (default ~/multica_workspaces)
- Add `KeepEnvAfterTask` config for debugging
- Default agent timeout increased from 20min to 2h
- `CompleteTask` now forwards branch name to server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 12:41:52 +08:00
Naiyuan Qing
0c52b89e40 fix: code review — WS sync bug, Hub race condition, error feedback
- Fix useRealtimeSync never receiving WSClient (useRef → useState for
  re-render trigger, keeping ref for lazy subscribe callback)
- Fix Hub.Run() global broadcast mutating map under RLock (same
  two-phase collect+cleanup pattern as BroadcastToWorkspace)
- Move visibleStatuses to module-level constant (prevent useCallback
  recreation every render)
- Replace console.error with toast.error for user-facing operations
  in issues page and inbox page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:37:23 +08:00
Naiyuan Qing
759dd741bd refactor(server): extract inbox creation to bus listeners, add agent visibility filtering
- Move all CreateInboxItem calls from handlers to centralized inbox_listeners.go
- Enrich issue:updated payload with change context (assignee_changed, status_changed, prev values)
- Enrich comment:created payload with issue context (assignee info)
- Bus listeners handle: issue assign, unassign, reassign, status change, comment notification
- ListAgents filters private agents: only visible to owner_id or workspace admin
- Zero CreateInboxItem calls remain in handler package

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:24:45 +08:00
Naiyuan Qing
3f71957608 feat(inbox): notification triggers, unread badge, archive UI, View Issue link
- Add GET /api/inbox/unread-count endpoint
- Comment on assigned issue notifies assignee (type: mentioned)
- Status change notifies creator in addition to assignee
- Reassignment notifies old assignee (Unassigned from: ...)
- Fix SDK return types: markInboxRead/archiveInbox return InboxItem
- Add getUnreadInboxCount() to SDK
- Sidebar shows unread inbox badge from store (real-time via WS)
- Inbox detail: View Issue link + Archive button
- Fix IssueAssigneeType in create issue dialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:00:07 +08:00
Naiyuan Qing
0ea9c38071 fix(workspace): permission enforcement, invite auto-create, switch clears stores
- DeleteAgent: require owner/admin role (was member-only check)
- ListAgentTasks: add workspace membership verification (was unauthenticated)
- CreateMember: auto-create user if email not found (enables invite flow)
- Workspace switch: clear issue/inbox/agent stores before hydrating new data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:46:53 +08:00
Naiyuan Qing
2c02aa357d fix(issues): board polish — blocked column, drag fix, comment perms, task cleanup
- Add "blocked" to STATUS_ORDER/ALL_STATUSES and board visible columns
- Add min-h-[200px] to droppable columns for reliable empty-column drops
- Fix card click-vs-drag conflict with pointer-events-none on Link
- List view uses STATUS_ORDER from config instead of hardcoded order
- Create Issue dialog: add AssigneePicker for assigning on creation
- Issue detail page syncs from global useIssueStore for real-time updates
- Comment UpdateComment/DeleteComment: add author-or-admin permission check
- DeleteIssue: cancel running agent tasks before deletion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:32:25 +08:00
Naiyuan Qing
9127e543d5 feat: add event bus, WS workspace isolation, and global store migration
- Add internal event bus (server/internal/events/) with synchronous
  pub/sub and panic isolation per listener
- Upgrade WebSocket Hub to workspace-scoped rooms with JWT auth
  and membership verification on connect
- Add 10 new WS event types (comment CRUD, inbox read/archive,
  agent create/delete, workspace/member events)
- Refactor all handlers and TaskService to publish events via Bus
  instead of direct Hub.Broadcast calls
- Add WS broadcast listener that routes events to correct workspace
- Frontend: WSClient sends token + workspace_id on connect with
  auto-reconnect refetch
- Frontend: centralized useRealtimeSync hook dispatches all WS
  events to global Zustand stores
- Migrate issues and inbox pages from local useState to global
  useIssueStore/useInboxStore
- Make store addIssue/addItem idempotent to prevent duplicates
- Remove dead packages/hooks/src/use-realtime.ts
- Add feature tracking files for 4 planned features

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:08:27 +08:00
Jiayuan Zhang
e86768823e refactor: remove repository field from issues
The repository JSONB column on the issue table is unused. This removes
it end-to-end: migration to drop the column, sqlc queries, Go handler/
service/daemon/protocol structs, TypeScript types, and the
RepositoryEditor UI component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:12:06 +08:00
yushen
0b7de54052 Merge remote-tracking branch 'origin/main' into feature/multi-agent-backend
Resolve conflicts:
- CLAUDE.md: merge feature-based frontend docs from main with comprehensive
  architecture docs from HEAD
- Makefile: merge .PHONY targets from both branches
- settings/page.tsx: keep Context field using main's Label component
- auth-context.test.tsx: accept main's deletion (moved to features/auth/)
- cmd/daemon/daemon.go: accept HEAD's deletion (moved to internal/daemon/)
- daemon/client.go: port requestError type and isWorkspaceNotFoundError from
  main's old daemon into the new internal/daemon package

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:53:24 +08:00
yushen
de0a983674 fix(server): remove debug logging and add error handling from review
- Remove debug log.Printf calls from handler/daemon.go and service/task.go
  that used the global log package instead of structured logging
- Remove unused truncate() helper from service/task.go
- Add error handling for EnqueueTaskForIssue in createAgentInitIssue
- Clean up verbose debug logging in daemon/daemon.go handleTask
- Add shutdown sequence comment to codex.go lifecycle goroutine

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:48:01 +08:00
yushen
a9bf22955d chore(daemon): add debug logging for task lifecycle troubleshooting
Add structured logging at key points in the task completion flow:
- Daemon: log result details before sending to server, log claim cycles
- Handler: log incoming CompleteTask requests
- TaskService: log each step of CompleteTask (DB update, issue status
  sync, comment creation, payload parsing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:38:06 +08:00
yushen
994242d2db feat(agent): auto-create init issue on agent creation with workspace context
When a new agent is created, automatically create an initialization issue
assigned to it so the agent starts working immediately. The issue
description incorporates the workspace context field, giving the agent
background info to set up its environment (clone repos, etc.).

Also adds workspace context to the task context snapshot for all tasks,
and renders it in the daemon prompt so agents always have workspace
background when executing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:38:00 +08:00
yushen
828b75c76d fix(daemon): resolve codex app-server deadlock after turn completion
The codex backend spawns a long-running app-server process that doesn't
exit after completing a turn. The lifecycle goroutine was waiting on
<-readerDone which blocks on scanner.Scan() until stdout closes — but
stdout never closes because the process stays alive. This caused the
entire poll loop to freeze, preventing any further task processing.

Fix: explicitly close stdin and cancel the context after the turn
completes, which terminates the codex process and unblocks the reader.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:37:52 +08:00
yushen
680668ffdb feat(workspace): add context field for AI agent background info
Add a `context` text field to workspaces, allowing users to provide
background information and context for AI agents working in the
workspace. Full stack: migration, sqlc queries, Go handler, TS types,
SDK, and settings page UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:59:11 +08:00
yushen
3293607bef fix(cli): address code review findings
1. Add Client.SendHeartbeat/Register methods — no more direct postJSON calls
2. Use url.Values for query params to prevent URL injection
3. Unexport helpers (envOrDefault, durationFromEnv, sleepWithContext)
4. CLI resolveWorkspaceID falls back to daemon.json
5. Implement agent stop (PUT /api/agents/{id} with status=offline)
6. Add --output flag to agent get for consistent UX
7. Add server/multica to .gitignore for stray builds
8. Inject version/commit via -ldflags in Makefile build target

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:49:32 +08:00
yushen
707b5ac6e7 refactor(cli): unify daemon into multica-cli binary with cobra subcommands
Extract daemon logic from cmd/daemon/ into internal/daemon/ package and
create a new unified CLI entry point at cmd/multica/ using cobra. The CLI
supports `daemon` as a long-running subcommand plus ctrl subcommands for
agent/runtime management, config, status, and version.

Server, migrate, and seed binaries remain unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:44:49 +08:00
Jiayuan Zhang
4c6eb81789 Provision default workspaces and harden daemon pairing 2026-03-24 15:19:27 +08:00
yushen
f2228e4f22 refactor(daemon): rename DefaultWorkdir to ReposRoot for clarity
MULTICA_AGENT_WORKDIR → MULTICA_REPOS_ROOT to make it clear this is
the parent directory containing all repos, not a single project workdir.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:36:09 +08:00
Jiayuan Zhang
2c28c4cba2 refactor(dev): share postgres across main and worktrees 2026-03-24 14:27:35 +08:00
yushen
96cfdc2e27 fix(agent): fix data races, add tests, and fix raw protocol detection
- Fix data race on output strings.Builder in codex backend by adding
  mutex and waiting for reader goroutine before reading final output
- Fix data race on onTurnDone by initializing it before reader starts
- Fix bug where notificationProtocol zero value "" never matched
  "unknown", silently dropping all raw v2 notifications from codex
- Add round-robin polling to prevent runtime starvation in poll loop
- Log errors in claude handleControlRequest instead of silently dropping
- Add 35 tests for pkg/agent covering claude parsing, codex JSON-RPC,
  protocol detection, event handling, and helper functions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:21:10 +08:00
yushen
0d9b687d92 fix(agent): address code review feedback
- Replace deprecated strings.Title with manual capitalize
- Fix race: set codexClient.onMessage before starting reader goroutine
- Remove unused msgCh parameter from codexClient.handleLine
- Route agent stderr through logger instead of dumping to os.Stderr
- Use deterministic agent order in ensurePaired (prefer codex)
- Increase message channel buffer from 64 to 256
- Rename test to match function rename (buildPrompt)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:10:08 +08:00
yushen
bb45f17cf9 feat(daemon): unified agent SDK supporting Claude Code and Codex
Add a reusable Go agent package (server/pkg/agent/) that provides a
unified Backend interface for executing prompts via either Claude Code
or Codex. The daemon now auto-detects which CLIs are available at
startup, registers a runtime for each, and routes tasks to the correct
backend based on task.Context.Runtime.Provider.

Key changes:
- server/pkg/agent/agent.go: Backend interface, Message/Result types, factory
- server/pkg/agent/claude.go: Spawns claude CLI with stream-json, parses output
- server/pkg/agent/codex.go: Spawns codex app-server, JSON-RPC 2.0 protocol
- server/cmd/daemon/daemon.go: Multi-runtime registration, round-robin polling,
  provider-based backend selection. Removes old runCodexExec/codexResultSchema.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:05:03 +08:00
Jiayuan Zhang
cdfa63af15 feat(runtime): add local codex daemon pairing 2026-03-24 12:03:14 +08:00
Naiyuan Qing
cc2281416e feat(server): add comment CRUD endpoints and issue filter/update enhancements
- Add UpdateComment and DeleteComment handlers with /api/comments/{commentId} routes
- Add broadcast for comment create/update/delete WebSocket events
- Support status, priority, and assignee_id filters on ListIssues
- Extend UpdateIssue to handle due_date, acceptance_criteria, context_refs, repository
- Properly distinguish "field not sent" vs "field sent as null" in UpdateIssue
- Add corresponding SDK methods and TypeScript types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:15:09 +08:00
Jiayuan Zhang
5a3a72c411 feat(server): add task service layer and daemon REST protocol
- Extract TaskService (server/internal/service/task.go) for task lifecycle:
  enqueue with context snapshot, claim, start, complete, fail, progress
- Add daemon protocol endpoints under /api/daemon/:
  register, heartbeat, claim task, start/progress/complete/fail task
- Task ↔ Issue status sync: running→in_progress, completed→in_review, failed→blocked
- Agent status auto-management: reconcile idle/working based on running tasks
- Enforce max_concurrent_tasks on task claiming (FOR UPDATE SKIP LOCKED)
- Add UpdateIssueStatus query (fixes bug where UpdateIssue nulls assignee)
- Extract shared pgx utils to server/internal/util/ to avoid circular imports
- Migration 003: add context JSONB to agent_task_queue, daemon unique constraint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:34:51 +08:00
Jiayuan Zhang
b4303f9bec feat(agent): add agent management UI, skills/tools/triggers, and issue assignment
- Complete agents management page with create dialog, runtime device selector,
  skills/tools/triggers/tasks tabs, and agent detail view
- Add AssigneePicker to issue detail page for assigning to members or agents
- Extend agent types with description, skills, tools, triggers, RuntimeDevice
- Add SDK methods for agent CRUD and task listing
- Add migration 002 for agent config columns (skills, tools, triggers)
- Update seed data with realistic agent configurations
- Use auth context as single source of truth for agents (fixes state sync)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:31:25 +08:00
Jiayuan Zhang
81e64e9fce Add workspace management and isolated worktree environments 2026-03-23 18:12:11 +08:00
Jiayuan Zhang
b5b0605e9a chore: add one-click setup/start/stop scripts, migration CLI, and seed tool
- Add idempotent seed tool with duplicate detection for agents/issues/comments
- Add migration CLI supporting up/down with schema_migrations tracking
- Add Makefile targets: make setup (first-time), make start, make stop
- Update .gitignore for test artifacts and compiled binaries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 11:50:33 +08:00
Jiayuan Zhang
6dfc61fa86 test: add comprehensive test suite (Go unit/integration, Vitest, Playwright E2E)
- Add JWT middleware unit tests (8 tests covering all auth edge cases)
- Add WebSocket hub tests (5 tests for client lifecycle and broadcast)
- Add full HTTP integration tests (12 tests through real Chi router with DB)
- Add frontend component tests for login, issues, and issue detail pages
- Add auth context unit tests (9 tests for login/logout/name resolution)
- Add Playwright E2E tests for auth, issues, comments, and navigation
- Configure Vitest with jsdom, React plugin, and path aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 11:50:25 +08:00
Jiayuan Zhang
1e61c1974c feat(server): implement full REST API with JWT auth and real-time WebSocket
- Add HTTP handlers for issues, comments, agents, workspaces, inbox, members, and activity
- Implement JWT authentication middleware with Bearer token validation
- Add sqlc queries for all entities (CRUD operations)
- Extract router into reusable NewRouter() for testability
- Expand SDK with full API client methods (CRUD for all resources)
- Add updateWorkspace to SDK, add Member type to shared types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 11:50:03 +08:00
Jiayuan Zhang
d4f5c5b16f
feat: pivot to AI-native task management platform (#232)
Replace the agent framework codebase with a new monorepo structure
for an AI-native Linear-like product where agents are first-class citizens.

New architecture:
- server/ — Go backend (Chi + gorilla/websocket + sqlc)
  - API server with REST routes for issues, agents, inbox, workspaces
  - WebSocket hub for real-time updates
  - Local daemon entry point for agent runtime connection
  - PostgreSQL migration with 13 tables (issue, agent, inbox, etc.)
  - WebSocket protocol types for server<->daemon communication
- apps/web/ — Next.js 16 frontend
  - Dashboard layout with sidebar navigation
  - Route skeleton: inbox, issues, agents, board, settings
- packages/ui/ — Preserved shadcn/ui design system (26+ components)
- packages/types/ — Full API contract types (Issue, Agent, Workspace, Inbox, Events)
- packages/sdk/ — REST ApiClient + WebSocket WSClient
- packages/store/ — Zustand stores (issue, agent, inbox, auth)
- packages/hooks/ — React hooks (useIssues, useAgents, useInbox, useRealtime)
- packages/utils/ — Shared utilities

Removed: apps/cli, apps/desktop, apps/mobile, apps/gateway,
packages/core, skills/, and all agent-framework code.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:55:49 +08:00