Back to docs

Architecture

Technical architecture overview for contributors — services, message protocol, and build system.

Overview

Opentix is a VS Code extension with two runtime contexts:

  • Extension Host — Runs in VS Code's Node.js process. Has full access to the file system, Git, and the VS Code API.
  • Webview — Runs in an isolated browser context (iframe). Communicates with the host via a typed postMessage protocol.

These two contexts are strictly separated. The webview has no access to Node.js APIs, and the host does not import webview code.

Project Structure

src/
├── extension.ts              # Entry point (activate/deactivate)
├── commands/                 # VS Code command handlers
│   ├── create-ticket.ts
│   ├── init-project.ts
│   ├── open-board.ts
│   └── sync-tickets.ts
├── models/                   # TypeScript interfaces and types
│   ├── config.model.ts
│   ├── sprint.model.ts
│   └── ticket.model.ts
├── services/                 # Core business logic
│   ├── ai.service.ts
│   ├── branch-watcher.service.ts
│   ├── git.service.ts
│   ├── index.service.ts
│   ├── sprint.service.ts
│   ├── sync.service.ts
│   ├── ticket.service.ts
│   └── watcher.service.ts
├── utils/                    # Pure utility functions
│   ├── agents-template.ts
│   ├── branch-utils.ts
│   ├── constants.ts
│   ├── id-generator.ts
│   └── markdown.ts
└── webview/                  # Webview UI code
    ├── kanban-view-provider.ts # Host-side webview manager
    └── kanban/               # Browser-side code
        ├── app.ts            # Main app (state, render, events)
        ├── bridge.ts         # Typed message protocol
        ├── index.html        # HTML template
        └── styles/
            ├── board.css
            └── theme.css

Service Dependency Graph

Services are instantiated in extension.ts and receive dependencies via constructor injection.

extension.ts (Entry Point)
├── GitService
├── TicketService (← GitService)
├── IndexService (← TicketService, GitService)
├── SyncService (← GitService, IndexService)
├── WatcherService (← GitService, IndexService)
├── SprintService (← GitService, TicketService)
├── AIService (← TicketService, IndexService)
├── BranchWatcherService (← GitService)
└── KanbanViewProvider (← TicketService, IndexService,
                          SyncService, SprintService, GitService)

Service Responsibilities

ServiceResponsibility
GitServiceGit operations, worktree management, team member registry, commit/push
TicketServiceTicket CRUD — create, read, update, delete ticket files
IndexServiceMaintains index.json cache, file watching, emits change events
SyncServiceBackground pull/push on interval
WatcherServiceFile watcher wrapper — detects changes in the ticket directory
SprintServiceSprint CRUD, date validation, current sprint detection
AIServiceGenerates CURRENT_TICKET.md and ticket context JSON
BranchWatcherServiceWatches Git HEAD for branch changes, triggers AI context updates
KanbanViewProviderBridges the webview and services, routes messages

Message Protocol

Communication between the extension host and webview uses typed messages defined in src/webview/kanban/bridge.ts.

Host → Webview

MessagePurpose
updateBoardFull board state (tickets grouped by status)
ticketDetailSingle ticket details for the detail panel
syncStatusCurrent sync state (syncing, synced, error)
configConfiguration data (statuses list)
sprintConfigSprint list and current sprint ID
teamMembersTeam member list and current user identity

Webview → Host

MessagePurpose
readyWebview loaded and ready to receive data
createTicketRequest to create a new ticket
moveTicketDrag-and-drop status change
openTicketRequest ticket details
updateTicketEdit ticket fields
deleteTicketDelete a ticket
addCommentAdd a comment to a ticket
syncTrigger manual sync
createSprintCreate a new sprint or break
updateSprintUpdate sprint name or dates
deleteSprintDelete a sprint

Build System

Opentix uses esbuild with two separate build targets configured in esbuild.config.mjs:

TargetFormatPlatformEntryOutput
Extension HostCommonJSNodesrc/extension.tsdist/extension.js
WebviewIIFEBrowsersrc/webview/kanban/app.tsdist/webview/kanban.js

The vscode module is marked as external — it is provided by VS Code at runtime and not bundled.

Source maps are enabled for both targets to support debugging.

Testing

TypeLocationRunnerCoverage
Unit teststest/unit/VitestUtilities, parsing, ID generation, sprint logic
Integration teststest/integration/vscode-test-electronVS Code API interactions
Fixturestest/fixtures/Sample ticket files for tests

Conventions

  • Services: Classes in *.service.ts, constructor injection, Disposable pattern
  • Commands: Async functions in their own files, receive services as parameters
  • Models: Interfaces in *.model.ts, no behavior
  • Utils: Pure functions, no side effects
  • Naming: kebab-case files, PascalCase classes, camelCase functions, UPPER_SNAKE_CASE constants

See the project's AGENTS.md for the full coding conventions reference.