Commit graph

1852 commits

Author SHA1 Message Date
Naiyuan Qing
030627c8c5 fix(web): prevent useWorkspaceId crash in AppSidebar before workspace hydration
AppSidebar renders outside the workspace guard in dashboard layout.
On first login, workspace hasn't hydrated yet → useWorkspaceId() throws.
Fix: read workspace?.id directly from store, use enabled guard on inbox query.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 18:39:32 +08:00
Naiyuan Qing
fe9479d6fc Merge remote-tracking branch 'origin/main' into feat/tanstack-query-migration
# Conflicts:
#	apps/web/features/issues/components/batch-action-toolbar.tsx
#	apps/web/features/issues/components/issues-page.tsx
#	apps/web/features/issues/store.ts
2026-04-07 18:39:13 +08:00
Naiyuan Qing
348133b63d merge: resolve conflicts with main (open_only pagination)
- Resolve issues/store.ts: keep client-only store, port pagination
  strategy (open_only + closed page) to core/issues/queries.ts
- Resolve issues-page.tsx, batch-action-toolbar.tsx: keep TQ mutations
- Auto-merge agents/page.tsx trigger null fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 18:08:35 +08:00
Naiyuan Qing
6032b5dfcb fix: mention closure, onSettled invalidation, cleanup singleton
- Fix Tiptap mention: pass QueryClient via closure from ContentEditor
  instead of getQueryClient() singleton (resolves @mention empty list)
- Add onSettled invalidation to useUpdateIssue (prevents cache drift
  with staleTime: Infinity + self-event WS filter)
- Add cache shape comment to issueListOptions (select transforms
  ListIssuesResponse → Issue[], but cache stores raw response)
- Memoize sidebar inbox dedup computation
- Remove dead getQueryClient/setQueryClient singleton + window property
- Remove ActorSync component and _members/_agents Zustand mirror
  (superseded by closure approach)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:53:49 +08:00
Bohan Jiang
23198f3c26
Merge pull request #461 from multica-ai/agent/j/70455bdb
fix(daemon): correct duplicate sub-step lettering in workflow instructions
2026-04-07 17:29:46 +08:00
Naiyuan Qing
e40341ab73 feat(core): migrate workspace + runtimes to TanStack Query (Phase 3+4)
- Create core/workspace/ with queries (members, agents, skills, list) and mutations
- Create core/runtimes/ with queries
- Migrate 11 consumer files from useWorkspaceStore.members/agents/skills to useQuery
- Replace all WS refreshMap entries with qc.invalidateQueries
- Simplify workspace store: delete members/agents/skills fields + refresh methods,
  hydrateWorkspace becomes synchronous (TQ auto-fetches on component mount)
- Delete useRuntimeStore (no consumers left), runtimes-page uses local useState + TQ
- Remove workspace→runtime cross-store dependency
- Clean up dead test helper mocks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:19:52 +08:00
Bohan Jiang
c695de5314
Merge pull request #468 from multica-ai/agent/j/272bc2a3
docs(web): add v0.1.8 changelog entry
2026-04-07 17:07:02 +08:00
Jiang Bohan
d6b59aade6 docs(web): add v0.1.8 changelog entry for 2026-04-07 2026-04-07 17:03:41 +08:00
Naiyuan Qing
1d812bd446 feat(core/inbox): migrate inbox to TanStack Query (Phase 2)
- Create core/inbox/ with queries, mutations, ws-updaters
- Migrate inbox page: useQuery + mutation hooks replace useInboxStore + api.*
- Migrate sidebar unread badge to read from TQ cache
- Delete useInboxStore (127 lines) — inbox has no client-only state
- Remove inbox deps from workspace store (hydrate + switch)
- Fix WS sync: use useQueryClient() instead of getQueryClient() singleton
  to ensure WS handlers write to the same QueryClient instance that
  components read from (singleton is unreliable under Next.js HMR)
- Add onInboxIssueStatusChanged for issue status sync in inbox items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:56:47 +08:00
devv-eve
abcc7bf3cd
feat(issues): load all open issues without limit, paginate closed (#459)
- Add ListOpenIssues SQL query (excludes done/cancelled, no LIMIT)
- Add CountIssues SQL query for true total count
- Backend: support open_only=true param, fix total to return real count
- Frontend: two-phase fetch in issue store (all open + first 50 closed)
- Add fetchMoreClosed action for paginated closed issue loading
- Replace all hardcoded limit:200 with store.fetch() calls

Resolves MUL-369

Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 00:59:03 -07:00
Naiyuan Qing
06fa65d4b5 test(issues): clean up dead useIssueStore mocks from tests
Remove mock issues[] and server state fields from useIssueStore mocks
since the store now only holds activeIssueId. Data flows through
TanStack Query (mockListIssues) not the store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:52:15 +08:00
Bohan Jiang
9d1570b301
Merge pull request #465 from multica-ai/agent/j/ffea36be
fix(auth): move Google callback to correct route path
2026-04-07 15:48:30 +08:00
Jiang Bohan
7f2ea9857d fix(auth): move Google callback page to correct route path
The callback page was placed under app/(auth)/callback/ — a Next.js
route group — which mapped to /callback instead of /auth/callback.
Move it to app/auth/callback/ so the URL matches the Google OAuth
redirect URI.
2026-04-07 15:47:44 +08:00
Naiyuan Qing
1ad057fb0f refactor(issues): migrate all consumers to TanStack Query (Phase 1, Commits 5-10)
- Migrate issue-detail.tsx: useQuery for issue data, useUpdateIssue/useDeleteIssue
- Migrate issues-page.tsx, my-issues-page.tsx, board-card.tsx: useQuery for list
- Migrate batch-action-toolbar.tsx, create-issue.tsx: mutation hooks
- Migrate edge consumers: mention-suggestion, mention-view, agents page, issue-mention-card
- Remove Zustand writes from WS sync (TQ cache is now sole source of truth)
- Remove useIssueStore.fetch() dependency from workspace store
- Gut useIssueStore to client-only: { activeIssueId, setActiveIssue }
- Update test wrappers with QueryClientProvider

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:46:08 +08:00
Bohan Jiang
b85c068e83
Merge pull request #464 from multica-ai/agent/j/272bc2a3
docs(web): add v0.1.7 changelog entry
2026-04-07 15:37:23 +08:00
Jiang Bohan
30cda933bc docs(web): add v0.1.7 changelog entry for 2026-04-05 2026-04-07 15:36:32 +08:00
Jiang Bohan
b5537077bc Merge branch 'main' of https://github.com/multica-ai/multica into agent/j/272bc2a3 2026-04-07 15:35:38 +08:00
Bohan Jiang
638033c9ff
Merge pull request #462 from multica-ai/agent/j/ffea36be
feat(auth): add Google OAuth login
2026-04-07 15:32:08 +08:00
Naiyuan Qing
7560f7be85 feat(core/issues): add TanStack Query layer and rewrite hooks (Phase 1, Commits 1-4)
- Add getQueryClient() singleton for non-React contexts (WS handlers, Zustand)
- Create issue query key factory + 5 queryOptions
- Create 11 mutation hooks with optimistic updates and rollback
- Create WS cache updaters + dual-write in use-realtime-sync
- Rewrite useIssueTimeline, useIssueReactions, useIssueSubscribers to TQ
  (return types unchanged, consumers unaffected)
- Add QueryClientProvider wrapper to issue detail tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:30:42 +08:00
Bohan Jiang
b84104b421
Merge pull request #463 from multica-ai/fix/agent-trigger-config-nullable-type
fix(types): make AgentTrigger.config nullable
2026-04-07 15:27:11 +08:00
Jiang Bohan
0c92fb2674 fix(types): make AgentTrigger.config nullable to match API reality
The API can return `config: null` for non-scheduled triggers, but the
type was `Record<string, unknown>` which doesn't reflect this. Update
to `Record<string, unknown> | null` so TypeScript catches unsafe access
at compile time.

Follow-up to #415.
2026-04-07 15:25:29 +08:00
Jiang Bohan
14fe8e9df9 feat(auth): add Google OAuth login
Support Google login that links to existing accounts by email.
When a user who registered via email OTP signs in with Google using
the same email, they are linked to the same account.

Backend:
- Add POST /auth/google endpoint that exchanges Google auth code for
  tokens, fetches user profile, and calls findOrCreateUser()
- Updates user name and avatar from Google profile on first Google login

Frontend:
- Add "Continue with Google" button on login page (shown when
  NEXT_PUBLIC_GOOGLE_CLIENT_ID is configured)
- Add /auth/callback page to handle Google OAuth redirect
- Add loginWithGoogle to auth store and API client
2026-04-07 15:25:26 +08:00
Bohan Jiang
f9c0fcba24
Merge pull request #415 from cocovs/codex/fix-agent-trigger-null-config-crash
fix(web): prevent Agents trigger crash when config is null
2026-04-07 15:24:15 +08:00
Jiang Bohan
47917825d1 fix(daemon): correct duplicate sub-step lettering in workflow instructions
When repos are present, sub-steps c/d/e/f are now distinct instead of
having two 'c' steps. Each branch (with/without repos) now has its own
complete set of correctly lettered sub-steps.
2026-04-07 15:22:02 +08:00
Bohan Jiang
eab5f8e7e8
Merge pull request #457 from multica-ai/agent/j/4420d1bf
fix(daemon): ensure multica CLI is on PATH in agent task environment
2026-04-07 15:03:56 +08:00
Jiang Bohan
9495179923 fix(daemon): ensure multica CLI is on PATH in agent task environment
Prepend the directory of the running multica binary to PATH in the
agent's environment variables. This fixes the issue where isolated
runtimes (e.g. Codex sandbox) cannot find the multica CLI, causing
agent tasks to fail immediately with "command not found: multica".

Closes #451
2026-04-07 15:01:48 +08:00
Bohan Jiang
f16b36fbc8
Merge pull request #456 from multica-ai/agent/j/25583cc6
feat(agent): add OpenClaw runtime support
2026-04-07 14:53:53 +08:00
Jiang Bohan
dd2ce90b1d fix(agent): address openclaw review feedback
- Remove duplicate extractOCToolOutput, reuse extractToolOutput from opencode.go
- Rename extractEventText → openclawExtractText to avoid package-level name collisions
- Add clarifying comments for error status stickiness and result event behavior
- Remove redundant extractOCToolOutput tests (already covered by opencode tests)
2026-04-07 14:52:54 +08:00
Bohan Jiang
88b87e2fa6
Merge pull request #455 from multica-ai/agent/j/653cfab4
fix(triggers): remove assignee skip in on_mention trigger
2026-04-07 14:49:45 +08:00
Naiyuan Qing
2be9f6cd2f feat(web): add TanStack Query infrastructure (Phase 0)
- Install @tanstack/react-query v5 + devtools
- Create core/query-client.ts with WS-optimized defaults (staleTime: Infinity)
- Create QueryProvider and wire into root layout
- Add @core/* path alias to tsconfig + vitest
- Add useWorkspaceId() bridge hook for query key scoping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:43:51 +08:00
Jiang Bohan
5cf4ba803d feat(agent): add OpenClaw runtime support
Add OpenClaw as a fourth supported agent runtime alongside Claude Code,
Codex, and OpenCode. OpenClaw CLI (`openclaw agent -p ... --output-format
stream-json`) is integrated via the same Backend interface pattern.

Changes:
- Add openclawBackend in server/pkg/agent/openclaw.go with NDJSON
  event stream parsing (text, thinking, tool_call, error, step, result)
- Register "openclaw" in the agent factory (agent.go)
- Add MULTICA_OPENCLAW_PATH / MULTICA_OPENCLAW_MODEL env var detection
  in daemon config
- Include "openclaw" in AGENTS.md config injection alongside codex/opencode
- Add comprehensive unit tests for all event handlers and processEvents
2026-04-07 14:40:51 +08:00
Jiang Bohan
cfb0365cb3 fix(triggers): remove assignee skip in enqueueMentionedAgentTasks
The assignee check in enqueueMentionedAgentTasks silently skipped
explicit @mentions when the target agent was the issue assignee in
a non-terminal status. This broke the review-rejection-retry loop:
when a reviewer rejected a PR and @mentioned the developer agent,
the mention was skipped because the developer was the assignee.

The downstream HasPendingTaskForIssueAndAgent check already prevents
duplicate queued tasks, making the assignee skip redundant. Removing
it ensures explicit @mentions always fire regardless of assignee status.

Closes #431
2026-04-07 14:36:08 +08:00
devv-eve
81d430d870
Merge pull request #445 from sunjie21/main
fix(auth): extend JWT and CloudFront cookie expiration from 72h to 30 days
2026-04-06 23:34:15 -07:00
Bohan Jiang
96d81f9836
Merge pull request #454 from multica-ai/agent/j/ea6693b0
fix(daemon): add missing CLI commands to agent instructions
2026-04-07 14:23:24 +08:00
Naiyuan Qing
5fe1ec806d docs: add TanStack Query migration plan
Phase 0-5 plan for migrating server state from Zustand to TanStack Query,
extracting headless business logic to core/ directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:20:43 +08:00
Bohan Jiang
2f63714dba
Merge pull request #410 from jtsang4/main
fix(build): include migrate binary in make build
2026-04-07 14:18:57 +08:00
Bohan Jiang
4cf18e122d
Merge pull request #413 from cocovs/codex/fix-daemon-pid-minus1
fix(cli): preserve daemon pid before releasing child process
2026-04-07 14:18:12 +08:00
Jiang Bohan
02a7598906 fix(daemon): add missing CLI commands to agent instructions
Add 5 missing commands to buildMetaSkillContent() so agents can
discover them:

Read:
- workspace members — query member IDs for mentions
- repo checkout — listed in command reference, not just prose

Write:
- issue create — create sub-issues and new tasks
- issue assign — assign/unassign issues
- issue comment delete — remove erroneous comments
2026-04-07 14:13:26 +08:00
Junlong
0263ecce9e
Docs: fix self hosting local deploy protocol (#433)
* fix: skip Docker check in ensure-postgres.sh when remote DATABASE_URL is set

When DATABASE_URL points to a non-localhost host, the script now skips
all Docker operations and only verifies remote DB connectivity via
pg_isready directly.

* fix: honor DATABASE_URL for remote postgres preflight

* fix(make): clarify stop output for remote database

* docs: add local deployment protocol guidance to SELF_HOSTING.md

Clarify that local deployments without TLS should use http:// and ws://
instead of https:// and wss://.

---------

Co-authored-by: Junlong Liu <junlong.liu@shopee.com>
2026-04-07 14:08:06 +08:00
yihong
d450b3d454
fix: run make test command (#449)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
2026-04-07 13:52:52 +08:00
Bohan Jiang
f1140222a1
Merge pull request #441 from quake/docs/cli-install-guide
docs: add CLI_INSTALL.md for agent-driven setup and update READMEs
2026-04-07 13:50:06 +08:00
诺墨
66067a267a
fix(makefile): binary build missing for migration (#447)
Signed-off-by: 诺墨 <normal@normalcoder.com>
2026-04-07 13:47:05 +08:00
Bohan Jiang
76c6b41033
Merge pull request #453 from multica-ai/agent/j/4c35cc35
docs: add PR template
2026-04-07 13:32:38 +08:00
Jiang Bohan
29507a2e3a docs: add AI prompt field to PR template
Encourage contributors to share the prompt they used when AI tools
were involved, helping reviewers understand intent and enabling
knowledge sharing across the community.
2026-04-07 13:30:54 +08:00
Jiang Bohan
ceec6d3795 docs: add PR template
Adds a structured PR template requiring change description, motivation,
type classification, test plan, and an optional AI disclosure field.
Part of the Phase 1 community management improvements (MUL-320).
2026-04-07 13:23:17 +08:00
Naiyuan Qing
08ba74b399
Merge pull request #309 from multica-ai/agent/lambda/83f444ab
fix(web): navigate to /issues when switching workspaces
2026-04-07 10:30:14 +08:00
Naiyuan Qing
ed7a288946 fix(web): prevent 404 on workspace switch and downgrade 404 log level
- Skip issue refetch when store is cleared during workspace switch by
  tracking which issue was already loaded (loadedIdRef pattern)
- Downgrade 404 responses from logger.error to logger.warn in ApiClient
  since resource-not-found is a normal business response, not a bug

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:26:53 +08:00
Naiyuan Qing
a26f9e965b
Merge pull request #448 from multica-ai/refactor/agent-live-card-sticky
refactor(web): redesign agent live card sticky behavior
2026-04-07 09:55:08 +08:00
Naiyuan Qing
6574d68d2b refactor(web): redesign agent live card — always sticky with manual toggle
Replace the oscillation-prone IntersectionObserver/sentinel pattern with
a simpler always-sticky collapsible card. The card defaults to collapsed
(mini bar) and users toggle it manually. Outer scroll auto-collapses the
timeline to stay out of the way, with scroll-chaining prevention via
overscroll-behavior-y: contain.

Key changes:
- Remove sentinel, IntersectionObserver, and bidirectional isStuck state
- Always sticky at top-4 with unified info color scheme
- Manual toggle via clickable header with grid-rows animation
- Auto-collapse on outer scroll (one-way, prevents oscillation)
- Consolidate three task-end handlers into single handleTaskEnd
- Add hover interaction (muted-foreground → foreground)
- Add aria-expanded for accessibility

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 09:47:02 +08:00
sunjie21
3bf094ebf7 fix(auth): extend JWT and CloudFront cookie expiration from 72h to 30 days
Reduces login frequency for users by increasing token lifetime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 21:48:31 +08:00