Squashed history of PR #4892 (pr-4784-fix). Makes spaces the primary
navigation and working surface, on the "associations bind at creation
time only" model.
Model
- Issue <-> space is the only enforced ownership (per-space numbering).
Parent/child and project<->space associations only seed defaults at
creation; cross-space/child and project-association validations are
removed.
- Moving an issue renumbers it and records the old identifier in
issue_identifier_alias; API/CLI lookups and GitHub branch/PR
auto-linking fall back to the alias, so old identifiers resolve forever.
- Membership drives only the sidebar and personal defaults — never
access. Anyone can configure any space's member set wholesale
(PUT /api/spaces/{id}/members); saving an empty set archives the
space behind a confirm.
- Per-user space order (workspace_space_member.sort_order, fractional):
drag-sorted sidebar, "my first space" is the personal issue-creation
default; the workspace default space backs headless creation
(agents/CLI/Slack) and system placement.
Surfaces
- Sidebar: joined-spaces section (drag reorder, row -> space page,
per-group persisted collapse), Workspace group with a More menu,
Settings demoted to a footer icon.
- /space/:key/{issues,projects,autopilots,settings} — space surfaces
reuse shared page components; a routed /space/new create page
(replacing the earlier create-space modal), reserved key "NEW" so it
can never collide with a real space's /space/:key detail page.
- Issue detail moves to /issue/:id (identifier-first, Linear-style; old
/issues/:id redirects); create dialogs lead with a required space pill.
- Agent runtime brief now carries Space context (id/key/name) through
the daemon claim -> TaskContextForEnv -> prompt pipeline, with a
"## Space Context" section and --space on issue create/update in both
brief renderers, matching Project's existing treatment.
- zh-Hans: Space translated to 空间 across locales and conventions.zh.mdx.
Fixes along the way
- Cache membership judgment gains the space dimension + space_changed
WS flag.
- Silent skip on default-space lookup during invite acceptance is now a
hard failure (no space-less members).
- Backfilled space_id into ~28 raw-SQL Go test fixtures across
internal/handler and cmd/server that predated migration 132's NOT
NULL cutover.
- Fixed a resolve-loop bug in the IssueDetail identifier wrapper (mount/
unmount cycle on resolution failure) and gave it its own loading
skeleton instead of a blank screen while resolving.
- reserved-slugs generator's stale hardcoded doc-comment example synced
back to /create-space.
Verification
- go build ./..., go vet ./..., go test ./... all clean.
- pnpm typecheck (core/views/web/desktop) clean.
- packages/views: 162 files / 1656 tests passing.
- pnpm generate:reserved-slugs produces no diff.
Follow-ups tracked in docs/follow-ups/space-rollout.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix GitHub pull_request and check_suite webhook routing so events are attributed to the workspace that registered the repository, with fallback to the installation workspace. Includes host-qualified repo matching, account-gated registry routing, deterministic matching, and regression coverage.
Adds avatar_url column to workspace, threads it through the API +
WorkspaceAvatar component, and adds a click-to-upload editor in the
workspace settings tab. Mirrors the squad avatar pattern (migration 086);
UI strings use "logo" while the schema/code uses avatar_url for codebase
consistency with user.avatar_url and squad.avatar_url.
- migration 093: ALTER TABLE workspace ADD COLUMN avatar_url TEXT
- UpdateWorkspace SQL + handler accept avatar_url (auth gated to
owner/admin at the router via RequireWorkspaceRoleFromURL)
- WorkspaceAvatar renders <img> when avatar_url is set, falls back to
the initial-letter span otherwise
- workspace-tab.tsx adds a 16x16 click-to-upload logo editor at the
top of the general settings card, using useFileUpload + accept=
image/png,image/jpeg,image/webp (server stores under workspaces/{id}/)
- en + zh-Hans settings i18n strings added
Co-authored-by: Matt Voska <voska@users.noreply.github.com>
- Add migration 106: CREATE INDEX CONCURRENTLY on member(user_id, workspace_id)
- Rewrite ListWorkspaces to drive from member table with explicit fields
- Regenerate all sqlc code with v1.31.1 (intentional version upgrade)
Co-authored-by: multica-agent <github@multica.ai>
Add per-workspace auto-incrementing issue numbers with a configurable
prefix, producing identifiers like "JIA-1" instead of truncated UUIDs.
Database:
- Add issue_prefix and issue_counter to workspace table
- Add number column to issue table with UNIQUE(workspace_id, number)
- Backfill existing issues with sequential numbers
Backend:
- Issue creation atomically increments counter in a transaction
- API responses include number and identifier fields
- Support issue lookup by identifier format (KEY-N)
- Workspace prefix auto-generated from name, customizable via API
Frontend:
- Display identifier in list rows and issue detail breadcrumb
- Add issue_prefix to Workspace type, number/identifier to Issue type
Add a `repos` JSONB column to the workspace table for storing
associated repository URLs and descriptions. This enables the daemon
to clone repos and set up git worktrees for agent task execution.
Structure: [{"url": "https://github.com/org/repo", "description": "..."}]
- Migration 014: adds repos column with default '[]'
- UpdateWorkspace query: supports updating repos
- Workspace API: returns repos in GET, accepts in PUT
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
- 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>