Projects Module
Purpose
- Handle project CRUD operations, settings management, and ticket prefix logic.
- Expose project-scoped APIs (agent profiles, GitHub import) while emitting lifecycle events for other domains.
Data & Event Flow
-
Project CRUD (
project.routes.ts+project.core.handlers.ts+core/projects/service.ts)createProjectsets up the board and emitsproject.created(consumed by tasks, filesystem, etc.).updateProjectemitsproject.updatedwith the delta.deleteProjectremoves the board and emitsproject.deleted(filesystem listener purges worktrees).
-
Project Settings (
project.settings.handlers.ts+core/projects/settings)ensureProjectSettings,updateProjectSettingslive in thecorepackage and manage branch/template defaults.- Settings updates emit
project.settings.updatedso other services can refresh caches. - GitHub Issue Sync settings (
githubIssueSyncEnabled,githubIssueSyncState,githubIssueSyncIntervalMinutes,githubIssueAutoCreateEnabled) are validated viaproject.schemas.tsand persisted alongside the existing flags, with metadata columns (lastGithubIssueSyncAt,lastGithubIssueSyncStatus) tracked incore/projects/settings/github-sync.ts. - Scheduled sync ticks from
server/src/github/sync.tsconsult these values, callgithub/import.service.ts, and update the metadata to avoid overlapping runs. autoCloseTicketOnPRMergetoggles the newserver/src/github/pr-auto-close.sync.tsscheduler, which moves Review cards with merged PR URLs to Done (unless the card explicitly setsdisableAutoCloseOnPRMerge) and emitsgithub.pr.merged.autoClosed.
-
Agent Profiles (
project.agents.routes.ts+project.agents.handlers.ts+core/agents/profiles)- CRUD endpoints emit
agent.profile.changedto keep UI caches synced.
- CRUD endpoints emit
-
Boards, Cards & Attempts (
board.routes.ts+board.*.handlers.ts)/projects/:projectId/board/*and/boards/:boardId/*provide board state, card CRUD/move, attempts, GitHub imports, and/boards/:boardId/github/issues/statsexposes lightweight linked issue counts (imported,exported,total).- Card images are supported via:
POST /boards/:boardId/cardsaccepts optionalimagesarray (base64-encoded PNG/JPEG/WebP, max 5 images, 10MB each).GET /boards/:boardId/cards/:cardId/imagesreturns{ images: MessageImage[] }for existing attachments.
- Image persistence uses
CardImagesRepo(getCardImages,setCardImages,deleteCardImages) with storage in thecard_imagestable.
-
GitHub Imports & exports
/projects/:projectId/board/import/github/issues(and/boards/:boardId/import/github/issues) callgithub/import.service.ts, which emitsgithub.issues.importedafter completion.- When
githubIssueAutoCreateEnabledis true and a ticket is created withcreateGithubIssue,createCardHandlerroutes throughgithub/export.service.ts#createGithubIssueForCard, stores the exported mapping, and surface any error information back to the client so the UI can show a toast while the card itself still succeeds.
Key Entry Points
core/projects/service.ts: abstraction around project records (imported by the server adapter).project.routes.ts: project-scoped Hono routes (CRUD, settings, ticket keys, agents, attempts).board.routes.ts: board-scoped Hono routes (board state, cards, attempts, imports).project.schemas.ts: shared Zod schemas for project and board payloads.core/projects/settings/service.ts: per-project settings primitives.
Ticket Enhancement Endpoint
POST /projects/:projectId/tickets/enhance- Request (JSON):
{ "title": string, "description"?: string, "agent"?: string, "profileId"?: string } - Response
200:{ "ticket": { "title": string, "description": string } } - Errors: returns RFC 7807-style problem JSON with
4xx/5xxstatus codes for project/agent failures.
- Request (JSON):
Open Tasks
- Move event emission out of routes and into service layer for reusability/testing.
- Add listeners reacting to
project.settings.updated(e.g., branch template refresh). - Provide tests for project lifecycle events and settings updates.